diff mbox series

[v2,3/6] x86/boot: Split bootsym() into four types of relocations

Message ID b14f575d4445e439e3d4fd7d385aab7f7f2bedd5.camel@infradead.org (mailing list archive)
State New, archived
Headers show
Series [v2,1/6] x86/boot: Remove gratuitous call back into low-memory code | expand

Commit Message

David Woodhouse Aug. 9, 2019, 3:01 p.m. UTC
From: David Woodhouse <dwmw@amazon.co.uk>

As a first step toward using the low-memory trampoline only when necessary
for a legacy boot without no-real-mode, clean up the relocations into
three separate groups.

 • bootsym() is now used only at boot time when no-real-mode isn't set.

 • bootdatasym() is for variables containing information discovered by
   the 16-bit boot code. This is currently accessed directly in place
   in low memory by Xen at runtime, but will be copied back to its
   location in high memory to avoid the pointer gymnastics (and because
   a subsequent patch will stop copying the 16-bit boot code into low
   memory at all when it isn't being used).

 • trampsym() is for the permanent 16-bit trampoline used for AP startup
   and for wake from sleep. This is not used at boot, and can be copied
   into (properly allocated) low memory once the system is running.

 • tramp32sym() is used both at boot and for AP startup/wakeup. During
   boot it can be used in-place, running from the physical address of
   the Xen image. For AP startup it can't, because at that point there
   isn't a full 1:1 mapping of all memory; only the low trampoline page
   is mapped.

No (intentional) functional change yet; just a "cleanup" to allow the
various parts to be treated separately in subsequent patches.

Signed-off-by: David Woodhouse <dwmw@amazon.co.uk>
---
 xen/arch/x86/boot/edd.S        | 16 +++----
 xen/arch/x86/boot/head.S       | 22 +++++++--
 xen/arch/x86/boot/mem.S        | 12 ++---
 xen/arch/x86/boot/trampoline.S | 85 ++++++++++++++++++++++++++--------
 xen/arch/x86/boot/video.S      |  6 +--
 xen/arch/x86/boot/wakeup.S     | 12 ++---
 xen/arch/x86/efi/efi-boot.h    |  8 ++--
 xen/arch/x86/xen.lds.S         | 15 ++++--
 8 files changed, 122 insertions(+), 54 deletions(-)

Comments

Jan Beulich Aug. 12, 2019, 9:41 a.m. UTC | #1
On 09.08.2019 17:01, David Woodhouse wrote:
> --- a/xen/arch/x86/boot/trampoline.S
> +++ b/xen/arch/x86/boot/trampoline.S
> @@ -16,21 +16,62 @@
>    * not guaranteed to persist.
>    */
>   
> -/* NB. bootsym() is only usable in real mode, or via BOOT_PSEUDORM_DS. */
> +/*
> + * There are four sets of relocations:
> + *
> + * bootsym():     Boot-time code relocated to low memory and run only once.
> + *                Only usable at boot, in real mode or via BOOT_PSEUDORM_DS.

I'm not a native speaker, so my viewing this as ambiguous may be wrong,
but to me it reads as "Only usable at boot or in real mode or via
BOOT_PSEUDORM_DS" when aiui it ought to be "Only usable at boot AND (in
real mode OR via BOOT_PSEUDORM_DS)". In which case how about "Only usable
at boot from real mode or via BOOT_PSEUDORM_DS"?

> + * bootdatasym(): Boot-time BIOS-discovered data, relocated back up to Xen
> + *                image after discovery.
> + * trampsym():    Trampoline code relocated into low memory for AP startup
> + *                and wakeup.
> + * tramp32sym():  32-bit trampoline code which at boot can be used directly
> + *                from the Xen image in memory, but which will need to be
> + *                relocated into low (well, into *mapped*) memory in order
> + *                to be used for AP startup.
> + */
>  #undef bootsym
>  #define bootsym(s) ((s)-trampoline_start)
>   
>  #define bootsym_rel(sym, off, opnd...)     \
>          bootsym(sym),##opnd;               \
>  111:;                                      \
> -        .pushsection .trampoline_rel, "a"; \
> +        .pushsection .bootsym_rel, "a";    \
>          .long 111b - (off) - .;            \
>          .popsection
>   
>  #define bootsym_segrel(sym, off)           \
>          $0,$bootsym(sym);                  \
>  111:;                                      \
> -        .pushsection .trampoline_seg, "a"; \
> +        .pushsection .bootsym_seg, "a";    \
> +        .long 111b - (off) - .;            \
> +        .popsection
> +
> +#define bootdatasym(s) ((s)-trampoline_start)
> +#define bootdatasym_rel(sym, off, opnd...) \
> +        bootdatasym(sym),##opnd;           \
> +111:;                                      \
> +        .pushsection .bootdatasym_rel, "a";\
> +        .long 111b - (off) - .;            \
> +        .popsection
> +
> +#undef trampsym
> +#define trampsym(s) ((s)-trampoline_start)
> +
> +#define trampsym_rel(sym, off, opnd...)    \
> +        trampsym(sym),##opnd;              \
> +111:;                                      \
> +        .pushsection .trampsym_rel, "a";   \
> +        .long 111b - (off) - .;            \
> +        .popsection
> +
> +#undef tramp32sym
> +#define tramp32sym(s) ((s)-trampoline_start)
> +
> +#define tramp32sym_rel(sym, off, opnd...)  \
> +        tramp32sym(sym),##opnd;            \
> +111:;                                      \
> +        .pushsection .tramp32sym_rel, "a"; \
>          .long 111b - (off) - .;            \
>          .popsection

This repeats the basically same sequence of things several times.
I've not peeked ahead yet to see in how far more differences would
appear later on, but I don't really expect much of a further
change. In which case it might be nice to reduce the redundancy
here (by introducing a single "base" macro from which the four
similar ones would be derived).

Furthermore, with the intended isolation, wouldn't it be better to
limit visibility of the individual macros, such that using the
wrong one will be easier noticeable? This would be helped by there
being such a single "base" macro, as permitted to use macros could
then be, if needed, defined and undefined perhaps even multiple
times (for the time being at least).

Jan
David Woodhouse Aug. 19, 2019, 3:24 p.m. UTC | #2
Apologies for delayed response; I was away last week and was frowned at
every time I so much as looked towards the laptop.


On Mon, 2019-08-12 at 11:41 +0200, Jan Beulich wrote:
> On 09.08.2019 17:01, David Woodhouse wrote:
> > --- a/xen/arch/x86/boot/trampoline.S
> > +++ b/xen/arch/x86/boot/trampoline.S
> > @@ -16,21 +16,62 @@
> >    * not guaranteed to persist.
> >    */
> >   
> > -/* NB. bootsym() is only usable in real mode, or via BOOT_PSEUDORM_DS. */
> > +/*
> > + * There are four sets of relocations:
> > + *
> > + * bootsym():     Boot-time code relocated to low memory and run only once.
> > + *                Only usable at boot, in real mode or via BOOT_PSEUDORM_DS.
> 
> I'm not a native speaker, so my viewing this as ambiguous may be wrong,
> but to me it reads as "Only usable at boot or in real mode or via
> BOOT_PSEUDORM_DS" when aiui it ought to be "Only usable at boot AND (in
> real mode OR via BOOT_PSEUDORM_DS)". In which case how about "Only usable
> at boot from real mode or via BOOT_PSEUDORM_DS"?

Yes, I suppose I see that ambiguity. But ultimately I file it under the
category of "don't hack boot code while drunk".

I agree that to the reader of English (native or otherwise), that
sentence may have either meaning. 

But this isn't documentation; it's code comments in an assembler file.
Anyone who is actually going to make a meaningful contribution to the
boot code, might reasonably be expected to understand that "real mode
or using the pseudo-realmode segment selector" are grouped together,
and that they must use one or the other of those. At boot time.

This is not an attempt at a two-line tutorial on all the pitfalls of
touching the boot code/data; via bootsym() or otherwise. It's just a
pointer in the right direction.

But sure, I'll have a look at fixing it — if I don't feel that what I
come up with is too clumsy.

> > + * bootdatasym(): Boot-time BIOS-discovered data, relocated back up to Xen
> > + *                image after discovery.
> > + * trampsym():    Trampoline code relocated into low memory for AP startup
> > + *                and wakeup.
> > + * tramp32sym():  32-bit trampoline code which at boot can be used directly
> > + *                from the Xen image in memory, but which will need to be
> > + *                relocated into low (well, into *mapped*) memory in order
> > + *                to be used for AP startup.
> > + */
> >  #undef bootsym
> >  #define bootsym(s) ((s)-trampoline_start)
> >   
> >  #define bootsym_rel(sym, off, opnd...)     \
> >          bootsym(sym),##opnd;               \
> >  111:;                                      \
> > -        .pushsection .trampoline_rel, "a"; \
> > +        .pushsection .bootsym_rel, "a";    \
> >          .long 111b - (off) - .;            \
> >          .popsection
> >   
> >  #define bootsym_segrel(sym, off)           \
> >          $0,$bootsym(sym);                  \
> >  111:;                                      \
> > -        .pushsection .trampoline_seg, "a"; \
> > +        .pushsection .bootsym_seg, "a";    \
> > +        .long 111b - (off) - .;            \
> > +        .popsection
> > +
> > +#define bootdatasym(s) ((s)-trampoline_start)
> > +#define bootdatasym_rel(sym, off, opnd...) \
> > +        bootdatasym(sym),##opnd;           \
> > +111:;                                      \
> > +        .pushsection .bootdatasym_rel, "a";\
> > +        .long 111b - (off) - .;            \
> > +        .popsection
> > +
> > +#undef trampsym
> > +#define trampsym(s) ((s)-trampoline_start)
> > +
> > +#define trampsym_rel(sym, off, opnd...)    \
> > +        trampsym(sym),##opnd;              \
> > +111:;                                      \
> > +        .pushsection .trampsym_rel, "a";   \
> > +        .long 111b - (off) - .;            \
> > +        .popsection
> > +
> > +#undef tramp32sym
> > +#define tramp32sym(s) ((s)-trampoline_start)
> > +
> > +#define tramp32sym_rel(sym, off, opnd...)  \
> > +        tramp32sym(sym),##opnd;            \
> > +111:;                                      \
> > +        .pushsection .tramp32sym_rel, "a"; \
> >          .long 111b - (off) - .;            \
> >          .popsection
> 
> This repeats the basically same sequence of things several times.
> I've not peeked ahead yet to see in how far more differences would
> appear later on, but I don't really expect much of a further
> change. In which case it might be nice to reduce the redundancy
> here (by introducing a single "base" macro from which the four
> similar ones would be derived).

They end up being more different than this. It was my judgement that
attempting to create a more generic building block from which they
could all be derived would end up being less readable than just a
little bit of partial duplication. If you feel strongly otherwise, I
would welcome a follow-on patch to attempt to remedy that, if you
choose to send one.

> Furthermore, with the intended isolation, wouldn't it be better to
> limit visibility of the individual macros, such that using the
> wrong one will be easier noticeable? This would be helped by there
> being such a single "base" macro, as permitted to use macros could
> then be, if needed, defined and undefined perhaps even multiple
> times (for the time being at least).

I think I'd class that under 'don't hack boot code while drunk" too,
which is apparently the existing approach taken by this most of code
(except on the occasions when people have clearly done precisely that
☺).

The other .S files are *included* from head.S; some indirectly via
trampoline.S. Various macros are defined just once in head.S rather
than being in a header file or with mixed visibility. There is a
potential cleanup to be done there, but it is not one of the cleanups I
had elected to make because I see it as being of limited utility except
cosmetic. Again, if you feel strongly then I would welcome a follow-on
patch or series to move everything out and build each .S file as a
separate compilation unit.
diff mbox series

Patch

diff --git a/xen/arch/x86/boot/edd.S b/xen/arch/x86/boot/edd.S
index 3df712bce1..434bbbd960 100644
--- a/xen/arch/x86/boot/edd.S
+++ b/xen/arch/x86/boot/edd.S
@@ -41,7 +41,7 @@  get_edd:
 # This code is sensitive to the size of the structs in edd.h
 edd_start:
         /* ds:si points at fn48 results. Fn41 results go immediately before. */
-        movw    $bootsym(boot_edd_info)+EDDEXTSIZE, %si
+        movw    $bootdatasym(boot_edd_info)+EDDEXTSIZE, %si
         movb    $0x80, %dl                      # BIOS device 0x80
 
 edd_check_ext:
@@ -56,7 +56,7 @@  edd_check_ext:
         movb    %dl, %ds:-8(%si)                # store device number
         movb    %ah, %ds:-7(%si)                # store version
         movw    %cx, %ds:-6(%si)                # store extensions
-        incb    bootsym(boot_edd_info_nr)       # note that we stored something
+        incb    bootdatasym(boot_edd_info_nr)   # note that we stored something
 
 edd_get_device_params:
         movw    $EDDPARMSIZE, %ds:(%si)         # put size
@@ -97,7 +97,7 @@  edd_legacy_done:
 edd_next:
         incb    %dl                             # increment to next device
         jz      edd_done
-        cmpb    $EDD_INFO_MAX,bootsym(boot_edd_info_nr)
+        cmpb    $EDD_INFO_MAX,bootdatasym(boot_edd_info_nr)
         jb      edd_check_ext
 
 edd_done:
@@ -108,11 +108,11 @@  edd_done:
 .Ledd_mbr_sig_start:
         pushw   %es
         movb    $0x80, %dl                      # from device 80
-        movw    $bootsym(boot_mbr_signature), %bx # store buffer ptr in bx
+        movw    $bootdatasym(boot_mbr_signature), %bx # store buffer ptr in bx
 .Ledd_mbr_sig_read:
         pushw   %bx
-        movw    $bootsym(boot_edd_info), %bx
-        movzbw  bootsym(boot_edd_info_nr), %cx
+        movw    $bootdatasym(boot_edd_info), %bx
+        movzbw  bootdatasym(boot_edd_info_nr), %cx
         jcxz    .Ledd_mbr_sig_default
 .Ledd_mbr_sig_find_info:
         cmpb    %dl, (%bx)
@@ -151,12 +151,12 @@  edd_done:
         jne     .Ledd_mbr_sig_next
         movb    %dl, (%bx)                      # store BIOS drive number
         movl    %ecx, 4(%bx)                    # store signature from MBR
-        incb    bootsym(boot_mbr_signature_nr)  # note that we stored something
+        incb    bootdatasym(boot_mbr_signature_nr) # note that we stored something
         addw    $8, %bx                         # increment sig buffer ptr
 .Ledd_mbr_sig_next:
         incb    %dl                             # increment to next device
         jz      .Ledd_mbr_sig_done
-        cmpb    $EDD_MBR_SIG_MAX, bootsym(boot_mbr_signature_nr)
+        cmpb    $EDD_MBR_SIG_MAX, bootdatasym(boot_mbr_signature_nr)
         jb      .Ledd_mbr_sig_read
 .Ledd_mbr_sig_done:
         popw    %es
diff --git a/xen/arch/x86/boot/head.S b/xen/arch/x86/boot/head.S
index e3b42e3263..07621d1a30 100644
--- a/xen/arch/x86/boot/head.S
+++ b/xen/arch/x86/boot/head.S
@@ -707,14 +707,30 @@  trampoline_setup:
         cmp     $sym_offs(__trampoline_rel_stop),%edi
         jb      1b
 
-        /* Patch in the trampoline segment. */
+        mov     $sym_offs(__trampoline32_rel_start),%edi
+1:
+        mov     %fs:(%edi),%eax
+        add     %edx,%fs:(%edi,%eax)
+        add     $4,%edi
+        cmp     $sym_offs(__trampoline32_rel_stop),%edi
+        jb      1b
+
+        mov     $sym_offs(__bootsym_rel_start),%edi
+1:
+        mov     %fs:(%edi),%eax
+        add     %edx,%fs:(%edi,%eax)
+        add     $4,%edi
+        cmp     $sym_offs(__bootsym_rel_stop),%edi
+        jb      1b
+
+        /* Patch in the boot trampoline segment. */
         shr     $4,%edx
-        mov     $sym_offs(__trampoline_seg_start),%edi
+        mov     $sym_offs(__bootsym_seg_start),%edi
 1:
         mov     %fs:(%edi),%eax
         mov     %dx,%fs:(%edi,%eax)
         add     $4,%edi
-        cmp     $sym_offs(__trampoline_seg_stop),%edi
+        cmp     $sym_offs(__bootsym_seg_stop),%edi
         jb      1b
 
         /* Do not parse command line on EFI platform here. */
diff --git a/xen/arch/x86/boot/mem.S b/xen/arch/x86/boot/mem.S
index 2d61d28835..aa39608442 100644
--- a/xen/arch/x86/boot/mem.S
+++ b/xen/arch/x86/boot/mem.S
@@ -7,7 +7,7 @@  get_memory_map:
 
 .Lmeme820:
         xorl    %ebx, %ebx                      # continuation counter
-        movw    $bootsym(bios_e820map), %di     # point into the whitelist
+        movw    $bootdatasym(bios_e820map), %di # point into the whitelist
                                                 # so we can have the bios
                                                 # directly write into it.
 
@@ -22,8 +22,8 @@  get_memory_map:
         cmpl    $SMAP,%eax                      # check the return is `SMAP'
         jne     .Lmem88
 
-        incw    bootsym(bios_e820nr)
-        cmpw    $E820_BIOS_MAX,bootsym(bios_e820nr) # up to this many entries
+        incw    bootdatasym(bios_e820nr)
+        cmpw    $E820_BIOS_MAX,bootdatasym(bios_e820nr) # up to this many entries
         jae     .Lmem88
 
         movw    %di,%ax
@@ -35,7 +35,7 @@  get_memory_map:
 .Lmem88:
         movb    $0x88, %ah
         int     $0x15
-        movw    %ax,bootsym(highmem_kb)
+        movw    %ax,bootdatasym(highmem_kb)
 
 .Lmeme801:
         stc                                     # fix to work around buggy
@@ -58,11 +58,11 @@  get_memory_map:
         shll    $6,%edx                         # and go from 64k to 1k chunks
         movzwl  %cx, %ecx
         addl    %ecx, %edx                      # add in lower memory
-        movl    %edx,bootsym(highmem_kb)        # store extended memory size
+        movl    %edx,bootdatasym(highmem_kb)    # store extended memory size
 
 .Lint12:
         int     $0x12
-        movw    %ax,bootsym(lowmem_kb)
+        movw    %ax,bootdatasym(lowmem_kb)
 
         ret
 
diff --git a/xen/arch/x86/boot/trampoline.S b/xen/arch/x86/boot/trampoline.S
index 429a088b19..95a4bef553 100644
--- a/xen/arch/x86/boot/trampoline.S
+++ b/xen/arch/x86/boot/trampoline.S
@@ -16,21 +16,62 @@ 
  * not guaranteed to persist.
  */
 
-/* NB. bootsym() is only usable in real mode, or via BOOT_PSEUDORM_DS. */
+/*
+ * There are four sets of relocations:
+ *
+ * bootsym():     Boot-time code relocated to low memory and run only once.
+ *                Only usable at boot, in real mode or via BOOT_PSEUDORM_DS.
+ * bootdatasym(): Boot-time BIOS-discovered data, relocated back up to Xen
+ *                image after discovery.
+ * trampsym():    Trampoline code relocated into low memory for AP startup
+ *                and wakeup.
+ * tramp32sym():  32-bit trampoline code which at boot can be used directly
+ *                from the Xen image in memory, but which will need to be
+ *                relocated into low (well, into *mapped*) memory in order
+ *                to be used for AP startup.
+ */
 #undef bootsym
 #define bootsym(s) ((s)-trampoline_start)
 
 #define bootsym_rel(sym, off, opnd...)     \
         bootsym(sym),##opnd;               \
 111:;                                      \
-        .pushsection .trampoline_rel, "a"; \
+        .pushsection .bootsym_rel, "a";    \
         .long 111b - (off) - .;            \
         .popsection
 
 #define bootsym_segrel(sym, off)           \
         $0,$bootsym(sym);                  \
 111:;                                      \
-        .pushsection .trampoline_seg, "a"; \
+        .pushsection .bootsym_seg, "a";    \
+        .long 111b - (off) - .;            \
+        .popsection
+
+#define bootdatasym(s) ((s)-trampoline_start)
+#define bootdatasym_rel(sym, off, opnd...) \
+        bootdatasym(sym),##opnd;           \
+111:;                                      \
+        .pushsection .bootdatasym_rel, "a";\
+        .long 111b - (off) - .;            \
+        .popsection
+
+#undef trampsym
+#define trampsym(s) ((s)-trampoline_start)
+
+#define trampsym_rel(sym, off, opnd...)    \
+        trampsym(sym),##opnd;              \
+111:;                                      \
+        .pushsection .trampsym_rel, "a";   \
+        .long 111b - (off) - .;            \
+        .popsection
+
+#undef tramp32sym
+#define tramp32sym(s) ((s)-trampoline_start)
+
+#define tramp32sym_rel(sym, off, opnd...)  \
+        tramp32sym(sym),##opnd;            \
+111:;                                      \
+        .pushsection .tramp32sym_rel, "a"; \
         .long 111b - (off) - .;            \
         .popsection
 
@@ -48,16 +89,19 @@ 
 GLOBAL(trampoline_realmode_entry)
         mov     %cs,%ax
         mov     %ax,%ds
-        movb    $0xA5,bootsym(trampoline_cpu_started)
+        movb    $0xA5,trampsym(trampoline_cpu_started)
         cld
         cli
-        lidt    bootsym(idt_48)
-        lgdt    bootsym(gdt_48)
+        lidt    trampsym(idt_48)
+        lgdt    trampsym(gdt_48)
         mov     $1,%bl                    # EBX != 0 indicates we are an AP
         xor     %ax, %ax
         inc     %ax
         lmsw    %ax                       # CR0.PE = 1 (enter protected mode)
-        ljmpl   $BOOT_CS32,$bootsym_rel(trampoline_protmode_entry,6)
+        ljmpl   $BOOT_CS32,$tramp32sym_rel(trampoline_protmode_entry,6)
+
+GLOBAL(trampoline_cpu_started)
+        .byte   0
 
 trampoline_gdt:
         /* 0x0000: unused */
@@ -79,8 +123,12 @@  trampoline_gdt:
          * address is computed at runtime.
          */
         .quad   0x00c0920000000fff
-
-        .pushsection .trampoline_rel, "a"
+        /*
+         * BOOT_PSEUDORM_CS and BOOT_PSEUDORM_DS are usable only at boot time,
+         * and their base addresses must reference the low location to which
+         * the boot-time code was loaded. Hence bootsym.
+         */
+        .pushsection .bootsym_rel, "a"
         .long   trampoline_gdt + BOOT_PSEUDORM_CS + 2 - .
         .long   trampoline_gdt + BOOT_PSEUDORM_DS + 2 - .
         .popsection
@@ -94,9 +142,6 @@  GLOBAL(cpuid_ext_features)
 GLOBAL(trampoline_xen_phys_start)
         .long   0
 
-GLOBAL(trampoline_cpu_started)
-        .byte   0
-
         .code32
 trampoline_protmode_entry:
         /* Set up a few descriptors: on entry only CS is guaranteed good. */
@@ -113,12 +158,12 @@  trampoline_protmode_entry:
 
         /* Load pagetable base register. */
         mov     $sym_offs(idle_pg_table),%eax
-        add     bootsym_rel(trampoline_xen_phys_start,4,%eax)
+        add     tramp32sym_rel(trampoline_xen_phys_start,4,%eax)
         mov     %eax,%cr3
 
         /* Adjust IA32_MISC_ENABLE if needed (for NX enabling below). */
-        mov     bootsym_rel(trampoline_misc_enable_off,4,%esi)
-        mov     bootsym_rel(trampoline_misc_enable_off+4,4,%edi)
+        mov     tramp32sym_rel(trampoline_misc_enable_off,4,%esi)
+        mov     tramp32sym_rel(trampoline_misc_enable_off+4,4,%edi)
         mov     %esi,%eax
         or      %edi,%eax
         jz      1f
@@ -132,7 +177,7 @@  trampoline_protmode_entry:
 1:
 
         /* Set up EFER (Extended Feature Enable Register). */
-        mov     bootsym_rel(cpuid_ext_features,4,%edi)
+        mov     tramp32sym_rel(cpuid_ext_features,4,%edi)
         movl    $MSR_EFER,%ecx
         rdmsr
         or      $EFER_LME|EFER_SCE,%eax   /* Long Mode + SYSCALL/SYSRET */
@@ -148,7 +193,7 @@  trampoline_protmode_entry:
 1:
 
         /* Now in compatibility mode. Long-jump into 64-bit mode. */
-        ljmp    $BOOT_CS64,$bootsym_rel(start64,6)
+        ljmp    $BOOT_CS64,$tramp32sym_rel(start64,6)
 
         .code64
 start64:
@@ -183,7 +228,7 @@  start64:
 idt_48: .word   0, 0, 0 # base = limit = 0
         .word   0
 gdt_48: .word   6*8-1
-        .long   bootsym_rel(trampoline_gdt,4)
+        .long   tramp32sym_rel(trampoline_gdt,4)
 
 /* The first page of trampoline is permanent, the rest boot-time only. */
 /* Reuse the boot trampoline on the 1st trampoline page as stack for wakeup. */
@@ -249,7 +294,7 @@  trampoline_boot_cpu_entry:
 
         mov     $0x0200,%ax
         int     $0x16
-        mov     %al,bootsym(kbd_shift_flags)
+        mov     %al,bootdatasym(kbd_shift_flags)
 
         /* Disable irqs before returning to protected mode. */
         cli
@@ -294,7 +339,7 @@  opt_edid:
         .byte   0
 
 #ifdef CONFIG_VIDEO
-GLOBAL(boot_vid_mode)
+boot_vid_mode:
         .word   VIDEO_80x25                     /* If we don't run at all, assume basic video mode 3 at 80x25. */
 vesa_size:
         .word   0,0,0                           /* width x depth x height */
diff --git a/xen/arch/x86/boot/video.S b/xen/arch/x86/boot/video.S
index 335a51c9b5..03907e9e9a 100644
--- a/xen/arch/x86/boot/video.S
+++ b/xen/arch/x86/boot/video.S
@@ -45,7 +45,7 @@ 
 #define PARAM_VESAPM_SEG        0x24
 #define PARAM_VESAPM_OFF        0x26
 #define PARAM_VESA_ATTRIB       0x28
-#define _param(param) bootsym(boot_vid_info)+(param)
+#define _param(param) bootdatasym(boot_vid_info)+(param)
 
 video:  xorw    %ax, %ax
         movw    %ax, %gs        # GS is zero
@@ -917,7 +917,7 @@  store_edid:
         cmpw    $0x004f, %ax            # Call failed?
         jne     .Lno_edid
 
-        movw    %bx, bootsym(boot_edid_caps)
+        movw    %bx, bootdatasym(boot_edid_caps)
 
         cmpb    $2, bootsym(opt_edid)   # EDID forced on cmdline (edid=force)?
         je      .Lforce_edid
@@ -933,7 +933,7 @@  store_edid:
         movw    $0x01, %bx
         movw    $0x00, %cx
         movw    $0x00, %dx
-        movw    $bootsym(boot_edid_info), %di
+        movw    $bootdatasym(boot_edid_info), %di
         int     $0x10
 
 .Lno_edid:
diff --git a/xen/arch/x86/boot/wakeup.S b/xen/arch/x86/boot/wakeup.S
index e3cb9e033a..95bedddd0f 100644
--- a/xen/arch/x86/boot/wakeup.S
+++ b/xen/arch/x86/boot/wakeup.S
@@ -53,7 +53,7 @@  ENTRY(wakeup_start)
 
         movw    $1, %ax
         lmsw    %ax             # Turn on CR0.PE 
-        ljmpl   $BOOT_CS32, $bootsym_rel(wakeup_32, 6)
+        ljmpl   $BOOT_CS32, $trampsym_rel(wakeup_32, 6)
 
 /* This code uses an extended set of video mode numbers. These include:
  * Aliases for standard modes
@@ -118,11 +118,11 @@  wakeup_32:
         mov     $BOOT_DS, %eax
         mov     %eax, %ds
         mov     %eax, %ss
-        mov     $bootsym_rel(wakeup_stack, 4, %esp)
+        mov     $trampsym_rel(wakeup_stack, 4, %esp)
 
         # check saved magic again
         mov     $sym_offs(saved_magic),%eax
-        add     bootsym_rel(trampoline_xen_phys_start, 4, %eax)
+        add     trampsym_rel(trampoline_xen_phys_start, 4, %eax)
         mov     (%eax), %eax
         cmp     $0x9abcdef0, %eax
         jne     bogus_saved_magic
@@ -135,12 +135,12 @@  wakeup_32:
 
         /* Load pagetable base register */
         mov     $sym_offs(idle_pg_table),%eax
-        add     bootsym_rel(trampoline_xen_phys_start,4,%eax)
+        add     trampsym_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_rel(cpuid_ext_features,4,%edi)
+        mov     trampsym_rel(cpuid_ext_features,4,%edi)
         test    $0x20100800,%edi /* SYSCALL/SYSRET, No Execute, Long Mode? */
         jz      .Lskip_eferw
         movl    $MSR_EFER,%ecx
@@ -162,7 +162,7 @@  wakeup_32:
 1:
 
         /* Now in compatibility mode. Long-jump to 64-bit mode */
-        ljmp    $BOOT_CS64, $bootsym_rel(wakeup_64,6)
+        ljmp    $BOOT_CS64, $trampsym_rel(wakeup_64,6)
 
         .code64
 wakeup_64:
diff --git a/xen/arch/x86/efi/efi-boot.h b/xen/arch/x86/efi/efi-boot.h
index 7a13a30bc0..556942482e 100644
--- a/xen/arch/x86/efi/efi-boot.h
+++ b/xen/arch/x86/efi/efi-boot.h
@@ -99,7 +99,7 @@  static void __init efi_arch_relocate_image(unsigned long delta)
 }
 
 extern const s32 __trampoline_rel_start[], __trampoline_rel_stop[];
-extern const s32 __trampoline_seg_start[], __trampoline_seg_stop[];
+extern const s32 __trampoline32_rel_start[], __trampoline32_rel_stop[];
 
 static void __init relocate_trampoline(unsigned long phys)
 {
@@ -115,10 +115,10 @@  static void __init relocate_trampoline(unsigned long phys)
           trampoline_ptr < __trampoline_rel_stop;
           ++trampoline_ptr )
         *(u32 *)(*trampoline_ptr + (long)trampoline_ptr) += phys;
-    for ( trampoline_ptr = __trampoline_seg_start;
-          trampoline_ptr < __trampoline_seg_stop;
+    for ( trampoline_ptr = __trampoline32_rel_start;
+          trampoline_ptr < __trampoline32_rel_stop;
           ++trampoline_ptr )
-        *(u16 *)(*trampoline_ptr + (long)trampoline_ptr) = phys >> 4;
+        *(u32 *)(*trampoline_ptr + (long)trampoline_ptr) += phys;
 }
 
 static void __init place_string(u32 *addr, const char *s)
diff --git a/xen/arch/x86/xen.lds.S b/xen/arch/x86/xen.lds.S
index a73139cd29..400dffaf23 100644
--- a/xen/arch/x86/xen.lds.S
+++ b/xen/arch/x86/xen.lds.S
@@ -237,11 +237,18 @@  SECTIONS
        *(.init.data.rel.*)
        . = ALIGN(4);
        __trampoline_rel_start = .;
-       *(.trampoline_rel)
+       *(.trampsym_rel)
        __trampoline_rel_stop = .;
-       __trampoline_seg_start = .;
-       *(.trampoline_seg)
-       __trampoline_seg_stop = .;
+       __trampoline32_rel_start = .;
+       *(.tramp32sym_rel)
+       __trampoline32_rel_stop = .;
+       __bootsym_rel_start = .;
+       *(.bootsym_rel)
+       *(.bootdatasym_rel)
+       __bootsym_rel_stop = .;
+       __bootsym_seg_start = .;
+       *(.bootsym_seg)
+       __bootsym_seg_stop = .;
        /*
         * struct alt_inst entries. From the header (alternative.h):
         * "Alternative instructions for different CPU types or capabilities"