|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [Xen-devel] [PATCH v3 5/5] x86/boot: Do not use trampoline for no-real-mode boot paths
On 21.08.2019 18:35, David Woodhouse wrote:
> From: David Woodhouse <dwmw@xxxxxxxxxxxx>
>
> Where booted from EFI or with no-real-mode, there is no need to stomp
> on low memory with the 16-boot code. Instead, just go straight to
> trampoline_protmode_entry() at its physical location within the Xen
> image, having applied suitable relocations.
>
> This means that the GDT has to be loaded with lgdtl because the 16-bit
> lgdt instruction would drop the high 8 bits of the gdt_trampoline
> address, causing failures if the Xen image was loaded above 16MiB.
There's a 2nd case where we assume an address not exceeding 16MiB:
The BOOT_PSEUDORM_{C,D}S entries on trampoline_gdt. While they'll
be unused (afaict) when not going through real mode, them getting
corrupted by applying relocations still seems somewhat risky to
me. I therefore wonder whether we shouldn't re-arrange this GDT's
layout in a prereq patch, such that theses two entries would go
last, and the GDT limit be reduced by two entries when skipping
real mode.
> --- a/xen/arch/x86/boot/head.S
> +++ b/xen/arch/x86/boot/head.S
> @@ -689,16 +689,23 @@ trampoline_setup:
> lea __PAGE_HYPERVISOR+sym_esi(l1_identmap),%edi
> mov %edi,sym_fs(l2_bootmap)
>
> - /* Apply relocations to bootstrap trampoline. */
> - mov sym_fs(trampoline_phys),%edx
> - mov $sym_offs(__trampoline_rel_start),%edi
> -1:
> - mov %fs:(%edi),%eax
> - add %edx,%fs:(%edi,%eax)
> - add $4,%edi
> - cmp $sym_offs(__trampoline_rel_stop),%edi
> - jb 1b
> + /* Do not parse command line on EFI platform here. */
> + cmpb $0,sym_fs(efi_platform)
> + jnz 1f
>
> + /* Bail if there is no command line to parse. */
> + mov sym_fs(multiboot_ptr),%ebx
> + testl $MBI_CMDLINE,MB_flags(%ebx)
> + jz 1f
As a really minor nit - I think it is generally better to have CMP
followed by JE/JNE, while (as you already have it) TEST/AND/OR are
better followed by JZ/JNZ. (Obviously this is a remark applicable to
the series as a whole.)
> @@ -90,6 +92,7 @@ GLOBAL(bootdata_start)
> * It is entered in Real Mode, with %cs = trampoline_realmode_entry >> 4 and
> * %ip = 0.
> */
> +
> GLOBAL(trampoline_realmode_entry)
> mov %cs,%ax
> mov %ax,%ds
I'd prefer if you didn't insert a blank line here, as the comment is
specifically associated with this label.
> @@ -97,7 +100,7 @@ GLOBAL(trampoline_realmode_entry)
> cld
> cli
> lidt trampsym(idt_48)
> - lgdt trampsym(gdt_48)
> + lgdtl trampsym(gdt_48)
> mov $1,%bl # EBX != 0 indicates we are an AP
> xor %ax, %ax
> inc %ax
As per the remark further up, trampoline_gdt's two entries (below
here) having a relocation associate with them should imo at least get
a comment added to state why (other than for the LGDTL here) there's
no issue with a relocation to an address above 16MiB.
> @@ -236,11 +239,23 @@ gdt_48: .word 7*8-1
>
> /* 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.
> */
> - .equ wakeup_stack, boot_trampoline_start + PAGE_SIZE
> + .equ wakeup_stack, perm_trampoline_start + PAGE_SIZE
Doesn't this, at the very least, render the comment stale?
> .global wakeup_stack
>
> +ENTRY(perm_trampoline_end)
> +
> /* From here on early boot only. */
>
> +ENTRY(boot_trampoline_start)
> +
> + .word 0
> +boot16_idt:
> + .word 0, 0, 0 # base = limit = 0
> + .word 0
> +boot16_gdt:
> + .word 7*8-1
> + .long tramp32sym_rel(trampoline_gdt,4)
As there's no change in this patch to how/where the boot trampoline
gets copied, am I understanding right that both end up at
trampoline_phys, just at different points in time? Otherwise I wonder
what the alignment of the relocated boot_trampoline_start end up
being, and hence whether the initial .word here is actually useful at
all.
> @@ -343,7 +358,8 @@ trampoline_boot_cpu_entry:
> xor %ebx,%ebx
>
> /* Jump to the common bootstrap entry point. */
> - jmp trampoline_protmode_entry
> + mov $tramp32sym_rel(trampoline_protmode_entry,4,%eax)
> + jmp *%eax
Do you really need to switch to an indirect branch here? I.e. can't
there be a relocation associated with the direct JMP's displacement?
> --- a/xen/arch/x86/setup.c
> +++ b/xen/arch/x86/setup.c
> @@ -679,6 +679,45 @@ static unsigned int __init copy_bios_e820(struct
> e820entry *map, unsigned int li
> return n;
> }
>
> +extern const s32 __trampoline_rel_start[], __trampoline_rel_stop[];
> +extern const s32 __trampoline32_rel_start[], __trampoline32_rel_stop[];
> +
> +static void __init relocate_trampoline(unsigned long phys)
> +{
> + const s32 *trampoline_ptr;
> + uint32_t tramp32_delta;
> +
> + /* Apply relocations to trampoline. */
> + for ( trampoline_ptr = __trampoline_rel_start;
> + trampoline_ptr < __trampoline_rel_stop;
> + ++trampoline_ptr )
> + *(u32 *)(*trampoline_ptr + (long)trampoline_ptr) += phys;
> +
> + tramp32_delta = phys;
> + if ( !efi_enabled(EFI_LOADER) )
> + {
> + /*
> + * The non-EFI boot code uses the 32-bit trampoline in place
> + * so will have relocated it to the physical address of
> + * perm_trampoline_start already. Undo that as it needs to
> + * run from low memory for AP startup, because the Xen
> + * physical address range won't be mapped.
> + */
> + tramp32_delta -= trampoline_xen_phys_start;
> + tramp32_delta -= (unsigned long)(perm_trampoline_start -
> __XEN_VIRT_START);
> + }
> + for ( trampoline_ptr = __trampoline32_rel_start;
> + trampoline_ptr < __trampoline32_rel_stop;
> + ++trampoline_ptr )
> + {
> + *(u32 *)(*trampoline_ptr + (long)trampoline_ptr) += tramp32_delta;
> + }
Along the lines of the loop further up, lease omit the braces here.
> --- a/xen/arch/x86/smpboot.c
> +++ b/xen/arch/x86/smpboot.c
> @@ -47,7 +47,7 @@
> #include <asm/tboot.h>
> #include <mach_apic.h>
>
> -#define setup_trampoline() (bootsym_phys(trampoline_realmode_entry))
> +#define setup_trampoline() (trampsym_phys(trampoline_realmode_entry))
Would you mind taking the opportunity and strip the unnecessary pair
of parentheses here?
> --- a/xen/arch/x86/x86_64/mm.c
> +++ b/xen/arch/x86/x86_64/mm.c
> @@ -697,7 +697,7 @@ void __init zap_low_mappings(void)
>
> /* Replace with mapping of the boot trampoline only. */
> map_pages_to_xen(trampoline_phys, maddr_to_mfn(trampoline_phys),
> - PFN_UP(boot_trampoline_end - boot_trampoline_start),
> + PFN_UP(perm_trampoline_end - perm_trampoline_start),
> __PAGE_HYPERVISOR);
You also want to adjust the comment then.
Jan
_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxxx
https://lists.xenproject.org/mailman/listinfo/xen-devel
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |