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

[Xen-devel] [PATCH 2/4] x86/boot: Minor improvements to efi_arch_post_exit_boot()

Split up the long asm block by commenting the logical subsections.

The movabs for obtaining __start_xen can be a rip-relative lea instead.  This
has the added advantage that objdump can now cross reference it during

The stack handing is confusing to follow.  %rsp is set up by reading
stack_start which is a pointer to cpu0_stack, then constructing an lret frame
under %rsp (to avoid clobbering whatever is adjacent to cpu0_stack), and uses
the Pascal form of lret to move %rsp to the base of cpu0_stack.

Remove stack_start from the mix and use a single lea to load cpu0_stack base
directly, and use the more common push/push/lretq sequence for reloading %cs.

Use unreachable() rather than an infinite for loop, which lets the compiler
discard all the epilogue code that it inserted previously.

Signed-off-by: Andrew Cooper <andrew.cooper3@xxxxxxxxxx>
CC: Jan Beulich <JBeulich@xxxxxxxx>
CC: Wei Liu <wl@xxxxxxx>
CC: Roger Pau Monné <roger.pau@xxxxxxxxxx>

Overall, the asm block is 10 bytes shorter, not that this was the point of the

In principle, the constraints for [cs] and [ds] could be relaxed to include
"m", but Clang decided to insert 5 rip-relative memory operands for the
segment loads, which isn't a clever optimisation to make.
 xen/arch/x86/efi/efi-boot.h | 15 +++++++++------
 1 file changed, 9 insertions(+), 6 deletions(-)

diff --git a/xen/arch/x86/efi/efi-boot.h b/xen/arch/x86/efi/efi-boot.h
index 7a13a30bc0..2f59d8bdbd 100644
--- a/xen/arch/x86/efi/efi-boot.h
+++ b/xen/arch/x86/efi/efi-boot.h
@@ -249,17 +249,20 @@ static void __init noreturn efi_arch_post_exit_boot(void)
                    "or     $"__stringify(X86_CR4_PGE)", %[cr4]\n\t"
                    "mov    %[cr4], %%cr4\n\t"
-                   "movabs $__start_xen, %[rip]\n\t"
+                   /* Load data segments. */
                    "lgdt   gdt_descr(%%rip)\n\t"
-                   "mov    stack_start(%%rip), %%rsp\n\t"
                    "mov    %[ds], %%ss\n\t"
                    "mov    %[ds], %%ds\n\t"
                    "mov    %[ds], %%es\n\t"
                    "mov    %[ds], %%fs\n\t"
                    "mov    %[ds], %%gs\n\t"
-                   "movl   %[cs], 8(%%rsp)\n\t"
-                   "mov    %[rip], (%%rsp)\n\t"
-                   "lretq  %[stkoff]-16"
+                   /* Switch stack, reload %cs and jump. */
+                   "lea    %c[stkoff] + cpu0_stack(%%rip), %%rsp\n\t"
+                   "lea    __start_xen(%%rip), %[rip]\n\t"
+                   "push   %[cs]\n\t"
+                   "push   %[rip]\n\t"
+                   "lretq"
                    : [rip] "=&r" (efer/* any dead 64-bit variable */),
                      [cr4] "+&r" (cr4)
                    : [cr3] "r" (idle_pg_table),
@@ -268,7 +271,7 @@ static void __init noreturn efi_arch_post_exit_boot(void)
                      [stkoff] "i" (STACK_SIZE - sizeof(struct cpu_info)),
                      "D" (&mbi)
                    : "memory" );
-    for( ; ; ); /* not reached */
+    unreachable();
 static void __init efi_arch_cfg_file_early(EFI_FILE_HANDLE dir_handle, char 

Xen-devel mailing list



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