Commit 215bfb2e authored by Julien Thierry's avatar Julien Thierry Committed by Alexandru Elisei
Browse files

pci: Fix ioport allocation size



The PCI Local Bus Specification, Rev. 3.0,
Section 6.2.5.1. "Address Maps" states:
"Devices that map control functions into I/O Space must not consume more
than 256 bytes per I/O Base Address register."

Yet all the PCI devices allocate IO ports of IOPORT_SIZE (= 1024 bytes).

Fix this by having PCI devices use 256 bytes ports for IO BARs.

There is no hard requirement on the size of the memory region described
by memory BARs. However, the region must be big enough to hold the
virtio common interface described in [1], which is 20 bytes, and other
MSI-X and/or device specific configuration. To be consistent, let's also
limit the memory region described by BAR1 to 256. This is the same size
used by BAR2 for each of the two MSI-X vectors.

[1] VIRTIO Version 1.0 Committee Specification 04, section 4.4.8.
Signed-off-by: default avatarJulien Thierry <julien.thierry@arm.com>
[Added rationale for changing BAR1 size to PCI_IO_SIZE]
Signed-off-by: Alexandru Elisei's avatarAlexandru Elisei <alexandru.elisei@arm.com>
parent 870836a9
......@@ -62,8 +62,8 @@ struct framebuffer *vesa__init(struct kvm *kvm)
if (!kvm->cfg.vnc && !kvm->cfg.sdl && !kvm->cfg.gtk)
return NULL;
r = pci_get_io_port_block(IOPORT_SIZE);
r = ioport__register(kvm, r, &vesa_io_ops, IOPORT_SIZE, NULL);
r = pci_get_io_port_block(PCI_IO_SIZE);
r = ioport__register(kvm, r, &vesa_io_ops, PCI_IO_SIZE, NULL);
if (r < 0)
return ERR_PTR(r);
......
......@@ -14,7 +14,6 @@
/* some ports we reserve for own use */
#define IOPORT_DBG 0xe0
#define IOPORT_SIZE 0x400
struct kvm;
......
......@@ -20,7 +20,7 @@ static u16 io_port_blocks = PCI_IOPORT_START;
u16 pci_get_io_port_block(u32 size)
{
u16 port = ALIGN(io_port_blocks, IOPORT_SIZE);
u16 port = ALIGN(io_port_blocks, PCI_IO_SIZE);
io_port_blocks = port + size;
return port;
......
......@@ -421,7 +421,7 @@ static void virtio_pci__io_mmio_callback(struct kvm_cpu *vcpu,
{
struct virtio_pci *vpci = ptr;
int direction = is_write ? KVM_EXIT_IO_OUT : KVM_EXIT_IO_IN;
u16 port = vpci->port_addr + (addr & (IOPORT_SIZE - 1));
u16 port = vpci->port_addr + (addr & (PCI_IO_SIZE - 1));
kvm__emulate_io(vcpu, port, data, direction, len, 1);
}
......@@ -435,17 +435,16 @@ int virtio_pci__init(struct kvm *kvm, void *dev, struct virtio_device *vdev,
vpci->kvm = kvm;
vpci->dev = dev;
BUILD_BUG_ON(!is_power_of_two(IOPORT_SIZE));
BUILD_BUG_ON(!is_power_of_two(PCI_IO_SIZE));
r = pci_get_io_port_block(IOPORT_SIZE);
r = ioport__register(kvm, r, &virtio_pci__io_ops, IOPORT_SIZE, vdev);
r = pci_get_io_port_block(PCI_IO_SIZE);
r = ioport__register(kvm, r, &virtio_pci__io_ops, PCI_IO_SIZE, vdev);
if (r < 0)
return r;
vpci->port_addr = (u16)r;
vpci->mmio_addr = pci_get_mmio_block(IOPORT_SIZE);
r = kvm__register_mmio(kvm, vpci->mmio_addr, IOPORT_SIZE, false,
vpci->mmio_addr = pci_get_mmio_block(PCI_IO_SIZE);
r = kvm__register_mmio(kvm, vpci->mmio_addr, PCI_IO_SIZE, false,
virtio_pci__io_mmio_callback, vpci);
if (r < 0)
goto free_ioport;
......@@ -475,8 +474,8 @@ int virtio_pci__init(struct kvm *kvm, void *dev, struct virtio_device *vdev,
| PCI_BASE_ADDRESS_SPACE_MEMORY),
.status = cpu_to_le16(PCI_STATUS_CAP_LIST),
.capabilities = (void *)&vpci->pci_hdr.msix - (void *)&vpci->pci_hdr,
.bar_size[0] = cpu_to_le32(IOPORT_SIZE),
.bar_size[1] = cpu_to_le32(IOPORT_SIZE),
.bar_size[0] = cpu_to_le32(PCI_IO_SIZE),
.bar_size[1] = cpu_to_le32(PCI_IO_SIZE),
.bar_size[2] = cpu_to_le32(PCI_IO_SIZE*2),
};
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment