All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] PCI: Fix pcibios_update_irq misuse of irq number
@ 2015-01-28 14:51 ` Marc Zyngier
  0 siblings, 0 replies; 58+ messages in thread
From: Marc Zyngier @ 2015-01-28 14:51 UTC (permalink / raw)
  To: Thomas Gleixner, Jiang Liu, Bjorn Helgaas
  Cc: Lorenzo Pieralisi, Andre Przywara, linux-pci, linux-arm-kernel,
	linux-kernel

pcibios_update_irq writes an irq number into the config space
of a given PCI device, but ignores the fact that this number
is a virtual interrupt number, which might be a very different
value from what the underlying hardware is using.

The obvious fix is to fetch the HW interrupt number from the
corresponding irq_data structure. This is slightly complicated
by the fact that this interrupt might be services by a stacked
domain.

This has been tested on KVM with kvmtool.

Reported-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
Tested-by: Andre Przywara <andre.przywara@arm.com>
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
---
 drivers/pci/setup-irq.c | 12 ++++++++++--
 1 file changed, 10 insertions(+), 2 deletions(-)

diff --git a/drivers/pci/setup-irq.c b/drivers/pci/setup-irq.c
index 4e2d595..828cbc9 100644
--- a/drivers/pci/setup-irq.c
+++ b/drivers/pci/setup-irq.c
@@ -15,11 +15,19 @@
 #include <linux/errno.h>
 #include <linux/ioport.h>
 #include <linux/cache.h>
+#include <linux/irq.h>
 
 void __weak pcibios_update_irq(struct pci_dev *dev, int irq)
 {
-	dev_dbg(&dev->dev, "assigning IRQ %02d\n", irq);
-	pci_write_config_byte(dev, PCI_INTERRUPT_LINE, irq);
+	struct irq_data *d;
+
+	d = irq_get_irq_data(irq);
+#ifdef CONFIG_IRQ_DOMAIN_HIERARCHY
+	while (d->parent_data)
+		d = d->parent_data;
+#endif
+	dev_dbg(&dev->dev, "assigning IRQ %02ld\n", d->hwirq);
+	pci_write_config_byte(dev, PCI_INTERRUPT_LINE, d->hwirq);
 }
 
 static void pdev_fixup_irq(struct pci_dev *dev,
-- 
2.1.4


^ permalink raw reply related	[flat|nested] 58+ messages in thread
* [PATCH] kvmtool: don't use PCI config space IRQ line field
@ 2015-06-04 15:20 ` Andre Przywara
  0 siblings, 0 replies; 58+ messages in thread
From: Andre Przywara @ 2015-06-04 15:20 UTC (permalink / raw)
  To: will.deacon; +Cc: penberg, kvm, kvmarm, linux-arm-kernel

In PCI config space there is an interrupt line field (offset 0x3f),
which is used to initially communicate the IRQ line number from
firmware to the OS. _Hardware_ should never use this information,
as the OS is free to write any information in there.
But kvmtool uses this number when it triggers IRQs in the guest,
which fails starting with Linux 3.19-rc1, where the PCI layer starts
writing the virtual IRQ number in there.

Fix that by storing the IRQ number in a separate field in
struct virtio_pci, which is independent from the PCI config space
and cannot be influenced by the guest.
This fixes ARM/ARM64 guests using PCI with newer kernels.

Signed-off-by: Andre Przywara <andre.przywara@arm.com>
---
 include/kvm/virtio-pci.h | 8 ++++++++
 virtio/pci.c             | 9 ++++++---
 2 files changed, 14 insertions(+), 3 deletions(-)

diff --git a/include/kvm/virtio-pci.h b/include/kvm/virtio-pci.h
index c795ce7..b70cadd 100644
--- a/include/kvm/virtio-pci.h
+++ b/include/kvm/virtio-pci.h
@@ -30,6 +30,14 @@ struct virtio_pci {
 	u8			isr;
 	u32			features;
 
+	/*
+	 * We cannot rely on the INTERRUPT_LINE byte in the config space once
+	 * we have run guest code, as the OS is allowed to use that field
+	 * as a scratch pad to communicate between driver and PCI layer.
+	 * So store our legacy interrupt line number in here for internal use.
+	 */
+	u8			legacy_irq_line;
+
 	/* MSI-X */
 	u16			config_vector;
 	u32			config_gsi;
diff --git a/virtio/pci.c b/virtio/pci.c
index 7556239..e17e5a9 100644
--- a/virtio/pci.c
+++ b/virtio/pci.c
@@ -141,7 +141,7 @@ static bool virtio_pci__io_in(struct ioport *ioport, struct kvm_cpu *vcpu, u16 p
 		break;
 	case VIRTIO_PCI_ISR:
 		ioport__write8(data, vpci->isr);
-		kvm__irq_line(kvm, vpci->pci_hdr.irq_line, VIRTIO_IRQ_LOW);
+		kvm__irq_line(kvm, vpci->legacy_irq_line, VIRTIO_IRQ_LOW);
 		vpci->isr = VIRTIO_IRQ_LOW;
 		break;
 	default:
@@ -299,7 +299,7 @@ int virtio_pci__signal_vq(struct kvm *kvm, struct virtio_device *vdev, u32 vq)
 			kvm__irq_trigger(kvm, vpci->gsis[vq]);
 	} else {
 		vpci->isr = VIRTIO_IRQ_HIGH;
-		kvm__irq_trigger(kvm, vpci->pci_hdr.irq_line);
+		kvm__irq_trigger(kvm, vpci->legacy_irq_line);
 	}
 	return 0;
 }
@@ -323,7 +323,7 @@ int virtio_pci__signal_config(struct kvm *kvm, struct virtio_device *vdev)
 			kvm__irq_trigger(kvm, vpci->config_gsi);
 	} else {
 		vpci->isr = VIRTIO_PCI_ISR_CONFIG;
-		kvm__irq_trigger(kvm, vpci->pci_hdr.irq_line);
+		kvm__irq_trigger(kvm, vpci->legacy_irq_line);
 	}
 
 	return 0;
@@ -422,6 +422,9 @@ int virtio_pci__init(struct kvm *kvm, void *dev, struct virtio_device *vdev,
 	if (r < 0)
 		goto free_msix_mmio;
 
+	/* save the IRQ that device__register() has allocated */
+	vpci->legacy_irq_line = vpci->pci_hdr.irq_line;
+
 	return 0;
 
 free_msix_mmio:
-- 
2.3.5


^ permalink raw reply related	[flat|nested] 58+ messages in thread

end of thread, other threads:[~2015-06-29 13:48 UTC | newest]

Thread overview: 58+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2015-01-28 14:51 [PATCH] PCI: Fix pcibios_update_irq misuse of irq number Marc Zyngier
2015-01-28 14:51 ` Marc Zyngier
2015-01-28 15:21 ` Jiang Liu
2015-01-28 15:21   ` Jiang Liu
2015-01-28 15:27   ` Marc Zyngier
2015-01-28 15:27     ` Marc Zyngier
2015-01-28 15:43     ` Bjorn Helgaas
2015-01-28 15:43       ` Bjorn Helgaas
2015-02-02 16:15       ` Marc Zyngier
2015-02-02 16:15         ` Marc Zyngier
2015-02-02 16:22         ` Bjorn Helgaas
2015-02-02 16:22           ` Bjorn Helgaas
2015-02-02 15:57 ` Bjorn Helgaas
2015-02-02 15:57   ` Bjorn Helgaas
2015-02-02 16:06   ` Jiang Liu
2015-02-02 16:06     ` Jiang Liu
2015-02-02 16:23   ` Marc Zyngier
2015-02-02 16:23     ` Marc Zyngier
2015-02-02 16:33 ` Russell King - ARM Linux
2015-02-02 16:33   ` Russell King - ARM Linux
2015-02-02 18:08   ` Marc Zyngier
2015-02-02 18:08     ` Marc Zyngier
2015-02-02 18:20     ` Russell King - ARM Linux
2015-02-02 18:20       ` Russell King - ARM Linux
2015-02-02 17:02 ` Arnd Bergmann
2015-02-02 17:02   ` Arnd Bergmann
2015-02-03 10:38   ` Marc Zyngier
2015-02-03 10:38     ` Marc Zyngier
2015-02-03 11:31     ` Arnd Bergmann
2015-02-03 11:31       ` Arnd Bergmann
2015-02-03 11:37       ` Marc Zyngier
2015-02-03 11:37         ` Marc Zyngier
2015-02-03 12:57         ` Arnd Bergmann
2015-02-03 12:57           ` Arnd Bergmann
2015-02-04 15:39       ` [PATCH] kvmtool: don't use PCI config space IRQ line field Andre Przywara
2015-02-04 15:39         ` Andre Przywara
2015-02-06 18:55         ` Will Deacon
2015-02-06 18:55           ` Will Deacon
2015-02-06 19:02           ` Peter Maydell
2015-02-06 19:02             ` Peter Maydell
2015-02-06 19:07             ` Will Deacon
2015-02-06 19:07               ` Will Deacon
2015-02-07 21:24               ` arnd at arndb.de
2015-02-07 21:24                 ` arnd
  -- strict thread matches above, loose matches on Subject: below --
2015-06-04 15:20 Andre Przywara
2015-06-04 15:20 ` Andre Przywara
2015-06-05 16:41 ` Will Deacon
2015-06-05 16:41   ` Will Deacon
2015-06-15 10:45   ` Andre Przywara
2015-06-15 10:45     ` Andre Przywara
2015-06-16 17:06     ` Will Deacon
2015-06-16 17:06       ` Will Deacon
2015-06-18 17:19       ` Andre Przywara
2015-06-18 17:19         ` Andre Przywara
2015-06-29 10:10         ` Will Deacon
2015-06-29 10:10           ` Will Deacon
2015-06-29 13:48           ` Andre Przywara
2015-06-29 13:48             ` Andre Przywara

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.