From: David Daney <david.daney@xxxxxxxxxx> It doesn't work on big endian hosts as is. Signed-off-by: David Daney <david.daney@xxxxxxxxxx> Signed-off-by: Andreas Herrmann <andreas.herrmann@xxxxxxxxxxxxxxxxxx> --- tools/kvm/pci.c | 16 +++++++++++++--- tools/kvm/virtio/pci.c | 6 +++--- 2 files changed, 16 insertions(+), 6 deletions(-) diff --git a/tools/kvm/pci.c b/tools/kvm/pci.c index c2da152..e4857b9 100644 --- a/tools/kvm/pci.c +++ b/tools/kvm/pci.c @@ -10,7 +10,7 @@ #define PCI_BAR_OFFSET(b) (offsetof(struct pci_device_header, bar[b])) -static union pci_config_address pci_config_address; +static u32 pci_config_address_bits; /* This is within our PCI gap - in an unused area. * Note this is a PCI *bus address*, is used to assign BARs etc.! @@ -49,7 +49,7 @@ static void *pci_config_address_ptr(u16 port) void *base; offset = port - PCI_CONFIG_ADDRESS; - base = &pci_config_address; + base = &pci_config_address_bits; return base + offset; } @@ -79,6 +79,10 @@ static struct ioport_operations pci_config_address_ops = { static bool pci_device_exists(u8 bus_number, u8 device_number, u8 function_number) { + union pci_config_address pci_config_address; + + pci_config_address.w = ioport__read32(&pci_config_address_bits); + if (pci_config_address.bus_number != bus_number) return false; @@ -90,6 +94,9 @@ static bool pci_device_exists(u8 bus_number, u8 device_number, u8 function_numbe static bool pci_config_data_out(struct ioport *ioport, struct kvm *kvm, u16 port, void *data, int size) { + union pci_config_address pci_config_address; + + pci_config_address.w = ioport__read32(&pci_config_address_bits); /* * If someone accesses PCI configuration space offsets that are not * aligned to 4 bytes, it uses ioports to signify that. @@ -103,6 +110,9 @@ static bool pci_config_data_out(struct ioport *ioport, struct kvm *kvm, u16 port static bool pci_config_data_in(struct ioport *ioport, struct kvm *kvm, u16 port, void *data, int size) { + union pci_config_address pci_config_address; + + pci_config_address.w = ioport__read32(&pci_config_address_bits); /* * If someone accesses PCI configuration space offsets that are not * aligned to 4 bytes, it uses ioports to signify that. @@ -133,7 +143,7 @@ void pci__config_wr(struct kvm *kvm, union pci_config_address addr, void *data, void *p = device__find_dev(DEVICE_BUS_PCI, dev_num)->data; struct pci_device_header *hdr = p; u8 bar = (offset - PCI_BAR_OFFSET(0)) / (sizeof(u32)); - u32 sz = PCI_IO_SIZE; + u32 sz = cpu_to_le32(PCI_IO_SIZE); if (bar < 6 && hdr->bar_size[bar]) sz = hdr->bar_size[bar]; diff --git a/tools/kvm/virtio/pci.c b/tools/kvm/virtio/pci.c index 665d492..f0ae8d4 100644 --- a/tools/kvm/virtio/pci.c +++ b/tools/kvm/virtio/pci.c @@ -376,9 +376,9 @@ 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] = IOPORT_SIZE, - .bar_size[1] = IOPORT_SIZE, - .bar_size[2] = PCI_IO_SIZE * 2, + .bar_size[0] = cpu_to_le32(IOPORT_SIZE), + .bar_size[1] = cpu_to_le32(IOPORT_SIZE), + .bar_size[2] = cpu_to_le32(PCI_IO_SIZE*2), }; vpci->dev_hdr = (struct device_header) { -- 1.7.9.5