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

[Xen-devel] [RFC PATCH v3 14/22] Detect live update breadcrumb at boot and map data stream



From: David Woodhouse <dwmw@xxxxxxxxxxxx>

Signed-off-by: David Woodhouse <dwmw@xxxxxxxxxxxx>
---
 xen/arch/x86/setup.c   | 35 +++++++++++++++++++++++++++++++++--
 xen/common/lu/stream.c | 34 ++++++++++++++++++++++++++++++++++
 xen/include/xen/lu.h   |  2 ++
 3 files changed, 69 insertions(+), 2 deletions(-)

diff --git a/xen/arch/x86/setup.c b/xen/arch/x86/setup.c
index ea3f423b4c..eea670e03b 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>
@@ -745,6 +746,8 @@ 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;
+    struct lu_stream lu_stream;
 
     /* Critical region without IDT or TSS.  Any fault is deadly! */
 
@@ -889,9 +892,16 @@ void __init noreturn __start_xen(unsigned long mbi_p)
     printk(" Found %d EDD information structures\n",
            bootsym(boot_edd_info_nr));
 
-    /* Check that we have at least one Multiboot module. */
     if ( !(mbi->flags & MBI_MODULES) || (mbi->mods_count == 0) )
-        panic("dom0 kernel not specified. Check bootloader configuration\n");
+    {
+        if ( !lu_breadcrumb_phys )
+            panic("dom0 kernel not specified. Check bootloader 
configuration\n");
+    }
+    else
+    {
+        /* If modules are provided, don't even look for live update data. */
+        lu_breadcrumb_phys = 0;
+    }
 
     /* Check that we don't have a silly number of modules. */
     if ( mbi->mods_count > sizeof(module_map) * 8 )
@@ -1337,6 +1347,22 @@ void __init noreturn __start_xen(unsigned long mbi_p)
     if ( !xen_phys_start )
         panic("Not enough memory to relocate Xen\n");
 
+    /* Check for the state breadcrumb before giving it to the boot allocator */
+    if ( lu_breadcrumb_phys )
+    {
+        uint64_t *breadcrumb = maddr_to_virt(lu_breadcrumb_phys);
+
+        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_breadcrumb_phys);
+        }
+    }
+
     if ( lu_bootmem_start )
     {
         if ( !lu_reserved )
@@ -1574,6 +1600,11 @@ void __init noreturn __start_xen(unsigned long mbi_p)
 
     vm_init();
 
+    if ( lu_breadcrumb_phys )
+    {
+        lu_stream_map(&lu_stream, 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/stream.c b/xen/common/lu/stream.c
index 10e123a466..8c44a4eb37 100644
--- a/xen/common/lu/stream.c
+++ b/xen/common/lu/stream.c
@@ -124,6 +124,40 @@ void lu_stream_free(struct lu_stream *stream)
     }
 }
 
+void lu_stream_map(struct lu_stream *stream, unsigned long mfns_phys, int 
nr_pages)
+{
+    unsigned int order = get_order_from_bytes((nr_pages + 1) * sizeof(mfn_t));
+    unsigned int i;
+
+    memset(stream, 0, sizeof(*stream));
+
+    stream->len = nr_pages << PAGE_SHIFT;
+    stream->nr_pages = nr_pages;
+    stream->pagelist = __va(mfns_phys);
+
+    map_pages_to_xen((unsigned long)stream->pagelist, maddr_to_mfn(mfns_phys),
+                     1 << order, PAGE_HYPERVISOR);
+
+    /* Reserve the pages used for the pagelist itself. */
+    for ( i = 0; i < (1 << order); i++ )
+    {
+        maddr_to_page(mfns_phys + (i << PAGE_SHIFT))->count_info |= 
PGC_allocated;
+    }
+
+    /* Validate and reserve the data pages */
+    for ( i = 0; i < nr_pages; i++ )
+    {
+        if (!mfn_valid(stream->pagelist[i]))
+            panic("Invalid MFN %lx in live update stream\n", 
mfn_x(stream->pagelist[i]));
+
+        mfn_to_page(stream->pagelist[i])->count_info |= PGC_allocated;
+    }
+
+    stream->data = vmap(stream->pagelist, nr_pages);
+    if (!stream->data)
+        panic("Failed to map live update data\n");
+}
+
 /*
  * local variables:
  * mode: c
diff --git a/xen/include/xen/lu.h b/xen/include/xen/lu.h
index f232a56950..21abace130 100644
--- a/xen/include/xen/lu.h
+++ b/xen/include/xen/lu.h
@@ -22,6 +22,8 @@ void lu_stream_free(struct lu_stream *stream);
 struct kexec_image;
 int lu_save_all(struct kexec_image *image);
 
+void lu_stream_map(struct lu_stream *stream, unsigned long mfns_phys, int 
nr_pages);
+
 #endif /* __XEN_LU_H__ */
 
 /*
-- 
2.21.0


_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxxx
https://lists.xenproject.org/mailman/listinfo/xen-devel

 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.