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

[PATCH RFC] x86/boot: Call efi_multiboot2() at it's linked address



When entering via MB2+EFI, the early EFI code hasn't been relocated down to
it's load address.  As a consequence, efi_multboot2() is still expecting to
run at high address.

To set this up, we need Xen's high mappings, while also retaining the EFI
physical-mode mappings in the low half.  Introduce a new efi_l4_bootmap[] for
the purpose.

Signed-off-by: Andrew Cooper <andrew.cooper3@xxxxxxxxxx>
---
CC: Jan Beulich <JBeulich@xxxxxxxx>
CC: Roger Pau Monné <roger.pau@xxxxxxxxxx>
CC: Frediano Ziglio <frediano.ziglio@xxxxxxxxx>
CC: Marek Marczykowski-Górecki <marmarek@xxxxxxxxxxxxxxxxxxxxxx>
CC: Daniel Smith <dpsmith@xxxxxxxxxxxxxxxxxxxx>

Very RFC, compile tested only.
---
 xen/arch/x86/boot/head.S   | 69 +++++++++++++++++++++++++++++++++++++-
 xen/arch/x86/boot/x86_64.S |  4 +++
 2 files changed, 72 insertions(+), 1 deletion(-)

diff --git a/xen/arch/x86/boot/head.S b/xen/arch/x86/boot/head.S
index e0901ee40044..ef07f30d13da 100644
--- a/xen/arch/x86/boot/head.S
+++ b/xen/arch/x86/boot/head.S
@@ -344,6 +344,66 @@ __efi64_mb2_start:
         lea     .Lmb2_no_ih(%rip),%r15
         jz      x86_32_switch
 
+        push    %rax
+        push    %rcx
+        push    %rdx
+        push    %rsi
+        push    %rdi
+
+        /* Merge lower half of EFI pagtables with upper half of Xen pagetables 
*/
+        mov     %cr3, %rsi
+        lea     efi_l4_bootmap(%rip), %rdi
+        mov     $L4_PAGETABLE_ENTRIES / 2, %ecx
+        rep movsq
+        lea     ((L4_PAGETABLE_ENTRIES / 2) * 8) + idle_pg_table(%rip), %rsi
+        mov     $L4_PAGETABLE_ENTRIES / 2, %ecx
+        rep movsq
+
+        /* Switch to merged pagetables */
+        lea     efi_l4_bootmap(%rip), %rax
+        mov     %rax, %cr3
+
+        lea     __image_base__(%rip), %esi
+
+        /* Map Xen into the higher mappings using 2M superpages. */
+        lea     _PAGE_PSE + PAGE_HYPERVISOR_RWX + sym_esi(_start), %eax
+        mov     $sym_offs(_start),   %ecx   /* %eax = PTE to write ^      */
+        mov     $sym_offs(_end - 1), %edx
+        shr     $L2_PAGETABLE_SHIFT, %ecx   /* %ecx = First slot to write */
+        shr     $L2_PAGETABLE_SHIFT, %edx   /* %edx = Final slot to write */
+
+1:      mov     %eax, sym_offs(l2_xenmap)(%esi, %ecx, 8)
+        add     $1, %ecx
+        add     $1 << L2_PAGETABLE_SHIFT, %eax
+
+        cmp     %edx, %ecx
+        jbe     1b
+
+        /*
+         * Map Xen into the directmap (needed for early-boot pagetable
+         * handling/walking), and identity map Xen into bootmap (needed for
+         * the transition into long mode), using 2M superpages.
+         */
+        lea     sym_esi(_start), %ecx
+        lea     -1 + sym_esi(_end), %edx
+        lea     _PAGE_PSE + PAGE_HYPERVISOR_RWX(%ecx), %eax /* PTE to write. */
+        shr     $L2_PAGETABLE_SHIFT, %ecx                   /* First slot to 
write. */
+        shr     $L2_PAGETABLE_SHIFT, %edx                   /* Final slot to 
write. */
+
+1:      mov     %eax, sym_offs(l2_bootmap)  (%esi, %ecx, 8)
+        mov     %eax, sym_offs(l2_directmap)(%esi, %ecx, 8)
+        add     $1, %ecx
+        add     $1 << L2_PAGETABLE_SHIFT, %eax
+
+        cmp     %edx, %ecx
+        jbe     1b
+
+        pop     %rdi
+        pop     %rsi
+        pop     %rdx
+        pop     %rcx
+        pop     %rax
+
         /* Save Multiboot2 magic on the stack. */
         push    %rax
 
@@ -354,8 +414,15 @@ __efi64_mb2_start:
          * efi_multiboot2() is called according to System V AMD64 ABI:
          *   - IN:  %rdi - EFI ImageHandle, %rsi - EFI SystemTable,
          *          %rdx - MB2 cmdline
+         *
+         * Call via the high mappings
          */
-        call    efi_multiboot2
+        lea     __image_base__(%rip), %r10
+        lea     efi_multiboot2(%rip), %rax
+        sub     %r10, %rax
+        mov     $__XEN_VIRT_START, %r10
+        addq    %r10, %rax
+        call    *%rax
 
         /* Just pop an item from the stack. */
         pop     %rax
diff --git a/xen/arch/x86/boot/x86_64.S b/xen/arch/x86/boot/x86_64.S
index 04bb62ae8680..93938d0b03f8 100644
--- a/xen/arch/x86/boot/x86_64.S
+++ b/xen/arch/x86/boot/x86_64.S
@@ -206,3 +206,7 @@ GLOBAL(l2_bootmap)
 GLOBAL(l3_bootmap)
         .fill L3_PAGETABLE_ENTRIES, 8, 0
         .size l3_bootmap, . - l3_bootmap
+
+efi_l4_bootmap:
+        .fill L4_PAGETABLE_ENTRIES, 8, 0
+        .size efi_l4_bootmap, . - efi_l4_bootmap

base-commit: 457052167b4dbcda59e06300039302479cc1debf
-- 
2.39.5




 


Rackspace

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