|
[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 |