aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJean-Philippe Brucker <jean-philippe.brucker@arm.com>2018-06-18 19:42:00 +0100
committerWill Deacon <will.deacon@arm.com>2018-06-19 12:26:38 +0100
commitff01b5dbbd040d39619f0f033da6eac5dbed3b2b (patch)
tree3c4ccb83acd2be552cf3c32b84fa5640607b3abe
parent023fdaae48b45aec087551804616e0836a74d675 (diff)
downloadkvmtool-ff01b5dbbd040d39619f0f033da6eac5dbed3b2b.tar.gz
pci: allow to specify IRQ type for PCI devices
Currently all our virtual device interrupts are edge-triggered. But we're going to need level-triggered interrupts when passing physical devices. Let the device configure its interrupt kind. Keep edge as default, to avoid changing existing users. Reviewed-by: Punit Agrawal <punit.agrawal@arm.com> Signed-off-by: Jean-Philippe Brucker <jean-philippe.brucker@arm.com> Signed-off-by: Will Deacon <will.deacon@arm.com>
-rw-r--r--arm/pci.c3
-rw-r--r--include/kvm/pci.h6
-rw-r--r--pci.c3
3 files changed, 11 insertions, 1 deletions
diff --git a/arm/pci.c b/arm/pci.c
index 813df26a..744b14c2 100644
--- a/arm/pci.c
+++ b/arm/pci.c
@@ -77,6 +77,7 @@ void pci__generate_fdt_nodes(void *fdt)
u8 dev_num = dev_hdr->dev_num;
u8 pin = pci_hdr->irq_pin;
u8 irq = pci_hdr->irq_line;
+ u32 irq_flags = pci_hdr->irq_type;
*entry = (struct of_interrupt_map_entry) {
.pci_irq_mask = {
@@ -93,7 +94,7 @@ void pci__generate_fdt_nodes(void *fdt)
.gic_irq = {
.type = cpu_to_fdt32(GIC_FDT_IRQ_TYPE_SPI),
.num = cpu_to_fdt32(irq - GIC_SPI_IRQ_BASE),
- .flags = cpu_to_fdt32(IRQ_TYPE_EDGE_RISING),
+ .flags = cpu_to_fdt32(irq_flags),
},
};
diff --git a/include/kvm/pci.h b/include/kvm/pci.h
index 56649d87..5d9c0f3b 100644
--- a/include/kvm/pci.h
+++ b/include/kvm/pci.h
@@ -9,6 +9,7 @@
#include "kvm/devices.h"
#include "kvm/kvm.h"
#include "kvm/msi.h"
+#include "kvm/fdt.h"
/*
* PCI Configuration Mechanism #1 I/O ports. See Section 3.7.4.1.
@@ -105,6 +106,11 @@ struct pci_device_header {
/* Private to lkvm */
u32 bar_size[6];
struct pci_config_operations cfg_ops;
+ /*
+ * PCI INTx# are level-triggered, but virtual device often feature
+ * edge-triggered INTx# for convenience.
+ */
+ enum irq_type irq_type;
};
int pci__init(struct kvm *kvm);
diff --git a/pci.c b/pci.c
index e48e24b8..5a8c2ef4 100644
--- a/pci.c
+++ b/pci.c
@@ -39,6 +39,9 @@ void pci__assign_irq(struct device_header *dev_hdr)
*/
pci_hdr->irq_pin = 1;
pci_hdr->irq_line = irq__alloc_line();
+
+ if (!pci_hdr->irq_type)
+ pci_hdr->irq_type = IRQ_TYPE_EDGE_RISING;
}
static void *pci_config_address_ptr(u16 port)