linux-arm-kernel.lists.infradead.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] kvmtool: don't use PCI config space IRQ line field
@ 2015-06-04 15:20 Andre Przywara
  2015-06-05 16:41 ` Will Deacon
  0 siblings, 1 reply; 12+ messages in thread
From: Andre Przywara @ 2015-06-04 15:20 UTC (permalink / raw)
  To: 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] 12+ messages in thread
* [PATCH] PCI: Fix pcibios_update_irq misuse of irq number
@ 2015-02-03 11:31 Arnd Bergmann
  2015-02-04 15:39 ` [PATCH] kvmtool: don't use PCI config space IRQ line field Andre Przywara
  0 siblings, 1 reply; 12+ messages in thread
From: Arnd Bergmann @ 2015-02-03 11:31 UTC (permalink / raw)
  To: linux-arm-kernel

On Tuesday 03 February 2015 10:38:25 Marc Zyngier wrote:
> 
> That's exactly what I thought until Lorenzo reported kvmtool falling
> over because of this write. Obviously, some platforms must actually
> require this (possibly for bridges that are not known by the firmware).

This sounds much like a bug in kvmtool.
 
> Entirely removing that code solves my problem too, but that'd cannot be
> the right solution...

The comment in pdev_fixup_irq() says 

        /* Always tell the device, so the driver knows what is
           the real IRQ to use; the device does not use it. */

which I read to mean that there are drivers that incorrectly use
'pci_read_config_byte(dev, PCI_INTERRUPT_LINE)' as the number
they pass into request_irq, rather than using dev->irq.
However, this means that your patch is actually wrong, because
what the driver cares about is the virtual irq number (which
request_irq expects), not the number relative to some interrupt
controller.

There is another comment in include/linux/pci.h that states
       /*
        * Instead of touching interrupt line and base address registers
        * directly, use the values stored here. They might be different!
        */
       unsigned int    irq;

so apparently this has been a cause for problems in the past,
and drivers that rely on the number are already broken.

I also checked ancient kernel versions from the 2.1 days when the
code was first added. And indeed at the time drivers used to read
the word, but now none of them use the number for anything real,
they were all fixed during linux-2.2 at the latest.

	Arnd

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

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

Thread overview: 12+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2015-06-04 15:20 [PATCH] kvmtool: don't use PCI config space IRQ line field Andre Przywara
2015-06-05 16:41 ` Will Deacon
2015-06-15 10:45   ` Andre Przywara
2015-06-16 17:06     ` Will Deacon
2015-06-18 17:19       ` Andre Przywara
2015-06-29 10:10         ` Will Deacon
2015-06-29 13:48           ` Andre Przywara
  -- strict thread matches above, loose matches on Subject: below --
2015-02-03 11:31 [PATCH] PCI: Fix pcibios_update_irq misuse of irq number Arnd Bergmann
2015-02-04 15:39 ` [PATCH] kvmtool: don't use PCI config space IRQ line field Andre Przywara
2015-02-06 18:55   ` Will Deacon
2015-02-06 19:02     ` Peter Maydell
2015-02-06 19:07       ` Will Deacon
2015-02-07 21:24         ` arnd at arndb.de

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).