aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndre Przywara <andre.przywara@arm.com>2021-03-15 15:33:46 +0000
committerWill Deacon <will@kernel.org>2021-03-18 09:44:45 +0000
commit1f56b9d10a28259f7a1aa6a379ab3ce9b3918ab6 (patch)
tree31c7a27bd5c0ea62144f9f5226e47aa4c055139c
parent205eaa794be7136b6fb8b7a7aedb78e92c972bb6 (diff)
downloadkvmtool-1f56b9d10a28259f7a1aa6a379ab3ce9b3918ab6.tar.gz
pci: Switch trap handling to use MMIO handler
With the planned retirement of the special ioport emulation code, we need to provide an emulation function compatible with the MMIO prototype. Merge the existing _in and _out handlers to adhere to that MMIO interface, and register these using the new registration function. Signed-off-by: Andre Przywara <andre.przywara@arm.com> Reviewed-by: Alexandru Elisei <alexandru.elisei@arm.com> Link: https://lore.kernel.org/r/20210315153350.19988-19-andre.przywara@arm.com Signed-off-by: Will Deacon <will@kernel.org>
-rw-r--r--pci.c82
1 files changed, 24 insertions, 58 deletions
diff --git a/pci.c b/pci.c
index 2e2c0270..d6da79e0 100644
--- a/pci.c
+++ b/pci.c
@@ -87,29 +87,16 @@ static void *pci_config_address_ptr(u16 port)
return base + offset;
}
-static bool pci_config_address_out(struct ioport *ioport, struct kvm_cpu *vcpu, u16 port, void *data, int size)
+static void pci_config_address_mmio(struct kvm_cpu *vcpu, u64 addr, u8 *data,
+ u32 len, u8 is_write, void *ptr)
{
- void *p = pci_config_address_ptr(port);
+ void *p = pci_config_address_ptr(addr);
- memcpy(p, data, size);
-
- return true;
-}
-
-static bool pci_config_address_in(struct ioport *ioport, struct kvm_cpu *vcpu, u16 port, void *data, int size)
-{
- void *p = pci_config_address_ptr(port);
-
- memcpy(data, p, size);
-
- return true;
+ if (is_write)
+ memcpy(p, data, len);
+ else
+ memcpy(data, p, len);
}
-
-static struct ioport_operations pci_config_address_ops = {
- .io_in = pci_config_address_in,
- .io_out = pci_config_address_out,
-};
-
static bool pci_device_exists(u8 bus_number, u8 device_number, u8 function_number)
{
union pci_config_address pci_config_address;
@@ -125,49 +112,27 @@ static bool pci_device_exists(u8 bus_number, u8 device_number, u8 function_numbe
return !IS_ERR_OR_NULL(device__find_dev(DEVICE_BUS_PCI, device_number));
}
-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;
-
- if (size > 4)
- size = 4;
-
- 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.
- */
- pci_config_address.reg_offset = port - PCI_CONFIG_DATA;
-
- pci__config_wr(vcpu->kvm, pci_config_address, data, size);
-
- return true;
-}
-
-static bool pci_config_data_in(struct ioport *ioport, struct kvm_cpu *vcpu, u16 port, void *data, int size)
+static void pci_config_data_mmio(struct kvm_cpu *vcpu, u64 addr, u8 *data,
+ u32 len, u8 is_write, void *kvm)
{
union pci_config_address pci_config_address;
- if (size > 4)
- size = 4;
+ if (len > 4)
+ len = 4;
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.
*/
- pci_config_address.reg_offset = port - PCI_CONFIG_DATA;
+ pci_config_address.reg_offset = addr - PCI_CONFIG_DATA;
- pci__config_rd(vcpu->kvm, pci_config_address, data, size);
-
- return true;
+ if (is_write)
+ pci__config_wr(vcpu->kvm, pci_config_address, data, len);
+ else
+ pci__config_rd(vcpu->kvm, pci_config_address, data, len);
}
-static struct ioport_operations pci_config_data_ops = {
- .io_in = pci_config_data_in,
- .io_out = pci_config_data_out,
-};
-
static int pci_activate_bar(struct kvm *kvm, struct pci_device_header *pci_hdr,
int bar_num)
{
@@ -512,11 +477,12 @@ int pci__init(struct kvm *kvm)
{
int r;
- r = ioport__register(kvm, PCI_CONFIG_DATA + 0, &pci_config_data_ops, 4, NULL);
+ r = kvm__register_pio(kvm, PCI_CONFIG_DATA, 4,
+ pci_config_data_mmio, NULL);
if (r < 0)
return r;
-
- r = ioport__register(kvm, PCI_CONFIG_ADDRESS + 0, &pci_config_address_ops, 4, NULL);
+ r = kvm__register_pio(kvm, PCI_CONFIG_ADDRESS, 4,
+ pci_config_address_mmio, NULL);
if (r < 0)
goto err_unregister_data;
@@ -528,17 +494,17 @@ int pci__init(struct kvm *kvm)
return 0;
err_unregister_addr:
- ioport__unregister(kvm, PCI_CONFIG_ADDRESS);
+ kvm__deregister_pio(kvm, PCI_CONFIG_ADDRESS);
err_unregister_data:
- ioport__unregister(kvm, PCI_CONFIG_DATA);
+ kvm__deregister_pio(kvm, PCI_CONFIG_DATA);
return r;
}
dev_base_init(pci__init);
int pci__exit(struct kvm *kvm)
{
- ioport__unregister(kvm, PCI_CONFIG_DATA);
- ioport__unregister(kvm, PCI_CONFIG_ADDRESS);
+ kvm__deregister_pio(kvm, PCI_CONFIG_DATA);
+ kvm__deregister_pio(kvm, PCI_CONFIG_ADDRESS);
return 0;
}