diff options
author | Jan Beulich <jbeulich@novell.com> | 2011-08-19 09:54:26 +0100 |
---|---|---|
committer | Jan Beulich <jbeulich@novell.com> | 2011-08-19 09:54:26 +0100 |
commit | bc4a68f21f43c2e37346cf5a1f37c19a53b540c2 (patch) | |
tree | 3b4af0bd3182a264bbe3b84a65e21a606e4f43ab /xen/arch/x86/boot | |
parent | 2f399b3bb0cae8072ed42856eac6a805728516fe (diff) | |
download | xen-bc4a68f21f43c2e37346cf5a1f37c19a53b540c2.tar.gz xen-bc4a68f21f43c2e37346cf5a1f37c19a53b540c2.tar.bz2 xen-bc4a68f21f43c2e37346cf5a1f37c19a53b540c2.zip |
x86: make run-time part of trampoline relocatable
In order to eliminate an initial hack in the EFI boot code (where
memory for the trampoline was just "claimed" instead of properly
allocated), the trampoline code must no longer make assumption on the
address at which it would be located. For the time being, the fixed
address is being retained for the traditional multiboot path.
As an additional benefit (at least from my pov) it allows confining
the visibility of the BOOT_TRAMPOLINE definition to just the boot
code.
Signed-off-by: Jan Beulich <jbeulich@novell.com>
Diffstat (limited to 'xen/arch/x86/boot')
-rw-r--r-- | xen/arch/x86/boot/Makefile | 4 | ||||
-rw-r--r-- | xen/arch/x86/boot/head.S | 13 | ||||
-rw-r--r-- | xen/arch/x86/boot/trampoline.S | 30 | ||||
-rw-r--r-- | xen/arch/x86/boot/wakeup.S | 20 |
4 files changed, 46 insertions, 21 deletions
diff --git a/xen/arch/x86/boot/Makefile b/xen/arch/x86/boot/Makefile index fb921173c2..64b5db4c19 100644 --- a/xen/arch/x86/boot/Makefile +++ b/xen/arch/x86/boot/Makefile @@ -2,8 +2,8 @@ obj-bin-y += head.o head.o: reloc.S -BOOT_TRAMPOLINE := $(shell sed -n 's,^\#define[[:space:]]\{1\,\}BOOT_TRAMPOLINE[[:space:]]\{1\,\},,p' $(BASEDIR)/include/asm-x86/config.h) +BOOT_TRAMPOLINE := $(shell sed -n 's,^\#define[[:space:]]\{1\,\}BOOT_TRAMPOLINE[[:space:]]\{1\,\},,p' head.S) %.S: %.c RELOC=$(BOOT_TRAMPOLINE) $(MAKE) -f build32.mk $@ -reloc.S: $(BASEDIR)/include/asm-x86/config.h +reloc.S: head.S diff --git a/xen/arch/x86/boot/head.S b/xen/arch/x86/boot/head.S index 0c59f2a750..d092579462 100644 --- a/xen/arch/x86/boot/head.S +++ b/xen/arch/x86/boot/head.S @@ -9,7 +9,7 @@ .text .code32 -#undef bootsym_phys +#define BOOT_TRAMPOLINE 0x7c000 #define sym_phys(sym) ((sym) - __XEN_VIRT_START) #define bootsym_phys(sym) ((sym) - trampoline_start + BOOT_TRAMPOLINE) @@ -189,6 +189,17 @@ __start: mov %edi,sym_phys(idle_pg_table_l2) + (__PAGE_OFFSET>>18) #endif + /* Apply relocations to bootstrap trampoline. */ + mov $BOOT_TRAMPOLINE,%edx + mov $sym_phys(__trampoline_rel_start),%edi + mov %edx,sym_phys(trampoline_phys) +1: + mov (%edi),%eax + add %edx,(%edi,%eax) + add $4,%edi + cmp $sym_phys(__trampoline_rel_stop),%edi + jb 1b + /* Copy bootstrap trampoline to low memory, below 1MB. */ mov $sym_phys(trampoline_start),%esi mov $bootsym_phys(trampoline_start),%edi diff --git a/xen/arch/x86/boot/trampoline.S b/xen/arch/x86/boot/trampoline.S index e5b4dbef45..37f64cf54f 100644 --- a/xen/arch/x86/boot/trampoline.S +++ b/xen/arch/x86/boot/trampoline.S @@ -4,6 +4,13 @@ #undef bootsym #define bootsym(s) ((s)-trampoline_start) +#define bootsym_rel(sym, off, opnd...) \ + bootsym(sym),##opnd; \ +111:; \ + .pushsection .trampoline_rel, "a"; \ + .long 111b - (off) - .; \ + .popsection + .globl trampoline_realmode_entry trampoline_realmode_entry: mov %cs,%ax @@ -17,11 +24,11 @@ trampoline_realmode_entry: xor %ax, %ax inc %ax lmsw %ax # CR0.PE = 1 (enter protected mode) - ljmpl $BOOT_CS32,$bootsym_phys(trampoline_protmode_entry) + ljmpl $BOOT_CS32,$bootsym_rel(trampoline_protmode_entry,6) idt_48: .word 0, 0, 0 # base = limit = 0 gdt_48: .word 6*8-1 - .long bootsym_phys(trampoline_gdt) + .long bootsym_rel(trampoline_gdt,4) trampoline_gdt: /* 0x0000: unused */ .quad 0x0000000000000000 @@ -32,11 +39,16 @@ trampoline_gdt: /* 0x0018: ring 0 data */ .quad 0x00cf92000000ffff /* 0x0020: real-mode code @ BOOT_TRAMPOLINE */ - .long 0x0000ffff | ((BOOT_TRAMPOLINE & 0x00ffff) << 16) - .long 0x00009a00 | ((BOOT_TRAMPOLINE & 0xff0000) >> 16) + .long 0x0000ffff + .long 0x00009a00 /* 0x0028: real-mode data @ BOOT_TRAMPOLINE */ - .long 0x0000ffff | ((BOOT_TRAMPOLINE & 0x00ffff) << 16) - .long 0x00009200 | ((BOOT_TRAMPOLINE & 0xff0000) >> 16) + .long 0x0000ffff + .long 0x00009200 + + .pushsection .trampoline_rel, "a" + .long trampoline_gdt + BOOT_PSEUDORM_CS + 2 - . + .long trampoline_gdt + BOOT_PSEUDORM_DS + 2 - . + .popsection .globl cpuid_ext_features cpuid_ext_features: @@ -66,11 +78,11 @@ trampoline_protmode_entry: /* Load pagetable base register. */ mov $sym_phys(idle_pg_table),%eax - add bootsym_phys(trampoline_xen_phys_start),%eax + add bootsym_rel(trampoline_xen_phys_start,4,%eax) mov %eax,%cr3 /* Set up EFER (Extended Feature Enable Register). */ - mov bootsym_phys(cpuid_ext_features),%edi + mov bootsym_rel(cpuid_ext_features,4,%edi) test $0x20100800,%edi /* SYSCALL/SYSRET, No Execute, Long Mode? */ jz .Lskip_efer movl $MSR_EFER,%ecx @@ -93,7 +105,7 @@ trampoline_protmode_entry: #if defined(__x86_64__) /* Now in compatibility mode. Long-jump into 64-bit mode. */ - ljmp $BOOT_CS64,$bootsym_phys(start64) + ljmp $BOOT_CS64,$bootsym_rel(start64,6) .code64 start64: diff --git a/xen/arch/x86/boot/wakeup.S b/xen/arch/x86/boot/wakeup.S index db367995ab..daf0d7126a 100644 --- a/xen/arch/x86/boot/wakeup.S +++ b/xen/arch/x86/boot/wakeup.S @@ -42,15 +42,13 @@ ENTRY(wakeup_start) # boot trampoline is under 1M, and shift its start into # %fs to reference symbols in that area - movl $BOOT_TRAMPOLINE, %eax - shrl $4, %eax - movl %eax, %fs + mov wakesym(trampoline_seg), %fs lidt %fs:bootsym(idt_48) lgdt %fs:bootsym(gdt_48) movw $1, %ax lmsw %ax # Turn on CR0.PE - ljmpl $BOOT_CS32, $bootsym_phys(wakeup_32) + ljmpl $BOOT_CS32, $bootsym_rel(wakeup_32, 6) /* This code uses an extended set of video mode numbers. These include: * Aliases for standard modes @@ -103,6 +101,10 @@ real_magic: .long 0x12345678 .globl video_mode, video_flags video_mode: .long 0 video_flags: .long 0 +trampoline_seg: .word BOOT_TRAMPOLINE >> 4 + .pushsection .trampoline_seg, "a" + .long trampoline_seg - . + .popsection .code32 @@ -114,11 +116,11 @@ wakeup_32: mov $BOOT_DS, %eax mov %eax, %ds mov %eax, %ss - mov $bootsym_phys(early_stack), %esp + mov $bootsym_rel(early_stack, 4, %esp) # check saved magic again mov $sym_phys(saved_magic), %eax - add bootsym_phys(trampoline_xen_phys_start), %eax + add bootsym_rel(trampoline_xen_phys_start, 4, %eax) mov (%eax), %eax cmp $0x9abcdef0, %eax jne bogus_saved_magic @@ -131,12 +133,12 @@ wakeup_32: /* Load pagetable base register */ mov $sym_phys(idle_pg_table),%eax - add bootsym_phys(trampoline_xen_phys_start),%eax + add bootsym_rel(trampoline_xen_phys_start,4,%eax) mov %eax,%cr3 /* Will cpuid feature change after resume? */ /* Set up EFER (Extended Feature Enable Register). */ - mov bootsym_phys(cpuid_ext_features),%edi + mov bootsym_rel(cpuid_ext_features,4,%edi) test $0x20100800,%edi /* SYSCALL/SYSRET, No Execute, Long Mode? */ jz .Lskip_eferw movl $MSR_EFER,%ecx @@ -162,7 +164,7 @@ wakeup_32: #if defined(__x86_64__) /* Now in compatibility mode. Long-jump to 64-bit mode */ - ljmp $BOOT_CS64, $bootsym_phys(wakeup_64) + ljmp $BOOT_CS64, $bootsym_rel(wakeup_64,6) .code64 wakeup_64: |