From: Richard Liu <richy.liu.2002@gmail.com>
To: qemu-devel@nongnu.org
Cc: alxndr@bu.edu, bsd@redhat.com, darren.kenny@oracle.com,
Richard Liu <richy.liu.2002@gmail.com>
Subject: [RFC 2/3] implement ram save/restore
Date: Fri, 22 Jul 2022 12:20:40 -0700 [thread overview]
Message-ID: <20220722192041.93006-3-richy.liu.2002@gmail.com> (raw)
In-Reply-To: <20220722192041.93006-1-richy.liu.2002@gmail.com>
Use a file-backed copy-on-write mmap region for snapshots. Restores are
handled by remmaping the fixed region. Currently, the snapshot file save
path (`filepath`) is hardcoded (to a path that is memory-backed on my
machine).
Signed-off-by: Richard Liu <richy.liu.2002@gmail.com>
---
hw/misc/snapshot.c | 72 ++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 72 insertions(+)
diff --git a/hw/misc/snapshot.c b/hw/misc/snapshot.c
index 2690b331fd..510bf59dce 100644
--- a/hw/misc/snapshot.c
+++ b/hw/misc/snapshot.c
@@ -18,8 +18,63 @@ DECLARE_INSTANCE_CHECKER(SnapshotState, SNAPSHOT,
struct SnapshotState {
PCIDevice pdev;
MemoryRegion mmio;
+
+ // track saved stated to prevent re-saving
+ bool is_saved;
+
+ // saved cpu and devices state
+ QIOChannelBuffer *ioc;
};
+// memory save location (for better performance, use tmpfs)
+const char *filepath = "/Volumes/RAMDisk/snapshot_0";
+
+static void save_snapshot(struct SnapshotState *s) {
+ if (s->is_saved) {
+ return;
+ }
+ s->is_saved = true;
+
+ // save memory state to file
+ int fd = -1;
+ uint8_t *guest_mem = current_machine->ram->ram_block->host;
+ size_t guest_size = current_machine->ram->ram_block->max_length;
+
+ fd = open(filepath, O_RDWR | O_CREAT | O_TRUNC, (mode_t)0600);
+ ftruncate(fd, guest_size);
+
+ char *map = mmap(0, guest_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
+ memcpy(map, guest_mem, guest_size);
+ msync(map, guest_size, MS_SYNC);
+ munmap(map, guest_size);
+ close(fd);
+
+ // unmap the guest, we will now use a MAP_PRIVATE
+ munmap(guest_mem, guest_size);
+
+ // map as MAP_PRIVATE to avoid carrying writes back to the saved file
+ fd = open(filepath, O_RDONLY);
+ mmap(guest_mem, guest_size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_FIXED, fd, 0);
+}
+
+static void restore_snapshot(struct SnapshotState *s) {
+ int fd = -1;
+ uint8_t *guest_mem = current_machine->ram->ram_block->host;
+ size_t guest_size = current_machine->ram->ram_block->max_length;
+
+ if (!s->is_saved) {
+ fprintf(stderr, "[QEMU] ERROR: attempting to restore but state has not been saved!\n");
+ return;
+ }
+
+ munmap(guest_mem, guest_size);
+
+ // remap the snapshot at the same location
+ fd = open(filepath, O_RDONLY);
+ mmap(guest_mem, guest_size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_FIXED, fd, 0);
+ close(fd);
+}
+
static uint64_t snapshot_mmio_read(void *opaque, hwaddr addr, unsigned size)
{
return 0;
@@ -28,6 +83,21 @@ static uint64_t snapshot_mmio_read(void *opaque, hwaddr addr, unsigned size)
static void snapshot_mmio_write(void *opaque, hwaddr addr, uint64_t val,
unsigned size)
{
+ SnapshotState *snapshot = opaque;
+ (void)snapshot;
+
+ switch (addr) {
+ case 0x00:
+ switch (val) {
+ case 0x101:
+ save_snapshot(snapshot);
+ break;
+ case 0x102:
+ restore_snapshot(snapshot);
+ break;
+ }
+ break;
+ }
}
static const MemoryRegionOps snapshot_mmio_ops = {
@@ -48,6 +118,8 @@ static const MemoryRegionOps snapshot_mmio_ops = {
static void pci_snapshot_realize(PCIDevice *pdev, Error **errp)
{
SnapshotState *snapshot = SNAPSHOT(pdev);
+ snapshot->is_saved = false;
+ snapshot->ioc = NULL;
memory_region_init_io(&snapshot->mmio, OBJECT(snapshot), &snapshot_mmio_ops, snapshot,
"snapshot-mmio", 1 * MiB);
--
2.35.1
next prev parent reply other threads:[~2022-07-22 19:25 UTC|newest]
Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-07-22 19:20 [RFC 0/3] add snapshot/restore fuzzing device Richard Liu
2022-07-22 19:20 ` [RFC 1/3] create skeleton snapshot device and add docs Richard Liu
2022-07-22 19:20 ` Richard Liu [this message]
2022-07-22 19:20 ` [RFC 3/3] use migration code for cpu and device save/restore Richard Liu
2022-07-22 20:10 ` [RFC 0/3] add snapshot/restore fuzzing device Claudio Fontana
2022-07-23 15:52 ` Alexander Bulekov
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=20220722192041.93006-3-richy.liu.2002@gmail.com \
--to=richy.liu.2002@gmail.com \
--cc=alxndr@bu.edu \
--cc=bsd@redhat.com \
--cc=darren.kenny@oracle.com \
--cc=qemu-devel@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 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).