[PATCH kvmtool 11/16] virtio/pci: Ignore MMIO and I/O accesses when they are disabled

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



A device's response to memory or I/O accesses is disabled when Memory
Space, respectively I/O Space, is set to 0 in the Command register.
According to the PCI Local Bus Specification Revision 3.0, those two
bits reset to 0.

Let's respect the specifiction, so set Command and I/O Space to 0 on
reset, and ignore accesses to a device's respective regions when they
are disabled.

Signed-off-by: Alexandru Elisei <alexandru.elisei@xxxxxxx>
---
 virtio/pci.c | 15 ++++++++++++++-
 1 file changed, 14 insertions(+), 1 deletion(-)

diff --git a/virtio/pci.c b/virtio/pci.c
index 6723a1f3a84d..9f86bb7b6f93 100644
--- a/virtio/pci.c
+++ b/virtio/pci.c
@@ -168,6 +168,9 @@ static bool virtio_pci__io_in(struct ioport *ioport, struct kvm_cpu *vcpu, u16 p
 	vpci = vdev->virtio;
 	offset = port - vpci->port_addr;
 
+	if (!(vpci->pci_hdr.command & PCI_COMMAND_IO))
+		return true;
+
 	return virtio_pci__data_in(vcpu, vdev, offset, data, size);
 }
 
@@ -328,6 +331,9 @@ static bool virtio_pci__io_out(struct ioport *ioport, struct kvm_cpu *vcpu, u16
 	vpci = vdev->virtio;
 	offset = port - vpci->port_addr;
 
+	if (!(vpci->pci_hdr.command & PCI_COMMAND_IO))
+		return true;
+
 	return virtio_pci__data_out(vcpu, vdev, offset, data, size);
 }
 
@@ -346,6 +352,9 @@ static void virtio_pci__msix_mmio_callback(struct kvm_cpu *vcpu,
 	int vecnum;
 	size_t offset;
 
+	if (!(vpci->pci_hdr.command & PCI_COMMAND_MEMORY))
+		return;
+
 	if (addr > vpci->msix_io_block + PCI_IO_SIZE) {
 		if (is_write)
 			return;
@@ -443,6 +452,9 @@ static void virtio_pci__io_mmio_callback(struct kvm_cpu *vcpu,
 	struct virtio_device *vdev = ptr;
 	struct virtio_pci *vpci = vdev->virtio;
 
+	if (!(vpci->pci_hdr.command & PCI_COMMAND_MEMORY))
+		return;
+
 	if (!is_write)
 		virtio_pci__data_in(vcpu, vdev, addr - vpci->mmio_addr,
 				    data, len);
@@ -483,7 +495,8 @@ int virtio_pci__init(struct kvm *kvm, void *dev, struct virtio_device *vdev,
 	vpci->pci_hdr = (struct pci_device_header) {
 		.vendor_id		= cpu_to_le16(PCI_VENDOR_ID_REDHAT_QUMRANET),
 		.device_id		= cpu_to_le16(device_id),
-		.command		= PCI_COMMAND_IO | PCI_COMMAND_MEMORY,
+		/* The Command register is 0 on RST. */
+		.command		= 0,
 		.header_type		= PCI_HEADER_TYPE_NORMAL,
 		.revision_id		= 0,
 		.class[0]		= class & 0xff,
-- 
2.20.1




[Index of Archives]     [KVM ARM]     [KVM ia64]     [KVM ppc]     [Virtualization Tools]     [Spice Development]     [Libvirt]     [Libvirt Users]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite Questions]     [Linux Kernel]     [Linux SCSI]     [XFree86]

  Powered by Linux