From: Matt Evans <matt@ozlabs.org>
To: kvm@vger.kernel.org, kvm-ppc@vger.kernel.org
Cc: penberg@kernel.org, asias.hejun@gmail.com,
levinsasha928@gmail.com, gorcunov@gmail.com
Subject: [PATCH V2 19/23] kvm tools: Endian-sanitise pci.h and PCI device
Date: Fri, 09 Dec 2011 06:55:36 +0000 [thread overview]
Message-ID: <4EE1B0E8.3080808@ozlabs.org> (raw)
In-Reply-To: <cover.1323413420.git.matt@ozlabs.org>
vesa, pci-shmem and virtio-pci devices need to set up config space with
little-endian conversions (as config space is LE). The pci_config_address
bitfield also needs to be reversed when building on BE systems.
Signed-off-by: Matt Evans <matt@ozlabs.org>
---
tools/kvm/hw/pci-shmem.c | 23 +++++++++++----------
tools/kvm/hw/vesa.c | 15 +++++++------
tools/kvm/include/kvm/ioport.h | 11 +++++----
tools/kvm/include/kvm/pci.h | 40 ++++++++++++++++++++++++++------------
tools/kvm/pci.c | 4 +-
tools/kvm/virtio/pci.c | 41 +++++++++++++++++++++------------------
6 files changed, 77 insertions(+), 57 deletions(-)
diff --git a/tools/kvm/hw/pci-shmem.c b/tools/kvm/hw/pci-shmem.c
index 780a377..fd954c5 100644
--- a/tools/kvm/hw/pci-shmem.c
+++ b/tools/kvm/hw/pci-shmem.c
@@ -8,21 +8,22 @@
#include "kvm/ioeventfd.h"
#include <linux/kvm.h>
+#include <linux/byteorder.h>
#include <sys/ioctl.h>
#include <fcntl.h>
#include <sys/mman.h>
static struct pci_device_header pci_shmem_pci_device = {
- .vendor_id = PCI_VENDOR_ID_REDHAT_QUMRANET,
- .device_id = 0x1110,
+ .vendor_id = cpu_to_le16(PCI_VENDOR_ID_REDHAT_QUMRANET),
+ .device_id = cpu_to_le16(0x1110),
.header_type = PCI_HEADER_TYPE_NORMAL,
- .class = 0xFF0000, /* misc pci device */
- .status = PCI_STATUS_CAP_LIST,
+ .class[2] = 0xFF, /* misc pci device */
+ .status = cpu_to_le16(PCI_STATUS_CAP_LIST),
.capabilities = (void *)&pci_shmem_pci_device.msix - (void *)&pci_shmem_pci_device,
.msix.cap = PCI_CAP_ID_MSIX,
- .msix.ctrl = 1,
- .msix.table_offset = 1, /* Use BAR 1 */
- .msix.pba_offset = 0x1001, /* Use BAR 1 */
+ .msix.ctrl = cpu_to_le16(1),
+ .msix.table_offset = cpu_to_le32(1), /* Use BAR 1 */
+ .msix.pba_offset = cpu_to_le32(0x1001), /* Use BAR 1 */
};
/* registers for the Inter-VM shared memory device */
@@ -123,7 +124,7 @@ int pci_shmem__get_local_irqfd(struct kvm *kvm)
if (fd < 0)
return fd;
- if (pci_shmem_pci_device.msix.ctrl & PCI_MSIX_FLAGS_ENABLE) {
+ if (pci_shmem_pci_device.msix.ctrl & cpu_to_le16(PCI_MSIX_FLAGS_ENABLE)) {
gsi = irq__add_msix_route(kvm, &msix_table[0].msg);
} else {
gsi = pci_shmem_pci_device.irq_line;
@@ -241,11 +242,11 @@ int pci_shmem__init(struct kvm *kvm)
* 1 - MSI-X MMIO space
* 2 - Shared memory block
*/
- pci_shmem_pci_device.bar[0] = ivshmem_registers | PCI_BASE_ADDRESS_SPACE_IO;
+ pci_shmem_pci_device.bar[0] = cpu_to_le32(ivshmem_registers | PCI_BASE_ADDRESS_SPACE_IO);
pci_shmem_pci_device.bar_size[0] = shmem_region->size;
- pci_shmem_pci_device.bar[1] = msix_block | PCI_BASE_ADDRESS_SPACE_MEMORY;
+ pci_shmem_pci_device.bar[1] = cpu_to_le32(msix_block | PCI_BASE_ADDRESS_SPACE_MEMORY);
pci_shmem_pci_device.bar_size[1] = 0x1010;
- pci_shmem_pci_device.bar[2] = shmem_region->phys_addr | PCI_BASE_ADDRESS_SPACE_MEMORY;
+ pci_shmem_pci_device.bar[2] = cpu_to_le32(shmem_region->phys_addr | PCI_BASE_ADDRESS_SPACE_MEMORY);
pci_shmem_pci_device.bar_size[2] = shmem_region->size;
pci__register(&pci_shmem_pci_device, dev);
diff --git a/tools/kvm/hw/vesa.c b/tools/kvm/hw/vesa.c
index 22b1652..63f1082 100644
--- a/tools/kvm/hw/vesa.c
+++ b/tools/kvm/hw/vesa.c
@@ -8,6 +8,7 @@
#include "kvm/irq.h"
#include "kvm/kvm.h"
#include "kvm/pci.h"
+#include <linux/byteorder.h>
#include <sys/mman.h>
#include <sys/types.h>
@@ -31,14 +32,14 @@ static struct ioport_operations vesa_io_ops = {
};
static struct pci_device_header vesa_pci_device = {
- .vendor_id = PCI_VENDOR_ID_REDHAT_QUMRANET,
- .device_id = PCI_DEVICE_ID_VESA,
+ .vendor_id = cpu_to_le16(PCI_VENDOR_ID_REDHAT_QUMRANET),
+ .device_id = cpu_to_le16(PCI_DEVICE_ID_VESA),
.header_type = PCI_HEADER_TYPE_NORMAL,
.revision_id = 0,
- .class = 0x030000,
- .subsys_vendor_id = PCI_SUBSYSTEM_VENDOR_ID_REDHAT_QUMRANET,
- .subsys_id = PCI_SUBSYSTEM_ID_VESA,
- .bar[1] = VESA_MEM_ADDR | PCI_BASE_ADDRESS_SPACE_MEMORY,
+ .class[2] = 0x03,
+ .subsys_vendor_id = cpu_to_le16(PCI_SUBSYSTEM_VENDOR_ID_REDHAT_QUMRANET),
+ .subsys_id = cpu_to_le16(PCI_SUBSYSTEM_ID_VESA),
+ .bar[1] = cpu_to_le32(VESA_MEM_ADDR | PCI_BASE_ADDRESS_SPACE_MEMORY),
.bar_size[1] = VESA_MEM_SIZE,
};
@@ -56,7 +57,7 @@ struct framebuffer *vesa__init(struct kvm *kvm)
vesa_pci_device.irq_pin = pin;
vesa_pci_device.irq_line = line;
vesa_base_addr = ioport__register(IOPORT_EMPTY, &vesa_io_ops, IOPORT_SIZE, NULL);
- vesa_pci_device.bar[0] = vesa_base_addr | PCI_BASE_ADDRESS_SPACE_IO;
+ vesa_pci_device.bar[0] = cpu_to_le32(vesa_base_addr | PCI_BASE_ADDRESS_SPACE_IO);
pci__register(&vesa_pci_device, dev);
mem = mmap(NULL, VESA_MEM_SIZE, PROT_RW, MAP_ANON_NORESERVE, -1, 0);
diff --git a/tools/kvm/include/kvm/ioport.h b/tools/kvm/include/kvm/ioport.h
index 61a70ec..09bf876 100644
--- a/tools/kvm/include/kvm/ioport.h
+++ b/tools/kvm/include/kvm/ioport.h
@@ -7,6 +7,7 @@
#include <limits.h>
#include <asm/types.h>
#include <linux/types.h>
+#include <linux/byteorder.h>
/* some ports we reserve for own use */
#define IOPORT_DBG 0xe0
@@ -36,15 +37,15 @@ static inline u8 ioport__read8(u8 *data)
{
return *data;
}
-
+/* On BE platforms, PCI I/O is byteswapped, i.e. LE, so swap back. */
static inline u16 ioport__read16(u16 *data)
{
- return *data;
+ return le16_to_cpu(*data);
}
static inline u32 ioport__read32(u32 *data)
{
- return *data;
+ return le32_to_cpu(*data);
}
static inline void ioport__write8(u8 *data, u8 value)
@@ -54,12 +55,12 @@ static inline void ioport__write8(u8 *data, u8 value)
static inline void ioport__write16(u16 *data, u16 value)
{
- *data = value;
+ *data = cpu_to_le16(value);
}
static inline void ioport__write32(u32 *data, u32 value)
{
- *data = value;
+ *data = cpu_to_le32(value);
}
#endif /* KVM__IOPORT_H */
diff --git a/tools/kvm/include/kvm/pci.h b/tools/kvm/include/kvm/pci.h
index b578ad7..21f93d0 100644
--- a/tools/kvm/include/kvm/pci.h
+++ b/tools/kvm/include/kvm/pci.h
@@ -5,6 +5,7 @@
#include <linux/kvm.h>
#include <linux/pci_regs.h>
#include <linux/msi.h>
+#include <endian.h>
#define PCI_MAX_DEVICES 256
/*
@@ -17,14 +18,27 @@
#define PCI_CONFIG_BUS_FORWARD 0xcfa
#define PCI_IO_SIZE 0x100
-struct pci_config_address {
- unsigned zeros : 2; /* 1 .. 0 */
- unsigned register_number : 6; /* 7 .. 2 */
- unsigned function_number : 3; /* 10 .. 8 */
- unsigned device_number : 5; /* 15 .. 11 */
- unsigned bus_number : 8; /* 23 .. 16 */
- unsigned reserved : 7; /* 30 .. 24 */
- unsigned enable_bit : 1; /* 31 */
+union pci_config_address {
+ struct {
+#if __BYTE_ORDER = __LITTLE_ENDIAN
+ unsigned zeros : 2; /* 1 .. 0 */
+ unsigned register_number : 6; /* 7 .. 2 */
+ unsigned function_number : 3; /* 10 .. 8 */
+ unsigned device_number : 5; /* 15 .. 11 */
+ unsigned bus_number : 8; /* 23 .. 16 */
+ unsigned reserved : 7; /* 30 .. 24 */
+ unsigned enable_bit : 1; /* 31 */
+#else
+ unsigned enable_bit : 1; /* 31 */
+ unsigned reserved : 7; /* 30 .. 24 */
+ unsigned bus_number : 8; /* 23 .. 16 */
+ unsigned device_number : 5; /* 15 .. 11 */
+ unsigned function_number : 3; /* 10 .. 8 */
+ unsigned register_number : 6; /* 7 .. 2 */
+ unsigned zeros : 2; /* 1 .. 0 */
+#endif
+ };
+ u32 w;
};
struct msix_table {
@@ -45,8 +59,8 @@ struct pci_device_header {
u16 device_id;
u16 command;
u16 status;
- u16 revision_id : 8;
- u32 class : 24;
+ u8 revision_id;
+ u8 class[3];
u8 cacheline_size;
u8 latency_timer;
u8 header_type;
@@ -56,8 +70,8 @@ struct pci_device_header {
u16 subsys_vendor_id;
u16 subsys_id;
u32 exp_rom_bar;
- u32 capabilities : 8;
- u32 reserved1 : 24;
+ u8 capabilities;
+ u8 reserved1[3];
u32 reserved2;
u8 irq_line;
u8 irq_pin;
@@ -66,7 +80,7 @@ struct pci_device_header {
struct msix_cap msix;
u8 empty[136]; /* Rest of PCI config space */
u32 bar_size[6];
-};
+} __attribute__((packed));
void pci__init(void);
void pci__register(struct pci_device_header *dev, u8 dev_num);
diff --git a/tools/kvm/pci.c b/tools/kvm/pci.c
index 920e13e..5bbcbc7 100644
--- a/tools/kvm/pci.c
+++ b/tools/kvm/pci.c
@@ -9,7 +9,7 @@
static struct pci_device_header *pci_devices[PCI_MAX_DEVICES];
-static struct pci_config_address pci_config_address;
+static union pci_config_address pci_config_address;
/* This is within our PCI gap - in an unused area */
static u32 io_space_blocks = KVM_32BIT_GAP_START + 0x1000000;
@@ -105,7 +105,7 @@ static bool pci_config_data_out(struct ioport *ioport, struct kvm *kvm, u16 port
* When the kernel got the size it would write the address
* back.
*/
- if (ioport__read32(p + offset)) {
+ if (*(u32 *)(p + offset)) {
/* See if kernel tries to mask one of the BARs */
if ((offset >= PCI_BAR_OFFSET(0)) &&
(offset <= PCI_BAR_OFFSET(6)) &&
diff --git a/tools/kvm/virtio/pci.c b/tools/kvm/virtio/pci.c
index d9fc3a5..acb7d96 100644
--- a/tools/kvm/virtio/pci.c
+++ b/tools/kvm/virtio/pci.c
@@ -9,6 +9,7 @@
#include "kvm/virtio-trans.h"
#include <linux/virtio_pci.h>
+#include <linux/byteorder.h>
#include <string.h>
struct virtio_trans_ops *virtio_pci__get_trans_ops(void)
@@ -59,7 +60,7 @@ static int virtio_pci__init_ioeventfd(struct kvm *kvm, struct virtio_trans *vtra
static inline bool virtio_pci__msix_enabled(struct virtio_pci *vpci)
{
- return vpci->pci_hdr.msix.ctrl & PCI_MSIX_FLAGS_ENABLE;
+ return vpci->pci_hdr.msix.ctrl & cpu_to_le16(PCI_MSIX_FLAGS_ENABLE);
}
static bool virtio_pci__specific_io_in(struct kvm *kvm, struct virtio_trans *vtrans, u16 port,
@@ -244,8 +245,8 @@ int virtio_pci__signal_vq(struct kvm *kvm, struct virtio_trans *vtrans, u32 vq)
int tbl = vpci->vq_vector[vq];
if (virtio_pci__msix_enabled(vpci)) {
- if (vpci->pci_hdr.msix.ctrl & PCI_MSIX_FLAGS_MASKALL ||
- vpci->msix_table[tbl].ctrl & PCI_MSIX_ENTRY_CTRL_MASKBIT) {
+ if (vpci->pci_hdr.msix.ctrl & cpu_to_le16(PCI_MSIX_FLAGS_MASKALL) ||
+ vpci->msix_table[tbl].ctrl & cpu_to_le16(PCI_MSIX_ENTRY_CTRL_MASKBIT)) {
vpci->msix_pba |= 1 << tbl;
return 0;
@@ -265,8 +266,8 @@ int virtio_pci__signal_config(struct kvm *kvm, struct virtio_trans *vtrans)
int tbl = vpci->config_vector;
if (virtio_pci__msix_enabled(vpci)) {
- if (vpci->pci_hdr.msix.ctrl & PCI_MSIX_FLAGS_MASKALL ||
- vpci->msix_table[tbl].ctrl & PCI_MSIX_ENTRY_CTRL_MASKBIT) {
+ if (vpci->pci_hdr.msix.ctrl & cpu_to_le16(PCI_MSIX_FLAGS_MASKALL) ||
+ vpci->msix_table[tbl].ctrl & cpu_to_le16(PCI_MSIX_ENTRY_CTRL_MASKBIT)) {
vpci->msix_pba |= 1 << tbl;
return 0;
@@ -296,19 +297,21 @@ int virtio_pci__init(struct kvm *kvm, struct virtio_trans *vtrans, void *dev,
kvm__register_mmio(kvm, vpci->msix_pba_block, 0x100, callback_mmio_pba, vpci);
vpci->pci_hdr = (struct pci_device_header) {
- .vendor_id = PCI_VENDOR_ID_REDHAT_QUMRANET,
- .device_id = device_id,
+ .vendor_id = cpu_to_le16(PCI_VENDOR_ID_REDHAT_QUMRANET),
+ .device_id = cpu_to_le16(device_id),
.header_type = PCI_HEADER_TYPE_NORMAL,
.revision_id = 0,
- .class = class,
- .subsys_vendor_id = PCI_SUBSYSTEM_VENDOR_ID_REDHAT_QUMRANET,
- .subsys_id = subsys_id,
- .bar[0] = vpci->base_addr | PCI_BASE_ADDRESS_SPACE_IO,
- .bar[1] = vpci->msix_io_block | PCI_BASE_ADDRESS_SPACE_MEMORY
- | PCI_BASE_ADDRESS_MEM_TYPE_64,
- .bar[3] = vpci->msix_pba_block | PCI_BASE_ADDRESS_SPACE_MEMORY
- | PCI_BASE_ADDRESS_MEM_TYPE_64,
- .status = PCI_STATUS_CAP_LIST,
+ .class[0] = class & 0xff,
+ .class[1] = (class >> 8) & 0xff,
+ .class[2] = (class >> 16) & 0xff,
+ .subsys_vendor_id = cpu_to_le16(PCI_SUBSYSTEM_VENDOR_ID_REDHAT_QUMRANET),
+ .subsys_id = cpu_to_le16(subsys_id),
+ .bar[0] = cpu_to_le32(vpci->base_addr | PCI_BASE_ADDRESS_SPACE_IO),
+ .bar[1] = cpu_to_le32(vpci->msix_io_block | PCI_BASE_ADDRESS_SPACE_MEMORY
+ | PCI_BASE_ADDRESS_MEM_TYPE_64),
+ .bar[3] = cpu_to_le32(vpci->msix_pba_block | PCI_BASE_ADDRESS_SPACE_MEMORY
+ | PCI_BASE_ADDRESS_MEM_TYPE_64),
+ .status = cpu_to_le16(PCI_STATUS_CAP_LIST),
.capabilities = (void *)&vpci->pci_hdr.msix - (void *)&vpci->pci_hdr,
};
@@ -325,14 +328,14 @@ int virtio_pci__init(struct kvm *kvm, struct virtio_trans *vtrans, void *dev,
* For example, a returned value of "00000000011"
* indicates a table size of 4.
*/
- vpci->pci_hdr.msix.ctrl = (VIRTIO_PCI_MAX_VQ + VIRTIO_PCI_MAX_CONFIG - 1);
+ vpci->pci_hdr.msix.ctrl = cpu_to_le16(VIRTIO_PCI_MAX_VQ + VIRTIO_PCI_MAX_CONFIG - 1);
/*
* Both table and PBA could be mapped on the same BAR, but for now
* we're not in short of BARs
*/
- vpci->pci_hdr.msix.table_offset = 1; /* Use BAR 1 */
- vpci->pci_hdr.msix.pba_offset = 3; /* Use BAR 3 */
+ vpci->pci_hdr.msix.table_offset = cpu_to_le32(1); /* Use BAR 1 */
+ vpci->pci_hdr.msix.pba_offset = cpu_to_le32(3); /* Use BAR 3 */
vpci->config_vector = 0;
if (irq__register_device(subsys_id, &ndev, &pin, &line) < 0)
WARNING: multiple messages have this Message-ID (diff)
From: Matt Evans <matt@ozlabs.org>
To: kvm@vger.kernel.org, kvm-ppc@vger.kernel.org
Cc: penberg@kernel.org, asias.hejun@gmail.com,
levinsasha928@gmail.com, gorcunov@gmail.com
Subject: [PATCH V2 19/23] kvm tools: Endian-sanitise pci.h and PCI device setup
Date: Fri, 09 Dec 2011 17:55:36 +1100 [thread overview]
Message-ID: <4EE1B0E8.3080808@ozlabs.org> (raw)
In-Reply-To: <cover.1323413420.git.matt@ozlabs.org>
vesa, pci-shmem and virtio-pci devices need to set up config space with
little-endian conversions (as config space is LE). The pci_config_address
bitfield also needs to be reversed when building on BE systems.
Signed-off-by: Matt Evans <matt@ozlabs.org>
---
tools/kvm/hw/pci-shmem.c | 23 +++++++++++----------
tools/kvm/hw/vesa.c | 15 +++++++------
tools/kvm/include/kvm/ioport.h | 11 +++++----
tools/kvm/include/kvm/pci.h | 40 ++++++++++++++++++++++++++------------
tools/kvm/pci.c | 4 +-
tools/kvm/virtio/pci.c | 41 +++++++++++++++++++++------------------
6 files changed, 77 insertions(+), 57 deletions(-)
diff --git a/tools/kvm/hw/pci-shmem.c b/tools/kvm/hw/pci-shmem.c
index 780a377..fd954c5 100644
--- a/tools/kvm/hw/pci-shmem.c
+++ b/tools/kvm/hw/pci-shmem.c
@@ -8,21 +8,22 @@
#include "kvm/ioeventfd.h"
#include <linux/kvm.h>
+#include <linux/byteorder.h>
#include <sys/ioctl.h>
#include <fcntl.h>
#include <sys/mman.h>
static struct pci_device_header pci_shmem_pci_device = {
- .vendor_id = PCI_VENDOR_ID_REDHAT_QUMRANET,
- .device_id = 0x1110,
+ .vendor_id = cpu_to_le16(PCI_VENDOR_ID_REDHAT_QUMRANET),
+ .device_id = cpu_to_le16(0x1110),
.header_type = PCI_HEADER_TYPE_NORMAL,
- .class = 0xFF0000, /* misc pci device */
- .status = PCI_STATUS_CAP_LIST,
+ .class[2] = 0xFF, /* misc pci device */
+ .status = cpu_to_le16(PCI_STATUS_CAP_LIST),
.capabilities = (void *)&pci_shmem_pci_device.msix - (void *)&pci_shmem_pci_device,
.msix.cap = PCI_CAP_ID_MSIX,
- .msix.ctrl = 1,
- .msix.table_offset = 1, /* Use BAR 1 */
- .msix.pba_offset = 0x1001, /* Use BAR 1 */
+ .msix.ctrl = cpu_to_le16(1),
+ .msix.table_offset = cpu_to_le32(1), /* Use BAR 1 */
+ .msix.pba_offset = cpu_to_le32(0x1001), /* Use BAR 1 */
};
/* registers for the Inter-VM shared memory device */
@@ -123,7 +124,7 @@ int pci_shmem__get_local_irqfd(struct kvm *kvm)
if (fd < 0)
return fd;
- if (pci_shmem_pci_device.msix.ctrl & PCI_MSIX_FLAGS_ENABLE) {
+ if (pci_shmem_pci_device.msix.ctrl & cpu_to_le16(PCI_MSIX_FLAGS_ENABLE)) {
gsi = irq__add_msix_route(kvm, &msix_table[0].msg);
} else {
gsi = pci_shmem_pci_device.irq_line;
@@ -241,11 +242,11 @@ int pci_shmem__init(struct kvm *kvm)
* 1 - MSI-X MMIO space
* 2 - Shared memory block
*/
- pci_shmem_pci_device.bar[0] = ivshmem_registers | PCI_BASE_ADDRESS_SPACE_IO;
+ pci_shmem_pci_device.bar[0] = cpu_to_le32(ivshmem_registers | PCI_BASE_ADDRESS_SPACE_IO);
pci_shmem_pci_device.bar_size[0] = shmem_region->size;
- pci_shmem_pci_device.bar[1] = msix_block | PCI_BASE_ADDRESS_SPACE_MEMORY;
+ pci_shmem_pci_device.bar[1] = cpu_to_le32(msix_block | PCI_BASE_ADDRESS_SPACE_MEMORY);
pci_shmem_pci_device.bar_size[1] = 0x1010;
- pci_shmem_pci_device.bar[2] = shmem_region->phys_addr | PCI_BASE_ADDRESS_SPACE_MEMORY;
+ pci_shmem_pci_device.bar[2] = cpu_to_le32(shmem_region->phys_addr | PCI_BASE_ADDRESS_SPACE_MEMORY);
pci_shmem_pci_device.bar_size[2] = shmem_region->size;
pci__register(&pci_shmem_pci_device, dev);
diff --git a/tools/kvm/hw/vesa.c b/tools/kvm/hw/vesa.c
index 22b1652..63f1082 100644
--- a/tools/kvm/hw/vesa.c
+++ b/tools/kvm/hw/vesa.c
@@ -8,6 +8,7 @@
#include "kvm/irq.h"
#include "kvm/kvm.h"
#include "kvm/pci.h"
+#include <linux/byteorder.h>
#include <sys/mman.h>
#include <sys/types.h>
@@ -31,14 +32,14 @@ static struct ioport_operations vesa_io_ops = {
};
static struct pci_device_header vesa_pci_device = {
- .vendor_id = PCI_VENDOR_ID_REDHAT_QUMRANET,
- .device_id = PCI_DEVICE_ID_VESA,
+ .vendor_id = cpu_to_le16(PCI_VENDOR_ID_REDHAT_QUMRANET),
+ .device_id = cpu_to_le16(PCI_DEVICE_ID_VESA),
.header_type = PCI_HEADER_TYPE_NORMAL,
.revision_id = 0,
- .class = 0x030000,
- .subsys_vendor_id = PCI_SUBSYSTEM_VENDOR_ID_REDHAT_QUMRANET,
- .subsys_id = PCI_SUBSYSTEM_ID_VESA,
- .bar[1] = VESA_MEM_ADDR | PCI_BASE_ADDRESS_SPACE_MEMORY,
+ .class[2] = 0x03,
+ .subsys_vendor_id = cpu_to_le16(PCI_SUBSYSTEM_VENDOR_ID_REDHAT_QUMRANET),
+ .subsys_id = cpu_to_le16(PCI_SUBSYSTEM_ID_VESA),
+ .bar[1] = cpu_to_le32(VESA_MEM_ADDR | PCI_BASE_ADDRESS_SPACE_MEMORY),
.bar_size[1] = VESA_MEM_SIZE,
};
@@ -56,7 +57,7 @@ struct framebuffer *vesa__init(struct kvm *kvm)
vesa_pci_device.irq_pin = pin;
vesa_pci_device.irq_line = line;
vesa_base_addr = ioport__register(IOPORT_EMPTY, &vesa_io_ops, IOPORT_SIZE, NULL);
- vesa_pci_device.bar[0] = vesa_base_addr | PCI_BASE_ADDRESS_SPACE_IO;
+ vesa_pci_device.bar[0] = cpu_to_le32(vesa_base_addr | PCI_BASE_ADDRESS_SPACE_IO);
pci__register(&vesa_pci_device, dev);
mem = mmap(NULL, VESA_MEM_SIZE, PROT_RW, MAP_ANON_NORESERVE, -1, 0);
diff --git a/tools/kvm/include/kvm/ioport.h b/tools/kvm/include/kvm/ioport.h
index 61a70ec..09bf876 100644
--- a/tools/kvm/include/kvm/ioport.h
+++ b/tools/kvm/include/kvm/ioport.h
@@ -7,6 +7,7 @@
#include <limits.h>
#include <asm/types.h>
#include <linux/types.h>
+#include <linux/byteorder.h>
/* some ports we reserve for own use */
#define IOPORT_DBG 0xe0
@@ -36,15 +37,15 @@ static inline u8 ioport__read8(u8 *data)
{
return *data;
}
-
+/* On BE platforms, PCI I/O is byteswapped, i.e. LE, so swap back. */
static inline u16 ioport__read16(u16 *data)
{
- return *data;
+ return le16_to_cpu(*data);
}
static inline u32 ioport__read32(u32 *data)
{
- return *data;
+ return le32_to_cpu(*data);
}
static inline void ioport__write8(u8 *data, u8 value)
@@ -54,12 +55,12 @@ static inline void ioport__write8(u8 *data, u8 value)
static inline void ioport__write16(u16 *data, u16 value)
{
- *data = value;
+ *data = cpu_to_le16(value);
}
static inline void ioport__write32(u32 *data, u32 value)
{
- *data = value;
+ *data = cpu_to_le32(value);
}
#endif /* KVM__IOPORT_H */
diff --git a/tools/kvm/include/kvm/pci.h b/tools/kvm/include/kvm/pci.h
index b578ad7..21f93d0 100644
--- a/tools/kvm/include/kvm/pci.h
+++ b/tools/kvm/include/kvm/pci.h
@@ -5,6 +5,7 @@
#include <linux/kvm.h>
#include <linux/pci_regs.h>
#include <linux/msi.h>
+#include <endian.h>
#define PCI_MAX_DEVICES 256
/*
@@ -17,14 +18,27 @@
#define PCI_CONFIG_BUS_FORWARD 0xcfa
#define PCI_IO_SIZE 0x100
-struct pci_config_address {
- unsigned zeros : 2; /* 1 .. 0 */
- unsigned register_number : 6; /* 7 .. 2 */
- unsigned function_number : 3; /* 10 .. 8 */
- unsigned device_number : 5; /* 15 .. 11 */
- unsigned bus_number : 8; /* 23 .. 16 */
- unsigned reserved : 7; /* 30 .. 24 */
- unsigned enable_bit : 1; /* 31 */
+union pci_config_address {
+ struct {
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+ unsigned zeros : 2; /* 1 .. 0 */
+ unsigned register_number : 6; /* 7 .. 2 */
+ unsigned function_number : 3; /* 10 .. 8 */
+ unsigned device_number : 5; /* 15 .. 11 */
+ unsigned bus_number : 8; /* 23 .. 16 */
+ unsigned reserved : 7; /* 30 .. 24 */
+ unsigned enable_bit : 1; /* 31 */
+#else
+ unsigned enable_bit : 1; /* 31 */
+ unsigned reserved : 7; /* 30 .. 24 */
+ unsigned bus_number : 8; /* 23 .. 16 */
+ unsigned device_number : 5; /* 15 .. 11 */
+ unsigned function_number : 3; /* 10 .. 8 */
+ unsigned register_number : 6; /* 7 .. 2 */
+ unsigned zeros : 2; /* 1 .. 0 */
+#endif
+ };
+ u32 w;
};
struct msix_table {
@@ -45,8 +59,8 @@ struct pci_device_header {
u16 device_id;
u16 command;
u16 status;
- u16 revision_id : 8;
- u32 class : 24;
+ u8 revision_id;
+ u8 class[3];
u8 cacheline_size;
u8 latency_timer;
u8 header_type;
@@ -56,8 +70,8 @@ struct pci_device_header {
u16 subsys_vendor_id;
u16 subsys_id;
u32 exp_rom_bar;
- u32 capabilities : 8;
- u32 reserved1 : 24;
+ u8 capabilities;
+ u8 reserved1[3];
u32 reserved2;
u8 irq_line;
u8 irq_pin;
@@ -66,7 +80,7 @@ struct pci_device_header {
struct msix_cap msix;
u8 empty[136]; /* Rest of PCI config space */
u32 bar_size[6];
-};
+} __attribute__((packed));
void pci__init(void);
void pci__register(struct pci_device_header *dev, u8 dev_num);
diff --git a/tools/kvm/pci.c b/tools/kvm/pci.c
index 920e13e..5bbcbc7 100644
--- a/tools/kvm/pci.c
+++ b/tools/kvm/pci.c
@@ -9,7 +9,7 @@
static struct pci_device_header *pci_devices[PCI_MAX_DEVICES];
-static struct pci_config_address pci_config_address;
+static union pci_config_address pci_config_address;
/* This is within our PCI gap - in an unused area */
static u32 io_space_blocks = KVM_32BIT_GAP_START + 0x1000000;
@@ -105,7 +105,7 @@ static bool pci_config_data_out(struct ioport *ioport, struct kvm *kvm, u16 port
* When the kernel got the size it would write the address
* back.
*/
- if (ioport__read32(p + offset)) {
+ if (*(u32 *)(p + offset)) {
/* See if kernel tries to mask one of the BARs */
if ((offset >= PCI_BAR_OFFSET(0)) &&
(offset <= PCI_BAR_OFFSET(6)) &&
diff --git a/tools/kvm/virtio/pci.c b/tools/kvm/virtio/pci.c
index d9fc3a5..acb7d96 100644
--- a/tools/kvm/virtio/pci.c
+++ b/tools/kvm/virtio/pci.c
@@ -9,6 +9,7 @@
#include "kvm/virtio-trans.h"
#include <linux/virtio_pci.h>
+#include <linux/byteorder.h>
#include <string.h>
struct virtio_trans_ops *virtio_pci__get_trans_ops(void)
@@ -59,7 +60,7 @@ static int virtio_pci__init_ioeventfd(struct kvm *kvm, struct virtio_trans *vtra
static inline bool virtio_pci__msix_enabled(struct virtio_pci *vpci)
{
- return vpci->pci_hdr.msix.ctrl & PCI_MSIX_FLAGS_ENABLE;
+ return vpci->pci_hdr.msix.ctrl & cpu_to_le16(PCI_MSIX_FLAGS_ENABLE);
}
static bool virtio_pci__specific_io_in(struct kvm *kvm, struct virtio_trans *vtrans, u16 port,
@@ -244,8 +245,8 @@ int virtio_pci__signal_vq(struct kvm *kvm, struct virtio_trans *vtrans, u32 vq)
int tbl = vpci->vq_vector[vq];
if (virtio_pci__msix_enabled(vpci)) {
- if (vpci->pci_hdr.msix.ctrl & PCI_MSIX_FLAGS_MASKALL ||
- vpci->msix_table[tbl].ctrl & PCI_MSIX_ENTRY_CTRL_MASKBIT) {
+ if (vpci->pci_hdr.msix.ctrl & cpu_to_le16(PCI_MSIX_FLAGS_MASKALL) ||
+ vpci->msix_table[tbl].ctrl & cpu_to_le16(PCI_MSIX_ENTRY_CTRL_MASKBIT)) {
vpci->msix_pba |= 1 << tbl;
return 0;
@@ -265,8 +266,8 @@ int virtio_pci__signal_config(struct kvm *kvm, struct virtio_trans *vtrans)
int tbl = vpci->config_vector;
if (virtio_pci__msix_enabled(vpci)) {
- if (vpci->pci_hdr.msix.ctrl & PCI_MSIX_FLAGS_MASKALL ||
- vpci->msix_table[tbl].ctrl & PCI_MSIX_ENTRY_CTRL_MASKBIT) {
+ if (vpci->pci_hdr.msix.ctrl & cpu_to_le16(PCI_MSIX_FLAGS_MASKALL) ||
+ vpci->msix_table[tbl].ctrl & cpu_to_le16(PCI_MSIX_ENTRY_CTRL_MASKBIT)) {
vpci->msix_pba |= 1 << tbl;
return 0;
@@ -296,19 +297,21 @@ int virtio_pci__init(struct kvm *kvm, struct virtio_trans *vtrans, void *dev,
kvm__register_mmio(kvm, vpci->msix_pba_block, 0x100, callback_mmio_pba, vpci);
vpci->pci_hdr = (struct pci_device_header) {
- .vendor_id = PCI_VENDOR_ID_REDHAT_QUMRANET,
- .device_id = device_id,
+ .vendor_id = cpu_to_le16(PCI_VENDOR_ID_REDHAT_QUMRANET),
+ .device_id = cpu_to_le16(device_id),
.header_type = PCI_HEADER_TYPE_NORMAL,
.revision_id = 0,
- .class = class,
- .subsys_vendor_id = PCI_SUBSYSTEM_VENDOR_ID_REDHAT_QUMRANET,
- .subsys_id = subsys_id,
- .bar[0] = vpci->base_addr | PCI_BASE_ADDRESS_SPACE_IO,
- .bar[1] = vpci->msix_io_block | PCI_BASE_ADDRESS_SPACE_MEMORY
- | PCI_BASE_ADDRESS_MEM_TYPE_64,
- .bar[3] = vpci->msix_pba_block | PCI_BASE_ADDRESS_SPACE_MEMORY
- | PCI_BASE_ADDRESS_MEM_TYPE_64,
- .status = PCI_STATUS_CAP_LIST,
+ .class[0] = class & 0xff,
+ .class[1] = (class >> 8) & 0xff,
+ .class[2] = (class >> 16) & 0xff,
+ .subsys_vendor_id = cpu_to_le16(PCI_SUBSYSTEM_VENDOR_ID_REDHAT_QUMRANET),
+ .subsys_id = cpu_to_le16(subsys_id),
+ .bar[0] = cpu_to_le32(vpci->base_addr | PCI_BASE_ADDRESS_SPACE_IO),
+ .bar[1] = cpu_to_le32(vpci->msix_io_block | PCI_BASE_ADDRESS_SPACE_MEMORY
+ | PCI_BASE_ADDRESS_MEM_TYPE_64),
+ .bar[3] = cpu_to_le32(vpci->msix_pba_block | PCI_BASE_ADDRESS_SPACE_MEMORY
+ | PCI_BASE_ADDRESS_MEM_TYPE_64),
+ .status = cpu_to_le16(PCI_STATUS_CAP_LIST),
.capabilities = (void *)&vpci->pci_hdr.msix - (void *)&vpci->pci_hdr,
};
@@ -325,14 +328,14 @@ int virtio_pci__init(struct kvm *kvm, struct virtio_trans *vtrans, void *dev,
* For example, a returned value of "00000000011"
* indicates a table size of 4.
*/
- vpci->pci_hdr.msix.ctrl = (VIRTIO_PCI_MAX_VQ + VIRTIO_PCI_MAX_CONFIG - 1);
+ vpci->pci_hdr.msix.ctrl = cpu_to_le16(VIRTIO_PCI_MAX_VQ + VIRTIO_PCI_MAX_CONFIG - 1);
/*
* Both table and PBA could be mapped on the same BAR, but for now
* we're not in short of BARs
*/
- vpci->pci_hdr.msix.table_offset = 1; /* Use BAR 1 */
- vpci->pci_hdr.msix.pba_offset = 3; /* Use BAR 3 */
+ vpci->pci_hdr.msix.table_offset = cpu_to_le32(1); /* Use BAR 1 */
+ vpci->pci_hdr.msix.pba_offset = cpu_to_le32(3); /* Use BAR 3 */
vpci->config_vector = 0;
if (irq__register_device(subsys_id, &ndev, &pin, &line) < 0)
next prev parent reply other threads:[~2011-12-09 6:55 UTC|newest]
Thread overview: 74+ messages / expand[flat|nested] mbox.gz Atom feed top
[not found] <cover.1323413420.git.matt@ozlabs.org>
2011-12-09 6:52 ` [PATCH V2 01/23] kvm tools: Only build/init i8042 on x86 Matt Evans
2011-12-09 6:52 ` Matt Evans
2011-12-09 6:52 ` [PATCH V2 03/23] kvm tools: Re-arrange Makefile to heed CFLAGS before Matt Evans
2011-12-09 6:52 ` [PATCH V2 03/23] kvm tools: Re-arrange Makefile to heed CFLAGS before checking for optional libs Matt Evans
2011-12-09 6:53 ` [PATCH V2 02/23] kvm tools: Add Makefile parameter for kernel include Matt Evans
2011-12-09 6:53 ` [PATCH V2 02/23] kvm tools: Add Makefile parameter for kernel include path Matt Evans
2011-12-09 6:53 ` [PATCH V2 04/23] kvm tools: Get correct 64-bit types on PPC64 and Matt Evans
2011-12-09 6:53 ` [PATCH V2 04/23] kvm tools: Get correct 64-bit types on PPC64 and link appropriately Matt Evans
2011-12-09 8:24 ` [PATCH V2 04/23] kvm tools: Get correct 64-bit types on PPC64 Sasha Levin
2011-12-09 8:24 ` [PATCH V2 04/23] kvm tools: Get correct 64-bit types on PPC64 and link appropriately Sasha Levin
2011-12-09 8:29 ` [PATCH V2 04/23] kvm tools: Get correct 64-bit types on PPC64 and Pekka Enberg
2011-12-09 8:29 ` [PATCH V2 04/23] kvm tools: Get correct 64-bit types on PPC64 and link appropriately Pekka Enberg
2011-12-12 1:03 ` [PATCH V2 04/23] kvm tools: Get correct 64-bit types on PPC64 Matt Evans
2011-12-12 1:03 ` [PATCH V2 04/23] kvm tools: Get correct 64-bit types on PPC64 and link appropriately Matt Evans
2011-12-12 5:57 ` [PATCH V2 04/23] kvm tools: Get correct 64-bit types on PPC64 Pekka Enberg
2011-12-12 5:57 ` [PATCH V2 04/23] kvm tools: Get correct 64-bit types on PPC64 and link appropriately Pekka Enberg
2011-12-13 6:44 ` [PATCH V2 04/23] kvm tools: Get correct 64-bit types on PPC64 Matt Evans
2011-12-13 6:44 ` [PATCH V2 04/23] kvm tools: Get correct 64-bit types on PPC64 and link appropriately Matt Evans
2011-12-09 6:53 ` [PATCH V2 05/23] kvm tools: Add arch-specific KVM_RUN exit handling Matt Evans
2011-12-09 6:53 ` [PATCH V2 05/23] kvm tools: Add arch-specific KVM_RUN exit handling via kvm_cpu__handle_exit() Matt Evans
2011-12-09 6:54 ` [PATCH V2 06/23] kvm tools: Don't die if KVM_CAP_NR_VCPUS isn't available Matt Evans
2011-12-09 6:54 ` Matt Evans
2011-12-09 6:54 ` [PATCH V2 07/23] kvm tools: Fix KVM_RUN exit code check Matt Evans
2011-12-09 6:54 ` Matt Evans
2011-12-09 6:54 ` [PATCH V2 08/23] kvm tools: Add kvm__arch_periodic_poll() Matt Evans
2011-12-09 6:54 ` Matt Evans
2011-12-09 6:54 ` [PATCH V2 09/23] kvm tools: Move arch-specific cmdline init into Matt Evans
2011-12-09 6:54 ` [PATCH V2 09/23] kvm tools: Move arch-specific cmdline init into kvm__arch_set_cmdline() Matt Evans
2011-12-09 6:54 ` [PATCH V2 10/23] kvm tools: Add CONSOLE_HV term type and allow it Matt Evans
2011-12-09 6:54 ` [PATCH V2 10/23] kvm tools: Add CONSOLE_HV term type and allow it to be selected Matt Evans
2011-12-09 6:54 ` [PATCH V2 11/23] kvm tools: Fix term_getc(), term_getc_iov() endian Matt Evans
2011-12-09 6:54 ` [PATCH V2 11/23] kvm tools: Fix term_getc(), term_getc_iov() endian bugs Matt Evans
2011-12-09 6:54 ` [PATCH V2 12/23] kvm tools: Allow initrd_check() to match a cpio Matt Evans
2011-12-09 6:54 ` Matt Evans
2011-12-09 6:54 ` [PATCH V2 13/23] kvm tools: Allow load_flat_binary() to load an initrd Matt Evans
2011-12-09 6:54 ` [PATCH V2 13/23] kvm tools: Allow load_flat_binary() to load an initrd alongside Matt Evans
2011-12-09 6:55 ` [PATCH V2 14/23] kvm tools: Initialise PCI before devices start getting Matt Evans
2011-12-09 6:55 ` [PATCH V2 14/23] kvm tools: Initialise PCI before devices start getting registered with PCI Matt Evans
2011-12-09 6:55 ` [PATCH V2 15/23] kvm tools: Perform CPU and firmware setup after Matt Evans
2011-12-09 6:55 ` [PATCH V2 15/23] kvm tools: Perform CPU and firmware setup after devices are added Matt Evans
2011-12-09 6:55 ` [PATCH V2 16/23] kvm tools: Init IRQs after determining nrcpus Matt Evans
2011-12-09 6:55 ` Matt Evans
2011-12-09 6:55 ` [PATCH V2 17/23] kvm tools: Add ability to map guest RAM from hugetlbfs Matt Evans
2011-12-09 6:55 ` Matt Evans
2011-12-09 7:39 ` [PATCH V2 17/23] kvm tools: Add ability to map guest RAM from Sasha Levin
2011-12-09 7:39 ` [PATCH V2 17/23] kvm tools: Add ability to map guest RAM from hugetlbfs Sasha Levin
2011-12-12 5:05 ` [PATCH V2 17/23] kvm tools: Add ability to map guest RAM from Matt Evans
2011-12-12 5:05 ` [PATCH V2 17/23] kvm tools: Add ability to map guest RAM from hugetlbfs Matt Evans
2011-12-09 8:38 ` Pekka Enberg
2011-12-09 8:38 ` Pekka Enberg
2011-12-12 6:19 ` [PATCH V2 17/23] kvm tools: Add ability to map guest RAM from Matt Evans
2011-12-12 6:19 ` [PATCH V2 17/23] kvm tools: Add ability to map guest RAM from hugetlbfs Matt Evans
2011-12-09 8:42 ` Pekka Enberg
2011-12-09 8:42 ` Pekka Enberg
2011-12-12 5:17 ` [PATCH V2 17/23] kvm tools: Add ability to map guest RAM from Matt Evans
2011-12-12 5:17 ` [PATCH V2 17/23] kvm tools: Add ability to map guest RAM from hugetlbfs Matt Evans
2011-12-12 6:06 ` Pekka Enberg
2011-12-12 6:06 ` Pekka Enberg
2011-12-09 6:55 ` [PATCH V2 18/23] kvm tools: Move PCI_MAX_DEVICES to pci.h Matt Evans
2011-12-09 6:55 ` Matt Evans
2011-12-09 6:55 ` Matt Evans [this message]
2011-12-09 6:55 ` [PATCH V2 19/23] kvm tools: Endian-sanitise pci.h and PCI device setup Matt Evans
2011-12-09 6:55 ` [PATCH V2 20/23] kvm tools: Correctly set virtio-pci bar_size and Matt Evans
2011-12-09 6:55 ` [PATCH V2 20/23] kvm tools: Correctly set virtio-pci bar_size and remove hardwired address Matt Evans
2011-12-09 6:55 ` [PATCH V2 21/23] kvm tools: Add pci__config_{rd,wr}(), pci__find_dev() Matt Evans
2011-12-09 6:55 ` Matt Evans
2011-12-09 6:55 ` [PATCH V2 22/23] kvm tools: Arch-specific define for PCI MMIO allocation Matt Evans
2011-12-09 6:55 ` [PATCH V2 22/23] kvm tools: Arch-specific define for PCI MMIO allocation area Matt Evans
2011-12-09 6:56 ` [PATCH V2 23/23] kvm tools: Create arch-specific kvm_cpu__emulate_{mm}io() Matt Evans
2011-12-09 6:56 ` Matt Evans
2011-12-09 7:53 ` [PATCH V2 23/23] kvm tools: Create arch-specific Sasha Levin
2011-12-09 7:53 ` [PATCH V2 23/23] kvm tools: Create arch-specific kvm_cpu__emulate_{mm}io() Sasha Levin
2011-12-12 1:08 ` Matt Evans
2011-12-12 1:08 ` Matt Evans
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=4EE1B0E8.3080808@ozlabs.org \
--to=matt@ozlabs.org \
--cc=asias.hejun@gmail.com \
--cc=gorcunov@gmail.com \
--cc=kvm-ppc@vger.kernel.org \
--cc=kvm@vger.kernel.org \
--cc=levinsasha928@gmail.com \
--cc=penberg@kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.