Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix non-deterministic delays when accessing a vcpu in "running" or "s… #81

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 18 additions & 7 deletions include/xhyve/vmm/vmm.h
Original file line number Diff line number Diff line change
Expand Up @@ -62,12 +62,18 @@ struct vm_object;
struct vm_guest_paging;
struct pmap;

struct vm_eventinfo {
void *rptr; /* rendezvous cookie */
int *sptr; /* suspend cookie */
int *iptr; /* reqidle cookie */
};

typedef int (*vmm_init_func_t)(void);
typedef int (*vmm_cleanup_func_t)(void);
typedef void *(*vmi_vm_init_func_t)(struct vm *vm);
typedef int (*vmi_vcpu_init_func_t)(void *vmi, int vcpu);
typedef int (*vmi_run_func_t)(void *vmi, int vcpu, register_t rip,
void *rendezvous_cookie, void *suspend_cookie);
struct vm_eventinfo *info);
typedef void (*vmi_vm_cleanup_func_t)(void *vmi);
typedef void (*vmi_vcpu_cleanup_func_t)(void *vmi, int vcpu);
typedef int (*vmi_get_register_t)(void *vmi, int vcpu, int num,
Expand Down Expand Up @@ -145,6 +151,7 @@ int vm_activate_cpu(struct vm *vm, int vcpu);
struct vm_exit *vm_exitinfo(struct vm *vm, int vcpuid);
void vm_exit_suspended(struct vm *vm, int vcpuid, uint64_t rip);
void vm_exit_rendezvous(struct vm *vm, int vcpuid, uint64_t rip);
void vm_exit_reqidle(struct vm *vm, int vcpuid, uint64_t rip);

/*
* Rendezvous all vcpus specified in 'dest' and execute 'func(arg)'.
Expand All @@ -167,17 +174,21 @@ cpuset_t vm_active_cpus(struct vm *vm);
cpuset_t vm_suspended_cpus(struct vm *vm);

static __inline int
vcpu_rendezvous_pending(void *rendezvous_cookie)
vcpu_rendezvous_pending(struct vm_eventinfo *info)
{

return (*(uintptr_t *)rendezvous_cookie != 0);
return (*((uintptr_t *)(info->rptr)) != 0);
}

static __inline int
vcpu_suspended(void *suspend_cookie)
vcpu_suspended(struct vm_eventinfo *info)
{
return (*info->sptr);
}

return (*(int *)suspend_cookie);
static __inline int
vcpu_reqidle(struct vm_eventinfo *info)
{
return (*info->iptr);
}

enum vcpu_state {
Expand Down Expand Up @@ -256,7 +267,7 @@ struct vm_copyinfo {
/*
* Set up 'copyinfo[]' to copy to/from guest linear address space starting
* at 'gla' and 'len' bytes long. The 'prot' should be set to PROT_READ for
* a copyin or PROT_WRITE for a copyout.
* a copyin or PROT_WRITE for a copyout.
*
* retval is_fault Intepretation
* 0 0 Success
Expand Down
1 change: 1 addition & 0 deletions include/xhyve/vmm/vmm_common.h
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,7 @@ enum vm_exitcode {
VM_EXITCODE_INOUT,
VM_EXITCODE_VMX,
VM_EXITCODE_BOGUS,
VM_EXITCODE_REQIDLE,
VM_EXITCODE_RDMSR,
VM_EXITCODE_WRMSR,
VM_EXITCODE_HLT,
Expand Down
20 changes: 10 additions & 10 deletions include/xhyve/vmm/vmm_ktr.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,32 +41,32 @@ struct vm;
extern const char *vm_name(struct vm *vm);

#define VCPU_CTR0(vm, vcpuid, format) \
vmmtrace("vm %s[%d]: " format "\n", vm_name((vm)), (vcpuid))
vmmtrace("vm %s[%d]: " format "\r\n", vm_name((vm)), (vcpuid))

#define VCPU_CTR1(vm, vcpuid, format, p1) \
vmmtrace("vm %s[%d]: " format "\n", vm_name((vm)), (vcpuid), (p1))
vmmtrace("vm %s[%d]: " format "\r\n", vm_name((vm)), (vcpuid), (p1))

#define VCPU_CTR2(vm, vcpuid, format, p1, p2) \
vmmtrace("vm %s[%d]: " format "\n", vm_name((vm)), (vcpuid), (p1), (p2))
vmmtrace("vm %s[%d]: " format "\r\n", vm_name((vm)), (vcpuid), (p1), (p2))

#define VCPU_CTR3(vm, vcpuid, format, p1, p2, p3) \
vmmtrace("vm %s[%d]: " format "\n", vm_name((vm)), (vcpuid), (p1), (p2), (p3))
vmmtrace("vm %s[%d]: " format "\r\n", vm_name((vm)), (vcpuid), (p1), (p2), (p3))

#define VCPU_CTR4(vm, vcpuid, format, p1, p2, p3, p4) \
vmmtrace("vm %s[%d]: " format "\n", vm_name((vm)), (vcpuid), \
vmmtrace("vm %s[%d]: " format "\r\n", vm_name((vm)), (vcpuid), \
(p1), (p2), (p3), (p4))

#define VM_CTR0(vm, format) \
vmmtrace("vm %s: " format "\n", vm_name((vm)))
vmmtrace("vm %s: " format "\r\n", vm_name((vm)))

#define VM_CTR1(vm, format, p1) \
vmmtrace("vm %s: " format "\n", vm_name((vm)), (p1))
vmmtrace("vm %s: " format "\r\n", vm_name((vm)), (p1))

#define VM_CTR2(vm, format, p1, p2) \
vmmtrace("vm %s: " format "\n", vm_name((vm)), (p1), (p2))
vmmtrace("vm %s: " format "\r\n", vm_name((vm)), (p1), (p2))

#define VM_CTR3(vm, format, p1, p2, p3) \
vmmtrace("vm %s: " format "\n", vm_name((vm)), (p1), (p2), (p3))
vmmtrace("vm %s: " format "\r\n", vm_name((vm)), (p1), (p2), (p3))

#define VM_CTR4(vm, format, p1, p2, p3, p4) \
vmmtrace("vm %s: " format "\n", vm_name((vm)), (p1), (p2), (p3), (p4))
vmmtrace("vm %s: " format "\r\n", vm_name((vm)), (p1), (p2), (p3), (p4))
7 changes: 4 additions & 3 deletions include/xhyve/vmm/vmm_stat.h
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ vmm_stat_array_incr(struct vm *vm, int vcpu, struct vmm_stat_type *vst,
{
#ifdef XHYVE_CONFIG_STATS
uint64_t *stats;

stats = vcpu_stats(vm, vcpu);

if (vst->index >= 0 && statidx < vst->nelems)
Expand All @@ -121,7 +121,7 @@ vmm_stat_array_set(struct vm *vm, int vcpu, struct vmm_stat_type *vst,
{
#ifdef XHYVE_CONFIG_STATS
uint64_t *stats;

stats = vcpu_stats(vm, vcpu);

if (vst->index >= 0 && statidx < vst->nelems)
Expand All @@ -134,7 +134,7 @@ vmm_stat_array_set(struct vm *vm, int vcpu, struct vmm_stat_type *vst,
(void) val;
#endif
}

static void __inline
vmm_stat_incr(struct vm *vm, int vcpu, struct vmm_stat_type *vst, uint64_t x)
{
Expand Down Expand Up @@ -183,3 +183,4 @@ VMM_STAT_DECLARE(VMEXIT_ASTPENDING);
VMM_STAT_DECLARE(VMEXIT_USERSPACE);
VMM_STAT_DECLARE(VMEXIT_RENDEZVOUS);
VMM_STAT_DECLARE(VMEXIT_EXCEPTION);
VMM_STAT_DECLARE(VMEXIT_REQIDLE);
20 changes: 12 additions & 8 deletions src/vmm/intel/vmx.c
Original file line number Diff line number Diff line change
Expand Up @@ -415,7 +415,7 @@ exit_reason_to_str(int reason)

// for (i = 0; i < 8; i++)
// error += guest_msr_ro(vmx, MSR_APIC_TMR0 + i);

// for (i = 0; i < 8; i++)
// error += guest_msr_ro(vmx, MSR_APIC_IRR0 + i);

Expand Down Expand Up @@ -670,7 +670,7 @@ vmx_handle_cpuid(struct vm *vm, int vcpuid)
{
uint32_t eax, ebx, ecx, edx;
int error;

eax = (uint32_t) reg_read(vcpuid, HV_X86_RAX);
ebx = (uint32_t) reg_read(vcpuid, HV_X86_RBX);
ecx = (uint32_t) reg_read(vcpuid, HV_X86_RCX);
Expand Down Expand Up @@ -2129,8 +2129,7 @@ vmx_exit_process(struct vmx *vmx, int vcpu, struct vm_exit *vmexit)
}

static int
vmx_run(void *arg, int vcpu, register_t rip, void *rendezvous_cookie,
void *suspend_cookie)
vmx_run(void *arg, int vcpu, register_t rip, struct vm_eventinfo *evinfo)
{
int handled;
struct vmx *vmx;
Expand Down Expand Up @@ -2161,16 +2160,21 @@ vmx_run(void *arg, int vcpu, register_t rip, void *rendezvous_cookie,
* vmx_inject_interrupts() can suspend the vcpu due to a
* triple fault.
*/
if (vcpu_suspended(suspend_cookie)) {
if (vcpu_suspended(evinfo)) {
vm_exit_suspended(vmx->vm, vcpu, ((uint64_t) rip));
break;
}

if (vcpu_rendezvous_pending(rendezvous_cookie)) {
if (vcpu_rendezvous_pending(evinfo)) {
vm_exit_rendezvous(vmx->vm, vcpu, ((uint64_t) rip));
break;
}

if (vcpu_reqidle(evinfo)) {
vm_exit_reqidle(vmx->vm, vcpu, ((uint64_t) rip));
break;
}

vmx_run_trace(vmx, vcpu);
hvr = hv_vcpu_run((hv_vcpuid_t) vcpu);
/* Collect some information for VM exit processing */
Expand Down Expand Up @@ -2382,7 +2386,7 @@ vmx_setreg(void *arg, int vcpu, int reg, uint64_t val)
if (shadow > 0) {
/*
* Store the unmodified value in the shadow
*/
*/
error = vmcs_setreg(vcpu, VMCS_IDENT(shadow), val);
}

Expand Down Expand Up @@ -2698,7 +2702,7 @@ vmx_vlapic_init(void *arg, int vcpuid)
struct vmx *vmx;
struct vlapic *vlapic;
struct vlapic_vtx *vlapic_vtx;

vmx = arg;

vlapic = malloc(sizeof(struct vlapic_vtx));
Expand Down
Loading