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.deacon@xxxxxxx> --- 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 majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html