[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [PATCH 4/7] x86/boot: apply trampoline relocations at destination position
On Tue, Mar 18, 2025 at 5:36 PM Roger Pau Monne <roger.pau@xxxxxxxxxx> wrote: > > Change the order relocations are applied. Currently the trampoline is > patched for relocations before being copied to the low 1MB region. Change > the order and instead copy the trampoline first to the low 1MB region and > then apply the relocations. > > This will allow making .init.text section read-only (so read and execute > permissions only), which is relevant when Xen is built as a PE image. > This change is not enough to make the section read-only, some other code writes directly into the trampoline at the not-relocated position. But this improves the situation. The code looks fine, I'll try the code if it passes some tests I did. > Signed-off-by: Roger Pau Monné <roger.pau@xxxxxxxxxx> > --- > xen/arch/x86/boot/build32.lds.S | 1 + > xen/arch/x86/boot/head.S | 6 +++--- > xen/arch/x86/boot/reloc-trampoline.c | 16 ++++++++-------- > xen/arch/x86/efi/efi-boot.h | 15 ++++++--------- > 4 files changed, 18 insertions(+), 20 deletions(-) > > diff --git a/xen/arch/x86/boot/build32.lds.S b/xen/arch/x86/boot/build32.lds.S > index 1e59732edd6e..92dc320b7380 100644 > --- a/xen/arch/x86/boot/build32.lds.S > +++ b/xen/arch/x86/boot/build32.lds.S > @@ -50,6 +50,7 @@ SECTIONS > DECLARE_IMPORT(__trampoline_seg_start); > DECLARE_IMPORT(__trampoline_seg_stop); > DECLARE_IMPORT(trampoline_phys); > + DECLARE_IMPORT(trampoline_start); > DECLARE_IMPORT(boot_vid_info); > . = . + GAP; > *(.text) > diff --git a/xen/arch/x86/boot/head.S b/xen/arch/x86/boot/head.S > index 59a2b5005cf6..3f81b21b5a7f 100644 > --- a/xen/arch/x86/boot/head.S > +++ b/xen/arch/x86/boot/head.S > @@ -679,9 +679,6 @@ trampoline_setup: > shr $PAGE_SHIFT, %ecx /* %ecx = Slot to write */ > mov %edx, sym_offs(l1_bootmap)(%esi, %ecx, 8) > > - /* Apply relocations to bootstrap trampoline. */ > - call reloc_trampoline32 > - > /* Do not parse command line on EFI platform here. */ > cmpb $0, sym_esi(efi_platform) > jnz 1f > @@ -709,6 +706,9 @@ trampoline_setup: > mov $((trampoline_end - trampoline_start) / 4),%ecx > rep movsl > > + /* Apply relocations to bootstrap trampoline. */ > + call reloc_trampoline32 > + > /* Jump into the relocated trampoline. */ > lret > > diff --git a/xen/arch/x86/boot/reloc-trampoline.c > b/xen/arch/x86/boot/reloc-trampoline.c > index e35e7c78aa86..ac54aef14eaf 100644 > --- a/xen/arch/x86/boot/reloc-trampoline.c > +++ b/xen/arch/x86/boot/reloc-trampoline.c > @@ -20,19 +20,19 @@ void reloc_trampoline64(void) > uint32_t phys = trampoline_phys; > const int32_t *trampoline_ptr; > > - /* > - * Apply relocations to trampoline. > - * > - * This modifies the trampoline in place within Xen, so that it will > - * operate correctly when copied into place. > - */ > + /* Apply relocations to trampoline after copy to destination. */ > +#define RELA_TARGET(ptr, bits) \ > + *(uint ## bits ## _t *)(phys + *ptr + (long)ptr - (long)trampoline_start) > + > for ( trampoline_ptr = __trampoline_rel_start; > trampoline_ptr < __trampoline_rel_stop; > ++trampoline_ptr ) > - *(uint32_t *)(*trampoline_ptr + (long)trampoline_ptr) += phys; > + RELA_TARGET(trampoline_ptr, 32) += phys; > > for ( trampoline_ptr = __trampoline_seg_start; > trampoline_ptr < __trampoline_seg_stop; > ++trampoline_ptr ) > - *(uint16_t *)(*trampoline_ptr + (long)trampoline_ptr) = phys >> 4; > + RELA_TARGET(trampoline_ptr, 16) = phys >> 4; > + > +#undef RELA_TARGET > } > diff --git a/xen/arch/x86/efi/efi-boot.h b/xen/arch/x86/efi/efi-boot.h > index 1d8902a9a724..e4ed8639b9ac 100644 > --- a/xen/arch/x86/efi/efi-boot.h > +++ b/xen/arch/x86/efi/efi-boot.h > @@ -105,10 +105,8 @@ static void __init efi_arch_relocate_image(unsigned long > delta) > } > } > > -static void __init relocate_trampoline(unsigned long phys) > +static void __init relocate_trampoline(void) > { > - trampoline_phys = phys; > - > if ( !efi_enabled(EFI_LOADER) ) > return; > > @@ -213,6 +211,8 @@ static void __init > efi_arch_process_memory_map(EFI_SYSTEM_TABLE *SystemTable, > } > } > > + if ( !trampoline_phys ) > + trampoline_phys = cfg.addr; > } > > static void *__init efi_arch_allocate_mmap_buffer(UINTN map_size) > @@ -223,11 +223,7 @@ static void *__init efi_arch_allocate_mmap_buffer(UINTN > map_size) > static void __init efi_arch_pre_exit_boot(void) > { > if ( !trampoline_phys ) > - { > - if ( !cfg.addr ) > - blexit(L"No memory for trampoline"); > - relocate_trampoline(cfg.addr); > - } > + blexit(L"No memory for trampoline"); > } > > static void __init noreturn efi_arch_post_exit_boot(void) > @@ -236,6 +232,7 @@ static void __init noreturn efi_arch_post_exit_boot(void) > > efi_arch_relocate_image(__XEN_VIRT_START - xen_phys_start); > memcpy(_p(trampoline_phys), trampoline_start, cfg.size); > + relocate_trampoline(); > > /* > * We're in physical mode right now (i.e. identity map), so a regular > @@ -638,7 +635,7 @@ static void __init efi_arch_memory_setup(void) > status = efi_bs->AllocatePages(AllocateMaxAddress, EfiLoaderData, > PFN_UP(cfg.size), &cfg.addr); > if ( status == EFI_SUCCESS ) > - relocate_trampoline(cfg.addr); > + trampoline_phys = cfg.addr; > else > { > cfg.addr = 0; Frediano
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |