Rather than performing all config accesses via ioports, map in a 24-bit
memory-mapped configuration space directly below the PCI MMIO region.

This will allow architectures to support PCI without having to support
legacy ioports in the guest kernel. Instead, kvm tool can forward the
config accesses directly to the relevant ioport config callbacks.

Signed-off-by: Will Deacon <will.dea...@arm.com>
---
 tools/kvm/arm/include/arm-common/kvm-arch.h |  7 +++++--
 tools/kvm/include/kvm/pci.h                 |  1 +
 tools/kvm/pci.c                             | 31 +++++++++++++++++++++++++----
 tools/kvm/powerpc/include/kvm/kvm-arch.h    |  5 +++--
 tools/kvm/x86/include/kvm/kvm-arch.h        |  5 +++--
 5 files changed, 39 insertions(+), 10 deletions(-)

diff --git a/tools/kvm/arm/include/arm-common/kvm-arch.h 
b/tools/kvm/arm/include/arm-common/kvm-arch.h
index 72b204fd45a4..caef590a44ff 100644
--- a/tools/kvm/arm/include/arm-common/kvm-arch.h
+++ b/tools/kvm/arm/include/arm-common/kvm-arch.h
@@ -19,10 +19,13 @@
 
 #define ARM_IOPORT_SIZE                (ARM_MMIO_AREA - ARM_IOPORT_AREA)
 #define ARM_VIRTIO_MMIO_SIZE   (ARM_AXI_AREA - (ARM_MMIO_AREA + ARM_GIC_SIZE))
-#define ARM_PCI_MMIO_SIZE      (ARM_MEMORY_AREA - ARM_AXI_AREA)
+#define ARM_PCI_CFG_SIZE       (1ULL << 24)
+#define ARM_PCI_MMIO_SIZE      (ARM_MEMORY_AREA - \
+                               (ARM_AXI_AREA + ARM_PCI_CFG_SIZE))
 
 #define KVM_IOPORT_AREA                ARM_IOPORT_AREA
-#define KVM_PCI_MMIO_AREA      ARM_AXI_AREA
+#define KVM_PCI_CFG_AREA       ARM_AXI_AREA
+#define KVM_PCI_MMIO_AREA      (KVM_PCI_CFG_AREA + ARM_PCI_CFG_SIZE)
 #define KVM_VIRTIO_MMIO_AREA   ARM_MMIO_AREA
 
 #define VIRTIO_DEFAULT_TRANS   VIRTIO_MMIO
diff --git a/tools/kvm/include/kvm/pci.h b/tools/kvm/include/kvm/pci.h
index 3da381175c8d..e1e621d51470 100644
--- a/tools/kvm/include/kvm/pci.h
+++ b/tools/kvm/include/kvm/pci.h
@@ -18,6 +18,7 @@
 #define PCI_CONFIG_DATA                0xcfc
 #define PCI_CONFIG_BUS_FORWARD 0xcfa
 #define PCI_IO_SIZE            0x100
+#define PCI_CFG_SIZE           (1ULL << 24)
 
 union pci_config_address {
        struct {
diff --git a/tools/kvm/pci.c b/tools/kvm/pci.c
index 8d3732d35842..e735352eb042 100644
--- a/tools/kvm/pci.c
+++ b/tools/kvm/pci.c
@@ -162,6 +162,20 @@ void pci__config_rd(struct kvm *kvm, union 
pci_config_address addr, void *data,
        }
 }
 
+static void pci_config_mmio_access(u64 addr, u8 *data, u32 len, u8 is_write, 
void *kvm)
+{
+       union pci_config_address cfg_addr;
+
+       addr                    -= KVM_PCI_CFG_AREA;
+       cfg_addr.w              = (u32)addr;
+       cfg_addr.enable_bit     = 1;
+
+       if (is_write)
+               pci__config_wr(kvm, cfg_addr, data, len);
+       else
+               pci__config_rd(kvm, cfg_addr, data, len);
+}
+
 struct pci_device_header *pci__find_dev(u8 dev_num)
 {
        struct device_header *hdr = device__find_dev(DEVICE_BUS_PCI, dev_num);
@@ -181,12 +195,21 @@ int pci__init(struct kvm *kvm)
                return r;
 
        r = ioport__register(kvm, PCI_CONFIG_ADDRESS + 0, 
&pci_config_address_ops, 4, NULL);
-       if (r < 0) {
-               ioport__unregister(kvm, PCI_CONFIG_DATA);
-               return r;
-       }
+       if (r < 0)
+               goto err_unregister_data;
+
+       r = kvm__register_mmio(kvm, KVM_PCI_CFG_AREA, PCI_CFG_SIZE, false,
+                              pci_config_mmio_access, kvm);
+       if (r < 0)
+               goto err_unregister_addr;
 
        return 0;
+
+err_unregister_addr:
+       ioport__unregister(kvm, PCI_CONFIG_ADDRESS);
+err_unregister_data:
+       ioport__unregister(kvm, PCI_CONFIG_DATA);
+       return r;
 }
 dev_base_init(pci__init);
 
diff --git a/tools/kvm/powerpc/include/kvm/kvm-arch.h 
b/tools/kvm/powerpc/include/kvm/kvm-arch.h
index 96dea91cbedd..c147c78b71e7 100644
--- a/tools/kvm/powerpc/include/kvm/kvm-arch.h
+++ b/tools/kvm/powerpc/include/kvm/kvm-arch.h
@@ -38,8 +38,9 @@
  * from.  Note that this is a PCI bus address.
  */
 #define KVM_IOPORT_AREA                        0x0
-#define KVM_PCI_MMIO_AREA              0x1000000
-#define KVM_VIRTIO_MMIO_AREA           0x2000000
+#define KVM_PCI_CFG_AREA               0x1000000
+#define KVM_PCI_MMIO_AREA              0x2000000
+#define KVM_VIRTIO_MMIO_AREA           0x3000000
 
 #define VIRTIO_DEFAULT_TRANS   VIRTIO_PCI
 
diff --git a/tools/kvm/x86/include/kvm/kvm-arch.h 
b/tools/kvm/x86/include/kvm/kvm-arch.h
index 6d59c8e5de0a..8e8389627354 100644
--- a/tools/kvm/x86/include/kvm/kvm-arch.h
+++ b/tools/kvm/x86/include/kvm/kvm-arch.h
@@ -21,8 +21,9 @@
  * from.  Note that this is a PCI bus address (though same on x86).
  */
 #define KVM_IOPORT_AREA                0x0
-#define KVM_PCI_MMIO_AREA      (KVM_MMIO_START + 0x1000000)
-#define KVM_VIRTIO_MMIO_AREA   (KVM_MMIO_START + 0x2000000)
+#define KVM_PCI_CFG_AREA       (KVM_MMIO_START + 0x1000000)
+#define KVM_PCI_MMIO_AREA      (KVM_MMIO_START + 0x2000000)
+#define KVM_VIRTIO_MMIO_AREA   (KVM_MMIO_START + 0x3000000)
 
 #define VIRTIO_DEFAULT_TRANS   VIRTIO_PCI
 
-- 
1.8.2.2

--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to