SyncSysMemMsg message format is defined. It is used to send file descriptors of the RAM regions to remote device. RAM on the remote device is configured with a set of file descriptors. Old RAM regions are deleted and new regions, each with an fd, is added to the RAM.
Signed-off-by: Jagannathan Raman <jag.ra...@oracle.com> Signed-off-by: John G Johnson <john.g.john...@oracle.com> Signed-off-by: Elena Ufimtseva <elena.ufimts...@oracle.com> Reviewed-by: Stefan Hajnoczi <stefa...@redhat.com> --- MAINTAINERS | 2 ++ hw/i386/meson.build | 1 + hw/i386/remote-memory.c | 58 +++++++++++++++++++++++++++++++++++++++++ include/hw/i386/remote-memory.h | 19 ++++++++++++++ include/io/mpqemu-link.h | 13 +++++++++ io/mpqemu-link.c | 11 ++++++++ 6 files changed, 104 insertions(+) create mode 100644 hw/i386/remote-memory.c create mode 100644 include/hw/i386/remote-memory.h diff --git a/MAINTAINERS b/MAINTAINERS index 487ab13..4aa00ec 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -3109,6 +3109,8 @@ F: include/io/mpqemu-link.h F: hw/i386/remote-msg.c F: include/hw/i386/remote-obj.h F: hw/i386/remote-obj.c +F: include/hw/i386/remote-memory.h +F: hw/i386/remote-memory.c Build and test automation ------------------------- diff --git a/hw/i386/meson.build b/hw/i386/meson.build index 9735f6b..b698b36 100644 --- a/hw/i386/meson.build +++ b/hw/i386/meson.build @@ -27,6 +27,7 @@ i386_ss.add(when: 'CONFIG_PC', if_true: files( i386_ss.add(when: 'CONFIG_MPQEMU', if_true: files('remote.c')) i386_ss.add(when: 'CONFIG_MPQEMU', if_true: files('remote-msg.c')) i386_ss.add(when: 'CONFIG_MPQEMU', if_true: files('remote-obj.c')) +i386_ss.add(when: 'CONFIG_MPQEMU', if_true: files('remote-memory.c')) subdir('kvm') subdir('xen') diff --git a/hw/i386/remote-memory.c b/hw/i386/remote-memory.c new file mode 100644 index 0000000..27bc8a7 --- /dev/null +++ b/hw/i386/remote-memory.c @@ -0,0 +1,58 @@ +/* + * Memory manager for remote device + * + * Copyright © 2018, 2020 Oracle and/or its affiliates. + * + * This work is licensed under the terms of the GNU GPL, version 2 or later. + * See the COPYING file in the top-level directory. + * + */ + +#include "qemu/osdep.h" +#include "qemu-common.h" + +#include "hw/i386/remote-memory.h" +#include "exec/address-spaces.h" +#include "exec/ram_addr.h" +#include "qapi/error.h" + +void remote_sysmem_reconfig(MPQemuMsg *msg, Error **errp) +{ + SyncSysmemMsg *sysmem_info = &msg->data.sync_sysmem; + MemoryRegion *sysmem, *subregion, *next; + static unsigned int suffix; + Error *local_err = NULL; + char *name; + int region; + + sysmem = get_system_memory(); + + memory_region_transaction_begin(); + + QTAILQ_FOREACH_SAFE(subregion, &sysmem->subregions, subregions_link, next) { + if (subregion->ram) { + memory_region_del_subregion(sysmem, subregion); + object_unparent(OBJECT(subregion)); + } + } + + for (region = 0; region < msg->num_fds; region++) { + subregion = g_new(MemoryRegion, 1); + name = g_strdup_printf("remote-mem-%u", suffix++); + memory_region_init_ram_from_fd(subregion, NULL, + name, sysmem_info->sizes[region], + RAM_SHARED, msg->fds[region], + sysmem_info->offsets[region], + &local_err); + g_free(name); + if (local_err) { + error_propagate(errp, local_err); + break; + } + + memory_region_add_subregion(sysmem, sysmem_info->gpas[region], + subregion); + } + + memory_region_transaction_commit(); +} diff --git a/include/hw/i386/remote-memory.h b/include/hw/i386/remote-memory.h new file mode 100644 index 0000000..aab3e4d --- /dev/null +++ b/include/hw/i386/remote-memory.h @@ -0,0 +1,19 @@ +/* + * Memory manager for remote device + * + * Copyright © 2018, 2020 Oracle and/or its affiliates. + * + * This work is licensed under the terms of the GNU GPL, version 2 or later. + * See the COPYING file in the top-level directory. + * + */ + +#ifndef REMOTE_MEMORY_H +#define REMOTE_MEMORY_H + +#include "exec/hwaddr.h" +#include "io/mpqemu-link.h" + +void remote_sysmem_reconfig(MPQemuMsg *msg, Error **errp); + +#endif diff --git a/include/io/mpqemu-link.h b/include/io/mpqemu-link.h index 3505e06..e33181a 100644 --- a/include/io/mpqemu-link.h +++ b/include/io/mpqemu-link.h @@ -14,6 +14,7 @@ #include "qom/object.h" #include "qemu/thread.h" #include "io/channel.h" +#include "exec/hwaddr.h" #define REMOTE_MAX_FDS 8 @@ -24,12 +25,22 @@ * * MPQemuCmd enum type to specify the command to be executed on the remote * device. + * + * SYNC_SYSMEM Shares QEMU's RAM with remote device's RAM */ typedef enum { MPQEMU_CMD_INIT, + SYNC_SYSMEM, + RET_MSG, MPQEMU_CMD_MAX, } MPQemuCmd; +typedef struct { + hwaddr gpas[REMOTE_MAX_FDS]; + uint64_t sizes[REMOTE_MAX_FDS]; + off_t offsets[REMOTE_MAX_FDS]; +} SyncSysmemMsg; + /** * MPQemuMsg: * @cmd: The remote command @@ -40,12 +51,14 @@ typedef enum { * MPQemuMsg Format of the message sent to the remote device from QEMU. * */ + typedef struct { int cmd; size_t size; union { uint64_t u64; + SyncSysmemMsg sync_sysmem; } data; int fds[REMOTE_MAX_FDS]; diff --git a/io/mpqemu-link.c b/io/mpqemu-link.c index d646aad..b30e27c 100644 --- a/io/mpqemu-link.c +++ b/io/mpqemu-link.c @@ -233,5 +233,16 @@ bool mpqemu_msg_valid(MPQemuMsg *msg) } } + /* Verify message specific fields. */ + switch (msg->cmd) { + case SYNC_SYSMEM: + if (msg->num_fds == 0 || msg->size != sizeof(SyncSysmemMsg)) { + return false; + } + break; + default: + break; + } + return true; } -- 1.8.3.1