diff options
-rw-r--r-- | sys/amd64/vmm/intel/vmx.c | 24 | ||||
-rw-r--r-- | sys/amd64/vmm/io/vatpic.c | 3 | ||||
-rw-r--r-- | sys/amd64/vmm/vmm_dev.c | 2 |
3 files changed, 22 insertions, 7 deletions
diff --git a/sys/amd64/vmm/intel/vmx.c b/sys/amd64/vmm/intel/vmx.c index 31fff50..2e1d144 100644 --- a/sys/amd64/vmm/intel/vmx.c +++ b/sys/amd64/vmm/intel/vmx.c @@ -2755,6 +2755,7 @@ vmx_inject_pir(struct vlapic *vlapic) } pirval = 0; + pirbase = -1; lapic = vlapic->apic_page; val = atomic_readandclear_long(&pir_desc->pir[0]); @@ -2788,16 +2789,29 @@ vmx_inject_pir(struct vlapic *vlapic) pirbase = 192; pirval = val; } - if (pirbase == -1) { - VCPU_CTR0(vlapic->vm, vlapic->vcpuid, "vmx_inject_pir: " - "no posted interrupt found"); - return; - } + VLAPIC_CTR_IRR(vlapic, "vmx_inject_pir"); /* * Update RVI so the processor can evaluate pending virtual * interrupts on VM-entry. + * + * It is possible for pirval to be 0 here, even though the + * pending bit has been set. The scenario is: + * CPU-Y is sending a posted interrupt to CPU-X, which + * is running a guest and processing posted interrupts in h/w. + * CPU-X will eventually exit and the state seen in s/w is + * the pending bit set, but no PIR bits set. + * + * CPU-X CPU-Y + * (vm running) (host running) + * rx posted interrupt + * CLEAR pending bit + * SET PIR bit + * READ/CLEAR PIR bits + * SET pending bit + * (vm exit) + * pending bit set, PIR 0 */ if (pirval != 0) { rvi = pirbase + flsl(pirval) - 1; diff --git a/sys/amd64/vmm/io/vatpic.c b/sys/amd64/vmm/io/vatpic.c index f6e84c1..bc05722 100644 --- a/sys/amd64/vmm/io/vatpic.c +++ b/sys/amd64/vmm/io/vatpic.c @@ -473,9 +473,10 @@ vatpic_master_handler(void *vm, int vcpuid, struct vm_exit *vmexit) { struct vatpic *vatpic; struct atpic *atpic; - int error = 0;; + int error; uint8_t val; + error = 0; vatpic = vm_atpic(vm); atpic = &vatpic->atpic[0]; diff --git a/sys/amd64/vmm/vmm_dev.c b/sys/amd64/vmm/vmm_dev.c index 0797a13..37d841d 100644 --- a/sys/amd64/vmm/vmm_dev.c +++ b/sys/amd64/vmm/vmm_dev.c @@ -171,6 +171,7 @@ vmmdev_ioctl(struct cdev *cdev, u_long cmd, caddr_t data, int fflag, if (sc == NULL) return (ENXIO); + error = 0; vcpu = -1; state_changed = 0; @@ -231,7 +232,6 @@ vmmdev_ioctl(struct cdev *cdev, u_long cmd, caddr_t data, int fflag, break; default: - error = EINVAL; break; } |