EFI 1:1 mapping
Borislav Petkov
maintainercover EFI 1:1 mapping
From: Borislav Petkov <[email protected]>
Hi all,
this is just a snapshot of the current state of affairs. The patchset starts to boot successfully on real hardware now but we're far away from the coverage we'd like to have before we even consider upstreaming it.
And yes, considering the sick f*ck EFI is, we're keeping the 1:1 mapping optional and off by default (you need to boot with "efi=1:1_map" to enable it).
Matt has picked up 1/4 already so I'll drop it when it lands into -tip and so on...
Thanks for any suggestions, as always.
Borislav Petkov (4):
efi: Convert runtime services function ptrs x86, cpa: Map in an arbitrary pgd
x86, efi: Add an efi= kernel command line parameter x86, efi: Map runtime services 1:1
arch/x86/boot/compressed/eboot.c | 2 +- arch/x86/include/asm/efi.h | 81 ++++++++++----- arch/x86/include/asm/pgtable_types.h | 3 +- arch/x86/mm/pageattr.c | 82 ++++++++++++---- arch/x86/platform/efi/efi.c | 184 +++++++++++++++++++++++++++++------ arch/x86/platform/efi/efi_stub_64.S | 56 +++++++++++ include/linux/efi.h | 28 +++--- 7 files changed, 348 insertions(+), 88 deletions(-)
Signature · 1 line
1.8.3
Borislav Petkov
maintainerPATCH 1/4 efi: Convert runtime services function ptrs
From: Borislav Petkov <[email protected]>
... to void * like the boot services and lose all the void * casts. No functionality change.
--- arch/x86/boot/compressed/eboot.c | 2 +- arch/x86/include/asm/efi.h | 28 ++++++++++++++-------------- include/linux/efi.h | 28 ++++++++++++++-------------- 3 files changed, 29 insertions(+), 29 deletions(-)
arch/x86/boot/compressed/eboot.c +1 -1
@@ -266,7 +266,7 @@ static efi_status_t setup_efi_vars(struct boot_params *params)while (data && data->next) data = (struct setup_data *)(unsigned long )data->next; - status = efi_call_phys4((void *)sys_table->runtime->query_variable_info, + status = efi_call_phys4(sys_table->runtime->query_variable_info, EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS, &store_size,
arch/x86/include/asm/efi.h +14 -14
@@ -52,40 +52,40 @@ extern u64 efi_call6(void *fp, u64 arg1, u64 arg2, u64 arg3, u64 arg4, u64 arg5, u64 arg6);#define efi_call_phys0 (f) \ - efi_call0((void *)(f)) + efi_call0((f))#define efi_call_phys1 (f, a1) \ - efi_call1((void *)(f), (u64)(a1)) + efi_call1((f), (u64)(a1))#define efi_call_phys2 (f, a1, a2) \ - efi_call2((void *)(f), (u64)(a1), (u64)(a2)) + efi_call2((f), (u64)(a1), (u64)(a2))#define efi_call_phys3 (f, a1, a2, a3) \ - efi_call3((void *)(f), (u64)(a1), (u64)(a2), (u64)(a3)) + efi_call3((f), (u64)(a1), (u64)(a2), (u64)(a3))#define efi_call_phys4 (f, a1, a2, a3, a4) \ - efi_call4((void *)(f), (u64)(a1), (u64)(a2), (u64)(a3), \ + efi_call4((f), (u64)(a1), (u64)(a2), (u64)(a3), \ (u64)(a4))#define efi_call_phys5 (f, a1, a2, a3, a4, a5) \ - efi_call5((void *)(f), (u64)(a1), (u64)(a2), (u64)(a3), \ + efi_call5((f), (u64)(a1), (u64)(a2), (u64)(a3), \ (u64)(a4), (u64)(a5))#define efi_call_phys6 (f, a1, a2, a3, a4, a5, a6) \ - efi_call6((void *)(f), (u64)(a1), (u64)(a2), (u64)(a3), \ + efi_call6((f), (u64)(a1), (u64)(a2), (u64)(a3), \ (u64)(a4), (u64)(a5), (u64)(a6))#define efi_call_virt0 (f) \ - efi_call0((void *)(efi.systab->runtime->f)) + efi_call0((efi.systab->runtime->f))#define efi_call_virt1 (f, a1) \ - efi_call1((void *)(efi.systab->runtime->f), (u64)(a1)) + efi_call1((efi.systab->runtime->f), (u64)(a1))#define efi_call_virt2 (f, a1, a2) \ - efi_call2((void *)(efi.systab->runtime->f), (u64)(a1), (u64)(a2)) + efi_call2((efi.systab->runtime->f), (u64)(a1), (u64)(a2))#define efi_call_virt3 (f, a1, a2, a3) \ - efi_call3((void *)(efi.systab->runtime->f), (u64)(a1), (u64)(a2), \ + efi_call3((efi.systab->runtime->f), (u64)(a1), (u64)(a2), \ (u64)(a3))#define efi_call_virt4 (f, a1, a2, a3, a4) \ - efi_call4((void *)(efi.systab->runtime->f), (u64)(a1), (u64)(a2), \ + efi_call4((efi.systab->runtime->f), (u64)(a1), (u64)(a2), \ (u64)(a3), (u64)(a4))#define efi_call_virt5 (f, a1, a2, a3, a4, a5) \ - efi_call5((void *)(efi.systab->runtime->f), (u64)(a1), (u64)(a2), \ + efi_call5((efi.systab->runtime->f), (u64)(a1), (u64)(a2), \ (u64)(a3), (u64)(a4), (u64)(a5))#define efi_call_virt6 (f, a1, a2, a3, a4, a5, a6) \ - efi_call6((void *)(efi.systab->runtime->f), (u64)(a1), (u64)(a2), \ + efi_call6((efi.systab->runtime->f), (u64)(a1), (u64)(a2), \ (u64)(a3), (u64)(a4), (u64)(a5), (u64)(a6)) extern void __iomem *efi_ioremap(unsigned long addr, unsigned long size,
include/linux/efi.h +14 -14
@@ -287,20 +287,20 @@ typedef struct {typedef struct {efi_table_hdr_t hdr; -unsigned long get_time; -unsigned long set_time; -unsigned long get_wakeup_time; -unsigned long set_wakeup_time; -unsigned long set_virtual_address_map; -unsigned long convert_pointer; -unsigned long get_variable; -unsigned long get_next_variable; -unsigned long set_variable; -unsigned long get_next_high_mono_count; -unsigned long reset_system; -unsigned long update_capsule; -unsigned long query_capsule_caps; -unsigned long query_variable_info; +void *get_time; +void *set_time; +void *get_wakeup_time; +void *set_wakeup_time; +void *set_virtual_address_map; +void *convert_pointer; +void *get_variable; +void *get_next_variable; +void *set_variable; +void *get_next_high_mono_count; +void *reset_system; +void *update_capsule; +void *query_capsule_caps; +void *query_variable_info; }efi_runtime_services_t ;typedef efi_status_t efi_get_time_t (efi_time_t *tm,efi_time_cap_t *tc);
Signature · 1 line
1.8.3
PATCH 1/1 sim: Add casts to avoid assignment warnings
Pointers in the efi_runtime_services_t structure now have type "void *" (formerly they were "unsigned long"). So we now see a bunch of warnings like this:
arch/ia64/hp/sim/boot/fw-emu.c:293: warning: assignment makes pointer from integer without a cast
Add (void *) casts to the 10 affected lines to make the build quiet again.
---
Boris, Matt - Can you add this patch to the same tree that
commit 43ab0476a648053e5998bf081f47f215375a4502 [linux-next id]
efi: Convert runtime services function ptrs
is in so that it will follow along behind it. Thanks.
arch/ia64/hp/sim/boot/fw-emu.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-)
arch/ia64/hp/sim/boot/fw-emu.c +10 -10
@@ -290,16 +290,16 @@ sys_fw_init (const char *args, int arglen) efi_runtime->hdr.signature =EFI_RUNTIME_SERVICES_SIGNATURE ; efi_runtime->hdr.revision =EFI_RUNTIME_SERVICES_REVISION ; efi_runtime->hdr.headersize =sizeof (efi_runtime->hdr); - efi_runtime->get_time =__pa (&fw_efi_get_time); - efi_runtime->set_time =__pa (&efi_unimplemented); - efi_runtime->get_wakeup_time =__pa (&efi_unimplemented); - efi_runtime->set_wakeup_time =__pa (&efi_unimplemented); - efi_runtime->set_virtual_address_map =__pa (&efi_unimplemented); - efi_runtime->get_variable =__pa (&efi_unimplemented); - efi_runtime->get_next_variable =__pa (&efi_unimplemented); - efi_runtime->set_variable =__pa (&efi_unimplemented); - efi_runtime->get_next_high_mono_count =__pa (&efi_unimplemented); - efi_runtime->reset_system =__pa (&efi_reset_system); + efi_runtime->get_time = (void *)__pa (&fw_efi_get_time); + efi_runtime->set_time = (void *)__pa (&efi_unimplemented); + efi_runtime->get_wakeup_time = (void *)__pa (&efi_unimplemented); + efi_runtime->set_wakeup_time = (void *)__pa (&efi_unimplemented); + efi_runtime->set_virtual_address_map = (void *)__pa (&efi_unimplemented); + efi_runtime->get_variable = (void *)__pa (&efi_unimplemented); + efi_runtime->get_next_variable = (void *)__pa (&efi_unimplemented); + efi_runtime->set_variable = (void *)__pa (&efi_unimplemented); + efi_runtime->get_next_high_mono_count = (void *)__pa (&efi_unimplemented); + efi_runtime->reset_system = (void *)__pa (&efi_reset_system); efi_tables->guid =SAL_SYSTEM_TABLE_GUID ; efi_tables->table =__pa (sal_systab);
Signature · 1 line
1.8.1.4
Re: [PATCH] [IA64] sim: Add casts to avoid assignment warnings
Oops - pasted in old e-mail address for Boris
Quoted 61 lines · Tony
Pointers in the
efi_runtime_services_tstructure now have type "void *" (formerly they were "unsigned long"). So we now see a bunch of warnings like this:
arch/ia64/hp/sim/boot/fw-emu.c:293: warning: assignment makes pointer from integer without a castAdd (void *) casts to the 10 affected lines to make the build quiet again.
Signed-off-by Tony Luck <[email protected]>---
Boris, Matt - Can you add this patch to the same tree that
commit
43ab0476a648053e5998bf081f47f215375a4502[linux-next id]
efi: Convert runtime services function ptrsis in so that it will follow along behind it. Thanks.
arch/ia64/hp/sim/boot/fw-emu.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-)arch/ia64/hp/sim/boot/fw-emu.c +10
-11@@ -290,16 +290,16 @@ sys_fw_init (const char *args, int arglen) efi_runtime->hdr.signature =EFI_RUNTIME_SERVICES_SIGNATURE ; efi_runtime->hdr.revision =EFI_RUNTIME_SERVICES_REVISION ; efi_runtime->hdr.headersize =sizeof (efi_runtime->hdr); - efi_runtime->get_time =__pa (&fw_efi_get_time); - efi_runtime->set_time =__pa (&efi_unimplemented); - efi_runtime->get_wakeup_time =__pa (&efi_unimplemented); - efi_runtime->set_wakeup_time =__pa (&efi_unimplemented); - efi_runtime->set_virtual_address_map =__pa (&efi_unimplemented); - efi_runtime->get_variable =__pa (&efi_unimplemented); - efi_runtime->get_next_variable =__pa (&efi_unimplemented); - efi_runtime->set_variable =__pa (&efi_unimplemented); - efi_runtime->get_next_high_mono_count =__pa (&efi_unimplemented); - efi_runtime->reset_system =__pa (&efi_reset_system); + efi_runtime->get_time = (void *)__pa (&fw_efi_get_time); + efi_runtime->set_time = (void *)__pa (&efi_unimplemented); + efi_runtime->get_wakeup_time = (void *)__pa (&efi_unimplemented); + efi_runtime->set_wakeup_time = (void *)__pa (&efi_unimplemented); + efi_runtime->set_virtual_address_map = (void *)__pa (&efi_unimplemented); + efi_runtime->get_variable = (void *)__pa (&efi_unimplemented); + efi_runtime->get_next_variable = (void *)__pa (&efi_unimplemented); + efi_runtime->set_variable = (void *)__pa (&efi_unimplemented); + efi_runtime->get_next_high_mono_count = (void *)__pa (&efi_unimplemented); + efi_runtime->reset_system = (void *)__pa (&efi_reset_system); efi_tables->guid =SAL_SYSTEM_TABLE_GUID ; efi_tables->table =__pa (sal_systab); --1.8.1.4
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
Fleming, Matt
AppliedRe: [PATCH] [IA64] sim: Add casts to avoid assignment warnings
Quoted 1 line · Tony Luck
Oops - pasted in old e-mail address for Boris
Applied, thanks Tony.
Borislav Petkov
maintainerPATCH 2/4 x86, cpa: Map in an arbitrary pgd
In reply to Borislav PetkovFrom: Borislav Petkov <[email protected]>
Add the ability to map pages in an arbitrary pgd.
--- arch/x86/include/asm/pgtable_types.h | 3 +- arch/x86/mm/pageattr.c | 82 ++++++++++++++++++++++++++++-------- 2 files changed, 67 insertions(+), 18 deletions(-)
arch/x86/include/asm/pgtable_types.h +2 -1
@@ -352,7 +352,8 @@ static inline void update_page_count(int level, unsigned long pages) { }*/ extern pte_t *lookup_address (unsigned long address,unsigned int *level);extern phys_addr_t slow_virt_to_phys (void *__address); - +extern void kernel_map_pages_in_pgd (pgd_t *pgd,unsigned long address, +unsigned numpages,unsigned long page_flags);#endif /* !__ASSEMBLY__ */ #endif /* _ASM_X86_PGTABLE_DEFS_H */
arch/x86/mm/pageattr.c +65 -17
169 lines not on this page · raw message
Signature · 1 line
1.8.3
Borislav Petkov
maintainerPATCH 3/4 x86, efi: Add an efi= kernel command line parameter
In reply to Borislav PetkovFrom: Borislav Petkov <[email protected]>
.. for passing miscellaneous options from the kernel command line.
--- arch/x86/platform/efi/efi.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+)
arch/x86/platform/efi/efi.c +19 -0
@@ -88,6 +88,11 @@ static u64 active_size;unsigned long x86_efi_facility; +/* 1:1 mapping of services regions */ +#define EFI_CFG_MAP11 BIT(0) + +static unsigned long efi_config; +/* * Returns 1 if 'facility' is enabled, 0 otherwise. */
@@ -1167,3 +1172,17 @@ efi_status_t efi_query_variable_store(u32 attributes, unsigned long size)return EFI_SUCCESS ; }EXPORT_SYMBOL_GPL (efi_query_variable_store); + +static int __init parse_efi_cmdline (char *str) +{ +if (*str =='=' ) + str++; + +#ifdef CONFIG_X86_64 +if (!strncmp (str,"1:1_map" ,7 )) + efi_config |=EFI_CFG_MAP11 ; +#endif + +return 0 ; +} +early_param ("efi" , parse_efi_cmdline);
Signature · 1 line
1.8.3
Borislav Petkov
maintainerPATCH 4/4 x86, efi: Map runtime services 1:1
In reply to Borislav PetkovFrom: Borislav Petkov <[email protected]>
Due to the braindead design of EFI, we cannot map runtime services more than once for the duration of a booted system. Thus, if we want to use EFI runtime services in a kexec'ed kernel, maybe the only possible and sensible approach would be to map them 1:1 so that when the kexec kernel loads, it can simply call those addresses without the need for remapping (which doesn't work anyway).
Furthermore, this mapping approach could be of help with b0rked EFI implementations for a different set of reasons.
This implementation is 64-bit only for now.
--- arch/x86/include/asm/efi.h | 67 +++++++++++---- arch/x86/platform/efi/efi.c | 165 +++++++++++++++++++++++++++++------- arch/x86/platform/efi/efi_stub_64.S | 56 ++++++++++++ 3 files changed, 240 insertions(+), 48 deletions(-)
arch/x86/include/asm/efi.h +50 -17
@@ -39,8 +39,13 @@ extern unsigned long asmlinkage efi_call_phys(void *, ...);#else /* !CONFIG_X86_32 */ +#include <linux/sched.h> +#define EFI_LOADER_SIGNATURE "EL64" +extern pgd_t *efi_pgt; +extern bool efi_use_11_map; +extern u64 efi_call0 (void *fp);extern u64 efi_call1 (void *fp,u64 arg1);extern u64 efi_call2 (void *fp,u64 arg1,u64 arg2);
@@ -51,6 +56,22 @@ extern u64 efi_call5(void *fp, u64 arg1, u64 arg2, u64 arg3,extern u64 efi_call6 (void *fp,u64 arg1,u64 arg2,u64 arg3,u64 arg4,u64 arg5,u64 arg6); +/* +* map-in low kernel mapping for passing arguments to EFI functions. +*/ +static inline void efi_sync_low_kernel_mappings (void ) +{ +unsigned num_pgds; +pgd_t *pgd; + + pgd = (pgd_t *)__va (real_mode_header->trampoline_pgd); + num_pgds =pgd_index (VMALLOC_START -1 ) -pgd_index (PAGE_OFFSET ); + +memcpy (pgd +pgd_index (PAGE_OFFSET ), + init_mm.pgd +pgd_index (PAGE_OFFSET ), +sizeof (pgd_t) * num_pgds); +} +#define efi_call_phys0 (f) \ efi_call0((f))#define efi_call_phys1 (f, a1) \
@@ -69,24 +90,36 @@ extern u64 efi_call6(void *fp, u64 arg1, u64 arg2, u64 arg3,efi_call6 ((f), (u64)(a1), (u64)(a2), (u64)(a3), \ (u64)(a4), (u64)(a5), (u64)(a6)) +#define _efi_call_virtX (x, f, ...) \ +({ \ + efi_status_t __s; \ + \ + if (efi_use_11_map) { \ + efi_sync_low_kernel_mappings(); \ + preempt_disable(); \ + } \ + \ + __s = efi_call##x(efi.systab->runtime->f, __VA_ARGS__); \ + \ + if (efi_use_11_map) \ + preempt_enable(); \ + __s; \ +}) +#define efi_call_virt0 (f) \ - efi_call0((efi.systab->runtime->f)) -#define efi_call_virt1 (f, a1) \ - efi_call1((efi.systab->runtime->f), (u64)(a1)) -#define efi_call_virt2 (f, a1, a2) \ - efi_call2((efi.systab->runtime->f), (u64)(a1), (u64)(a2)) -#define efi_call_virt3 (f, a1, a2, a3) \ - efi_call3((efi.systab->runtime->f), (u64)(a1), (u64)(a2), \ - (u64)(a3)) -#define efi_call_virt4 (f, a1, a2, a3, a4) \ - efi_call4((efi.systab->runtime->f), (u64)(a1), (u64)(a2), \ - (u64)(a3), (u64)(a4)) -#define efi_call_virt5 (f, a1, a2, a3, a4, a5) \ - efi_call5((efi.systab->runtime->f), (u64)(a1), (u64)(a2), \ - (u64)(a3), (u64)(a4), (u64)(a5)) -#define efi_call_virt6 (f, a1, a2, a3, a4, a5, a6) \ - efi_call6((efi.systab->runtime->f), (u64)(a1), (u64)(a2), \ - (u64)(a3), (u64)(a4), (u64)(a5), (u64)(a6)) + _efi_call_virtX(0, f) +#define efi_call_virt1 (f, a1) \ + _efi_call_virtX(1, f, (u64)(a1)) +#define efi_call_virt2 (f, a1, a2) \ + _efi_call_virtX(2, f, (u64)(a1), (u64)(a2)) +#define efi_call_virt3 (f, a1, a2, a3) \ + _efi_call_virtX(3, f, (u64)(a1), (u64)(a2), (u64)(a3)) +#define efi_call_virt4 (f, a1, a2, a3, a4) \ + _efi_call_virtX(4, f, (u64)(a1), (u64)(a2), (u64)(a3), (u64)(a4)) +#define efi_call_virt5 (f, a1, a2, a3, a4, a5) \ + _efi_call_virtX(5, f, (u64)(a1), (u64)(a2), (u64)(a3), (u64)(a4), (u64)(a5)) +#define efi_call_virt6 (f, a1, a2, a3, a4, a5, a6) \ + _efi_call_virtX(6, f, (u64)(a1), (u64)(a2), (u64)(a3), (u64)(a4), (u64)(a5), (u64)(a6))extern void __iomem *efi_ioremap (unsigned long addr,unsigned long size,u32 type,u64 attribute);
arch/x86/platform/efi/efi.c +134 -31
215 lines not on this page · raw message
arch/x86/platform/efi/efi_stub_64.S +56 -0
109 lines not on this page · raw message
Signature · 1 line
1.8.3
Re: [PATCH -v2 4/4] x86, efi: Map runtime services 1:1
Quoted 20 lines · Borislav Petkov
From: Borislav Petkov <[email protected]>
Due to the braindead design of EFI, we cannot map runtime services more than once for the duration of a booted system. Thus, if we want to use EFI runtime services in a kexec'ed kernel, maybe the only possible and sensible approach would be to map them 1:1 so that when the kexec kernel loads, it can simply call those addresses without the need for remapping (which doesn't work anyway).
Furthermore, this mapping approach could be of help with b0rked EFI implementations for a different set of reasons.
This implementation is 64-bit only for now.
Signed-off-by Borislav Petkov <[email protected]>--- arch/x86/include/asm/efi.h | 67 +++++++++++---- arch/x86/platform/efi/efi.c | 165 +++++++++++++++++++++++++++++------- arch/x86/platform/efi/efi_stub_64.S | 56 ++++++++++++ 3 files changed, 240 insertions(+), 48 deletions(-)
[...]
arch/x86/platform/efi/efi_stub_64.S line 52
Quoted 3 lines
arch/x86/platform/efi/efi_stub_64.S +3
-0+ .macro SWITCH_PGT + cmpb $0, efi_use_11_map + je 1f;
Actually, this needs to be,
cmpb $0, efi_use_11_map(%rip)
because this code is built into the EFI boot stub which isn't loaded at a fixed address and needs to be position independent.
Signature · 1 line
Matt Fleming, Intel Open Source Technology Center
Re: [PATCH -v2 4/4] x86, efi: Map runtime services 1:1
In reply to Borislav Petkov於 一,2013-06-17 於 19:50 +0200,Borislav Petkov 提到:
arch/x86/platform/efi/efi.c void __init efi_enter_virtual_mode(void) · line 1172
Quoted 5 lines
arch/x86/platform/efi/efi.c +5
-0+#ifdef CONFIG_X86_64 + efi_scratch.pgt11 = (pgd_t *)(unsigned long )real_mode_header->trampoline_pgd; +#endif + efi_use_11_map = true; +
I think "efi_use_11_map = true" should moved to before "#endif", otherwise kernel will build fail on i586 architecture.
I got build error:arch/x86/platform/efi/efi.c:1074: error: ‘efi_use_11_map’ undeclared (first use in this function) arch/x86/platform/efi/efi.c:1074: error: (Each undeclared identifier is reported only once arch/x86/platform/efi/efi.c:1074: error: for each function it appears in.)
Thanks a lot!
Joey Lee
Quoted 7 lines · Borislav Petkov
From: Borislav Petkov <[email protected]>
Hi all,
this is just a snapshot of the current state of affairs. The patchset starts to boot successfully on real hardware now but we're far away from the coverage we'd like to have before we even consider upstreaming it.
Looks pretty clean.
Quoted 3 lines
And yes, considering the sick f*ck EFI is, we're keeping the 1:1 mapping optional and off by default (you need to boot with "efi=1:1_map" to enable it).
I hope making it a weird boot option is not the end plan, there's little point in _not_ enabling 1:1 mappings by default eventually: the 1:1 mapping is supposed to emulate a "Windows compatible" EFI environment better and is expected to work around certain EFI runtime crashes.
Thanks,
Ingo
Borislav Petkov
maintainerQuoted 5 lines · Ingo Molnar
I hope making it a weird boot option is not the end plan, there's little point in _not_ enabling 1:1 mappings by default eventually:
the 1:1 mapping is supposed to emulate a "Windows compatible" EFI environment better and is expected to work around certain EFI runtime crashes.
And yet there are the Macs which reportedly cannot stomach this.
And then there's the issue where some boxes cannot boot through the EFI stub with those patches even without "efi=1:1_map" on the command line. The issue has something to do with the "cmpb $0, efi_use_11_map" in the efi_callX stubs.
And then again, other boxes have no problem with it and boot perfectly fine.
So I don't know - it all looks like a weird boot, opt-in option for now.
Signature · 5 lines
Regards/Gruss,
Boris.
Sent from a fat crate under my desk. Formatting is fine.
--Quoted 8 lines · Borislav Petkov
Quoted 5 lines · Ingo Molnar
I hope making it a weird boot option is not the end plan, there's little point in _not_ enabling 1:1 mappings by default eventually:
the 1:1 mapping is supposed to emulate a "Windows compatible" EFI environment better and is expected to work around certain EFI runtime crashes.And yet there are the Macs which reportedly cannot stomach this.
Do we know why?
Quoted 4 lines
And then there's the issue where some boxes cannot boot through the EFI stub with those patches even without "efi=1:1_map" on the command line. The issue has something to do with the "cmpb $0,
efi_use_11_map" in theefi_callXstubs.
A bug I suspect?
Quoted 4 lines
And then again, other boxes have no problem with it and boot perfectly fine.
So I don't know - it all looks like a weird boot, opt-in option for now.
But once it works reliably we can enable it, right?
Thanks,
Ingo
Borislav Petkov
maintainerQuoted 1 line · Ingo Molnar
Do we know why?
Well, according to mjg59 some Macs break if we don't give them a map which uses high addresses.
I can imagine flipping the meaning of this option to be on by default and "efi=no_11_map" to disable the 1:1 map for those Macs.
Quoted 1 line
A bug I suspect?
Probably. The problem is, it is very hard to debug the boot stub that early. And of course, I can't reproduce it in qemu :(. If only I had a hardware debugger...
Quoted 1 line
But once it works reliably we can enable it, right?
It's all the same to me - I hate EFI with passion so whatever people agree upon, I'll do it.
Signature · 5 lines
Regards/Gruss,
Boris.
Sent from a fat crate under my desk. Formatting is fine.
--Quoted 4 lines · Ingo Molnar
Quoted 1 line · Borislav Petkov
And yet there are the Macs which reportedly cannot stomach this.
Do we know why?
I got lost in a maze of pointer arithmetic. There seems to be an assumption that nvram writes should be forbidden if in runtime mode but with pointers still below the phys/virt split, which obviously makes no sense but hey.
But, as always, the only reliable thing to do here is to behave as much like Windows as possible. Which means performing the 1:1 mapping but maintaining the high mapping, and passing the high values via SetVirtualAddressMap.
Signature · 1 line
Matthew Garrett | [email protected]
Borislav Petkov
maintainerQuoted 4 lines · Matthew Garrett
But, as always, the only reliable thing to do here is to behave as much like Windows as possible. Which means performing the 1:1 mapping but maintaining the high mapping, and passing the high values via SetVirtualAddressMap.
We can't pass the high values via SetVirtualAddressMap and have EFI runtime in the kexec-ed kernel, as you and I established last week. And since not all would want EFI runtime in the kexec-ed kernel, I'm leaning more towards a boot-time option which enables the 1:1 mapping.
Btw, why would you even want the 1:1 mappings if we pass the high values via SetVirtualAddressMap?
Signature · 5 lines
Regards/Gruss,
Boris.
Sent from a fat crate under my desk. Formatting is fine.
--Quoted 10 lines · Borislav Petkov
Quoted 4 lines · Matthew Garrett
But, as always, the only reliable thing to do here is to behave as much like Windows as possible. Which means performing the 1:1 mapping but maintaining the high mapping, and passing the high values via SetVirtualAddressMap.
We can't pass the high values via SetVirtualAddressMap and have EFI runtime in the kexec-ed kernel, as you and I established last week. And since not all would want EFI runtime in the kexec-ed kernel, I'm leaning more towards a boot-time option which enables the 1:1 mapping.
Yes, kexec needs a different solution.
Quoted 2 lines
Btw, why would you even want the 1:1 mappings if we pass the high values via SetVirtualAddressMap?
Because firmware images don't always update all of the pointers, and so will crash if the 1:1 mappings aren't present.
Signature · 1 line
Matthew Garrett | [email protected]
Borislav Petkov
maintainerQuoted 1 line · Matthew Garrett
Yes, kexec needs a different solution.
No need. If we say, "efi=use_11_map", the 1:1 map will be shoved down SetVirtualAddressMap. Otherwise the high mappings.
Quoted 2 lines
Because firmware images don't always update all of the pointers, and so will crash if the 1:1 mappings aren't present.
Ok, so it sounds like we want to *always* create both mappings but, depending on what we want, to shove down SetVirtualAddressMap a different set. And the 1:1 map will be the optional one which we give SetVirtualAddressMap only when user wants it, i.e. when booting with "efi=1:1_map".
Makes sense?
Signature · 5 lines
Regards/Gruss,
Boris.
Sent from a fat crate under my desk. Formatting is fine.
--Quoted 5 lines · Borislav Petkov
Quoted 1 line · Matthew Garrett
Yes, kexec needs a different solution.
No need. If we say, "efi=use_11_map", the 1:1 map will be shoved down SetVirtualAddressMap. Otherwise the high mappings.
Ah, sure - if we're willing to take an argument then we can leave it at that. But having a stable set of high addresses for UEFI is also an option.
Quoted 8 lines
Quoted 2 lines
Because firmware images don't always update all of the pointers, and so will crash if the 1:1 mappings aren't present.
Ok, so it sounds like we want to *always* create both mappings but, depending on what we want, to shove down SetVirtualAddressMap a different set. And the 1:1 map will be the optional one which we give SetVirtualAddressMap only when user wants it, i.e. when booting with "efi=1:1_map".
Yup, I think that sounds ideal.
Signature · 1 line
Matthew Garrett | [email protected]
Borislav Petkov
maintainerQuoted 7 lines · Matthew Garrett
Quoted 5 lines
Ok, so it sounds like we want to *always* create both mappings but, depending on what we want, to shove down SetVirtualAddressMap a different set. And the 1:1 map will be the optional one which we give SetVirtualAddressMap only when user wants it, i.e. when booting with "efi=1:1_map".
Yup, I think that sounds ideal.
Crap, I got completely sidetracked. The 1:1 mappings go in a different pagetable (real_mode_header->trampoline_pgd) than the kernel one (i.e. init_mm.pgd). However, the ->trampoline_pgd has all mappings anyway, which means that if we want to do EFI runtime calls with the high mappings but *also* have the 1:1 mappings established, we should *always* switch to that pagetable when doing those calls.
hpa, MattF, agreed?
Signature · 5 lines
Regards/Gruss,
Boris.
Sent from a fat crate under my desk. Formatting is fine.
--H. Peter Anvin
reviewerQuoted 9 lines · Borislav Petkov
Quoted 7 lines · Matthew Garrett
Quoted 5 lines
Ok, so it sounds like we want to *always* create both mappings but, depending on what we want, to shove down SetVirtualAddressMap a different set. And the 1:1 map will be the optional one which we give SetVirtualAddressMap only when user wants it, i.e. when booting with "efi=1:1_map".
Yup, I think that sounds ideal.
Quoted 9 lines
Crap, I got completely sidetracked. The 1:1 mappings go in a different pagetable (
real_mode_header->trampoline_pgd) than the kernel one (i.e. init_mm.pgd). However, the ->trampoline_pgd has all mappings anyway, which means that if we want to do EFI runtime calls with the high mappings but *also* have the 1:1 mappings established, we should *always* switch to that pagetable when doing those calls.hpa, MattF, agreed?
Yes.
-hpa
Quoted 9 lines · Borislav Petkov
Quoted 7 lines · Matthew Garrett
Quoted 5 lines
Ok, so it sounds like we want to *always* create both mappings but, depending on what we want, to shove down SetVirtualAddressMap a different set. And the 1:1 map will be the optional one which we give SetVirtualAddressMap only when user wants it, i.e. when booting with "efi=1:1_map".
Yup, I think that sounds ideal.
Quoted 8 lines
Crap, I got completely sidetracked. The 1:1 mappings go in a different pagetable (
real_mode_header->trampoline_pgd) than the kernel one (i.e. init_mm.pgd). However, the ->trampoline_pgd has all mappings anyway, which means that if we want to do EFI runtime calls with the high mappings but *also* have the 1:1 mappings established, we should *always* switch to that pagetable when doing those calls.hpa, MattF, agreed?
Yep.
Signature · 1 line
Matt Fleming, Intel Open Source Technology Center
Quoted 9 lines · Borislav Petkov
Quoted 1 line · Matthew Garrett
Yes, kexec needs a different solution.
No need. If we say, "efi=use_11_map", the 1:1 map will be shoved down SetVirtualAddressMap. Otherwise the high mappings.
Quoted 2 lines
Because firmware images don't always update all of the pointers, and so will crash if the 1:1 mappings aren't present.
Quoted 7 lines
Ok, so it sounds like we want to *always* create both mappings but, depending on what we want, to shove down SetVirtualAddressMap a different set. And the 1:1 map will be the optional one which we give SetVirtualAddressMap only when user wants it, i.e. when booting with "efi=1:1_map".
Makes sense?
I think it will work. The only thing I'd worry about is aliasing. This scheme clearly won't work for any virtually indexed processor (so it's basically x86 only) but even on Physically Indexed, you do have to make sure the cache attributes of any given page are the same for all virtual address aliases. As long as the 1:1 mapping is writeback, I think this is satisfied.
James
Quoted 6 lines · Matthew Garrett
Quoted 4 lines · Ingo Molnar
Quoted 1 line · Borislav Petkov
And yet there are the Macs which reportedly cannot stomach this.
Do we know why?
Quoted 7 lines
I got lost in a maze of pointer arithmetic. There seems to be an assumption that nvram writes should be forbidden if in runtime mode but with pointers still below the phys/virt split, which obviously makes no sense but hey.
But, as always, the only reliable thing to do here is to behave as much like Windows as possible. [...]
Amen ...
Quoted 2 lines
[...] Which means performing the 1:1 mapping but maintaining the high mapping, and passing the high values via SetVirtualAddressMap.
Cool - and supposedly this will work in a Mac environment as well? Would be very nice to avoid fundamentally fragile system specific quirks for something as fundamental as the EFI runtime memory mapping model ...
Thanks,
Ingo
Quoted 3 lines · Ingo Molnar
Cool - and supposedly this will work in a Mac environment as well? Would be very nice to avoid fundamentally fragile system specific quirks for something as fundamental as the EFI runtime memory mapping model ...
Apple is the only case where I'd expect there to be an issue, since they only started supporting booting Windows via UEFI on very recent systems. However, unless they're actually sniffing the page tables on UEFI entry, I can't see any way that this could break things…
Signature · 1 line
Matthew Garrett | [email protected]
Quoted 10 lines · Matthew Garrett
Quoted 3 lines · Ingo Molnar
Cool - and supposedly this will work in a Mac environment as well? Would be very nice to avoid fundamentally fragile system specific quirks for something as fundamental as the EFI runtime memory mapping model ...
Apple is the only case where I'd expect there to be an issue, since they only started supporting booting Windows via UEFI on very recent systems. However, unless they're actually sniffing the page tables on UEFI entry, I can't see any way that this could break things???
Agreed - I was susprised to see that the runtime was able to _break_ in any way due to 1:1: my assumption was that it can only get better.
But I did not realize that the 1:1 boot flag also changed what was passed down, which probably explains the breakages.
I'd even argue to not do this whole boot flag thing at all - just standardize on the Windows compatibility model as closely as possible.
Thanks,
Ingo
Borislav Petkov
maintainerQuoted 9 lines · Ingo Molnar
Quoted 8 lines
Quoted 3 lines
Cool - and supposedly this will work in a Mac environment as well? Would be very nice to avoid fundamentally fragile system specific quirks for something as fundamental as the EFI runtime memory mapping model ...
Apple is the only case where I'd expect there to be an issue, since they only started supporting booting Windows via UEFI on very recent systems. However, unless they're actually sniffing the page tables on UEFI entry, I can't see any way that this could break things???
Quoted 5 lines
Agreed - I was susprised to see that the runtime was able to _break_ in any way due to 1:1: my assumption was that it can only get better.
But I did not realize that the 1:1 boot flag also changed what was passed down, which probably explains the breakages.
Right, in the next version, the boot flag will influence only what's being passed down.
Quoted 2 lines
I'd even argue to not do this whole boot flag thing at all - just standardize on the Windows compatibility model as closely as possible.
This will break the Macs so maybe we can do
efi=no_11_map
so the Macs can still boot but use the 1:1 map by default.
Signature · 5 lines
Regards/Gruss,
Boris.
Sent from a fat crate under my desk. Formatting is fine.
--Quoted 5 lines · Borislav Petkov
This will break the Macs so maybe we can do
efi=no_11_map
so the Macs can still boot but use the 1:1 map by default.
I'm going to guess that there are more people running unmodified Linux kernels on Macs than there are people using kexec, so just pass the high maps by default and let the enterprise kernels that care about kexec do something different.
Signature · 1 line
Matthew Garrett | [email protected]
Quoted 8 lines · Matthew Garrett
Quoted 5 lines
This will break the Macs so maybe we can do
efi=no_11_map
so the Macs can still boot but use the 1:1 map by default.
I'm going to guess that there are more people running unmodified Linux kernels on Macs than there are people using kexec,
I'd be careful in order not to underestimate how much kexec is being used. [At least some] distros are using it during installation process.
Signature · 2 lines
Jiri Kosina SUSE Labs
Quoted 11 lines · Matthew Garrett
Quoted 5 lines · Borislav Petkov
This will break the Macs so maybe we can do
efi=no_11_map
so the Macs can still boot but use the 1:1 map by default.
I'm going to guess that there are more people running unmodified Linux kernels on Macs than there are people using kexec, so just pass the high maps by default and let the enterprise kernels that care about kexec do something different.
Do we have to make this a popularity contest? Parallels is currently in beta with a ksplice like upgrade involving kexec ... basically you checkpoint the system to ram, kexec to the new kernel and restore the images from ram ... it can upgrade a new kernel in a matter of seconds (and unlike ksplice, it's the correct kernel and can move between major versions). Since all the components that do this are open source, we anticipate this will become a common way to maintain servers, so kexec will see even more use than it currently does.
Can't we detect Macs from some of the UEFI strings at boot time and do the right thing with the boot switch (which can be overriden from the kernel command line if we get it wrong)?
James
Quoted 3 lines · James Bottomley
Can't we detect Macs from some of the UEFI strings at boot time and do the right thing with the boot switch (which can be overriden from the kernel command line if we get it wrong)?
Yes, and then our behaviour differs from Windows and so we'll have inevitably broken some other system.
Signature · 1 line
Matthew Garrett | [email protected]
Quoted 5 lines · Matthew Garrett
Quoted 3 lines
Can't we detect Macs from some of the UEFI strings at boot time and do the right thing with the boot switch (which can be overriden from the kernel command line if we get it wrong)?
Yes, and then our behaviour differs from Windows
How so? Windows don't work on those older Macs as well, do they?
So if we properly detect those (and only those), we mimic Windows completely, right?
Signature · 2 lines
Jiri Kosina SUSE Labs
Quoted 2 lines · Jiri Kosina
So if we properly detect those (and only those), we mimic Windows completely, right?
No. Windows passes addresses above the phys/virt split to SetVirtualAddressMap().
Signature · 1 line
Matthew Garrett | [email protected]
Quoted 8 lines · Matthew Garrett
Quoted 3 lines · James Bottomley
Can't we detect Macs from some of the UEFI strings at boot time and do the right thing with the boot switch (which can be overriden from the kernel command line if we get it wrong)?
Yes, and then our behaviour differs from Windows and so we'll have inevitably broken some other system.
Unless you can think of the way out of this, we seem to have the stark choice of behave like windows or allow kexec. For the server market, kexec wins, so either we find a way not to have to make the choice or we do something automatic to make it fairly painless.
James
Quoted 4 lines · James Bottomley
Unless you can think of the way out of this, we seem to have the stark choice of behave like windows or allow kexec. For the server market, kexec wins, so either we find a way not to have to make the choice or we do something automatic to make it fairly painless.
hpa suggested ensuring that UEFI regions are mapped at fixed high offsets. Someone who cares about kexec should probably make that happen.
Signature · 1 line
Matthew Garrett | [email protected]
Borislav Petkov
maintainerQuoted 9 lines · Matthew Garrett
Quoted 4 lines · James Bottomley
Unless you can think of the way out of this, we seem to have the stark choice of behave like windows or allow kexec. For the server market, kexec wins, so either we find a way not to have to make the choice or we do something automatic to make it fairly painless.
hpa suggested ensuring that UEFI regions are mapped at fixed high offsets. Someone who cares about kexec should probably make that happen.
If we can detect the Macs, we can make this decision automatic. And since no Mac boots windoze, a single DMI check of the sort "if (Mac)" should suffice.
Signature · 5 lines
Regards/Gruss,
Boris.
Sent from a fat crate under my desk. Formatting is fine.
--Quoted 3 lines · Borislav Petkov
If we can detect the Macs, we can make this decision automatic. And since no Mac boots windoze, a single DMI check of the sort "if (Mac)" should suffice.
Yes, we can special-case Macs. But since our behaviour is then obviously different to Windows, we'll inevitably break some other system.
Signature · 1 line
Matthew Garrett | [email protected]
Borislav Petkov
maintainerQuoted 8 lines · Matthew Garrett
Quoted 3 lines · Borislav Petkov
If we can detect the Macs, we can make this decision automatic. And since no Mac boots windoze, a single DMI check of the sort "if (Mac)" should suffice.
Yes, we can special-case Macs. But since our behaviour is then obviously different to Windows, we'll inevitably break some other system.
Why different? We'll have the high mappings and shove the 1:1 mappings down SetVirtualAddressMap by default.
Signature · 5 lines
Regards/Gruss,
Boris.
Sent from a fat crate under my desk. Formatting is fine.
--Quoted 7 lines · Borislav Petkov
Quoted 6 lines · Matthew Garrett
Quoted 3 lines · Borislav Petkov
If we can detect the Macs, we can make this decision automatic. And since no Mac boots windoze, a single DMI check of the sort "if (Mac)" should suffice.
Quoted 5 lines
Quoted 2 lines
Yes, we can special-case Macs. But since our behaviour is then obviously different to Windows, we'll inevitably break some other system.
Why different? We'll have the high mappings and shove the 1:1 mappings down SetVirtualAddressMap by default.
Because Windows passes high addresses to SetVirtualAddressMap(), and because if you can imagine firmware developers getting it wrong then firmware developers will have got it wrong.
Signature · 1 line
Matthew Garrett | [email protected]
Borislav Petkov
maintainerQuoted 3 lines · Matthew Garrett
Because Windows passes high addresses to
SetVirtualAddressMap(), and because if you can imagine firmware developers getting it wrong then firmware developers will have got it wrong.
Can we reversely assume that if we'd used fixed high offsets, as hpa suggests, then it'll be fine? IOW, are any high addresses, even fixed ones, fine?
Signature · 5 lines
Regards/Gruss,
Boris.
Sent from a fat crate under my desk. Formatting is fine.
--Quoted 8 lines · Borislav Petkov
Quoted 3 lines · Matthew Garrett
Because Windows passes high addresses to
SetVirtualAddressMap(), and because if you can imagine firmware developers getting it wrong then firmware developers will have got it wrong.Can we reversely assume that if we'd used fixed high offsets, as hpa suggests, then it'll be fine? IOW, are any high addresses, even fixed ones, fine?
Windows actually seems to start at the top of address space and go down
- this is what I get booting Windows 8 under kvm. It looks like very high addresses are fine, and we're currently using "low" high addresses, so I suspect we're fine pretty much anywhere in that range.
****** SetVirtualAddressMap
Type: 5
Physical Start: 3E878000
Virtual Start: FFFFFFFFFFBEB000
Number Of Pages: 15
Attributes: 800000000000000F
Type: 6
Physical Start: 3E88D000
Virtual Start: FFFFFFFFFFBD6000
Number Of Pages: 15
Attributes: 800000000000000F
Type: 5
Physical Start: 3FB22000
Virtual Start: FFFFFFFFFFBA6000
Number Of Pages: 30
Attributes: 800000000000000F
Type: 6
Physical Start: 3FB52000
Virtual Start: FFFFFFFFFFB82000
Number Of Pages: 24
Attributes: 800000000000000F
Type: 6
Physical Start: 3FFE0000
Virtual Start: FFFFFFFFFFB62000
Number Of Pages: 20
Signature · 1 line
Matthew Garrett | [email protected]
Borislav Petkov
maintainerQuoted 32 lines · Matthew Garrett
Quoted 8 lines · Borislav Petkov
Quoted 3 lines · Matthew Garrett
Because Windows passes high addresses to
SetVirtualAddressMap(), and because if you can imagine firmware developers getting it wrong then firmware developers will have got it wrong.Can we reversely assume that if we'd used fixed high offsets, as hpa suggests, then it'll be fine? IOW, are any high addresses, even fixed ones, fine?
Windows actually seems to start at the top of address space and go down
- this is what I get booting Windows 8 under kvm. It looks like very high addresses are fine, and we're currently using "low" high addresses, so I suspect we're fine pretty much anywhere in that range.****** SetVirtualAddressMap
Type: 5
Physical Start: 3E878000
Virtual Start: FFFFFFFFFFBEB000
Number Of Pages: 15
Attributes: 800000000000000F
Type: 6
Physical Start: 3E88D000
Virtual Start: FFFFFFFFFFBD6000
Number Of Pages: 15
Attributes: 800000000000000F
Type: 5
Physical Start: 3FB22000
Virtual Start: FFFFFFFFFFBA6000
Number Of Pages: 30
Attributes: 800000000000000F
Type: 6
Quoted 8 lines
Physical Start: 3FB52000
Virtual Start: FFFFFFFFFFB82000
Number Of Pages: 24
Attributes: 800000000000000F
Type: 6
Physical Start: 3FFE0000
Virtual Start: FFFFFFFFFFB62000
Number Of Pages: 20
I guess we can do a top-down allocation, starting from the highest virtual addresses:
EFI_HIGHEST_ADDRESS
| | size1 | --> region1 | | size2 |
--> region2
...
and we make EFI_HIGHEST_ADDRESS be the same absolute number on every system.
hpa, is this close to what you had in mind? It would be prudent to verify whether this will suit well with the kexec virtual space layout though...
Thanks.
Signature · 5 lines
Regards/Gruss,
Boris.
Sent from a fat crate under my desk. Formatting is fine.
--H. Peter Anvin
reviewerQuoted 14 lines · Borislav Petkov
I guess we can do a top-down allocation, starting from the highest virtual addresses:
EFI_HIGHEST_ADDRESS| | size1 | --> region1 | | size2 |--> region2
Quoted 9 lines
...
and we make
EFI_HIGHEST_ADDRESSbe the same absolute number on every system.hpa, is this close to what you had in mind? It would be prudent to verify whether this will suit well with the kexec virtual space layout though...
This would work really well, I think. The tricky part here is to pick a safe EFI_HIGHEST_ADDRESS as it is an ABI.
My preference would be to make EFI_HIGHEST_ADDRESS = -4 GB, which is *not* what Windows uses, but will leave the high negative range clear, and allows a range where we can grow down without much risk of interfering with anything else.
-hpa
Borislav Petkov
maintainerQuoted 25 lines · H. Peter Anvin
Quoted 14 lines · Borislav Petkov
I guess we can do a top-down allocation, starting from the highest virtual addresses:
EFI_HIGHEST_ADDRESS| | size1 | --> region1 | | size2 |--> region2
Quoted 9 lines
...
and we make
EFI_HIGHEST_ADDRESSbe the same absolute number on every system.hpa, is this close to what you had in mind? It would be prudent to verify whether this will suit well with the kexec virtual space layout though...
Quoted 7 lines
This would work really well, I think. The tricky part here is to pick a safe
EFI_HIGHEST_ADDRESSas it is an ABI.My preference would be to make
EFI_HIGHEST_ADDRESS= -4 GB, which is *not* what Windows uses, but will leave the high negative range clear, and allows a range where we can grow down without much risk of interfering with anything else.
Hmm, cool. Let me see whether my primitive math still has it:
-(4 << 30) = 0xffffffff00000000.
Staring at Documentation/x86/x86_64/mm.txt, that's right in the unused hole, sandwiched between:
ffffea0000000000 - ffffeaffffffffff (=40 bits) virtual memory map (1TB)
xxxxxxxxxxxxxxxx - ffffffff00000000 (=XX bits, not a lot :-), maybe 4, i.e. 64G) EFI
ffffffff80000000 - ffffffffa0000000 (=512 MB) kernel text mapping, from phys 0
Now, if we go and do that, what are we going to say for the lower bound, in case later someone wants to use some more of the rest of the unused hole? Should we limit it to say
0xffffffff00000000 -0xfffffff000000000 = 64G max EFI mappable region.
Or am I too generous? The remaining hole is around
(0xfffffff000000000 - 0xffffeaffffffffff) >> 40 = 20TB.
Thanks.
Signature · 5 lines
Regards/Gruss,
Boris.
Sent from a fat crate under my desk. Formatting is fine.
--H. Peter Anvin
reviewerIf you cap it you are basically imposing a constraint on the firmware and may not run properly (or at least have to turn off EFI runtime calls with all that implies.) It might be good to have a sanity check but it needs to be pretty generous.
Quoted 66 lines · Borislav Petkov
Quoted 15 lines · H. Peter Anvin
Quoted 14 lines · Borislav Petkov
I guess we can do a top-down allocation, starting from the highest virtual addresses:
EFI_HIGHEST_ADDRESS| | size1 | --> region1 | | size2 |--> region2
Quoted 3 lines
Quoted 3 lines
...
and we make
EFI_HIGHEST_ADDRESSbe the same absolute number onevery
Quoted 4 lines
Quoted 4 lines
system.
hpa, is this close to what you had in mind? It would be prudent to verify whether this will suit well with the kexec virtual space
layout
Quoted 4 lines
Quoted 2 lines
though...
This would work really well, I think. The tricky part here is to
pick a
Quoted 4 lines
safe
EFI_HIGHEST_ADDRESSas it is an ABI.My preference would be to make
EFI_HIGHEST_ADDRESS= -4 GB, which is *not* what Windows uses, but will leave the high negative rangeclear,
Quoted 2 lines
and allows a range where we can grow down without much risk of interfering with anything else.
Hmm, cool. Let me see whether my primitive math still has it:
-(4 << 30) =
0xffffffff00000000.Staring at
Documentation/x86/x86_64/mm.txt, that's right in the unused hole, sandwiched between:
ffffea0000000000- ffffeaffffffffff (=40 bits) virtual memory map (1TB)xxxxxxxxxxxxxxxx -
ffffffff00000000(=XX bits, not a lot :-), maybe 4, i.e. 64G) EFI
ffffffff80000000-ffffffffa0000000(=512 MB) kernel text mapping, from phys 0Now, if we go and do that, what are we going to say for the lower bound,
in case later someone wants to use some more of the rest of the unused hole? Should we limit it to say
0xffffffff00000000-0xfffffff000000000= 64G max EFI mappable region.Or am I too generous? The remaining hole is around
(
0xfffffff000000000-0xffffeaffffffffff) >> 40 = 20TB.Thanks.
Signature · 1 line
Sent from my mobile phone. Please excuse brevity and lack of formatting.
Borislav Petkov
maintainerQuoted 3 lines · H. Peter Anvin
If you cap it you are basically imposing a constraint on the firmware and may not run properly (or at least have to turn off EFI runtime calls with all that implies.)
I don't want to cap EFI just for the fun of it but rather set a limit so that the next one who wants a chunk of the virtual address space can have a reliable limit from where she/he can start. Otherwise we won't know where EFI reliably ends...
Quoted 2 lines
It might be good to have a sanity check but it needs to be pretty generous.
64 Gb generous enough?
Signature · 5 lines
Regards/Gruss,
Boris.
Sent from a fat crate under my desk. Formatting is fine.
--H. Peter Anvin
reviewerQuoted 10 lines · Borislav Petkov
Quoted 3 lines · H. Peter Anvin
If you cap it you are basically imposing a constraint on the firmware and may not run properly (or at least have to turn off EFI runtime calls with all that implies.)
I don't want to cap EFI just for the fun of it but rather set a limit so that the next one who wants a chunk of the virtual address space can have a reliable limit from where she/he can start. Otherwise we won't know where EFI reliably ends...
We don't... and I don't think there is anything we can do about it. If some messed-up firmware wants to map a terabyte we either refuse and don't allow EFI runtime calls on that machine or we accept it.
Fortunately the space is extremely large and with growing down from a known address it is less likely that we'll conflict with something.
Quoted 4 lines
Quoted 2 lines
It might be good to have a sanity check but it needs to be pretty generous.
64 Gb generous enough?
Let's start there and see if we run into something that gives us trouble.
-hpa
Quoted 12 lines · H. Peter Anvin
Quoted 10 lines · Borislav Petkov
Quoted 3 lines · H. Peter Anvin
If you cap it you are basically imposing a constraint on the firmware and may not run properly (or at least have to turn off EFI runtime calls with all that implies.)
I don't want to cap EFI just for the fun of it but rather set a limit so that the next one who wants a chunk of the virtual address space can have a reliable limit from where she/he can start. Otherwise we won't know where EFI reliably ends...
Quoted 6 lines
We don't... and I don't think there is anything we can do about it. If some messed-up firmware wants to map a terabyte we either refuse and don't allow EFI runtime calls on that machine or we accept it.
Fortunately the space is extremely large and with growing down from a known address it is less likely that we'll conflict with something.
Hmm, will not setting up huge areas be slow?
Or we are going to use 2G pages or something?
Or should we make it slow on purpose so that at least server vendors are discouraged from using big areas? :-)
Signature · 2 lines
(english) http://www.livejournal.com/~pavelmachek (cesky, pictures) http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html
Quoted 8 lines · Borislav Petkov
Quoted 5 lines · Ingo Molnar
I hope making it a weird boot option is not the end plan, there's little point in _not_ enabling 1:1 mappings by default eventually:
the 1:1 mapping is supposed to emulate a "Windows compatible" EFI environment better and is expected to work around certain EFI runtime crashes.And yet there are the Macs which reportedly cannot stomach this.
I suspect they'll be fine with having a 1:1 map, as long as we pass the high mappings via SetVirtualAddressMap().
Signature · 1 line
Matthew Garrett | [email protected]
H. Peter Anvin
reviewerQuoted 3 lines · Borislav Petkov
And yet there are the Macs which reportedly cannot stomach this.
No, the reports are that if you use the 1:1 map as the primary address on Macs the drivers fail... not that you can't have a 1:1 map.
-hpa
Borislav Petkov
maintainerQuoted 6 lines · H. Peter Anvin
Quoted 3 lines · Borislav Petkov
And yet there are the Macs which reportedly cannot stomach this.
No, the reports are that if you use the 1:1 map as the primary address on Macs the drivers fail... not that you can't have a 1:1 map.
That's what I meant: ... cannot stomach when the 1:1 map is shoved down SetVirtualAddressMap.
The thing is, if we want to have both the 1:1 map and the high map during an EFI runtime call, we would need to *always* switch the pagetable for an EFI runtime call and establish both mappings in ->trampoline_pgd beforehand.
Signature · 5 lines
Regards/Gruss,
Boris.
Sent from a fat crate under my desk. Formatting is fine.
--H. Peter Anvin
reviewerQuoted 8 lines · Borislav Petkov
Quoted 6 lines · H. Peter Anvin
Quoted 3 lines · Borislav Petkov
And yet there are the Macs which reportedly cannot stomach this.
No, the reports are that if you use the 1:1 map as the primary address on Macs the drivers fail... not that you can't have a 1:1 map.
Quoted 8 lines
That's what I meant: ... cannot stomach when the 1:1 map is shoved down SetVirtualAddressMap.
The thing is, if we want to have both the 1:1 map and the high map during an EFI runtime call, we would need to *always* switch the pagetable for an EFI runtime call and establish both mappings in ->trampoline_pgd beforehand.
I thought that was the plan?
-hpa
Borislav Petkov
maintainerQuoted 1 line · H. Peter Anvin
I thought that was the plan?
Well, currently if I'm booted with "efi=1:1_map" I'm creating only the 1:1 mapping in ->trampoline_pgd and switching the pagetable only then. Otherwise, I'm using the high, ioremapped mappings - i.e., what we have now.
I guess I can sync the kernel address space into ->trampoline_pgd after having created the 1:1 mappings and always switch the pagetable later, after we've done SetVirtualAddressMap.
Which should take care of the EFI boot stub issue too, as I can define another set of efi_callX which switch the pagetable unconditionally.
Let me see how that pans out...
Signature · 5 lines
Regards/Gruss,
Boris.
Sent from a fat crate under my desk. Formatting is fine.
--