diff --git a/sys/amd64/vmm/intel/vmcs.c b/sys/amd64/vmm/intel/vmcs.c index 1ddefe0d6833..cc97d9516613 100644 --- a/sys/amd64/vmm/intel/vmcs.c +++ b/sys/amd64/vmm/intel/vmcs.c @@ -231,7 +231,7 @@ vmcs_setreg(struct vmcs *vmcs, int running, int ident, uint64_t val) } int -vmcs_setdesc(struct vmcs *vmcs, int seg, struct seg_desc *desc) +vmcs_setdesc(struct vmcs *vmcs, int running, int seg, struct seg_desc *desc) { int error; uint32_t base, limit, access; @@ -240,7 +240,8 @@ vmcs_setdesc(struct vmcs *vmcs, int seg, struct seg_desc *desc) if (error != 0) panic("vmcs_setdesc: invalid segment register %d", seg); - VMPTRLD(vmcs); + if (!running) + VMPTRLD(vmcs); if ((error = vmwrite(base, desc->base)) != 0) goto done; @@ -252,12 +253,13 @@ vmcs_setdesc(struct vmcs *vmcs, int seg, struct seg_desc *desc) goto done; } done: - VMCLEAR(vmcs); + if (!running) + VMCLEAR(vmcs); return (error); } int -vmcs_getdesc(struct vmcs *vmcs, int seg, struct seg_desc *desc) +vmcs_getdesc(struct vmcs *vmcs, int running, int seg, struct seg_desc *desc) { int error; uint32_t base, limit, access; @@ -267,7 +269,8 @@ vmcs_getdesc(struct vmcs *vmcs, int seg, struct seg_desc *desc) if (error != 0) panic("vmcs_getdesc: invalid segment register %d", seg); - VMPTRLD(vmcs); + if (!running) + VMPTRLD(vmcs); if ((error = vmread(base, &u64)) != 0) goto done; desc->base = u64; @@ -282,7 +285,8 @@ vmcs_getdesc(struct vmcs *vmcs, int seg, struct seg_desc *desc) desc->access = u64; } done: - VMCLEAR(vmcs); + if (!running) + VMCLEAR(vmcs); return (error); } diff --git a/sys/amd64/vmm/intel/vmcs.h b/sys/amd64/vmm/intel/vmcs.h index 9cde99903f5f..657d5b0f65cb 100644 --- a/sys/amd64/vmm/intel/vmcs.h +++ b/sys/amd64/vmm/intel/vmcs.h @@ -49,9 +49,9 @@ int vmcs_set_msr_save(struct vmcs *vmcs, u_long g_area, u_int g_count); int vmcs_init(struct vmcs *vmcs); int vmcs_getreg(struct vmcs *vmcs, int running, int ident, uint64_t *rv); int vmcs_setreg(struct vmcs *vmcs, int running, int ident, uint64_t val); -int vmcs_getdesc(struct vmcs *vmcs, int ident, +int vmcs_getdesc(struct vmcs *vmcs, int running, int ident, struct seg_desc *desc); -int vmcs_setdesc(struct vmcs *vmcs, int ident, +int vmcs_setdesc(struct vmcs *vmcs, int running, int ident, struct seg_desc *desc); static __inline uint64_t diff --git a/sys/amd64/vmm/intel/vmx.c b/sys/amd64/vmm/intel/vmx.c index 9f4e799e9822..51f6615eaa7e 100644 --- a/sys/amd64/vmm/intel/vmx.c +++ b/sys/amd64/vmm/intel/vmx.c @@ -2409,17 +2409,27 @@ vmx_setreg(void *arg, int vcpu, int reg, uint64_t val) static int vmx_getdesc(void *arg, int vcpu, int reg, struct seg_desc *desc) { + int hostcpu, running; struct vmx *vmx = arg; - return (vmcs_getdesc(&vmx->vmcs[vcpu], reg, desc)); + running = vcpu_is_running(vmx->vm, vcpu, &hostcpu); + if (running && hostcpu != curcpu) + panic("vmx_getdesc: %s%d is running", vm_name(vmx->vm), vcpu); + + return (vmcs_getdesc(&vmx->vmcs[vcpu], running, reg, desc)); } static int vmx_setdesc(void *arg, int vcpu, int reg, struct seg_desc *desc) { + int hostcpu, running; struct vmx *vmx = arg; - return (vmcs_setdesc(&vmx->vmcs[vcpu], reg, desc)); + running = vcpu_is_running(vmx->vm, vcpu, &hostcpu); + if (running && hostcpu != curcpu) + panic("vmx_setdesc: %s%d is running", vm_name(vmx->vm), vcpu); + + return (vmcs_setdesc(&vmx->vmcs[vcpu], running, reg, desc)); } static int