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

[Xen-changelog] [xen stable-4.2] x86/EFI: make trampoline allocation more flexible



commit d9def91db8a25b666928f686b6450a5b783d2d69
Author:     Jan Beulich <jbeulich@xxxxxxxx>
AuthorDate: Fri Nov 15 11:44:17 2013 +0100
Commit:     Jan Beulich <jbeulich@xxxxxxxx>
CommitDate: Fri Nov 15 11:44:17 2013 +0100

    x86/EFI: make trampoline allocation more flexible
    
    Certain UEFI implementations reserve all memory below 1Mb at boot time,
    making it impossible to properly allocate the chunk necessary for the
    trampoline. Fall back to simply grabbing a chunk from EfiBootServices*
    regions immediately prior to calling ExitBootServices().
    
    Signed-off-by: Jan Beulich <jbeulich@xxxxxxxx>
    Acked-by: Keir Fraser <keir@xxxxxxx>
    master commit: c1f2dfe8f6a559bc28935f24e31bb33d17d9713d
    master date: 2013-11-08 11:08:32 +0100
---
 xen/arch/x86/efi/boot.c |   49 ++++++++++++++++++++++++++++++----------------
 1 files changed, 32 insertions(+), 17 deletions(-)

diff --git a/xen/arch/x86/efi/boot.c b/xen/arch/x86/efi/boot.c
index 5fe31d6..6c0b689 100644
--- a/xen/arch/x86/efi/boot.c
+++ b/xen/arch/x86/efi/boot.c
@@ -621,6 +621,22 @@ static void __init relocate_image(unsigned long delta)
 extern const s32 __trampoline_rel_start[], __trampoline_rel_stop[];
 extern const s32 __trampoline_seg_start[], __trampoline_seg_stop[];
 
+static void __init relocate_trampoline(unsigned long phys)
+{
+    const s32 *trampoline_ptr;
+
+    trampoline_phys = phys;
+    /* Apply relocations to trampoline. */
+    for ( trampoline_ptr = __trampoline_rel_start;
+          trampoline_ptr < __trampoline_rel_stop;
+          ++trampoline_ptr )
+        *(u32 *)(*trampoline_ptr + (long)trampoline_ptr) += phys;
+    for ( trampoline_ptr = __trampoline_seg_start;
+          trampoline_ptr < __trampoline_seg_stop;
+          ++trampoline_ptr )
+        *(u16 *)(*trampoline_ptr + (long)trampoline_ptr) = phys >> 4;
+}
+
 void EFIAPI __init __attribute__((__noreturn__))
 efi_start(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable)
 {
@@ -638,7 +654,6 @@ efi_start(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE 
*SystemTable)
     EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *mode_info;
     EFI_FILE_HANDLE dir_handle;
     union string section = { NULL }, name;
-    const s32 *trampoline_ptr;
     struct e820entry *e;
     u64 efer;
     bool_t base_video = 0;
@@ -1095,23 +1110,13 @@ efi_start(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE 
*SystemTable)
     cfg.size = trampoline_end - trampoline_start;
     status = efi_bs->AllocatePages(AllocateMaxAddress, EfiLoaderData,
                                    PFN_UP(cfg.size), &cfg.addr);
-    if ( EFI_ERROR(status) )
+    if ( status == EFI_SUCCESS )
+        relocate_trampoline(cfg.addr);
+    else
     {
         cfg.addr = 0;
-        blexit(L"No memory for trampoline\r\n");
+        PrintStr(L"Trampoline space cannot be allocated; will try 
fallback.\r\n");
     }
-    trampoline_phys = cfg.addr;
-    /* Apply relocations to trampoline. */
-    for ( trampoline_ptr = __trampoline_rel_start;
-          trampoline_ptr < __trampoline_rel_stop;
-          ++trampoline_ptr )
-        *(u32 *)(*trampoline_ptr + (long)trampoline_ptr) +=
-            trampoline_phys;
-    for ( trampoline_ptr = __trampoline_seg_start;
-          trampoline_ptr < __trampoline_seg_stop;
-          ++trampoline_ptr )
-        *(u16 *)(*trampoline_ptr + (long)trampoline_ptr) =
-            trampoline_phys >> 4;
 
     /* Initialise L2 identity-map and xen page table entries (16MB). */
     for ( i = 0; i < 8; ++i )
@@ -1255,10 +1260,14 @@ efi_start(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE 
*SystemTable)
             type = E820_RESERVED;
             break;
         case EfiConventionalMemory:
-        case EfiLoaderCode:
-        case EfiLoaderData:
         case EfiBootServicesCode:
         case EfiBootServicesData:
+            if ( !trampoline_phys && desc->PhysicalStart + len <= 0x100000 &&
+                 len >= cfg.size && desc->PhysicalStart + len > cfg.addr )
+                cfg.addr = (desc->PhysicalStart + len - cfg.size) & PAGE_MASK;
+            /* fall through */
+        case EfiLoaderCode:
+        case EfiLoaderData:
             if ( desc->Attribute & EFI_MEMORY_WB )
                 type = E820_RAM;
             else
@@ -1286,6 +1295,12 @@ efi_start(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE 
*SystemTable)
             ++e820nr;
         }
     }
+    if ( !trampoline_phys )
+    {
+        if ( !cfg.addr )
+            blexit(L"No memory for trampoline");
+        relocate_trampoline(cfg.addr);
+    }
 
     status = efi_bs->ExitBootServices(ImageHandle, map_key);
     if ( EFI_ERROR(status) )
--
generated by git-patchbot for /home/xen/git/xen.git#stable-4.2

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog


 


Rackspace

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