diff mbox series

[RFC,v2,13/14] Basic shell of lu_reserve_all() from breadcrumb at boot

Message ID 20200122085357.2092778-13-dwmw2@infradead.org (mailing list archive)
State New, archived
Headers show
Series Live update: boot memory management, data stream handling | expand

Commit Message

David Woodhouse Jan. 22, 2020, 8:53 a.m. UTC
From: David Woodhouse <dwmw@amazon.co.uk>

This mostly just reserves pages, hence the name. The rest of the actual
restoration will happen later, after the heap allocator works.

Signed-off-by: David Woodhouse <dwmw@amazon.co.uk>
---
 xen/arch/x86/setup.c    | 20 +++++++++++++++++++
 xen/common/lu/Makefile  |  2 +-
 xen/common/lu/restore.c | 44 +++++++++++++++++++++++++++++++++++++++++
 xen/include/xen/lu.h    |  1 +
 4 files changed, 66 insertions(+), 1 deletion(-)
 create mode 100644 xen/common/lu/restore.c
diff mbox series

Patch

diff --git a/xen/arch/x86/setup.c b/xen/arch/x86/setup.c
index bd65d6bf5d..af874ee8b5 100644
--- a/xen/arch/x86/setup.c
+++ b/xen/arch/x86/setup.c
@@ -25,6 +25,7 @@ 
 #include <xen/nodemask.h>
 #include <xen/virtual_region.h>
 #include <xen/watchdog.h>
+#include <xen/lu.h>
 #include <public/version.h>
 #include <compat/platform.h>
 #include <compat/xen.h>
@@ -739,6 +740,7 @@  void __init noreturn __start_xen(unsigned long mbi_p)
         .max_maptrack_frames = -1,
     };
     const char *hypervisor_name;
+    uint64_t lu_mfnlist_phys = 0, lu_nr_pages = 0;
 
     /* Critical region without IDT or TSS.  Any fault is deadly! */
 
@@ -1336,6 +1338,21 @@  void __init noreturn __start_xen(unsigned long mbi_p)
     if ( !xen_phys_start )
         panic("Not enough memory to relocate Xen\n");
 
+    if ( lu_data )
+    {
+        uint64_t *breadcrumb = maddr_to_virt(lu_data);
+
+        lu_mfnlist_phys = breadcrumb[1];
+        lu_nr_pages = breadcrumb[2] >> PAGE_SHIFT;
+
+        if ( breadcrumb[0] == LIVE_UPDATE_MAGIC && lu_nr_pages) {
+            printk("%ld pages of live update data at 0x%lx\n", lu_nr_pages, lu_mfnlist_phys);
+        } else {
+            panic("Live update breadcrumb not found: %lx %lx %lx at %lx\n",
+                  breadcrumb[0], breadcrumb[1], breadcrumb[2], lu_data);
+        }
+    }
+
     if ( lu_bootmem_start )
     {
         if ( !lu_reserved )
@@ -1571,6 +1588,9 @@  void __init noreturn __start_xen(unsigned long mbi_p)
 
     numa_initmem_init(0, raw_max_page);
 
+    if ( lu_data )
+        lu_reserve_pages(lu_mfnlist_phys, lu_nr_pages);
+
     if ( lu_bootmem_start )
     {
         unsigned long limit = virt_to_mfn(HYPERVISOR_VIRT_END - 1);
diff --git a/xen/common/lu/Makefile b/xen/common/lu/Makefile
index 7b7d975f65..592c72e1ec 100644
--- a/xen/common/lu/Makefile
+++ b/xen/common/lu/Makefile
@@ -1 +1 @@ 
-obj-y += stream.o save.o
+obj-y += stream.o save.o restore.o
diff --git a/xen/common/lu/restore.c b/xen/common/lu/restore.c
new file mode 100644
index 0000000000..7f40513ef9
--- /dev/null
+++ b/xen/common/lu/restore.c
@@ -0,0 +1,44 @@ 
+#include <xen/types.h>
+#include <xen/vmap.h>
+#include <xen/lu.h>
+#include <xen/sched.h>
+
+#define MFNS_PER_PAGE (PAGE_SIZE / sizeof(mfn_t))
+
+/* Returns void. There's not a lot we can do if this fails except panic. */
+void lu_reserve_pages(paddr_t mfns_p, int nr_pages)
+{
+    unsigned int index_pages = (nr_pages + MFNS_PER_PAGE - 1) / MFNS_PER_PAGE;
+    unsigned char *p;
+    mfn_t *mfns;
+    int i;
+
+    /* Would like to vmap(). Too early. */
+    mfns = __va(mfns_p);
+    map_pages_to_xen((unsigned long)mfns, maddr_to_mfn(mfns_p), index_pages, PAGE_HYPERVISOR);
+
+    for ( i = 0; i < index_pages; i++ )
+    {
+        maddr_to_page(mfns_p + (i << PAGE_SHIFT))->count_info |= PGC_allocated;
+    }
+
+    for ( i = 0; i < nr_pages; i++ )
+    {
+        if (!mfn_valid(mfns[i]))
+            panic("Invalid MFN %lx in live update stream\n", mfn_x(mfns[i]));
+
+        mfn_to_page(mfns[i])->count_info |= PGC_allocated;
+	}
+
+    /* XX: Consume the stream of data and mark all domain pages as allocated too. */
+}
+
+/*
+ * Local variables:
+ * mode: C
+ * c-file-style: "BSD"
+ * c-basic-offset: 4
+ * tab-width: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
diff --git a/xen/include/xen/lu.h b/xen/include/xen/lu.h
index 6e8377b6c3..496db9bfe1 100644
--- a/xen/include/xen/lu.h
+++ b/xen/include/xen/lu.h
@@ -13,3 +13,4 @@  void lu_stream_free(struct lu_stream *stream);
 
 struct kexec_image;
 int lu_save_all(struct kexec_image *image);
+void lu_reserve_pages(paddr_t mfnlist, int nr_pages);