kvm tools: Handle virtio/pci I/O space as little endian

It doesn't work on big endian hosts as is.

Signed-off-by: David Daney <david.daney@cavium.com>
Signed-off-by: Andreas Herrmann <andreas.herrmann@caviumnetworks.com>
Signed-off-by: Pekka Enberg <penberg@kernel.org>
This commit is contained in:
David Daney
2014-05-28 22:28:03 +02:00
committed by Will Deacon
parent 9902a02cef
commit a0a7d66f12
2 changed files with 16 additions and 6 deletions
+13 -3
View File
@@ -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_cpu *vcpu, 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_cpu *vcpu, u16
static bool pci_config_data_in(struct ioport *ioport, struct kvm_cpu *vcpu, 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];
+3 -3
View File
@@ -385,9 +385,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) {