qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: elena.ufimtseva@oracle.com
To: qemu-devel@nongnu.org
Cc: elena.ufimtseva@oracle.com, fam@euphon.net,
	swapnil.ingle@nutanix.com, john.g.johnson@oracle.com,
	kraxel@redhat.com, jag.raman@oracle.com, quintela@redhat.com,
	mst@redhat.com, armbru@redhat.com, kanth.ghatraju@oracle.com,
	felipe@nutanix.com, thuth@redhat.com, ehabkost@redhat.com,
	konrad.wilk@oracle.com, dgilbert@redhat.com,
	liran.alon@oracle.com, stefanha@redhat.com,
	thanos.makatos@nutanix.com, rth@twiddle.net, kwolf@redhat.com,
	berrange@redhat.com, mreitz@redhat.com,
	ross.lagerwall@citrix.com, marcandre.lureau@gmail.com,
	pbonzini@redhat.com
Subject: [PATCH RESEND v6 21/36] multi-process: PCI BAR read/write handling for proxy & remote endpoints
Date: Wed, 22 Apr 2020 21:13:56 -0700	[thread overview]
Message-ID: <5484f5bc8b9e80d50331b32b971f433b5c062e3a.1587614626.git.elena.ufimtseva@oracle.com> (raw)
In-Reply-To: <cover.1587614626.git.elena.ufimtseva@oracle.com>

From: Jagannathan Raman <jag.raman@oracle.com>

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>
---
 hw/proxy/qemu-proxy.c         | 64 ++++++++++++++++++++++++++
 include/hw/proxy/qemu-proxy.h | 20 ++++++++-
 include/io/mpqemu-link.h      | 12 +++++
 io/mpqemu-link.c              |  6 +++
 remote/remote-main.c          | 84 +++++++++++++++++++++++++++++++++++
 5 files changed, 184 insertions(+), 2 deletions(-)

diff --git a/hw/proxy/qemu-proxy.c b/hw/proxy/qemu-proxy.c
index 87cf39c672..7fd0a312a5 100644
--- a/hw/proxy/qemu-proxy.c
+++ b/hw/proxy/qemu-proxy.c
@@ -169,3 +169,67 @@ static void pci_proxy_dev_register_types(void)
 
 type_init(pci_proxy_dev_register_types)
 
+static void send_bar_access_msg(PCIProxyDev *dev, MemoryRegion *mr,
+                                bool write, hwaddr addr, uint64_t *val,
+                                unsigned size, bool memory)
+{
+    MPQemuLinkState *mpqemu_link = dev->mpqemu_link;
+    MPQemuMsg msg;
+    int wait;
+
+    memset(&msg, 0, sizeof(MPQemuMsg));
+
+    msg.bytestream = 0;
+    msg.size = sizeof(msg.data1);
+    msg.data1.bar_access.addr = mr->addr + addr;
+    msg.data1.bar_access.size = size;
+    msg.data1.bar_access.memory = memory;
+
+    if (write) {
+        msg.cmd = BAR_WRITE;
+        msg.data1.bar_access.val = *val;
+    } else {
+        wait = GET_REMOTE_WAIT;
+
+        msg.cmd = BAR_READ;
+        msg.num_fds = 1;
+        msg.fds[0] = wait;
+    }
+
+    mpqemu_msg_send(&msg, mpqemu_link->dev);
+
+    if (!write) {
+        *val = wait_for_remote(wait);
+        PUT_REMOTE_WAIT(wait);
+    }
+}
+
+void proxy_default_bar_write(void *opaque, hwaddr addr, uint64_t val,
+                             unsigned size)
+{
+    ProxyMemoryRegion *pmr = opaque;
+
+    send_bar_access_msg(pmr->dev, &pmr->mr, true, addr, &val, size,
+                        pmr->memory);
+}
+
+uint64_t proxy_default_bar_read(void *opaque, hwaddr addr, unsigned size)
+{
+    ProxyMemoryRegion *pmr = opaque;
+    uint64_t val;
+
+    send_bar_access_msg(pmr->dev, &pmr->mr, false, addr, &val, size,
+                        pmr->memory);
+
+     return val;
+}
+
+const MemoryRegionOps proxy_default_ops = {
+    .read = proxy_default_bar_read,
+    .write = proxy_default_bar_write,
+    .endianness = DEVICE_NATIVE_ENDIAN,
+    .impl = {
+        .min_access_size = 1,
+        .max_access_size = 1,
+    },
+};
diff --git a/include/hw/proxy/qemu-proxy.h b/include/hw/proxy/qemu-proxy.h
index d7eaf26f29..9e4127eccb 100644
--- a/include/hw/proxy/qemu-proxy.h
+++ b/include/hw/proxy/qemu-proxy.h
@@ -26,14 +26,25 @@
 #define PCI_PROXY_DEV_GET_CLASS(obj) \
             OBJECT_GET_CLASS(PCIProxyDevClass, (obj), TYPE_PCI_PROXY_DEV)
 
-typedef struct PCIProxyDev {
+typedef struct PCIProxyDev PCIProxyDev;
+
+typedef struct ProxyMemoryRegion {
+    PCIProxyDev *dev;
+    MemoryRegion mr;
+    bool memory;
+    bool present;
+    uint8_t type;
+} ProxyMemoryRegion;
+
+struct PCIProxyDev {
     PCIDevice parent_dev;
 
     MPQemuLinkState *mpqemu_link;
 
     int socket;
 
-} PCIProxyDev;
+    ProxyMemoryRegion region[PCI_NUM_REGIONS];
+};
 
 typedef struct PCIProxyDevClass {
     PCIDeviceClass parent_class;
@@ -43,4 +54,9 @@ typedef struct PCIProxyDevClass {
     char *command;
 } PCIProxyDevClass;
 
+void proxy_default_bar_write(void *opaque, hwaddr addr, uint64_t val,
+                             unsigned size);
+
+uint64_t proxy_default_bar_read(void *opaque, hwaddr addr, unsigned size);
+
 #endif /* QEMU_PROXY_H */
diff --git a/include/io/mpqemu-link.h b/include/io/mpqemu-link.h
index 7228a1915e..41cf092f9e 100644
--- a/include/io/mpqemu-link.h
+++ b/include/io/mpqemu-link.h
@@ -31,6 +31,8 @@
 /**
  * mpqemu_cmd_t:
  * SYNC_SYSMEM      Shares QEMU's RAM with remote device's RAM
+ * BAR_WRITE        Writes to PCI BAR region
+ * BAR_READ         Reads from PCI BAR region
  *
  * proc_cmd_t enum type to specify the command to be executed on the remote
  * device.
@@ -41,6 +43,8 @@ typedef enum {
     CONNECT_DEV,
     PCI_CONFIG_WRITE,
     PCI_CONFIG_READ,
+    BAR_WRITE,
+    BAR_READ,
     MAX,
 } mpqemu_cmd_t;
 
@@ -56,6 +60,13 @@ typedef struct {
     ram_addr_t offsets[REMOTE_MAX_FDS];
 } sync_sysmem_msg_t;
 
+typedef struct {
+    hwaddr addr;
+    uint64_t val;
+    unsigned size;
+    bool memory;
+} bar_access_msg_t;
+
 /**
  * MPQemuMsg:
  * @cmd: The remote command
@@ -78,6 +89,7 @@ typedef struct {
     union {
         uint64_t u64;
         sync_sysmem_msg_t sync_sysmem;
+        bar_access_msg_t bar_access;
     } data1;
 
     int fds[REMOTE_MAX_FDS];
diff --git a/io/mpqemu-link.c b/io/mpqemu-link.c
index ef4a07b81a..5cb93fc47b 100644
--- a/io/mpqemu-link.c
+++ b/io/mpqemu-link.c
@@ -387,6 +387,12 @@ bool mpqemu_msg_valid(MPQemuMsg *msg)
             return false;
         }
         break;
+    case BAR_WRITE:
+    case BAR_READ:
+        if (msg->size != sizeof(msg->data1)) {
+            return false;
+        }
+        break;
     default:
         break;
     }
diff --git a/remote/remote-main.c b/remote/remote-main.c
index 834574e172..0990509f7a 100644
--- a/remote/remote-main.c
+++ b/remote/remote-main.c
@@ -34,6 +34,7 @@
 #include "block/block.h"
 #include "exec/ramlist.h"
 #include "remote/remote-common.h"
+#include "exec/memattrs.h"
 
 static void process_msg(GIOCondition cond, MPQemuLinkState *link,
                         MPQemuChannel *chan);
@@ -114,6 +115,77 @@ exit:
     notify_proxy(wait, ret);
 }
 
+/* TODO: confirm memtx attrs. */
+static void process_bar_write(MPQemuMsg *msg, Error **errp)
+{
+    bar_access_msg_t *bar_access = &msg->data1.bar_access;
+    AddressSpace *as =
+        bar_access->memory ? &address_space_memory : &address_space_io;
+    MemTxResult res;
+
+    assert(is_power_of_2(bar_access->size) &&
+           bar_access->size <= sizeof(uint64_t));
+
+    res = address_space_rw(as, bar_access->addr, MEMTXATTRS_UNSPECIFIED,
+                           (uint8_t *)&bar_access->val, bar_access->size,
+                           true);
+
+    if (res != MEMTX_OK) {
+        error_setg(errp, "Could not perform address space write operation,"
+                   " inaccessible address: %lx in pid %d, %s.",
+                   bar_access->addr, getpid(), __progname);
+    }
+}
+
+static void process_bar_read(MPQemuMsg *msg, Error **errp)
+{
+    bar_access_msg_t *bar_access = &msg->data1.bar_access;
+    AddressSpace *as;
+    int wait = msg->fds[0];
+    MemTxResult res;
+    uint64_t val = 0;
+
+    as = bar_access->memory ? &address_space_memory : &address_space_io;
+
+    assert(is_power_of_2(bar_access->size) &&
+           bar_access->size <= sizeof(uint64_t));
+
+    res = address_space_rw(as, bar_access->addr, MEMTXATTRS_UNSPECIFIED,
+                           (uint8_t *)&val, bar_access->size, false);
+
+    if (res != MEMTX_OK) {
+        error_setg(errp, "Could not perform address space read operation,"
+                   " inaccessible address: %lx in pid %d, %s.",
+                   bar_access->addr, getpid(), __progname);
+        val = (uint64_t)-1;
+        goto fail;
+    }
+
+    switch (bar_access->size) {
+    case 8:
+        /* Nothing to do as val is already 8 bytes long */
+        break;
+    case 4:
+        val = *((uint32_t *)&val);
+        break;
+    case 2:
+        val = *((uint16_t *)&val);
+        break;
+    case 1:
+        val = *((uint8_t *)&val);
+        break;
+    default:
+        error_setg(errp, "Invalid PCI BAR read size in pid %d, %s",
+                   getpid(), __progname);
+        return;
+    }
+
+fail:
+    notify_proxy(wait, val);
+
+    PUT_REMOTE_WAIT(wait);
+}
+
 static void process_msg(GIOCondition cond, MPQemuLinkState *link,
                         MPQemuChannel *chan)
 {
@@ -147,6 +219,18 @@ static void process_msg(GIOCondition cond, MPQemuLinkState *link,
     case PCI_CONFIG_READ:
         process_config_read(LINK_TO_DEV(link), msg);
         break;
+    case BAR_WRITE:
+        process_bar_write(msg, &err);
+        if (err) {
+            goto finalize_loop;
+        }
+        break;
+    case BAR_READ:
+        process_bar_read(msg, &err);
+        if (err) {
+            goto finalize_loop;
+        }
+        break;
     default:
         error_setg(&err, "Unknown command in %s", print_pid_exec(pid_exec));
         goto finalize_loop;
-- 
2.25.GIT



  parent reply	other threads:[~2020-04-23  4:20 UTC|newest]

Thread overview: 94+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-04-23  4:13 [PATCH RESEND v6 00/36] Initial support for multi-process qemu elena.ufimtseva
2020-04-23  4:13 ` [PATCH RESEND v6 01/36] memory: alloc RAM from file at offset elena.ufimtseva
2020-05-12  8:26   ` Stefan Hajnoczi
2020-05-12  8:48   ` Daniel P. Berrangé
2020-05-12 11:56     ` Jag Raman
2020-05-13  8:40       ` Stefan Hajnoczi
2020-05-13 15:25         ` Igor Mammedov
2020-05-13 20:08           ` Jag Raman
2020-05-14  9:47             ` Igor Mammedov
2020-05-14  9:51             ` Dr. David Alan Gilbert
2020-04-23  4:13 ` [PATCH RESEND v6 02/36] multi-process: Refactor machine_init and exit notifiers elena.ufimtseva
2020-04-23 14:13   ` Philippe Mathieu-Daudé
2020-04-23  4:13 ` [PATCH RESEND v6 03/36] command-line: refractor parser code elena.ufimtseva
2020-04-24 12:55   ` Stefan Hajnoczi
2020-04-23  4:13 ` [PATCH RESEND v6 04/36] multi-process: Refactor chardev functions out of vl.c elena.ufimtseva
2020-04-23  4:13 ` [PATCH RESEND v6 05/36] multi-process: Refactor monitor " elena.ufimtseva
2020-04-24 13:02   ` Stefan Hajnoczi
2020-04-23  4:13 ` [PATCH RESEND v6 06/36] monitor: destaticize HMP commands elena.ufimtseva
2020-04-23 14:14   ` Philippe Mathieu-Daudé
2020-04-23 15:07     ` Jag Raman
2020-04-23 15:58       ` Philippe Mathieu-Daudé
2020-04-23  4:13 ` [PATCH RESEND v6 07/36] multi-process: add a command line option for debug file elena.ufimtseva
2020-04-23  4:13 ` [PATCH RESEND v6 08/36] multi-process: Add stub functions to facilitate build of multi-process elena.ufimtseva
2020-04-24 13:12   ` Stefan Hajnoczi
2020-04-24 13:47     ` Jag Raman
2020-04-28 16:29       ` Stefan Hajnoczi
2020-04-28 18:58         ` Jag Raman
2020-04-29  9:41           ` Stefan Hajnoczi
2020-04-23  4:13 ` [PATCH RESEND v6 09/36] multi-process: Add config option for multi-process QEMU elena.ufimtseva
2020-04-24 13:47   ` Stefan Hajnoczi
2020-04-23  4:13 ` [PATCH RESEND v6 10/36] multi-process: build system for remote device process elena.ufimtseva
2020-04-24 15:04   ` Stefan Hajnoczi
2020-04-23  4:13 ` [PATCH RESEND v6 11/36] multi-process: define mpqemu-link object elena.ufimtseva
2020-05-12  8:56   ` Stefan Hajnoczi
2020-05-12 12:09     ` Jag Raman
2020-04-23  4:13 ` [PATCH RESEND v6 12/36] multi-process: add functions to synchronize proxy and remote endpoints elena.ufimtseva
2020-05-12 10:21   ` Stefan Hajnoczi
2020-05-12 12:28     ` Jag Raman
2020-05-13  8:43       ` Stefan Hajnoczi
2020-04-23  4:13 ` [PATCH RESEND v6 13/36] multi-process: setup PCI host bridge for remote device elena.ufimtseva
2020-05-12 10:31   ` Stefan Hajnoczi
2020-04-23  4:13 ` [PATCH RESEND v6 14/36] multi-process: setup a machine object for remote device process elena.ufimtseva
2020-05-12 10:43   ` Stefan Hajnoczi
2020-05-12 12:12     ` Jag Raman
2020-04-23  4:13 ` [PATCH RESEND v6 15/36] multi-process: setup memory manager for remote device elena.ufimtseva
2020-05-12 12:11   ` Stefan Hajnoczi
2020-04-23  4:13 ` [PATCH RESEND v6 16/36] multi-process: remote process initialization elena.ufimtseva
2020-04-23  4:13 ` [PATCH RESEND v6 17/36] multi-process: introduce proxy object elena.ufimtseva
2020-05-12 12:23   ` Stefan Hajnoczi
2020-05-12 12:35     ` Jag Raman
2020-04-23  4:13 ` [PATCH RESEND v6 18/36] multi-process: Initialize Proxy Object's communication channel elena.ufimtseva
2020-05-12 12:35   ` Stefan Hajnoczi
2020-04-23  4:13 ` [PATCH RESEND v6 19/36] multi-process: Connect Proxy Object with device in the remote process elena.ufimtseva
2020-05-12 12:54   ` Stefan Hajnoczi
2020-04-23  4:13 ` [PATCH RESEND v6 20/36] multi-process: Forward PCI config space acceses to " elena.ufimtseva
2020-05-12 13:50   ` Stefan Hajnoczi
2020-04-23  4:13 ` elena.ufimtseva [this message]
2020-05-12 14:19   ` [PATCH RESEND v6 21/36] multi-process: PCI BAR read/write handling for proxy & remote endpoints Stefan Hajnoczi
2020-04-23  4:13 ` [PATCH RESEND v6 22/36] multi-process: Synchronize remote memory elena.ufimtseva
2020-05-12 15:07   ` Stefan Hajnoczi
2020-05-12 15:49     ` Dr. David Alan Gilbert
2020-04-23  4:13 ` [PATCH RESEND v6 23/36] multi-process: create IOHUB object to handle irq elena.ufimtseva
2020-05-12 15:57   ` Stefan Hajnoczi
2020-05-12 16:12   ` Stefan Hajnoczi
2020-04-23  4:13 ` [PATCH RESEND v6 24/36] multi-process: Retrieve PCI info from remote process elena.ufimtseva
2020-05-12 16:07   ` Stefan Hajnoczi
2020-04-23  4:14 ` [PATCH RESEND v6 25/36] multi-process: Introduce build flags to separate remote process code elena.ufimtseva
2020-04-23  4:14 ` [PATCH RESEND v6 26/36] multi-process: add parse_cmdline in remote process elena.ufimtseva
2020-04-23  4:14 ` [PATCH RESEND v6 27/36] multi-process: add support to parse device option elena.ufimtseva
2020-04-23  4:14 ` [PATCH RESEND v6 28/36] multi-process: send heartbeat messages to remote elena.ufimtseva
2020-04-23  4:14 ` [PATCH RESEND v6 29/36] multi-process: handle heartbeat messages in remote process elena.ufimtseva
2020-04-23  4:14 ` [PATCH RESEND v6 30/36] multi-process: perform device reset in the " elena.ufimtseva
2020-04-23  4:14 ` [PATCH RESEND v6 31/36] multi-process/mon: choose HMP commands based on target elena.ufimtseva
2020-04-23  4:14 ` [PATCH RESEND v6 32/36] multi-process/mon: stub functions to enable QMP module for remote process elena.ufimtseva
2020-04-23  4:14 ` [PATCH RESEND v6 33/36] multi-process/mon: enable QMP module support in the " elena.ufimtseva
2020-04-23  4:14 ` [PATCH RESEND v6 34/36] multi-process/mon: Initialize QMP module for remote processes elena.ufimtseva
2020-04-23  4:14 ` [PATCH RESEND v6 35/36] multi-process: add the concept description to docs/devel/qemu-multiprocess elena.ufimtseva
2020-04-23  4:14 ` [PATCH RESEND v6 36/36] multi-process: add configure and usage information elena.ufimtseva
2020-04-23 13:54   ` 罗勇刚(Yonggang Luo)
2020-04-23 15:01     ` Jag Raman
2020-04-23 22:56       ` 罗勇刚(Yonggang Luo)
2020-04-24  0:34       ` 罗勇刚(Yonggang Luo)
2020-04-24 12:48 ` [PATCH RESEND v6 00/36] Initial support for multi-process qemu Stefan Hajnoczi
2020-04-24 12:53   ` Daniel P. Berrangé
2020-04-24 12:53   ` Eric Blake
2020-04-24 13:42     ` Max Reitz
2020-04-28 17:29 ` Stefan Hajnoczi
2020-04-28 17:47   ` Michael S. Tsirkin
2020-04-29  9:30     ` Stefan Hajnoczi
2020-04-29  9:59       ` Michael S. Tsirkin
2020-05-11 14:40 ` Stefan Hajnoczi
2020-05-11 19:30   ` Jag Raman
2020-05-12 16:13     ` Stefan Hajnoczi
2020-05-12 16:55       ` Jag Raman

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=5484f5bc8b9e80d50331b32b971f433b5c062e3a.1587614626.git.elena.ufimtseva@oracle.com \
    --to=elena.ufimtseva@oracle.com \
    --cc=armbru@redhat.com \
    --cc=berrange@redhat.com \
    --cc=dgilbert@redhat.com \
    --cc=ehabkost@redhat.com \
    --cc=fam@euphon.net \
    --cc=felipe@nutanix.com \
    --cc=jag.raman@oracle.com \
    --cc=john.g.johnson@oracle.com \
    --cc=kanth.ghatraju@oracle.com \
    --cc=konrad.wilk@oracle.com \
    --cc=kraxel@redhat.com \
    --cc=kwolf@redhat.com \
    --cc=liran.alon@oracle.com \
    --cc=marcandre.lureau@gmail.com \
    --cc=mreitz@redhat.com \
    --cc=mst@redhat.com \
    --cc=pbonzini@redhat.com \
    --cc=qemu-devel@nongnu.org \
    --cc=quintela@redhat.com \
    --cc=ross.lagerwall@citrix.com \
    --cc=rth@twiddle.net \
    --cc=stefanha@redhat.com \
    --cc=swapnil.ingle@nutanix.com \
    --cc=thanos.makatos@nutanix.com \
    --cc=thuth@redhat.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).