Index: sys/amd64/include/vmm.h =================================================================== --- sys/amd64/include/vmm.h +++ sys/amd64/include/vmm.h @@ -281,6 +281,10 @@ return (*info->iptr); } +#ifdef INVARIANTS +struct mtx *vcpu_mtx(struct vm *vm, int vcpuid); +#endif + /* * Return 1 if device indicated by bus/slot/func is supposed to be a * pci passthrough device. @@ -301,6 +305,17 @@ int vcpu_set_state(struct vm *vm, int vcpu, enum vcpu_state state, bool from_idle); enum vcpu_state vcpu_get_state(struct vm *vm, int vcpu, int *hostcpu); +enum vcpu_state vcpu_get_state_locked(struct vm *vm, int vcpu, int *hostcpu); +enum vcpu_state vcpu_get_state_(struct vm *vm, int vcpu, int *hostcpu, int locked); + +static int __inline +vcpu_is_running_(struct vm *vm, int vcpu, int *hostcpu, int locked) +{ + if (locked) + return (vcpu_get_state_locked(vm, vcpu, hostcpu) == VCPU_RUNNING); + else + return (vcpu_get_state(vm, vcpu, hostcpu) == VCPU_RUNNING); +} static int __inline vcpu_is_running(struct vm *vm, int vcpu, int *hostcpu) Index: sys/amd64/vmm/intel/vmx.c =================================================================== --- sys/amd64/vmm/intel/vmx.c +++ sys/amd64/vmm/intel/vmx.c @@ -2946,12 +2946,12 @@ } static int -vmx_getreg(void *arg, int vcpu, int reg, uint64_t *retval) +vmx_getreg_(void *arg, int vcpu, int reg, uint64_t *retval, int locked) { int running, hostcpu; struct vmx *vmx = arg; - running = vcpu_is_running(vmx->vm, vcpu, &hostcpu); + running = vcpu_is_running_(vmx->vm, vcpu, &hostcpu, locked); if (running && hostcpu != curcpu) panic("vmx_getreg: %s%d is running", vm_name(vmx->vm), vcpu); @@ -2964,6 +2964,18 @@ return (vmcs_getreg(&vmx->vmcs[vcpu], running, reg, retval)); } +static int +vmx_getreg(void *arg, int vcpu, int reg, uint64_t *retval) +{ + return (vmx_getreg_(arg, vcpu, reg, retval, 0)); +} + +static int +vmx_getreg_locked(void *arg, int vcpu, int reg, uint64_t *retval) +{ + return (vmx_getreg_(arg, vcpu, reg, retval, 1)); +} + static int vmx_setreg(void *arg, int vcpu, int reg, uint64_t val) { @@ -3242,12 +3254,17 @@ static int vmx_pending_intr(struct vlapic *vlapic, int *vecptr) { - struct vlapic_vtx *vlapic_vtx; struct pir_desc *pir_desc; struct LAPIC *lapic; uint64_t pending, pirval; uint32_t ppr, vpr; int i; + struct vlapic_vtx *vlapic_vtx = (struct vlapic_vtx *)vlapic; +#ifdef INVARIANTS + struct mtx *m = vcpu_mtx(vlapic_vtx->vmx->vm, vlapic->vcpuid); + + mtx_assert(m, MA_OWNED); +#endif /* * This function is only expected to be called from the 'HLT' exit @@ -3255,7 +3272,6 @@ */ KASSERT(vecptr == NULL, ("vmx_pending_intr: vecptr must be NULL")); - vlapic_vtx = (struct vlapic_vtx *)vlapic; pir_desc = vlapic_vtx->pir_desc; pending = atomic_load_acq_long(&pir_desc->pending); @@ -3270,7 +3286,7 @@ uint64_t val; uint8_t rvi, ppr; - vmx_getreg(vlapic_vtx->vmx, vlapic->vcpuid, + vmx_getreg_locked(vlapic_vtx->vmx, vlapic->vcpuid, VMCS_IDENT(VMCS_GUEST_INTR_STATUS), &val); rvi = val & APIC_TPR_INT; lapic = vlapic->apic_page; Index: sys/amd64/vmm/vmm.c =================================================================== --- sys/amd64/vmm/vmm.c +++ sys/amd64/vmm/vmm.c @@ -307,6 +307,14 @@ return (trace_guest_exceptions); } +#ifdef INVARIANTS +struct mtx * +vcpu_mtx(struct vm *vm, int vcpuid) +{ + return &(vm->vcpu[vcpuid].mtx); +} +#endif + struct vm_exit * vm_exitinfo(struct vm *vm, int cpuid) { @@ -2309,7 +2317,7 @@ } enum vcpu_state -vcpu_get_state(struct vm *vm, int vcpuid, int *hostcpu) +vcpu_get_state_(struct vm *vm, int vcpuid, int *hostcpu, int locked) { struct vcpu *vcpu; enum vcpu_state state; @@ -2319,15 +2327,29 @@ vcpu = &vm->vcpu[vcpuid]; - vcpu_lock(vcpu); + if (!locked) + vcpu_lock(vcpu); state = vcpu->state; if (hostcpu != NULL) *hostcpu = vcpu->hostcpu; - vcpu_unlock(vcpu); + if (!locked) + vcpu_unlock(vcpu); return (state); } +enum vcpu_state +vcpu_get_state(struct vm *vm, int vcpuid, int *hostcpu) +{ + return (vcpu_get_state_(vm, vcpuid, hostcpu, 0)); +} + +enum vcpu_state +vcpu_get_state_locked(struct vm *vm, int vcpuid, int *hostcpu) +{ + return (vcpu_get_state_(vm, vcpuid, hostcpu, 1)); +} + int vm_activate_cpu(struct vm *vm, int vcpuid) {