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

[Xen-devel] [PATCH for-4.10] libxc: load acpi RSDP table at correct address



For PVH domains loading of the ACPI RSDP table is done via allocating
a domain loader segment after having loaded the kernel. This leads to
the RSDP table being loaded at an arbitrary guest address instead of
the architectural correct address just below 1MB.

When using the Linux kernel this is currently no problem as the
bzImage loader is being used, which is loading ACPI tables via an
alternative method.

Using grub2 however exposes this problem leading to the selected
kernel no longer being able to find the RSDP table.

To solve this issue allow to load the RSDP table below the already
loaded kernel if this space hasn't been used before.

Signed-off-by: Juergen Gross <jgross@xxxxxxxx>
---
Not sure if this is acceptable for 4.10, but I think PVH guest support
should include the possibility to use grub2 as a boot loader.

So please consider this patch for 4.10.
---
 tools/libxc/xc_dom_hvmloader.c | 39 +++++++++++++++++++++++++++++++--------
 1 file changed, 31 insertions(+), 8 deletions(-)

diff --git a/tools/libxc/xc_dom_hvmloader.c b/tools/libxc/xc_dom_hvmloader.c
index 59f94e51e5..2284c7f9df 100644
--- a/tools/libxc/xc_dom_hvmloader.c
+++ b/tools/libxc/xc_dom_hvmloader.c
@@ -135,20 +135,43 @@ static int module_init_one(struct xc_dom_image *dom,
 {
     struct xc_dom_seg seg;
     void *dest;
+    xen_pfn_t start, end;
+    unsigned int page_size = XC_DOM_PAGE_SIZE(dom);
 
     if ( module->length )
     {
-        if ( xc_dom_alloc_segment(dom, &seg, name, 0, module->length) )
-            goto err;
-        dest = xc_dom_seg_to_ptr(dom, &seg);
-        if ( dest == NULL )
+        /*
+         * Check for module located below kernel.
+         * Make sure not to be fooled by a kernel based on virtual address.
+         */
+        if ( module->guest_addr_out && !(dom->kernel_seg.vstart >> 32) &&
+             module->guest_addr_out + module->length <= dom->kernel_seg.vstart 
)
         {
-            DOMPRINTF("%s: xc_dom_seg_to_ptr(dom, &seg) => NULL",
-                      __FUNCTION__);
-            goto err;
+            start = module->guest_addr_out / page_size;
+            end = (module->guest_addr_out + module->length + page_size - 1) /
+                  page_size;
+            dest = xc_dom_pfn_to_ptr(dom, start, end - start);
+            if ( dest == NULL )
+            {
+                DOMPRINTF("%s: xc_dom_pfn_to_ptr() => NULL", __FUNCTION__);
+                goto err;
+            }
+            dest += module->guest_addr_out - start * page_size;
+        }
+        else
+        {
+            if ( xc_dom_alloc_segment(dom, &seg, name, 0, module->length) )
+                goto err;
+            dest = xc_dom_seg_to_ptr(dom, &seg);
+            if ( dest == NULL )
+            {
+                DOMPRINTF("%s: xc_dom_seg_to_ptr(dom, &seg) => NULL",
+                          __FUNCTION__);
+                goto err;
+            }
+            module->guest_addr_out = seg.vstart;
         }
         memcpy(dest, module->data, module->length);
-        module->guest_addr_out = seg.vstart;
 
         assert(dom->mmio_start > 0 && dom->mmio_start < UINT32_MAX);
         if ( module->guest_addr_out > dom->mmio_start ||
-- 
2.12.3


_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxx
https://lists.xen.org/xen-devel

 


Rackspace

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