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