direct-io.hg
changeset 15377:75d82009ec70
Fix 32on64 kexec trampoline. This was broken when Xen was modified to
physically relocate itself.
Signed-off-by: Ian Campbell <ian.campbell@xensource.com>
physically relocate itself.
Signed-off-by: Ian Campbell <ian.campbell@xensource.com>
author | Ian Campbell <ian.campbell@xensource.com> |
---|---|
date | Tue Jun 19 11:06:25 2007 +0100 (2007-06-19) |
parents | c3f280acf41a |
children | 5794f9b80c3f |
files | xen/arch/x86/x86_64/compat_kexec.S |
line diff
1.1 --- a/xen/arch/x86/x86_64/compat_kexec.S Mon Jun 18 16:59:06 2007 +0100 1.2 +++ b/xen/arch/x86/x86_64/compat_kexec.S Tue Jun 19 11:06:25 2007 +0100 1.3 @@ -2,13 +2,32 @@ 1.4 * Compatibility kexec handler. 1.5 */ 1.6 1.7 +/* 1.8 + * NOTE: We rely on Xen not relocating itself above the 4G boundary. This is 1.9 + * currently true but if it ever changes then compat_pg_table will 1.10 + * need to be moved back below 4G at run time. 1.11 + */ 1.12 + 1.13 #include <xen/config.h> 1.14 1.15 #include <asm/asm_defns.h> 1.16 #include <asm/msr.h> 1.17 #include <asm/page.h> 1.18 1.19 -#define SYM_PHYS(sym) ((sym) - __XEN_VIRT_START) 1.20 +/* The unrelocated physical address of a symbol. */ 1.21 +#define SYM_PHYS(sym) ((sym) - __XEN_VIRT_START) 1.22 + 1.23 +/* Load physical address of symbol into register and relocate it. */ 1.24 +#define RELOCATE_SYM(sym,reg) mov $SYM_PHYS(sym), reg ; \ 1.25 + add xen_phys_start(%rip), reg 1.26 + 1.27 +/* 1.28 + * Relocate a physical address in memory. Size of temporary register 1.29 + * determines size of the value to relocate. 1.30 + */ 1.31 +#define RELOCATE_MEM(addr,reg) mov addr(%rip), reg ; \ 1.32 + add xen_phys_start(%rip), reg ; \ 1.33 + mov reg, addr(%rip) 1.34 1.35 .text 1.36 1.37 @@ -31,21 +50,32 @@ 1: dec %r9 1.38 test %r9,%r9 1.39 jnz 1b 1.40 1.41 - mov $SYM_PHYS(compat_page_list),%rdx 1.42 + RELOCATE_SYM(compat_page_list,%rdx) 1.43 + 1.44 + /* Relocate compatibility mode entry point address. */ 1.45 + RELOCATE_MEM(compatibility_mode_far,%eax) 1.46 + 1.47 + /* Relocate compat_pg_table. */ 1.48 + RELOCATE_MEM(compat_pg_table, %rax) 1.49 + RELOCATE_MEM(compat_pg_table+0x8, %rax) 1.50 + RELOCATE_MEM(compat_pg_table+0x10,%rax) 1.51 + RELOCATE_MEM(compat_pg_table+0x18,%rax) 1.52 1.53 /* 1.54 * Setup an identity mapped region in PML4[0] of idle page 1.55 * table. 1.56 */ 1.57 - lea l3_identmap(%rip),%rax 1.58 - sub %rbx,%rax 1.59 + RELOCATE_SYM(l3_identmap,%rax) 1.60 or $0x63,%rax 1.61 mov %rax, idle_pg_table(%rip) 1.62 1.63 /* Switch to idle page table. */ 1.64 - movq $SYM_PHYS(idle_pg_table), %rax 1.65 + RELOCATE_SYM(idle_pg_table,%rax) 1.66 movq %rax, %cr3 1.67 1.68 + /* Save xen_phys_start for 32 bit code. */ 1.69 + movq xen_phys_start(%rip), %rbx 1.70 + 1.71 /* Jump to low identity mapping in compatibility mode. */ 1.72 ljmp *compatibility_mode_far(%rip) 1.73 ud2 1.74 @@ -56,6 +86,17 @@ compatibility_mode_far: 1.75 1.76 .code32 1.77 1.78 +#undef RELOCATE_SYM 1.79 +#undef RELOCATE_MEM 1.80 + 1.81 +/* 1.82 + * Load physical address of symbol into register and relocate it. %rbx 1.83 + * contains xen_phys_start(%rip) saved before jump to compatibility 1.84 + * mode. 1.85 + */ 1.86 +#define RELOCATE_SYM(sym,reg) mov $SYM_PHYS(sym), reg ; \ 1.87 + add %ebx, reg 1.88 + 1.89 compatibility_mode: 1.90 /* Setup some sane segments. */ 1.91 movl $__HYPERVISOR_DS32, %eax 1.92 @@ -78,7 +119,7 @@ compatibility_mode: 1.93 movl %eax, %cr0 1.94 1.95 /* Switch to 32 bit page table. */ 1.96 - movl $SYM_PHYS(compat_pg_table), %eax 1.97 + RELOCATE_SYM(compat_pg_table, %eax) 1.98 movl %eax, %cr3 1.99 1.100 /* Clear MSR_EFER[LME], disabling long mode */