@@ -54,7 +54,20 @@ SYM_CODE_START(pvh_start_xen)
UNWIND_HINT_END_OF_STACK
cld
- lgdt (_pa(gdt))
+ /*
+ * This is position dependent code that can only execute correctly from
+ * the physical address that the kernel was linked to run at. Use the
+ * symbols emitted for the ELF note to construct the build time physical
+ * address of pvh_start_xen(), without relying on absolute 32-bit ELF
+ * relocations, as these are not supported by the linker when running in
+ * -pie mode, and should be avoided in .head.text in general.
+ */
+0: mov $xen_elfnote_phys32_entry_offset - 0b, %ebp
+ sub $xen_elfnote_phys32_entry - 0b, %ebp
+
+ lea (gdt - pvh_start_xen)(%ebp), %eax
+ add %eax, 2(%eax)
+ lgdt (%eax)
mov $PVH_DS_SEL,%eax
mov %eax,%ds
@@ -62,14 +75,14 @@ SYM_CODE_START(pvh_start_xen)
mov %eax,%ss
/* Stash hvm_start_info. */
- mov $_pa(pvh_start_info), %edi
+ lea (pvh_start_info - pvh_start_xen)(%ebp), %edi
mov %ebx, %esi
- mov _pa(pvh_start_info_sz), %ecx
+ mov (pvh_start_info_sz - pvh_start_xen)(%ebp), %ecx
shr $2,%ecx
rep
movsl
- mov $_pa(early_stack_end), %esp
+ lea (early_stack_end - pvh_start_xen)(%ebp), %esp
/* Enable PAE mode. */
mov %cr4, %eax
@@ -84,17 +97,21 @@ SYM_CODE_START(pvh_start_xen)
wrmsr
/* Enable pre-constructed page tables. */
- mov $_pa(init_top_pgt), %eax
+ lea (init_top_pgt - pvh_start_xen)(%ebp), %eax
mov %eax, %cr3
mov $(X86_CR0_PG | X86_CR0_PE), %eax
mov %eax, %cr0
/* Jump to 64-bit mode. */
- ljmp $PVH_CS_SEL, $_pa(1f)
+ lea (1f - pvh_start_xen)(%ebp), %eax
+ push $PVH_CS_SEL
+ push %eax
+ lret
/* 64-bit entry point. */
.code64
1:
+ UNWIND_HINT_END_OF_STACK
/* Clear %gs so early per-CPU references target the per-CPU load area */
mov $MSR_GS_BASE,%ecx
xor %eax, %eax
@@ -108,10 +125,8 @@ SYM_CODE_START(pvh_start_xen)
call *%rax
/* startup_64 expects boot_params in %rsi. */
- mov $_pa(pvh_bootparams), %rsi
- mov $_pa(startup_64), %rax
- ANNOTATE_RETPOLINE_SAFE
- jmp *%rax
+ lea pvh_bootparams(%rip), %rsi
+ jmp startup_64
#else /* CONFIG_X86_64 */
@@ -146,8 +161,8 @@ SYM_CODE_END(pvh_start_xen)
.section ".init.data","aw"
.balign 8
SYM_DATA_START_LOCAL(gdt)
- .word gdt_end - gdt_start
- .long _pa(gdt_start)
+ .word gdt_end - gdt_start - 1
+ .long gdt_start - gdt
.word 0
SYM_DATA_END(gdt)
SYM_DATA_START_LOCAL(gdt_start)