summaryrefslogtreecommitdiffstats
path: root/hw/remote/message.c
diff options
context:
space:
mode:
authorJagannathan Raman2021-01-29 17:46:17 +0100
committerStefan Hajnoczi2021-02-10 10:23:28 +0100
commit7ee3f82384f07e84f1d2e26a0ab1e5efa7e7f822 (patch)
treeea9a7b872ac3d6ee0fbb8d2fe7496e0aed0318a8 /hw/remote/message.c
parentmulti-process: Forward PCI config space acceses to the remote process (diff)
downloadqemu-7ee3f82384f07e84f1d2e26a0ab1e5efa7e7f822.tar.gz
qemu-7ee3f82384f07e84f1d2e26a0ab1e5efa7e7f822.tar.xz
qemu-7ee3f82384f07e84f1d2e26a0ab1e5efa7e7f822.zip
multi-process: PCI BAR read/write handling for proxy & remote endpoints
Proxy device object implements handler for PCI BAR writes and reads. The handler uses BAR_WRITE/BAR_READ message to communicate to the remote process with the BAR address and value to be written/read. The remote process implements handler for BAR_WRITE/BAR_READ message. Signed-off-by: Jagannathan Raman <jag.raman@oracle.com> Signed-off-by: Elena Ufimtseva <elena.ufimtseva@oracle.com> Signed-off-by: John G Johnson <john.g.johnson@oracle.com> Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com> Message-id: a8b76714a9688be5552c4c92d089bc9e8a4707ff.1611938319.git.jag.raman@oracle.com Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
Diffstat (limited to 'hw/remote/message.c')
-rw-r--r--hw/remote/message.c83
1 files changed, 83 insertions, 0 deletions
diff --git a/hw/remote/message.c b/hw/remote/message.c
index 636bd161bd..f2e84457e0 100644
--- a/hw/remote/message.c
+++ b/hw/remote/message.c
@@ -16,11 +16,14 @@
#include "qapi/error.h"
#include "sysemu/runstate.h"
#include "hw/pci/pci.h"
+#include "exec/memattrs.h"
static void process_config_write(QIOChannel *ioc, PCIDevice *dev,
MPQemuMsg *msg, Error **errp);
static void process_config_read(QIOChannel *ioc, PCIDevice *dev,
MPQemuMsg *msg, Error **errp);
+static void process_bar_write(QIOChannel *ioc, MPQemuMsg *msg, Error **errp);
+static void process_bar_read(QIOChannel *ioc, MPQemuMsg *msg, Error **errp);
void coroutine_fn mpqemu_remote_msg_loop_co(void *data)
{
@@ -52,6 +55,12 @@ void coroutine_fn mpqemu_remote_msg_loop_co(void *data)
case MPQEMU_CMD_PCI_CFGREAD:
process_config_read(com->ioc, pci_dev, &msg, &local_err);
break;
+ case MPQEMU_CMD_BAR_WRITE:
+ process_bar_write(com->ioc, &msg, &local_err);
+ break;
+ case MPQEMU_CMD_BAR_READ:
+ process_bar_read(com->ioc, &msg, &local_err);
+ break;
default:
error_setg(&local_err,
"Unknown command (%d) received for device %s"
@@ -115,3 +124,77 @@ static void process_config_read(QIOChannel *ioc, PCIDevice *dev,
getpid());
}
}
+
+static void process_bar_write(QIOChannel *ioc, MPQemuMsg *msg, Error **errp)
+{
+ ERRP_GUARD();
+ BarAccessMsg *bar_access = &msg->data.bar_access;
+ AddressSpace *as =
+ bar_access->memory ? &address_space_memory : &address_space_io;
+ MPQemuMsg ret = { 0 };
+ MemTxResult res;
+ uint64_t val;
+
+ if (!is_power_of_2(bar_access->size) ||
+ (bar_access->size > sizeof(uint64_t))) {
+ ret.data.u64 = UINT64_MAX;
+ goto fail;
+ }
+
+ val = cpu_to_le64(bar_access->val);
+
+ res = address_space_rw(as, bar_access->addr, MEMTXATTRS_UNSPECIFIED,
+ (void *)&val, bar_access->size, true);
+
+ if (res != MEMTX_OK) {
+ error_setg(errp, "Bad address %"PRIx64" for mem write, pid "FMT_pid".",
+ bar_access->addr, getpid());
+ ret.data.u64 = -1;
+ }
+
+fail:
+ ret.cmd = MPQEMU_CMD_RET;
+ ret.size = sizeof(ret.data.u64);
+
+ if (!mpqemu_msg_send(&ret, ioc, NULL)) {
+ error_prepend(errp, "Error returning code to proxy, pid "FMT_pid": ",
+ getpid());
+ }
+}
+
+static void process_bar_read(QIOChannel *ioc, MPQemuMsg *msg, Error **errp)
+{
+ ERRP_GUARD();
+ BarAccessMsg *bar_access = &msg->data.bar_access;
+ MPQemuMsg ret = { 0 };
+ AddressSpace *as;
+ MemTxResult res;
+ uint64_t val = 0;
+
+ as = bar_access->memory ? &address_space_memory : &address_space_io;
+
+ if (!is_power_of_2(bar_access->size) ||
+ (bar_access->size > sizeof(uint64_t))) {
+ val = UINT64_MAX;
+ goto fail;
+ }
+
+ res = address_space_rw(as, bar_access->addr, MEMTXATTRS_UNSPECIFIED,
+ (void *)&val, bar_access->size, false);
+
+ if (res != MEMTX_OK) {
+ error_setg(errp, "Bad address %"PRIx64" for mem read, pid "FMT_pid".",
+ bar_access->addr, getpid());
+ val = UINT64_MAX;
+ }
+
+fail:
+ ret.cmd = MPQEMU_CMD_RET;
+ ret.data.u64 = le64_to_cpu(val);
+ ret.size = sizeof(ret.data.u64);
+
+ if (!mpqemu_msg_send(&ret, ioc, NULL)) {
+ error_prepend(errp, "Error returning code to proxy, pid "FMT_pid": ",
+ getpid());
+ }
+}