diff --git a/devicemodel/arch/x86/pm.c b/devicemodel/arch/x86/pm.c index 37d3b875c..52fe2aea1 100644 --- a/devicemodel/arch/x86/pm.c +++ b/devicemodel/arch/x86/pm.c @@ -93,7 +93,7 @@ sci_assert(struct vmctx *ctx) { if (sci_active) return; - vm_isa_assert_irq(ctx, SCI_INT, SCI_INT); + vm_set_gsi_irq(ctx, SCI_INT, GSI_SET_HIGH); sci_active = 1; } @@ -102,7 +102,7 @@ sci_deassert(struct vmctx *ctx) { if (!sci_active) return; - vm_isa_deassert_irq(ctx, SCI_INT, SCI_INT); + vm_set_gsi_irq(ctx, SCI_INT, GSI_SET_LOW); sci_active = 0; } diff --git a/devicemodel/core/vmmapi.c b/devicemodel/core/vmmapi.c index a5bfa1f41..58cb1e37e 100644 --- a/devicemodel/core/vmmapi.c +++ b/devicemodel/core/vmmapi.c @@ -416,58 +416,15 @@ vm_lapic_msi(struct vmctx *ctx, uint64_t addr, uint64_t msg) } int -vm_ioapic_assert_irq(struct vmctx *ctx, int irq) +vm_set_gsi_irq(struct vmctx *ctx, int gsi, uint32_t operation) { - struct acrn_irqline ioapic_irq; + struct acrn_irqline_ops op; + uint64_t *req = (uint64_t *)&op; - bzero(&ioapic_irq, sizeof(ioapic_irq)); - ioapic_irq.intr_type = ACRN_INTR_TYPE_IOAPIC; - ioapic_irq.ioapic_irq = irq; + op.op = operation; + op.nr_gsi = (uint32_t)gsi; - return ioctl(ctx->fd, IC_ASSERT_IRQLINE, &ioapic_irq); -} - -int -vm_ioapic_deassert_irq(struct vmctx *ctx, int irq) -{ - struct acrn_irqline ioapic_irq; - - bzero(&ioapic_irq, sizeof(ioapic_irq)); - ioapic_irq.intr_type = ACRN_INTR_TYPE_IOAPIC; - ioapic_irq.ioapic_irq = irq; - - return ioctl(ctx->fd, IC_DEASSERT_IRQLINE, &ioapic_irq); -} - -static int -vm_isa_irq(struct vmctx *ctx, int irq, int ioapic_irq, unsigned long call_id) -{ - struct acrn_irqline isa_irq; - - bzero(&isa_irq, sizeof(isa_irq)); - isa_irq.intr_type = ACRN_INTR_TYPE_ISA; - isa_irq.pic_irq = irq; - isa_irq.ioapic_irq = ioapic_irq; - - return ioctl(ctx->fd, call_id, &isa_irq); -} - -int -vm_isa_assert_irq(struct vmctx *ctx, int atpic_irq, int ioapic_irq) -{ - return vm_isa_irq(ctx, atpic_irq, ioapic_irq, IC_ASSERT_IRQLINE); -} - -int -vm_isa_deassert_irq(struct vmctx *ctx, int atpic_irq, int ioapic_irq) -{ - return vm_isa_irq(ctx, atpic_irq, ioapic_irq, IC_DEASSERT_IRQLINE); -} - -int -vm_isa_pulse_irq(struct vmctx *ctx, int atpic_irq, int ioapic_irq) -{ - return vm_isa_irq(ctx, atpic_irq, ioapic_irq, IC_PULSE_IRQLINE); + return ioctl(ctx->fd, IC_SET_IRQLINE, *req); } int diff --git a/devicemodel/hw/pci/irq.c b/devicemodel/hw/pci/irq.c index 3fb8a5f35..1bc156a59 100644 --- a/devicemodel/hw/pci/irq.c +++ b/devicemodel/hw/pci/irq.c @@ -94,10 +94,10 @@ pirq_write(struct vmctx *ctx, int pin, uint8_t val) pthread_mutex_lock(&pirq->lock); if (pirq->reg != (val & (PIRQ_DIS | PIRQ_IRQ))) { if (pirq->active_count != 0 && pirq_valid_irq(pirq->reg)) - vm_isa_deassert_irq(ctx, pirq->reg & PIRQ_IRQ, -1); + vm_set_gsi_irq(ctx, pirq->reg & PIRQ_IRQ, GSI_SET_LOW); pirq->reg = val & (PIRQ_DIS | PIRQ_IRQ); if (pirq->active_count != 0 && pirq_valid_irq(pirq->reg)) - vm_isa_assert_irq(ctx, pirq->reg & PIRQ_IRQ, -1); + vm_set_gsi_irq(ctx, pirq->reg & PIRQ_IRQ, GSI_SET_HIGH); } pthread_mutex_unlock(&pirq->lock); } @@ -147,43 +147,13 @@ void pci_irq_deinit(struct vmctx *ctx) void pci_irq_assert(struct pci_vdev *dev) { - struct pirq *pirq; - - if (dev->lintr.pirq_pin > 0) { - assert(dev->lintr.pirq_pin <= nitems(pirqs)); - pirq = &pirqs[dev->lintr.pirq_pin - 1]; - pthread_mutex_lock(&pirq->lock); - pirq->active_count++; - if (pirq->active_count == 1 && pirq_valid_irq(pirq->reg)) { - vm_isa_assert_irq(dev->vmctx, pirq->reg & PIRQ_IRQ, - dev->lintr.ioapic_irq); - pthread_mutex_unlock(&pirq->lock); - return; - } - pthread_mutex_unlock(&pirq->lock); - } - vm_ioapic_assert_irq(dev->vmctx, dev->lintr.ioapic_irq); + vm_set_gsi_irq(dev->vmctx, dev->lintr.ioapic_irq, GSI_SET_HIGH); } void pci_irq_deassert(struct pci_vdev *dev) { - struct pirq *pirq; - - if (dev->lintr.pirq_pin > 0) { - assert(dev->lintr.pirq_pin <= nitems(pirqs)); - pirq = &pirqs[dev->lintr.pirq_pin - 1]; - pthread_mutex_lock(&pirq->lock); - pirq->active_count--; - if (pirq->active_count == 0 && pirq_valid_irq(pirq->reg)) { - vm_isa_deassert_irq(dev->vmctx, pirq->reg & PIRQ_IRQ, - dev->lintr.ioapic_irq); - pthread_mutex_unlock(&pirq->lock); - return; - } - pthread_mutex_unlock(&pirq->lock); - } - vm_ioapic_deassert_irq(dev->vmctx, dev->lintr.ioapic_irq); + vm_set_gsi_irq(dev->vmctx, dev->lintr.ioapic_irq, GSI_SET_LOW); } int diff --git a/devicemodel/hw/pci/lpc.c b/devicemodel/hw/pci/lpc.c index 28cd97b02..d5f0060df 100644 --- a/devicemodel/hw/pci/lpc.c +++ b/devicemodel/hw/pci/lpc.c @@ -105,9 +105,9 @@ lpc_uart_intr_assert(void *arg) assert(lpc_uart->irq >= 0); if (lpc_bridge) - vm_isa_pulse_irq(lpc_bridge->vmctx, + vm_set_gsi_irq(lpc_bridge->vmctx, lpc_uart->irq, - lpc_uart->irq); + GSI_RAISING_PULSE); } static void diff --git a/devicemodel/hw/platform/atkbdc.c b/devicemodel/hw/platform/atkbdc.c index a436004c0..8966b4b58 100644 --- a/devicemodel/hw/platform/atkbdc.c +++ b/devicemodel/hw/platform/atkbdc.c @@ -49,7 +49,7 @@ atkbdc_assert_kbd_intr(struct atkbdc_base *base) { if ((base->ram[0] & KBD_ENABLE_KBD_INT) != 0) { base->kbd.irq_active = true; - vm_isa_pulse_irq(base->ctx, base->kbd.irq, base->kbd.irq); + vm_set_gsi_irq(base->ctx, base->kbd.irq, GSI_RAISING_PULSE); } } @@ -58,7 +58,7 @@ atkbdc_assert_aux_intr(struct atkbdc_base *base) { if ((base->ram[0] & KBD_ENABLE_AUX_INT) != 0) { base->aux.irq_active = true; - vm_isa_pulse_irq(base->ctx, base->aux.irq, base->aux.irq); + vm_set_gsi_irq(base->ctx, base->aux.irq, GSI_RAISING_PULSE); } } diff --git a/devicemodel/hw/platform/pit.c b/devicemodel/hw/platform/pit.c index 77a33276d..0e9512362 100644 --- a/devicemodel/hw/platform/pit.c +++ b/devicemodel/hw/platform/pit.c @@ -245,7 +245,7 @@ vpit_timer_handler(union sigval s) c = &vpit->channel[arg->channel_num]; /* generate a rising edge on OUT */ - vm_isa_pulse_irq(vpit->vm, PIT_ATPIC_IRQ, PIT_IOAPIC_IRQ); + vm_set_gsi_irq(vpit->vm, PIT_IOAPIC_IRQ, GSI_RAISING_PULSE); /* CR -> CE if necessary */ pit_load_ce(c); diff --git a/devicemodel/hw/platform/rtc.c b/devicemodel/hw/platform/rtc.c index 1ca652d34..3376f6ec2 100644 --- a/devicemodel/hw/platform/rtc.c +++ b/devicemodel/hw/platform/rtc.c @@ -716,13 +716,10 @@ vrtc_set_reg_c(struct vrtc *vrtc, uint8_t newval) } if (!oldirqf && newirqf) { - - vm_isa_assert_irq(vrtc->vm, RTC_IRQ, RTC_IRQ); - /*vm_ioapic_assert_irq(vrtc->vm, RTC_IRQ);*/ + vm_set_gsi_irq(vrtc->vm, RTC_IRQ, GSI_SET_HIGH); RTC_DEBUG("RTC irq %d asserted\n", RTC_IRQ); } else if (oldirqf && !newirqf) { - vm_isa_deassert_irq(vrtc->vm, RTC_IRQ, RTC_IRQ); - /*vm_ioapic_deassert_irq(vrtc->vm, RTC_IRQ);*/ + vm_set_gsi_irq(vrtc->vm, RTC_IRQ, GSI_SET_LOW); RTC_DEBUG("RTC irq %d deasserted\n", RTC_IRQ); } } diff --git a/devicemodel/include/public/acrn_common.h b/devicemodel/include/public/acrn_common.h index c2a3f706e..f898c9d63 100644 --- a/devicemodel/include/public/acrn_common.h +++ b/devicemodel/include/public/acrn_common.h @@ -350,40 +350,23 @@ struct acrn_set_ioreq_buffer { uint64_t req_buf; } __aligned(8); -/** Interrupt type for acrn_irqline: inject interrupt to IOAPIC */ -#define ACRN_INTR_TYPE_ISA 0U - -/** Interrupt type for acrn_irqline: inject interrupt to both PIC and IOAPIC */ -#define ACRN_INTR_TYPE_IOAPIC 1U +/** Operation types for setting IRQ line */ +#define GSI_SET_HIGH 0U +#define GSI_SET_LOW 1U +#define GSI_RAISING_PULSE 2U +#define GSI_FALLING_PULSE 3U /** - * @brief Info to assert/deassert/pulse a virtual IRQ line for a VM + * @brief Info to Set/Clear/Pulse a virtual IRQ line for a VM * - * the parameter for HC_ASSERT_IRQLINE/HC_DEASSERT_IRQLINE/HC_PULSE_IRQLINE - * hypercall + * the parameter for HC_SET_IRQLINE hypercall */ -struct acrn_irqline { - /** interrupt type which could be IOAPIC or ISA */ - uint32_t intr_type; - - /** reserved for alignment padding */ - uint32_t reserved; - - /** pic IRQ for ISA type */ - uint32_t pic_irq; - - /** Reserved */ - uint32_t reserved0; - - /** ioapic IRQ for IOAPIC & ISA TYPE, - * if ~0U then this IRQ will not be injected - */ - uint32_t ioapic_irq; - - /** Reserved */ - uint32_t reserved1; +struct acrn_irqline_ops { + uint32_t nr_gsi; + uint32_t op; } __aligned(8); + /** * @brief Info to inject a MSI interrupt to VM * diff --git a/devicemodel/include/public/vhm_ioctl_defs.h b/devicemodel/include/public/vhm_ioctl_defs.h index 1ea8fac39..dda0d5894 100644 --- a/devicemodel/include/public/vhm_ioctl_defs.h +++ b/devicemodel/include/public/vhm_ioctl_defs.h @@ -77,11 +77,9 @@ /* IRQ and Interrupts */ #define IC_ID_IRQ_BASE 0x20UL -#define IC_ASSERT_IRQLINE _IC_ID(IC_ID, IC_ID_IRQ_BASE + 0x00) -#define IC_DEASSERT_IRQLINE _IC_ID(IC_ID, IC_ID_IRQ_BASE + 0x01) -#define IC_PULSE_IRQLINE _IC_ID(IC_ID, IC_ID_IRQ_BASE + 0x02) #define IC_INJECT_MSI _IC_ID(IC_ID, IC_ID_IRQ_BASE + 0x03) #define IC_VM_INTR_MONITOR _IC_ID(IC_ID, IC_ID_IRQ_BASE + 0x04) +#define IC_SET_IRQLINE _IC_ID(IC_ID, IC_ID_IRQ_BASE + 0x05) /* DM ioreq management */ #define IC_ID_IOREQ_BASE 0x30UL diff --git a/devicemodel/include/vmmapi.h b/devicemodel/include/vmmapi.h index 7a304e608..aea6bf405 100644 --- a/devicemodel/include/vmmapi.h +++ b/devicemodel/include/vmmapi.h @@ -116,11 +116,7 @@ int vm_run(struct vmctx *ctx); int vm_suspend(struct vmctx *ctx, enum vm_suspend_how how); int vm_apicid2vcpu(struct vmctx *ctx, int apicid); int vm_lapic_msi(struct vmctx *ctx, uint64_t addr, uint64_t msg); -int vm_ioapic_assert_irq(struct vmctx *ctx, int irq); -int vm_ioapic_deassert_irq(struct vmctx *ctx, int irq); -int vm_isa_assert_irq(struct vmctx *ctx, int atpic_irq, int ioapic_irq); -int vm_isa_deassert_irq(struct vmctx *ctx, int atpic_irq, int ioapic_irq); -int vm_isa_pulse_irq(struct vmctx *ctx, int atpic_irq, int ioapic_irq); +int vm_set_gsi_irq(struct vmctx *ctx, int gsi, uint32_t operation); int vm_assign_ptdev(struct vmctx *ctx, int bus, int slot, int func); int vm_unassign_ptdev(struct vmctx *ctx, int bus, int slot, int func); int vm_map_ptdev_mmio(struct vmctx *ctx, int bus, int slot, int func,