clear-pkgs-linux-iot-lts2018/1197-vhm-Emulate-PCI-extend...

67 lines
2.2 KiB
Diff

From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Liu Xinyun <xinyun.liu@intel.com>
Date: Thu, 21 Feb 2019 11:37:04 +0800
Subject: [PATCH] vhm: Emulate PCI extended cfg mmio access as PCI request
This kind of specific mmio access is to access PCI configuration space.
Treat them as PCI request for other ioreq client to handle them more
conveniently.
v2: Removed previous limitation that for gvt device only.
v3: sustract address base offset
Tracked-On: projectacrn/acrn-hypervisor#2971
Signed-off-by: Liu Xinyun <xinyun.liu@intel.com>
Reviewed-by: Zhao Yakui <yakui.zhao@intel.com>
---
drivers/vhm/vhm_ioreq.c | 26 ++++++++++++++++++++++++++
1 file changed, 26 insertions(+)
diff --git a/drivers/vhm/vhm_ioreq.c b/drivers/vhm/vhm_ioreq.c
index 6dd5783f3aae..8aab2c3cb55d 100644
--- a/drivers/vhm/vhm_ioreq.c
+++ b/drivers/vhm/vhm_ioreq.c
@@ -838,6 +838,31 @@ static int handle_cf8cfc(struct vhm_vm *vm, struct vhm_request *req, int vcpu)
return err ? err: req_handled;
}
+#define MAXBUSES (PCI_BUSMAX + 1)
+#define PCI_EMUL_ECFG_BASE 0xE0000000
+#define PCI_EMUL_ECFG_SIZE (MAXBUSES * 1024 * 1024)
+#define PCI_EMUL_ECFG_BOARDER (PCI_EMUL_ECFG_BASE + PCI_EMUL_ECFG_SIZE)
+
+static int handle_pcie_cfg(struct vhm_vm *vm, struct vhm_request *req, int vcpu)
+{
+ uint64_t addr = req->reqs.mmio_request.address;
+
+ if (req->type != REQ_MMIO || addr < PCI_EMUL_ECFG_BASE ||
+ addr + req->reqs.mmio_request.size >= PCI_EMUL_ECFG_BOARDER) {
+ return -1;
+ }
+
+ addr -= PCI_EMUL_ECFG_BASE;
+
+ req->type = REQ_PCICFG;
+ req->reqs.pci_request.bus = (addr >> 20) & 0xFF;
+ req->reqs.pci_request.dev = (addr >> 15) & 0x1F;
+ req->reqs.pci_request.func = (addr >> 12) & 0x7;
+ req->reqs.pci_request.reg = addr & 0xfff;
+
+ return 0;
+}
+
static bool bdf_match(struct vhm_request *req, struct ioreq_client *client)
{
int cached_bus, cached_dev, cached_func;
@@ -923,6 +948,7 @@ int acrn_ioreq_distribute_request(struct vhm_vm *vm)
if (atomic_read(&req->processed) == REQ_STATE_PENDING) {
if (handle_cf8cfc(vm, req, i))
continue;
+ handle_pcie_cfg(vm, req, i);
client = acrn_ioreq_find_client_by_request(vm, req);
if (client == NULL) {
pr_err("vhm-ioreq: failed to "
--
https://clearlinux.org