diff options
author | Elena Ufimtseva <elena.ufimtseva@oracle.com> | 2021-01-29 11:46:16 -0500 |
---|---|---|
committer | Stefan Hajnoczi <stefanha@redhat.com> | 2021-02-10 09:23:28 +0000 |
commit | 11ab872588335918ddc83c73957077bb85a38a6d (patch) | |
tree | cded7359c1b1b5493739e1485ef91d9c49de0ebe /hw/remote/proxy.c | |
parent | e7b2c9eaa258f9ba647fa81aaab344ddd82d0ecc (diff) |
multi-process: Forward PCI config space acceses to the remote process
The Proxy Object sends the PCI config space accesses as messages
to the remote process over the communication channel
Signed-off-by: Elena Ufimtseva <elena.ufimtseva@oracle.com>
Signed-off-by: Jagannathan Raman <jag.raman@oracle.com>
Signed-off-by: John G Johnson <john.g.johnson@oracle.com>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Message-id: d3c94f4618813234655356c60e6f0d0362ff42d6.1611938319.git.jag.raman@oracle.com
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
Diffstat (limited to 'hw/remote/proxy.c')
-rw-r--r-- | hw/remote/proxy.c | 55 |
1 files changed, 55 insertions, 0 deletions
diff --git a/hw/remote/proxy.c b/hw/remote/proxy.c index cd5b071ab4..2b1439432b 100644 --- a/hw/remote/proxy.c +++ b/hw/remote/proxy.c @@ -17,6 +17,8 @@ #include "monitor/monitor.h" #include "migration/blocker.h" #include "qemu/sockets.h" +#include "hw/remote/mpqemu-link.h" +#include "qemu/error-report.h" static void pci_proxy_dev_realize(PCIDevice *device, Error **errp) { @@ -65,6 +67,56 @@ static void pci_proxy_dev_exit(PCIDevice *pdev) error_free(dev->migration_blocker); } +static void config_op_send(PCIProxyDev *pdev, uint32_t addr, uint32_t *val, + int len, unsigned int op) +{ + MPQemuMsg msg = { 0 }; + uint64_t ret = -EINVAL; + Error *local_err = NULL; + + msg.cmd = op; + msg.data.pci_conf_data.addr = addr; + msg.data.pci_conf_data.val = (op == MPQEMU_CMD_PCI_CFGWRITE) ? *val : 0; + msg.data.pci_conf_data.len = len; + msg.size = sizeof(PciConfDataMsg); + + ret = mpqemu_msg_send_and_await_reply(&msg, pdev, &local_err); + if (local_err) { + error_report_err(local_err); + } + + if (ret == UINT64_MAX) { + error_report("Failed to perform PCI config %s operation", + (op == MPQEMU_CMD_PCI_CFGREAD) ? "READ" : "WRITE"); + } + + if (op == MPQEMU_CMD_PCI_CFGREAD) { + *val = (uint32_t)ret; + } +} + +static uint32_t pci_proxy_read_config(PCIDevice *d, uint32_t addr, int len) +{ + uint32_t val; + + config_op_send(PCI_PROXY_DEV(d), addr, &val, len, MPQEMU_CMD_PCI_CFGREAD); + + return val; +} + +static void pci_proxy_write_config(PCIDevice *d, uint32_t addr, uint32_t val, + int len) +{ + /* + * Some of the functions access the copy of remote device's PCI config + * space which is cached in the proxy device. Therefore, maintain + * it updated. + */ + pci_default_write_config(d, addr, val, len); + + config_op_send(PCI_PROXY_DEV(d), addr, &val, len, MPQEMU_CMD_PCI_CFGWRITE); +} + static Property proxy_properties[] = { DEFINE_PROP_STRING("fd", PCIProxyDev, fd), DEFINE_PROP_END_OF_LIST(), @@ -77,6 +129,9 @@ static void pci_proxy_dev_class_init(ObjectClass *klass, void *data) k->realize = pci_proxy_dev_realize; k->exit = pci_proxy_dev_exit; + k->config_read = pci_proxy_read_config; + k->config_write = pci_proxy_write_config; + device_class_set_props(dc, proxy_properties); } |