[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH] EFI: add efi=mapbs option and parse efi= early
When booting Xen via xen.efi, there is /mapbs option to workaround certain platform issues (added in f36886bdf4 "EFI/early: add /mapbs to map EfiBootServices{Code,Data}"). Add support for efi=mapbs on Xen cmdline for the same effect and parse it very early in the multiboot2+EFI boot path. Normally cmdline is parsed after relocating MB2 structure, which happens too late. To have efi= parsed early enough, save cmdline pointer in head.S and pass it as yet another argument to efi_multiboot2(). This way we avoid introducing yet another MB2 structure parser. To keep consistency, handle efi= parameter early in xen.efi too, both in xen.efi command line and cfg file. Signed-off-by: Marek Marczykowski-Górecki <marmarek@xxxxxxxxxxxxxxxxxxxxxx> --- docs/misc/xen-command-line.pandoc | 6 +++++- xen/arch/x86/boot/head.S | 21 ++++++++++++++++++--- xen/arch/x86/efi/efi-boot.h | 10 ++++++++-- xen/arch/x86/x86_64/asm-offsets.c | 1 + xen/common/efi/boot.c | 23 ++++++++++++++++++++++- 5 files changed, 54 insertions(+), 7 deletions(-) diff --git a/docs/misc/xen-command-line.pandoc b/docs/misc/xen-command-line.pandoc index 7c72e31032..b2dfd64b48 100644 --- a/docs/misc/xen-command-line.pandoc +++ b/docs/misc/xen-command-line.pandoc @@ -886,7 +886,7 @@ disable it (edid=no). This option should not normally be required except for debugging purposes. ### efi - = List of [ rs=<bool>, attr=no|uc ] + = List of [ rs=<bool>, attr=no|uc, mapbs=<bool> ] Controls for interacting with the system Extended Firmware Interface. @@ -899,6 +899,10 @@ Controls for interacting with the system Extended Firmware Interface. leave the memory regions unmapped, while `attr=uc` will map them as fully uncacheable. +* The `mapbs=` boolean controls whether EfiBootServices{Code,Data} should + remain mapped after Exit() BootServices call. By default those memory regions + will not be mapped after Exit() BootServices call. + ### ept > `= List of [ ad=<bool>, pml=<bool> ]` diff --git a/xen/arch/x86/boot/head.S b/xen/arch/x86/boot/head.S index d78bed394a..b13f46c70e 100644 --- a/xen/arch/x86/boot/head.S +++ b/xen/arch/x86/boot/head.S @@ -224,9 +224,10 @@ __efi64_mb2_start: jmp x86_32_switch .Lefi_multiboot2_proto: - /* Zero EFI SystemTable and EFI ImageHandle addresses. */ + /* Zero EFI SystemTable, EFI ImageHandle and cmdline addresses. */ xor %esi,%esi xor %edi,%edi + xor %rdx,%rdx /* Skip Multiboot2 information fixed part. */ lea (MB2_fixed_sizeof+MULTIBOOT2_TAG_ALIGN-1)(%rbx),%ecx @@ -241,7 +242,7 @@ __efi64_mb2_start: /* Are EFI boot services available? */ cmpl $MULTIBOOT2_TAG_TYPE_EFI_BS,MB2_tag_type(%rcx) - jne .Lefi_mb2_st + jne .Lefi_mb2_cmdline /* We are on EFI platform and EFI boot services are available. */ incb efi_platform(%rip) @@ -253,6 +254,14 @@ __efi64_mb2_start: incb skip_realmode(%rip) jmp .Lefi_mb2_next_tag +.Lefi_mb2_cmdline: + /* Get cmdline address from Multiboot2 information. */ + cmpl $MULTIBOOT2_TAG_TYPE_CMDLINE,MB2_tag_type(%rcx) + jne .Lefi_mb2_st + + lea MB2_string(%rcx),%rdx + jmp .Lefi_mb2_next_tag + .Lefi_mb2_st: /* Get EFI SystemTable address from Multiboot2 information. */ cmpl $MULTIBOOT2_TAG_TYPE_EFI64,MB2_tag_type(%rcx) @@ -264,6 +273,11 @@ __efi64_mb2_start: cmove MB2_efi64_ih(%rcx),%rdi je .Lefi_mb2_next_tag + /* Get cmdline address from Multiboot2 information. */ + cmpl $MULTIBOOT2_TAG_TYPE_CMDLINE,MB2_tag_type(%rcx) + cmove MB2_efi64_ih(%rcx),%rdi + je .Lefi_mb2_next_tag + /* Is it the end of Multiboot2 information? */ cmpl $MULTIBOOT2_TAG_TYPE_END,MB2_tag_type(%rcx) je .Lrun_bs @@ -327,7 +341,8 @@ __efi64_mb2_start: /* * efi_multiboot2() is called according to System V AMD64 ABI: - * - IN: %rdi - EFI ImageHandle, %rsi - EFI SystemTable. + * - IN: %rdi - EFI ImageHandle, %rsi - EFI SystemTable, + * %rdx - MB2 cmdline. */ call efi_multiboot2 diff --git a/xen/arch/x86/efi/efi-boot.h b/xen/arch/x86/efi/efi-boot.h index 7a13a30bc0..df5e98e6bc 100644 --- a/xen/arch/x86/efi/efi-boot.h +++ b/xen/arch/x86/efi/efi-boot.h @@ -315,8 +315,10 @@ static void __init efi_arch_handle_cmdline(CHAR16 *image_name, name.s = "xen"; place_string(&mbi.cmdline, name.s); - if ( mbi.cmdline ) + if ( mbi.cmdline ) { mbi.flags |= MBI_CMDLINE; + efi_early_parse_cmdline(mbi.cmdline); + } /* * These must not be initialized statically, since the value must * not get relocated when processing base relocations later. @@ -675,7 +677,8 @@ static bool __init efi_arch_use_config_file(EFI_SYSTEM_TABLE *SystemTable) static void __init efi_arch_flush_dcache_area(const void *vaddr, UINTN size) { } -void __init efi_multiboot2(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable) +void __init efi_multiboot2(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable, + const char *cmdline) { EFI_GRAPHICS_OUTPUT_PROTOCOL *gop; UINTN cols, gop_mode = ~0, rows; @@ -685,6 +688,9 @@ void __init efi_multiboot2(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable efi_init(ImageHandle, SystemTable); + if (cmdline) + efi_early_parse_cmdline(cmdline); + efi_console_set_mode(); if ( StdOut->QueryMode(StdOut, StdOut->Mode->Mode, diff --git a/xen/arch/x86/x86_64/asm-offsets.c b/xen/arch/x86/x86_64/asm-offsets.c index 33930ce97c..b5be6ca30f 100644 --- a/xen/arch/x86/x86_64/asm-offsets.c +++ b/xen/arch/x86/x86_64/asm-offsets.c @@ -163,6 +163,7 @@ void __dummy__(void) OFFSET(MB2_mem_lower, multiboot2_tag_basic_meminfo_t, mem_lower); OFFSET(MB2_efi64_st, multiboot2_tag_efi64_t, pointer); OFFSET(MB2_efi64_ih, multiboot2_tag_efi64_ih_t, pointer); + OFFSET(MB2_string, multiboot2_tag_string_t, string); BLANK(); DEFINE(l2_identmap_sizeof, sizeof(l2_identmap)); diff --git a/xen/common/efi/boot.c b/xen/common/efi/boot.c index 79193784ff..a8514bbb5f 100644 --- a/xen/common/efi/boot.c +++ b/xen/common/efi/boot.c @@ -126,6 +126,7 @@ static bool read_file(EFI_FILE_HANDLE dir_handle, CHAR16 *name, static size_t wstrlen(const CHAR16 * s); static int set_color(u32 mask, int bpp, u8 *pos, u8 *sz); static bool match_guid(const EFI_GUID *guid1, const EFI_GUID *guid2); +static void efi_early_parse_cmdline(const char *cmdline); static void efi_init(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable); static void efi_console_set_mode(void); @@ -1386,6 +1387,10 @@ efi_start(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable) static bool __initdata efi_map_uc; +/* + * Warning: this function must be idempotent as it may be called multiple + * times. + */ static int __init parse_efi_param(const char *s) { const char *ss; @@ -1412,16 +1417,32 @@ static int __init parse_efi_param(const char *s) else rc = -EINVAL; } + else if ( (val = parse_boolean("mapbs", s, ss)) >= 0 ) + { + map_bs = val; + } else rc = -EINVAL; s = ss + 1; - } while ( *ss ); + /* + * End parsing on both '\0' and ' ', + * to make efi_early_parse_cmdline simpler. + */ + } while ( *ss && *ss != ' '); return rc; } custom_param("efi", parse_efi_param); +/* Extract efi= param early in the boot */ +static void __init efi_early_parse_cmdline(const char *cmdline) +{ + const char *efi_opt = strstr(cmdline, "efi="); + if ( efi_opt ) + parse_efi_param(efi_opt + 4); +} + #ifndef USE_SET_VIRTUAL_ADDRESS_MAP static __init void copy_mapping(unsigned long mfn, unsigned long end, bool (*is_valid)(unsigned long smfn, -- 2.20.1 _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxxxxxxxxx https://lists.xenproject.org/mailman/listinfo/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |