From eb9a58c70e0673b92f6758de0c077d4a3e703973 Mon Sep 17 00:00:00 2001 From: Zhao Yakui Date: Thu, 17 Feb 2022 16:54:11 +0800 Subject: [PATCH] ACRN:DM: Set the desired state to inject PCI legacy intx When the virtio-XXX pci devices fall back to legacy PCI intx, the pci_irq_assert is called to inject the interrupt and then the pci_irq_deassert is used to mark the completion of PCI interrupt. Currently the HV vIOAPIC uses the pin_state for the interrupt injection of legacy PCI intx. In such case it will fail to inject the PCI legacy intx and the guest system fails to be booted when adding the boot option of "pci=nomsi". PCI legacy INTx usually use active low level trigger mode as it is Open-Drain state and allows multitple interrupt signals to share a single line. https://wiki.osdev.org/PCI_Local_Bus_Signals In such case DM needs to set the correct state for the PCI device so that the HV vIOAPIC can help to inject the PCI legacy intx. BTW: When the MSI/MSIX is used for PCI device, it uses another mechanism to inject the interrupt. It is harmless to configure the initial state. Tracked-On: #7124 Signed-off-by: Zhao Yakui Acked-by: Wang, Yu1 --- devicemodel/hw/pci/core.c | 2 ++ devicemodel/hw/pci/irq.c | 4 ++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/devicemodel/hw/pci/core.c b/devicemodel/hw/pci/core.c index 9527d66d2..75c31f8ce 100644 --- a/devicemodel/hw/pci/core.c +++ b/devicemodel/hw/pci/core.c @@ -2031,6 +2031,8 @@ pci_lintr_route(struct pci_vdev *dev) dev->lintr.ioapic_irq = ii->ii_ioapic_irq; dev->lintr.pirq_pin = ii->ii_pirq_pin; pci_set_cfgdata8(dev, PCIR_INTLINE, pirq_irq(ii->ii_pirq_pin)); + /* Initialize it to High */ + vm_set_gsi_irq(dev->vmctx, ii->ii_ioapic_irq, GSI_SET_HIGH); } /** diff --git a/devicemodel/hw/pci/irq.c b/devicemodel/hw/pci/irq.c index 9d4ea323a..cba6cd781 100644 --- a/devicemodel/hw/pci/irq.c +++ b/devicemodel/hw/pci/irq.c @@ -147,13 +147,13 @@ void pci_irq_deinit(struct vmctx *ctx) void pci_irq_assert(struct pci_vdev *dev) { - vm_set_gsi_irq(dev->vmctx, dev->lintr.ioapic_irq, GSI_SET_HIGH); + vm_set_gsi_irq(dev->vmctx, dev->lintr.ioapic_irq, GSI_SET_LOW); } void pci_irq_deassert(struct pci_vdev *dev) { - vm_set_gsi_irq(dev->vmctx, dev->lintr.ioapic_irq, GSI_SET_LOW); + vm_set_gsi_irq(dev->vmctx, dev->lintr.ioapic_irq, GSI_SET_HIGH); } int