qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemu-devel] [PATCH V5 1/1] qmp: add pmemload command


From: Baojun Wang
Subject: [Qemu-devel] [PATCH V5 1/1] qmp: add pmemload command
Date: Wed, 9 Apr 2014 10:49:04 -0700

I found this could be useful to have qemu-softmmu as a cross debugger (launch
with -s -S command line option), then if we can have a command to load guest
physical memory, we can use cross gdb to do some target debug which gdb cannot
do directly.

Many thanks to Eric Blake for review the patch and suggestions.

Signed-off-by: Baojun Wang <address@hidden>
---
 cpus.c           | 29 +++++++++++++++++++++++++++++
 hmp-commands.hx  | 13 +++++++++++++
 hmp.c            | 11 +++++++++++
 hmp.h            |  1 +
 qapi-schema.json | 18 ++++++++++++++++++
 qmp-commands.hx  | 27 +++++++++++++++++++++++++++
 6 files changed, 99 insertions(+)

diff --git a/cpus.c b/cpus.c
index 1104d61..230664f 100644
--- a/cpus.c
+++ b/cpus.c
@@ -1467,6 +1467,35 @@ exit:
     fclose(f);
 }
 
+void qmp_pmemload(const char* filename, int64_t addr, int64_t size,
+                  Error **errp)
+{
+    int fd;
+    ssize_t l;
+    uint8_t buf[4096];
+
+    fd = qemu_open(filename, O_RDONLY | O_BINARY);
+    if (fd < 0) {
+        error_setg_file_open(errp, errno, filename);
+        return;
+    }
+
+    while (size != 0) {
+        l = read(fd, buf, sizeof(buf));
+        if (l != sizeof(buf)) {
+            error_set(errp, QERR_IO_ERROR);
+            goto exit;
+        }
+        if (l > size)
+            l = size;
+        cpu_physical_memory_rw(addr, buf, l, 1);
+        addr += l;
+        size -= l;
+    }
+
+exit:
+    qemu_close(fd);
+}
 void qmp_inject_nmi(Error **errp)
 {
 #if defined(TARGET_I386)
diff --git a/hmp-commands.hx b/hmp-commands.hx
index f3fc514..1eae6e3 100644
--- a/hmp-commands.hx
+++ b/hmp-commands.hx
@@ -809,6 +809,19 @@ save to disk physical memory dump starting at @var{addr} 
of size @var{size}.
 ETEXI
 
     {
+        .name       = "pmemload",
+        .args_type  = "filename:s,val:l,size:i",
+        .params     = "file addr size",
+        .help       = "load from disk physical memory dump starting at 'addr' 
of size 'size'",
+        .mhandler.cmd = hmp_pmemload,
+    },
+
+STEXI
address@hidden pmemload @var{file} @var{addr} @var{size}
address@hidden pmemload
+load from disk physical memory dump starting at @var{addr} of size @var{size}.
+ETEXI
+    {
         .name       = "boot_set",
         .args_type  = "bootdevice:s",
         .params     = "bootdevice",
diff --git a/hmp.c b/hmp.c
index 2f279c4..745c087 100644
--- a/hmp.c
+++ b/hmp.c
@@ -767,6 +767,17 @@ void hmp_pmemsave(Monitor *mon, const QDict *qdict)
     hmp_handle_error(mon, &errp);
 }
 
+void hmp_pmemload(Monitor *mon, const QDict *qdict)
+{
+    uint32_t size = qdict_get_int(qdict, "size");
+    const char *filename = qdict_get_str(qdict, "filename");
+    uint64_t addr = qdict_get_int(qdict, "val");
+    Error *errp = NULL;
+
+    qmp_pmemload(filename, addr, size, &errp);
+    hmp_handle_error(mon, &errp);
+}
+
 void hmp_ringbuf_write(Monitor *mon, const QDict *qdict)
 {
     const char *chardev = qdict_get_str(qdict, "device");
diff --git a/hmp.h b/hmp.h
index ed58f0e..f5f2a16 100644
--- a/hmp.h
+++ b/hmp.h
@@ -44,6 +44,7 @@ void hmp_system_powerdown(Monitor *mon, const QDict *qdict);
 void hmp_cpu(Monitor *mon, const QDict *qdict);
 void hmp_memsave(Monitor *mon, const QDict *qdict);
 void hmp_pmemsave(Monitor *mon, const QDict *qdict);
+void hmp_pmemload(Monitor *mon, const QDict *qdict);
 void hmp_ringbuf_write(Monitor *mon, const QDict *qdict);
 void hmp_ringbuf_read(Monitor *mon, const QDict *qdict);
 void hmp_cont(Monitor *mon, const QDict *qdict);
diff --git a/qapi-schema.json b/qapi-schema.json
index 391356f..7198242 100644
--- a/qapi-schema.json
+++ b/qapi-schema.json
@@ -1708,6 +1708,24 @@
   'data': {'val': 'int', 'size': 'int', 'filename': 'str'} }
 
 ##
+# @pmemload:
+#
+# Load a portion of guest physical memory from a file.
+#
+# @filename: the file to load the memory from as binary data
+#
+# @val: the physical address of the guest to start from
+#
+# @size: the size of memory region to load
+#
+# Returns: Nothing on success
+#
+# Since: 2.1
+##
+{ 'command': 'pmemload',
+  'data': {'filename': 'str', 'val': 'int', 'size': 'int'} }
+
+##
 # @cont:
 #
 # Resume guest VCPU execution.
diff --git a/qmp-commands.hx b/qmp-commands.hx
index ed3ab92..2831038 100644
--- a/qmp-commands.hx
+++ b/qmp-commands.hx
@@ -468,6 +468,33 @@ Example:
 EQMP
 
     {
+        .name       = "pmemload",
+        .args_type  = "filename:s,val:l,size:i",
+        .mhandler.cmd_new = qmp_marshal_input_pmemload,
+    },
+
+SQMP
+pmemload
+--------
+
+load from disk physical memory dump starting at 'val' of size 'size'.
+
+Arguments:
+
+- "filename": file path (json-string)
+- "val": the starting address (json-int)
+- "size": the memory size, in bytes (json-int)
+
+Example:
+
+-> { "execute": "pmemload",
+             "arguments": { "filename": "/tmp/physical-mem-dump",
+                            "val": 10,
+                            "size": 100 } }
+<- { "return": {} }
+
+EQMP
+    {
         .name       = "inject-nmi",
         .args_type  = "",
         .mhandler.cmd_new = qmp_marshal_input_inject_nmi,
-- 
1.9.1




reply via email to

[Prev in Thread] Current Thread [Next in Thread]