ia64/xen-unstable

changeset 15382: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>
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 */