diff --git a/xen/arch/x86/boot/head.S b/xen/arch/x86/boot/head.S
index c730810461..250587fdf0 100644
--- a/xen/arch/x86/boot/head.S
+++ b/xen/arch/x86/boot/head.S
@@ -400,7 +400,7 @@ __pvh_start:
         sub     $sym_offs(1b), %esi
 
         /* Set up stack. */
-        lea     STACK_SIZE + sym_esi(cpu0_stack), %esp
+        lea     STACK_SIZE - CPUINFO_sizeof + sym_esi(cpu0_stack), %esp
 
         mov     %ebx, sym_esi(pvh_start_info_pa)
 
@@ -447,7 +447,7 @@ __start:
         sub     $sym_offs(1b), %esi
 
         /* Set up stack. */
-        lea     STACK_SIZE + sym_esi(cpu0_stack), %esp
+        lea     STACK_SIZE - CPUINFO_sizeof + sym_esi(cpu0_stack), %esp
 
         /* Bootloaders may set multiboot{1,2}.mem_lower to a nonzero value. */
         xor     %edx,%edx
@@ -616,7 +616,11 @@ trampoline_setup:
         cmpb    $0,sym_fs(efi_platform)
         jnz     1f
 
-        /* Initialize BSS (no nasty surprises!). */
+        /*
+         * Initialise the BSS.
+         *
+         * !!! WARNING - also zeroes the current stack !!!
+         */
         lea     sym_esi(__bss_start), %edi
         lea     sym_esi(__bss_end), %ecx
         sub     %edi,%ecx
diff --git a/xen/arch/x86/boot/x86_64.S b/xen/arch/x86/boot/x86_64.S
index b54d3aceea..0acf5e860c 100644
--- a/xen/arch/x86/boot/x86_64.S
+++ b/xen/arch/x86/boot/x86_64.S
@@ -16,7 +16,6 @@ ENTRY(__high_start)
         mov     %rcx,%cr4
 
         mov     stack_start(%rip),%rsp
-        or      $(STACK_SIZE-CPUINFO_sizeof),%rsp
 
         /* Reset EFLAGS (subsumes CLI and CLD). */
         pushq   $0
@@ -42,7 +41,7 @@ multiboot_ptr:
         .long   0
 
 GLOBAL(stack_start)
-        .quad   cpu0_stack
+        .quad   cpu0_stack + STACK_SIZE - CPUINFO_sizeof
 
         .section .data.page_aligned, "aw", @progbits
         .align PAGE_SIZE, 0
diff --git a/xen/arch/x86/efi/efi-boot.h b/xen/arch/x86/efi/efi-boot.h
index 676d616ff8..9c036d5f4c 100644
--- a/xen/arch/x86/efi/efi-boot.h
+++ b/xen/arch/x86/efi/efi-boot.h
@@ -249,23 +249,24 @@ static void __init noreturn efi_arch_post_exit_boot(void)
                    "or     $"__stringify(X86_CR4_PGE)", %[cr4]\n\t"
                    "mov    %[cr4], %%cr4\n\t"
 #endif
-                   "movabs $__start_xen, %[rip]\n\t"
                    "lgdt   boot_gdtr(%%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"
+
+                   /* Jump to higher mappings. */
+                   "mov    stack_start(%%rip), %%rsp\n\t"
+                   "movabs $__start_xen, %[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),
-                     [cs] "ir" (__HYPERVISOR_CS),
+                     [cs] "i" (__HYPERVISOR_CS),
                      [ds] "r" (__HYPERVISOR_DS),
-                     [stkoff] "i" (STACK_SIZE - sizeof(struct cpu_info)),
                      "D" (&mbi)
                    : "memory" );
     unreachable();
diff --git a/xen/arch/x86/smpboot.c b/xen/arch/x86/smpboot.c
index 301f746979..c9d1ab4423 100644
--- a/xen/arch/x86/smpboot.c
+++ b/xen/arch/x86/smpboot.c
@@ -554,7 +554,7 @@ static int do_boot_cpu(int apicid, int cpu)
         printk("Booting processor %d/%d eip %lx\n",
                cpu, apicid, start_eip);
 
-    stack_start = stack_base[cpu];
+    stack_start = stack_base[cpu] + STACK_SIZE - sizeof(struct cpu_info);
 
     /* This grunge runs the startup process for the targeted processor. */
 
@@ -1084,7 +1084,7 @@ void __init smp_prepare_cpus(void)
     boot_cpu_physical_apicid = get_apic_id();
     x86_cpu_to_apicid[0] = boot_cpu_physical_apicid;
 
-    stack_base[0] = stack_start;
+    stack_base[0] = (void *)((unsigned long)stack_start & ~(STACK_SIZE - 1));
 
     rc = setup_cpu_root_pgt(0);
     if ( rc )
