diff options
-rw-r--r-- | lib/libvmmapi/vmmapi.c | 11 | ||||
-rw-r--r-- | lib/libvmmapi/vmmapi.h | 1 | ||||
-rw-r--r-- | sys/amd64/include/vmm_dev.h | 3 | ||||
-rw-r--r-- | sys/amd64/vmm/io/vioapic.c | 34 | ||||
-rw-r--r-- | sys/amd64/vmm/io/vioapic.h | 1 | ||||
-rw-r--r-- | sys/amd64/vmm/vmm_dev.c | 4 | ||||
-rw-r--r-- | usr.sbin/bhyve/pci_emul.c | 12 | ||||
-rw-r--r-- | usr.sbin/bhyve/pci_emul.h | 1 | ||||
-rw-r--r-- | usr.sbin/bhyve/pci_lpc.c | 11 | ||||
-rw-r--r-- | usr.sbin/bhyve/pit_8254.c | 3 |
10 files changed, 67 insertions, 14 deletions
diff --git a/lib/libvmmapi/vmmapi.c b/lib/libvmmapi/vmmapi.c index 5ece80b..85b1069 100644 --- a/lib/libvmmapi/vmmapi.c +++ b/lib/libvmmapi/vmmapi.c @@ -419,6 +419,17 @@ vm_ioapic_deassert_irq(struct vmctx *ctx, int irq) } int +vm_ioapic_pulse_irq(struct vmctx *ctx, int irq) +{ + struct vm_ioapic_irq ioapic_irq; + + bzero(&ioapic_irq, sizeof(struct vm_ioapic_irq)); + ioapic_irq.irq = irq; + + return (ioctl(ctx->fd, VM_IOAPIC_PULSE_IRQ, &ioapic_irq)); +} + +int vm_inject_nmi(struct vmctx *ctx, int vcpu) { struct vm_nmi vmnmi; diff --git a/lib/libvmmapi/vmmapi.h b/lib/libvmmapi/vmmapi.h index c9a2a09..8eaea29 100644 --- a/lib/libvmmapi/vmmapi.h +++ b/lib/libvmmapi/vmmapi.h @@ -69,6 +69,7 @@ int vm_inject_event2(struct vmctx *ctx, int vcpu, enum vm_event_type type, int vm_lapic_irq(struct vmctx *ctx, int vcpu, int vector); int vm_ioapic_assert_irq(struct vmctx *ctx, int irq); int vm_ioapic_deassert_irq(struct vmctx *ctx, int irq); +int vm_ioapic_pulse_irq(struct vmctx *ctx, int irq); int vm_inject_nmi(struct vmctx *ctx, int vcpu); int vm_capability_name2type(const char *capname); const char *vm_capability_type2name(int type); diff --git a/sys/amd64/include/vmm_dev.h b/sys/amd64/include/vmm_dev.h index 2adf50d..cd4332b 100644 --- a/sys/amd64/include/vmm_dev.h +++ b/sys/amd64/include/vmm_dev.h @@ -170,6 +170,7 @@ enum { IOCNUM_INJECT_NMI = 32, IOCNUM_IOAPIC_ASSERT_IRQ = 33, IOCNUM_IOAPIC_DEASSERT_IRQ = 34, + IOCNUM_IOAPIC_PULSE_IRQ = 35, /* PCI pass-thru */ IOCNUM_BIND_PPTDEV = 40, @@ -209,6 +210,8 @@ enum { _IOW('v', IOCNUM_IOAPIC_ASSERT_IRQ, struct vm_ioapic_irq) #define VM_IOAPIC_DEASSERT_IRQ \ _IOW('v', IOCNUM_IOAPIC_DEASSERT_IRQ, struct vm_ioapic_irq) +#define VM_IOAPIC_PULSE_IRQ \ + _IOW('v', IOCNUM_IOAPIC_PULSE_IRQ, struct vm_ioapic_irq) #define VM_SET_CAPABILITY \ _IOW('v', IOCNUM_SET_CAPABILITY, struct vm_capability) #define VM_GET_CAPABILITY \ diff --git a/sys/amd64/vmm/io/vioapic.c b/sys/amd64/vmm/io/vioapic.c index bc8485e..9ce8a5e 100644 --- a/sys/amd64/vmm/io/vioapic.c +++ b/sys/amd64/vmm/io/vioapic.c @@ -160,8 +160,14 @@ vioapic_set_pinstate(struct vioapic *vioapic, int pin, bool newstate) } } +enum irqstate { + IRQSTATE_ASSERT, + IRQSTATE_DEASSERT, + IRQSTATE_PULSE +}; + static int -vioapic_set_irqstate(struct vm *vm, int irq, bool state) +vioapic_set_irqstate(struct vm *vm, int irq, enum irqstate irqstate) { struct vioapic *vioapic; @@ -171,7 +177,20 @@ vioapic_set_irqstate(struct vm *vm, int irq, bool state) vioapic = vm_ioapic(vm); VIOAPIC_LOCK(vioapic); - vioapic_set_pinstate(vioapic, irq, state); + switch (irqstate) { + case IRQSTATE_ASSERT: + vioapic_set_pinstate(vioapic, irq, true); + break; + case IRQSTATE_DEASSERT: + vioapic_set_pinstate(vioapic, irq, false); + break; + case IRQSTATE_PULSE: + vioapic_set_pinstate(vioapic, irq, true); + vioapic_set_pinstate(vioapic, irq, false); + break; + default: + panic("vioapic_set_irqstate: invalid irqstate %d", irqstate); + } VIOAPIC_UNLOCK(vioapic); return (0); @@ -181,14 +200,21 @@ int vioapic_assert_irq(struct vm *vm, int irq) { - return (vioapic_set_irqstate(vm, irq, true)); + return (vioapic_set_irqstate(vm, irq, IRQSTATE_ASSERT)); } int vioapic_deassert_irq(struct vm *vm, int irq) { - return (vioapic_set_irqstate(vm, irq, false)); + return (vioapic_set_irqstate(vm, irq, IRQSTATE_DEASSERT)); +} + +int +vioapic_pulse_irq(struct vm *vm, int irq) +{ + + return (vioapic_set_irqstate(vm, irq, IRQSTATE_PULSE)); } static uint32_t diff --git a/sys/amd64/vmm/io/vioapic.h b/sys/amd64/vmm/io/vioapic.h index 54ad36a..3890250 100644 --- a/sys/amd64/vmm/io/vioapic.h +++ b/sys/amd64/vmm/io/vioapic.h @@ -41,6 +41,7 @@ void vioapic_cleanup(struct vioapic *vioapic); int vioapic_assert_irq(struct vm *vm, int irq); int vioapic_deassert_irq(struct vm *vm, int irq); +int vioapic_pulse_irq(struct vm *vm, int irq); int vioapic_mmio_write(void *vm, int vcpuid, uint64_t gpa, uint64_t wval, int size, void *arg); diff --git a/sys/amd64/vmm/vmm_dev.c b/sys/amd64/vmm/vmm_dev.c index a639ce9..500ef41 100644 --- a/sys/amd64/vmm/vmm_dev.c +++ b/sys/amd64/vmm/vmm_dev.c @@ -303,6 +303,10 @@ vmmdev_ioctl(struct cdev *cdev, u_long cmd, caddr_t data, int fflag, ioapic_irq = (struct vm_ioapic_irq *)data; error = vioapic_deassert_irq(sc->vm, ioapic_irq->irq); break; + case VM_IOAPIC_PULSE_IRQ: + ioapic_irq = (struct vm_ioapic_irq *)data; + error = vioapic_pulse_irq(sc->vm, ioapic_irq->irq); + break; case VM_MAP_MEMORY: seg = (struct vm_memory_segment *)data; error = vm_malloc(sc->vm, seg->gpa, seg->len); diff --git a/usr.sbin/bhyve/pci_emul.c b/usr.sbin/bhyve/pci_emul.c index fd087fa..c7086dd 100644 --- a/usr.sbin/bhyve/pci_emul.c +++ b/usr.sbin/bhyve/pci_emul.c @@ -1135,7 +1135,11 @@ pci_lintr_assert(struct pci_devinst *pi) { assert(pi->pi_lintr_pin >= 0); - vm_ioapic_assert_irq(pi->pi_vmctx, pi->pi_lintr_pin); + + if (pi->pi_lintr_state == 0) { + pi->pi_lintr_state = 1; + vm_ioapic_assert_irq(pi->pi_vmctx, pi->pi_lintr_pin); + } } void @@ -1143,7 +1147,11 @@ pci_lintr_deassert(struct pci_devinst *pi) { assert(pi->pi_lintr_pin >= 0); - vm_ioapic_deassert_irq(pi->pi_vmctx, pi->pi_lintr_pin); + + if (pi->pi_lintr_state == 1) { + pi->pi_lintr_state = 0; + vm_ioapic_deassert_irq(pi->pi_vmctx, pi->pi_lintr_pin); + } } /* diff --git a/usr.sbin/bhyve/pci_emul.h b/usr.sbin/bhyve/pci_emul.h index ebcf834..6a1d757 100644 --- a/usr.sbin/bhyve/pci_emul.h +++ b/usr.sbin/bhyve/pci_emul.h @@ -104,6 +104,7 @@ struct pci_devinst { struct vmctx *pi_vmctx; uint8_t pi_bus, pi_slot, pi_func; int8_t pi_lintr_pin; + int8_t pi_lintr_state; char pi_name[PI_NAMESZ]; int pi_bar_getsize; diff --git a/usr.sbin/bhyve/pci_lpc.c b/usr.sbin/bhyve/pci_lpc.c index 5dc79e0..4157c5c 100644 --- a/usr.sbin/bhyve/pci_lpc.c +++ b/usr.sbin/bhyve/pci_lpc.c @@ -94,17 +94,16 @@ lpc_uart_intr_assert(void *arg) assert(sc->irq >= 0); - vm_ioapic_assert_irq(lpc_bridge->pi_vmctx, sc->irq); + vm_ioapic_pulse_irq(lpc_bridge->pi_vmctx, sc->irq); } static void lpc_uart_intr_deassert(void *arg) { - struct lpc_uart_softc *sc = arg; - - assert(sc->irq >= 0); - - vm_ioapic_deassert_irq(lpc_bridge->pi_vmctx, sc->irq); + /* + * The COM devices on the LPC bus generate edge triggered interrupts, + * so nothing more to do here. + */ } static int diff --git a/usr.sbin/bhyve/pit_8254.c b/usr.sbin/bhyve/pit_8254.c index fd05b00..9ecb565 100644 --- a/usr.sbin/bhyve/pit_8254.c +++ b/usr.sbin/bhyve/pit_8254.c @@ -105,8 +105,7 @@ pit_mevent_cb(int fd, enum ev_type type, void *param) pit_mev_count++; - vm_ioapic_assert_irq(c->ctx, 2); - vm_ioapic_deassert_irq(c->ctx, 2); + vm_ioapic_pulse_irq(c->ctx, 2); /* * Delete the timer for one-shots |