All of lore.kernel.org
 help / color / mirror / Atom feed
From: Baojun Wang <wangbj@gmail.com>
To: qemu-devel@nongnu.org
Cc: qemu-trivial@nongnu.org, wangbj@gmail.com, eblake@redhat.com
Subject: [Qemu-trivial] [PATCH V3 1/1] Add pmemsave command for both monitor and qmp, which could be useful to have qemu-softmmu as a cross debugger to load guest physical memory.
Date: Tue,  8 Apr 2014 12:30:38 -0700	[thread overview]
Message-ID: <1396985438-19741-1-git-send-email-wangbj@gmail.com> (raw)

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.

---
 cpus.c           | 24 ++++++++++++++++++++++++
 hmp-commands.hx  | 13 +++++++++++++
 hmp.c            | 11 +++++++++++
 hmp.h            |  1 +
 qapi-schema.json | 20 ++++++++++++++++++++
 qmp-commands.hx  | 27 +++++++++++++++++++++++++++
 6 files changed, 96 insertions(+)

diff --git a/cpus.c b/cpus.c
index 1104d61..03d1277 100644
--- a/cpus.c
+++ b/cpus.c
@@ -1467,6 +1467,30 @@ exit:
     fclose(f);
 }
 
+void qmp_pmemload(int64_t addr, int64_t size, const char *filename,
+                  Error **errp)
+{
+    FILE *f;
+    uint32_t l;
+    uint8_t buf[1024];
+
+    f = fopen(filename, "rb");
+    if (!f) {
+        error_setg_file_open(errp, errno, filename);
+        return;
+    }
+
+    while (size != 0) {
+        l = fread(buf, 1, sizeof(buf), f);
+        if (l > size)
+            l = size;
+        cpu_physical_memory_rw(addr, buf, l, 1);
+        addr += l;
+        size -= l;
+    }
+
+    fclose(f);
+}
 void qmp_inject_nmi(Error **errp)
 {
 #if defined(TARGET_I386)
diff --git a/hmp-commands.hx b/hmp-commands.hx
index f3fc514..18604a6 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  = "val:l,size:i,filename:s",
+        .params     = "addr size file",
+        .help       = "load from disk physical memory dump starting at 'addr' of size 'size'",
+        .mhandler.cmd = hmp_pmemload,
+    },
+
+STEXI
+@item pmemload @var{addr} @var{size} @var{file}
+@findex 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..6e932f9 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(addr, size, filename, &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..f251f5d 100644
--- a/qapi-schema.json
+++ b/qapi-schema.json
@@ -1708,6 +1708,26 @@
   'data': {'val': 'int', 'size': 'int', 'filename': 'str'} }
 
 ##
+# @pmemload:
+#
+# Load a portion of guest physical memory from a file.
+#
+# @val: the physical address of the guest to start from
+#
+# @size: the size of memory region to load
+#
+# @filename: the file to load the memory from as binary data
+#
+# Returns: Nothing on success
+#
+# Since: 2.1
+#
+# Notes: Errors were not reliably returned until 2.1
+##
+{ 'command': 'pmemload',
+  'data': {'val': 'int', 'size': 'int', 'filename': 'str'} }
+
+##
 # @cont:
 #
 # Resume guest VCPU execution.
diff --git a/qmp-commands.hx b/qmp-commands.hx
index ed3ab92..584d6cf 100644
--- a/qmp-commands.hx
+++ b/qmp-commands.hx
@@ -468,6 +468,33 @@ Example:
 EQMP
 
     {
+        .name       = "pmemload",
+        .args_type  = "val:l,size:i,filename:s",
+        .mhandler.cmd_new = qmp_marshal_input_pmemload,
+    },
+
+SQMP
+pmemload
+--------
+
+load from disk physical memory dump starting at 'val' of size 'size'.
+
+Arguments:
+
+- "val": the starting address (json-int)
+- "size": the memory size, in bytes (json-int)
+- "filename": file path (json-string)
+
+Example:
+
+-> { "execute": "pmemload",
+             "arguments": { "val": 10,
+                            "size": 100,
+                            "filename": "/tmp/physical-mem-dump" } }
+<- { "return": {} }
+
+EQMP
+    {
         .name       = "inject-nmi",
         .args_type  = "",
         .mhandler.cmd_new = qmp_marshal_input_inject_nmi,
-- 
1.9.1



WARNING: multiple messages have this Message-ID (diff)
From: Baojun Wang <wangbj@gmail.com>
To: qemu-devel@nongnu.org
Cc: qemu-trivial@nongnu.org, wangbj@gmail.com
Subject: [Qemu-devel] [PATCH V3 1/1] Add pmemsave command for both monitor and qmp, which could be useful to have qemu-softmmu as a cross debugger to load guest physical memory.
Date: Tue,  8 Apr 2014 12:30:38 -0700	[thread overview]
Message-ID: <1396985438-19741-1-git-send-email-wangbj@gmail.com> (raw)

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.

---
 cpus.c           | 24 ++++++++++++++++++++++++
 hmp-commands.hx  | 13 +++++++++++++
 hmp.c            | 11 +++++++++++
 hmp.h            |  1 +
 qapi-schema.json | 20 ++++++++++++++++++++
 qmp-commands.hx  | 27 +++++++++++++++++++++++++++
 6 files changed, 96 insertions(+)

diff --git a/cpus.c b/cpus.c
index 1104d61..03d1277 100644
--- a/cpus.c
+++ b/cpus.c
@@ -1467,6 +1467,30 @@ exit:
     fclose(f);
 }
 
+void qmp_pmemload(int64_t addr, int64_t size, const char *filename,
+                  Error **errp)
+{
+    FILE *f;
+    uint32_t l;
+    uint8_t buf[1024];
+
+    f = fopen(filename, "rb");
+    if (!f) {
+        error_setg_file_open(errp, errno, filename);
+        return;
+    }
+
+    while (size != 0) {
+        l = fread(buf, 1, sizeof(buf), f);
+        if (l > size)
+            l = size;
+        cpu_physical_memory_rw(addr, buf, l, 1);
+        addr += l;
+        size -= l;
+    }
+
+    fclose(f);
+}
 void qmp_inject_nmi(Error **errp)
 {
 #if defined(TARGET_I386)
diff --git a/hmp-commands.hx b/hmp-commands.hx
index f3fc514..18604a6 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  = "val:l,size:i,filename:s",
+        .params     = "addr size file",
+        .help       = "load from disk physical memory dump starting at 'addr' of size 'size'",
+        .mhandler.cmd = hmp_pmemload,
+    },
+
+STEXI
+@item pmemload @var{addr} @var{size} @var{file}
+@findex 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..6e932f9 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(addr, size, filename, &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..f251f5d 100644
--- a/qapi-schema.json
+++ b/qapi-schema.json
@@ -1708,6 +1708,26 @@
   'data': {'val': 'int', 'size': 'int', 'filename': 'str'} }
 
 ##
+# @pmemload:
+#
+# Load a portion of guest physical memory from a file.
+#
+# @val: the physical address of the guest to start from
+#
+# @size: the size of memory region to load
+#
+# @filename: the file to load the memory from as binary data
+#
+# Returns: Nothing on success
+#
+# Since: 2.1
+#
+# Notes: Errors were not reliably returned until 2.1
+##
+{ 'command': 'pmemload',
+  'data': {'val': 'int', 'size': 'int', 'filename': 'str'} }
+
+##
 # @cont:
 #
 # Resume guest VCPU execution.
diff --git a/qmp-commands.hx b/qmp-commands.hx
index ed3ab92..584d6cf 100644
--- a/qmp-commands.hx
+++ b/qmp-commands.hx
@@ -468,6 +468,33 @@ Example:
 EQMP
 
     {
+        .name       = "pmemload",
+        .args_type  = "val:l,size:i,filename:s",
+        .mhandler.cmd_new = qmp_marshal_input_pmemload,
+    },
+
+SQMP
+pmemload
+--------
+
+load from disk physical memory dump starting at 'val' of size 'size'.
+
+Arguments:
+
+- "val": the starting address (json-int)
+- "size": the memory size, in bytes (json-int)
+- "filename": file path (json-string)
+
+Example:
+
+-> { "execute": "pmemload",
+             "arguments": { "val": 10,
+                            "size": 100,
+                            "filename": "/tmp/physical-mem-dump" } }
+<- { "return": {} }
+
+EQMP
+    {
         .name       = "inject-nmi",
         .args_type  = "",
         .mhandler.cmd_new = qmp_marshal_input_inject_nmi,
-- 
1.9.1

             reply	other threads:[~2014-04-08 20:53 UTC|newest]

Thread overview: 15+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-04-08 19:30 Baojun Wang [this message]
2014-04-08 19:30 ` [Qemu-devel] [PATCH V3 1/1] Add pmemsave command for both monitor and qmp, which could be useful to have qemu-softmmu as a cross debugger to load guest physical memory Baojun Wang
2014-04-08 19:42 ` [Qemu-trivial] " Eric Blake
2014-04-08 19:42   ` [Qemu-devel] " Eric Blake
2014-04-08 23:29   ` [Qemu-trivial] " Baojun Wang
2014-04-08 23:29     ` [Qemu-devel] " Baojun Wang
2014-04-09 16:54     ` [Qemu-trivial] [PATCH V4 1/1] qmp: add pmemload command Baojun Wang
2014-04-09 16:54       ` [Qemu-devel] " Baojun Wang
2014-04-09 17:02       ` [Qemu-trivial] " Eric Blake
2014-04-09 17:02         ` [Qemu-devel] " Eric Blake
2014-04-09 17:49         ` [Qemu-trivial] [PATCH V5 " Baojun Wang
2014-04-09 17:49           ` [Qemu-devel] " Baojun Wang
2014-04-27  9:18           ` [Qemu-trivial] " Michael Tokarev
2014-04-28  6:30             ` [Qemu-trivial] [Qemu-devel] " Markus Armbruster
2014-04-30 18:00             ` [Qemu-trivial] " Baojun Wang

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=1396985438-19741-1-git-send-email-wangbj@gmail.com \
    --to=wangbj@gmail.com \
    --cc=eblake@redhat.com \
    --cc=qemu-devel@nongnu.org \
    --cc=qemu-trivial@nongnu.org \
    /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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.