diff mbox

[29/46] postcopy: ram_enable_notify to switch on userfault

Message ID 1404495717-4239-30-git-send-email-dgilbert@redhat.com
State New
Headers show

Commit Message

Dr. David Alan Gilbert July 4, 2014, 5:41 p.m. UTC
From: "Dr. David Alan Gilbert" <dgilbert@redhat.com>

Signed-off-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
---
 include/migration/postcopy-ram.h |  5 +++++
 postcopy-ram.c                   | 36 +++++++++++++++++++++++++++++++++++-
 2 files changed, 40 insertions(+), 1 deletion(-)
diff mbox

Patch

diff --git a/include/migration/postcopy-ram.h b/include/migration/postcopy-ram.h
index b5f0cb5..383b1e8 100644
--- a/include/migration/postcopy-ram.h
+++ b/include/migration/postcopy-ram.h
@@ -28,6 +28,11 @@  int postcopy_send_discard_bitmap(MigrationState *ms);
 int postcopy_ram_discard_range(MigrationIncomingState *mis, uint8_t *start,
                                uint8_t *end);
 
+/*
+ * Make all of RAM sensitive to accesses to areas that haven't yet been written
+ * and wire up anything necessary to deal with it.
+ */
+int postcopy_ram_enable_notify(MigrationIncomingState *mis);
 
 /*
  * Initialise postcopy-ram, setting the RAM to a state where we can go into
diff --git a/postcopy-ram.c b/postcopy-ram.c
index 2159c60..c605dd3 100644
--- a/postcopy-ram.c
+++ b/postcopy-ram.c
@@ -337,9 +337,38 @@  int postcopy_ram_incoming_cleanup(MigrationIncomingState *mis)
     return 0;
 }
 
+/*
+ * Mark the given area of RAM as requiring notification to unwritten areas
+ * Used as a  callback on qemu_ram_foreach_block.
+ *   host_addr: Base of area to mark
+ *   offset: Offset in the whole ram arena
+ *   length: Length of the section
+ *   opaque: Unused
+ * Returns 0 on success
+ */
+static int postcopy_ram_sensitise_area(const char *block_name, void *host_addr,
+                                       ram_addr_t offset, ram_addr_t length,
+                                       void *opaque)
+{
+    if (madvise(host_addr, length, MADV_USERFAULT)) {
+        perror("postcopy_ram_sensitise_area");
+        return -1;
+    }
+    return 0;
+}
+
+int postcopy_ram_enable_notify(MigrationIncomingState *mis)
+{
+    /* Mark so that we get notified of accesses to unwritten areas */
+    if (qemu_ram_foreach_block(postcopy_ram_sensitise_area, NULL)) {
+        return -1;
+    }
+
+    return 0;
+}
+
 #else
 /* No target OS support, stubs just fail */
-
 int postcopy_ram_hosttest(void)
 {
     error_report("postcopy_ram_hosttest: No OS support");
@@ -365,6 +394,11 @@  int postcopy_ram_incoming_cleanup(MigrationIncomingState *mis)
     return -1;
 }
 
+int postcopy_ram_enable_notify(MigrationIncomingState *mis)
+{
+    fprintf(stderr, "postcopy_ram_enable_notify: No OS support\n");
+    return -1;
+}
 #endif
 
 /* ------------------------------------------------------------------------- */