|
[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
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |