summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lib/libvmmapi/vmmapi.c11
-rw-r--r--lib/libvmmapi/vmmapi.h1
-rw-r--r--sys/amd64/include/vmm_dev.h3
-rw-r--r--sys/amd64/vmm/io/vioapic.c34
-rw-r--r--sys/amd64/vmm/io/vioapic.h1
-rw-r--r--sys/amd64/vmm/vmm_dev.c4
-rw-r--r--usr.sbin/bhyve/pci_emul.c12
-rw-r--r--usr.sbin/bhyve/pci_emul.h1
-rw-r--r--usr.sbin/bhyve/pci_lpc.c11
-rw-r--r--usr.sbin/bhyve/pit_8254.c3
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
OpenPOWER on IntegriCloud