[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [xen-unstable] x86: make run-time part of trampoline relocatable
# HG changeset patch # User Jan Beulich <jbeulich@xxxxxxxxxx> # Date 1313744066 -3600 # Node ID 29aeed4979a78f26519f5fde8a405f8438297ab9 # Parent fc2be6cb89ad49efd90fe1b650f7efaab72f61b2 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@xxxxxxxxxx> --- diff -r fc2be6cb89ad -r 29aeed4979a7 xen/arch/x86/boot/Makefile --- a/xen/arch/x86/boot/Makefile Tue Aug 16 15:05:55 2011 +0100 +++ b/xen/arch/x86/boot/Makefile Fri Aug 19 09:54:26 2011 +0100 @@ -2,8 +2,8 @@ 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 -r fc2be6cb89ad -r 29aeed4979a7 xen/arch/x86/boot/head.S --- a/xen/arch/x86/boot/head.S Tue Aug 16 15:05:55 2011 +0100 +++ b/xen/arch/x86/boot/head.S Fri Aug 19 09:54:26 2011 +0100 @@ -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 @@ 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 -r fc2be6cb89ad -r 29aeed4979a7 xen/arch/x86/boot/trampoline.S --- a/xen/arch/x86/boot/trampoline.S Tue Aug 16 15:05:55 2011 +0100 +++ b/xen/arch/x86/boot/trampoline.S Fri Aug 19 09:54:26 2011 +0100 @@ -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 @@ 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 @@ /* 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 @@ /* 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 @@ #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 -r fc2be6cb89ad -r 29aeed4979a7 xen/arch/x86/boot/wakeup.S --- a/xen/arch/x86/boot/wakeup.S Tue Aug 16 15:05:55 2011 +0100 +++ b/xen/arch/x86/boot/wakeup.S Fri Aug 19 09:54:26 2011 +0100 @@ -42,15 +42,13 @@ # 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 @@ .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 @@ 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 @@ /* 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 @@ #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: diff -r fc2be6cb89ad -r 29aeed4979a7 xen/arch/x86/efi/boot.c --- a/xen/arch/x86/efi/boot.c Tue Aug 16 15:05:55 2011 +0100 +++ b/xen/arch/x86/efi/boot.c Fri Aug 19 09:54:26 2011 +0100 @@ -599,6 +599,9 @@ } } +extern const s32 __trampoline_rel_start[], __trampoline_rel_stop[]; +extern const s32 __trampoline_seg_start[], __trampoline_seg_stop[]; + void EFIAPI __init __attribute__((__noreturn__)) efi_start(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable) { @@ -614,9 +617,10 @@ EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *mode_info; EFI_FILE_HANDLE dir_handle; union string section = { NULL }, name; + const s32 *trampoline_ptr; struct e820entry *e; u64 efer; - bool_t base_video = 0, trampoline_okay = 0; + bool_t base_video = 0; efi_ih = ImageHandle; efi_bs = SystemTable->BootServices; @@ -914,15 +918,27 @@ dmi_efi_get_table((void *)(long)efi.smbios); /* Allocate space for trampoline (in first Mb). */ - cfg.addr = BOOT_TRAMPOLINE; + cfg.addr = 0x100000; cfg.size = trampoline_end - trampoline_start; - status = efi_bs->AllocatePages(AllocateAddress, EfiLoaderData, + status = efi_bs->AllocatePages(AllocateMaxAddress, EfiLoaderData, PFN_UP(cfg.size), &cfg.addr); if ( EFI_ERROR(status) ) { cfg.addr = 0; - PrintErr(L"Note: Trampoline area is in use\r\n"); + blexit(L"No memory for trampoline\r\n"); } + trampoline_phys = cfg.addr; + /* Apply relocations to trampoline. */ + for ( trampoline_ptr = __trampoline_rel_start; + trampoline_ptr < __trampoline_rel_stop; + ++trampoline_ptr ) + *(u32 *)(*trampoline_ptr + (long)trampoline_ptr) += + trampoline_phys; + for ( trampoline_ptr = __trampoline_seg_start; + trampoline_ptr < __trampoline_seg_stop; + ++trampoline_ptr ) + *(u16 *)(*trampoline_ptr + (long)trampoline_ptr) = + trampoline_phys >> 4; /* Initialise L2 identity-map and xen page table entries (16MB). */ for ( i = 0; i < 8; ++i ) @@ -1096,14 +1112,8 @@ e->type = type; ++e820nr; } - if ( type == E820_RAM && e->addr <= BOOT_TRAMPOLINE && - e->addr + e->size >= BOOT_TRAMPOLINE + cfg.size ) - trampoline_okay = 1; } - if ( !trampoline_okay ) - blexit(L"Trampoline area unavailable\r\n"); - status = efi_bs->ExitBootServices(ImageHandle, map_key); if ( EFI_ERROR(status) ) PrintErrMesg(L"Cannot exit boot services", status); @@ -1117,7 +1127,7 @@ efi_fw_vendor = (void *)efi_fw_vendor + DIRECTMAP_VIRT_START; relocate_image(__XEN_VIRT_START - xen_phys_start); - memcpy((void *)(long)BOOT_TRAMPOLINE, trampoline_start, cfg.size); + memcpy((void *)trampoline_phys, trampoline_start, cfg.size); /* Set system registers and transfer control. */ asm volatile("pushq $0\n\tpopfq"); diff -r fc2be6cb89ad -r 29aeed4979a7 xen/arch/x86/smpboot.c --- a/xen/arch/x86/smpboot.c Tue Aug 16 15:05:55 2011 +0100 +++ b/xen/arch/x86/smpboot.c Fri Aug 19 09:54:26 2011 +0100 @@ -48,6 +48,8 @@ #define setup_trampoline() (bootsym_phys(trampoline_realmode_entry)) +unsigned long __read_mostly trampoline_phys; + /* representing HT siblings of each logical CPU */ DEFINE_PER_CPU_READ_MOSTLY(cpumask_t, cpu_sibling_map); /* representing HT and core siblings of each logical CPU */ diff -r fc2be6cb89ad -r 29aeed4979a7 xen/arch/x86/x86_32/mm.c --- a/xen/arch/x86/x86_32/mm.c Tue Aug 16 15:05:55 2011 +0100 +++ b/xen/arch/x86/x86_32/mm.c Fri Aug 19 09:54:26 2011 +0100 @@ -166,8 +166,9 @@ flush_all(FLUSH_TLB_GLOBAL); /* Replace with mapping of the boot trampoline only. */ - map_pages_to_xen(BOOT_TRAMPOLINE, BOOT_TRAMPOLINE >> PAGE_SHIFT, - 0x10, __PAGE_HYPERVISOR); + map_pages_to_xen(trampoline_phys, trampoline_phys >> PAGE_SHIFT, + PFN_UP(trampoline_end - trampoline_start), + __PAGE_HYPERVISOR); } void __init subarch_init_memory(void) diff -r fc2be6cb89ad -r 29aeed4979a7 xen/arch/x86/x86_64/mm.c --- a/xen/arch/x86/x86_64/mm.c Tue Aug 16 15:05:55 2011 +0100 +++ b/xen/arch/x86/x86_64/mm.c Fri Aug 19 09:54:26 2011 +0100 @@ -829,7 +829,7 @@ flush_local(FLUSH_TLB_GLOBAL); /* Replace with mapping of the boot trampoline only. */ - map_pages_to_xen(BOOT_TRAMPOLINE, BOOT_TRAMPOLINE >> PAGE_SHIFT, + map_pages_to_xen(trampoline_phys, trampoline_phys >> PAGE_SHIFT, PFN_UP(trampoline_end - trampoline_start), __PAGE_HYPERVISOR); } diff -r fc2be6cb89ad -r 29aeed4979a7 xen/arch/x86/xen.lds.S --- a/xen/arch/x86/xen.lds.S Tue Aug 16 15:05:55 2011 +0100 +++ b/xen/arch/x86/xen.lds.S Fri Aug 19 09:54:26 2011 +0100 @@ -103,6 +103,13 @@ *(.init.data) *(.init.data.rel) *(.init.data.rel.*) + . = ALIGN(4); + __trampoline_rel_start = .; + *(.trampoline_rel) + __trampoline_rel_stop = .; + __trampoline_seg_start = .; + *(.trampoline_seg) + __trampoline_seg_stop = .; } :text . = ALIGN(32); .init.setup : { diff -r fc2be6cb89ad -r 29aeed4979a7 xen/include/asm-x86/config.h --- a/xen/include/asm-x86/config.h Tue Aug 16 15:05:55 2011 +0100 +++ b/xen/include/asm-x86/config.h Fri Aug 19 09:54:26 2011 +0100 @@ -95,13 +95,13 @@ /* Primary stack is restricted to 8kB by guard pages. */ #define PRIMARY_STACK_SIZE 8192 -#define BOOT_TRAMPOLINE 0x7c000 +#ifndef __ASSEMBLY__ +extern unsigned long trampoline_phys; #define bootsym_phys(sym) \ - (((unsigned long)&(sym)-(unsigned long)&trampoline_start)+BOOT_TRAMPOLINE) + (((unsigned long)&(sym)-(unsigned long)&trampoline_start)+trampoline_phys) #define bootsym(sym) \ (*RELOC_HIDE((typeof(&(sym)))__va(__pa(&(sym))), \ - BOOT_TRAMPOLINE-__pa(trampoline_start))) -#ifndef __ASSEMBLY__ + trampoline_phys-__pa(trampoline_start))) extern char trampoline_start[], trampoline_end[]; extern char trampoline_realmode_entry[]; extern unsigned int trampoline_xen_phys_start; _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |