[tip: efi/urgent] efi: use 32-bit alignment for efi_guid_t literals

2021-03-19 Thread tip-bot2 for Ard Biesheuvel
The following commit has been merged into the efi/urgent branch of tip:

Commit-ID: fb98cc0b3af2ba4d87301dff2b381b12eee35d7d
Gitweb:
https://git.kernel.org/tip/fb98cc0b3af2ba4d87301dff2b381b12eee35d7d
Author:Ard Biesheuvel 
AuthorDate:Wed, 10 Mar 2021 08:33:19 +01:00
Committer: Ard Biesheuvel 
CommitterDate: Fri, 19 Mar 2021 07:44:28 +01:00

efi: use 32-bit alignment for efi_guid_t literals

Commit 494c704f9af0 ("efi: Use 32-bit alignment for efi_guid_t") updated
the type definition of efi_guid_t to ensure that it always appears
sufficiently aligned (the UEFI spec is ambiguous about this, but given
the fact that its EFI_GUID type is defined in terms of a struct carrying
a uint32_t, the natural alignment is definitely >= 32 bits).

However, we missed the EFI_GUID() macro which is used to instantiate
efi_guid_t literals: that macro is still based on the guid_t type,
which does not have a minimum alignment at all. This results in warnings
such as

  In file included from drivers/firmware/efi/mokvar-table.c:35:
  include/linux/efi.h:1093:34: warning: passing 1-byte aligned argument to
  4-byte aligned parameter 2 of 'get_var' may result in an unaligned pointer
  access [-Walign-mismatch]
  status = get_var(L"SecureBoot", &EFI_GLOBAL_VARIABLE_GUID, NULL, 
&size,
  ^
  include/linux/efi.h:1101:24: warning: passing 1-byte aligned argument to
  4-byte aligned parameter 2 of 'get_var' may result in an unaligned pointer
  access [-Walign-mismatch]
  get_var(L"SetupMode", &EFI_GLOBAL_VARIABLE_GUID, NULL, &size, 
&setupmode);

The distinction only matters on CPUs that do not support misaligned loads
fully, but 32-bit ARM's load-multiple instructions fall into that category,
and these are likely to be emitted by the compiler that built the firmware
for loading word-aligned 128-bit GUIDs from memory

So re-implement the initializer in terms of our own efi_guid_t type, so that
the alignment becomes a property of the literal's type.

Fixes: 494c704f9af0 ("efi: Use 32-bit alignment for efi_guid_t")
Reported-by: Nathan Chancellor 
Reviewed-by: Nick Desaulniers 
Reviewed-by: Nathan Chancellor 
Tested-by: Nathan Chancellor 
Link: https://github.com/ClangBuiltLinux/linux/issues/1327
Signed-off-by: Ard Biesheuvel 
---
 include/linux/efi.h | 6 --
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/include/linux/efi.h b/include/linux/efi.h
index 8710f57..6b5d36b 100644
--- a/include/linux/efi.h
+++ b/include/linux/efi.h
@@ -72,8 +72,10 @@ typedef void *efi_handle_t;
  */
 typedef guid_t efi_guid_t __aligned(__alignof__(u32));
 
-#define EFI_GUID(a,b,c,d0,d1,d2,d3,d4,d5,d6,d7) \
-   GUID_INIT(a, b, c, d0, d1, d2, d3, d4, d5, d6, d7)
+#define EFI_GUID(a, b, c, d...) (efi_guid_t){ {
\
+   (a) & 0xff, ((a) >> 8) & 0xff, ((a) >> 16) & 0xff, ((a) >> 24) & 0xff,  
\
+   (b) & 0xff, ((b) >> 8) & 0xff,  
\
+   (c) & 0xff, ((c) >> 8) & 0xff, d } }
 
 /*
  * Generic EFI table header


[tip: efi/urgent] efi: stub: omit SetVirtualAddressMap() if marked unsupported in RT_PROP table

2021-03-08 Thread tip-bot2 for Ard Biesheuvel
The following commit has been merged into the efi/urgent branch of tip:

Commit-ID: 9e9888a0fe97b9501a40f717225d2bef7100a2c1
Gitweb:
https://git.kernel.org/tip/9e9888a0fe97b9501a40f717225d2bef7100a2c1
Author:Ard Biesheuvel 
AuthorDate:Fri, 05 Mar 2021 10:21:05 +01:00
Committer: Ard Biesheuvel 
CommitterDate: Sun, 07 Mar 2021 09:31:02 +01:00

efi: stub: omit SetVirtualAddressMap() if marked unsupported in RT_PROP table

The EFI_RT_PROPERTIES_TABLE contains a mask of runtime services that are
available after ExitBootServices(). This mostly does not concern the EFI
stub at all, given that it runs before that. However, there is one call
that is made at runtime, which is the call to SetVirtualAddressMap()
(which is not even callable at boot time to begin with)

So add the missing handling of the RT_PROP table to ensure that we only
call SetVirtualAddressMap() if it is not being advertised as unsupported
by the firmware.

Cc:  # v5.10+
Tested-by: Shawn Guo 
Signed-off-by: Ard Biesheuvel 
---
 drivers/firmware/efi/libstub/efi-stub.c | 16 
 1 file changed, 16 insertions(+)

diff --git a/drivers/firmware/efi/libstub/efi-stub.c 
b/drivers/firmware/efi/libstub/efi-stub.c
index ec2f398..26e6978 100644
--- a/drivers/firmware/efi/libstub/efi-stub.c
+++ b/drivers/firmware/efi/libstub/efi-stub.c
@@ -96,6 +96,18 @@ static void install_memreserve_table(void)
efi_err("Failed to install memreserve config table!\n");
 }
 
+static u32 get_supported_rt_services(void)
+{
+   const efi_rt_properties_table_t *rt_prop_table;
+   u32 supported = EFI_RT_SUPPORTED_ALL;
+
+   rt_prop_table = get_efi_config_table(EFI_RT_PROPERTIES_TABLE_GUID);
+   if (rt_prop_table)
+   supported &= rt_prop_table->runtime_services_supported;
+
+   return supported;
+}
+
 /*
  * EFI entry point for the arm/arm64 EFI stubs.  This is the entrypoint
  * that is described in the PE/COFF header.  Most of the code is the same
@@ -250,6 +262,10 @@ efi_status_t __efiapi efi_pe_entry(efi_handle_t handle,
  (prop_tbl->memory_protection_attribute &
   
EFI_PROPERTIES_RUNTIME_MEMORY_PROTECTION_NON_EXECUTABLE_PE_DATA);
 
+   /* force efi_novamap if SetVirtualAddressMap() is unsupported */
+   efi_novamap |= !(get_supported_rt_services() &
+EFI_RT_SUPPORTED_SET_VIRTUAL_ADDRESS_MAP);
+
/* hibernation expects the runtime regions to stay in the same place */
if (!IS_ENABLED(CONFIG_HIBERNATION) && !efi_nokaslr && 
!flat_va_mapping) {
/*


[tip: efi/core] efi: x86: move mixed mode stack PA variable out of 'efi_scratch'

2021-01-27 Thread tip-bot2 for Ard Biesheuvel
The following commit has been merged into the efi/core branch of tip:

Commit-ID: 3e1e00c00e2b9b5c9a2f47f1c67720a5d430e4d0
Gitweb:
https://git.kernel.org/tip/3e1e00c00e2b9b5c9a2f47f1c67720a5d430e4d0
Author:Ard Biesheuvel 
AuthorDate:Tue, 19 Jan 2021 15:16:27 +01:00
Committer: Ard Biesheuvel 
CommitterDate: Tue, 19 Jan 2021 17:57:16 +01:00

efi: x86: move mixed mode stack PA variable out of 'efi_scratch'

As a first step to removing the awkward 'struct efi_scratch' definition
that conveniently combines the storage of the mixed mode stack pointer
with the MM pointer variable that records the task's MM pointer while it
is being replaced with the EFI MM one, move the mixed mode stack pointer
into a separate variable.

Signed-off-by: Ard Biesheuvel 
---
 arch/x86/include/asm/efi.h   | 3 +--
 arch/x86/platform/efi/efi_64.c   | 2 +-
 arch/x86/platform/efi/efi_thunk_64.S | 6 +-
 3 files changed, 7 insertions(+), 4 deletions(-)

diff --git a/arch/x86/include/asm/efi.h b/arch/x86/include/asm/efi.h
index c98f783..5e37e6d 100644
--- a/arch/x86/include/asm/efi.h
+++ b/arch/x86/include/asm/efi.h
@@ -12,6 +12,7 @@
 #include 
 
 extern unsigned long efi_fw_vendor, efi_config_table;
+extern unsigned long efi_mixed_mode_stack_pa;
 
 /*
  * We map the EFI regions needed for runtime services non-contiguously,
@@ -96,11 +97,9 @@ extern asmlinkage u64 __efi_call(void *fp, ...);
 
 /*
  * struct efi_scratch - Scratch space used while switching to/from efi_mm
- * @phys_stack: stack used during EFI Mixed Mode
  * @prev_mm:store/restore stolen mm_struct while switching to/from efi_mm
  */
 struct efi_scratch {
-   u64 phys_stack;
struct mm_struct*prev_mm;
 } __packed;
 
diff --git a/arch/x86/platform/efi/efi_64.c b/arch/x86/platform/efi/efi_64.c
index e1e8d4e..1d90418 100644
--- a/arch/x86/platform/efi/efi_64.c
+++ b/arch/x86/platform/efi/efi_64.c
@@ -256,7 +256,7 @@ int __init efi_setup_page_tables(unsigned long pa_memmap, 
unsigned num_pages)
return 1;
}
 
-   efi_scratch.phys_stack = page_to_phys(page + 1); /* stack grows down */
+   efi_mixed_mode_stack_pa = page_to_phys(page + 1); /* stack grows down */
 
npages = (_etext - _text) >> PAGE_SHIFT;
text = __pa(_text);
diff --git a/arch/x86/platform/efi/efi_thunk_64.S 
b/arch/x86/platform/efi/efi_thunk_64.S
index 26f0da2..fd3dd17 100644
--- a/arch/x86/platform/efi/efi_thunk_64.S
+++ b/arch/x86/platform/efi/efi_thunk_64.S
@@ -33,7 +33,7 @@ SYM_CODE_START(__efi64_thunk)
 * Switch to 1:1 mapped 32-bit stack pointer.
 */
movq%rsp, %rax
-   movqefi_scratch(%rip), %rsp
+   movqefi_mixed_mode_stack_pa(%rip), %rsp
push%rax
 
/*
@@ -70,3 +70,7 @@ SYM_CODE_START(__efi64_thunk)
pushl   %ebp
lret
 SYM_CODE_END(__efi64_thunk)
+
+   .bss
+   .balign 8
+SYM_DATA(efi_mixed_mode_stack_pa, .quad 0)


[tip: efi/core] efi/libstub: fix prototype of efi_tcg2_protocol::get_event_log()

2021-01-27 Thread tip-bot2 for Ard Biesheuvel
The following commit has been merged into the efi/core branch of tip:

Commit-ID: cdec91c034a2c99331b62a5f417bf7527fa6d490
Gitweb:
https://git.kernel.org/tip/cdec91c034a2c99331b62a5f417bf7527fa6d490
Author:Ard Biesheuvel 
AuthorDate:Mon, 02 Nov 2020 10:04:39 +01:00
Committer: Ard Biesheuvel 
CommitterDate: Tue, 19 Jan 2021 17:57:15 +01:00

efi/libstub: fix prototype of efi_tcg2_protocol::get_event_log()

efi_tcg2_protocol::get_event_log() takes a protocol pointer as the
first argument, not a EFI handle.

Signed-off-by: Ard Biesheuvel 
---
 drivers/firmware/efi/libstub/efistub.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/firmware/efi/libstub/efistub.h 
b/drivers/firmware/efi/libstub/efistub.h
index b50a6c6..2b7438b 100644
--- a/drivers/firmware/efi/libstub/efistub.h
+++ b/drivers/firmware/efi/libstub/efistub.h
@@ -672,7 +672,7 @@ typedef union efi_tcg2_protocol efi_tcg2_protocol_t;
 union efi_tcg2_protocol {
struct {
void *get_capability;
-   efi_status_t (__efiapi *get_event_log)(efi_handle_t,
+   efi_status_t (__efiapi *get_event_log)(efi_tcg2_protocol_t *,
   
efi_tcg2_event_log_format,
   efi_physical_addr_t *,
   efi_physical_addr_t *,


[tip: efi/core] efi/libstub: move TPM related prototypes into efistub.h

2021-01-27 Thread tip-bot2 for Ard Biesheuvel
The following commit has been merged into the efi/core branch of tip:

Commit-ID: 3820749ddcee694abfd5ae6cabc18aaab11eab34
Gitweb:
https://git.kernel.org/tip/3820749ddcee694abfd5ae6cabc18aaab11eab34
Author:Ard Biesheuvel 
AuthorDate:Mon, 02 Nov 2020 11:51:10 +01:00
Committer: Ard Biesheuvel 
CommitterDate: Tue, 19 Jan 2021 17:57:15 +01:00

efi/libstub: move TPM related prototypes into efistub.h

Move TPM related definitions that are only used in the EFI stub into
efistub.h, which is a local header.

Signed-off-by: Ard Biesheuvel 
---
 drivers/firmware/efi/libstub/efistub.h |  9 +
 include/linux/efi.h|  9 -
 2 files changed, 9 insertions(+), 9 deletions(-)

diff --git a/drivers/firmware/efi/libstub/efistub.h 
b/drivers/firmware/efi/libstub/efistub.h
index 2b7438b..cde0a2e 100644
--- a/drivers/firmware/efi/libstub/efistub.h
+++ b/drivers/firmware/efi/libstub/efistub.h
@@ -849,4 +849,13 @@ void efi_handle_post_ebs_state(void);
 
 enum efi_secureboot_mode efi_get_secureboot(void);
 
+#ifdef CONFIG_RESET_ATTACK_MITIGATION
+void efi_enable_reset_attack_mitigation(void);
+#else
+static inline void
+efi_enable_reset_attack_mitigation(void) { }
+#endif
+
+void efi_retrieve_tpm2_eventlog(void);
+
 #endif
diff --git a/include/linux/efi.h b/include/linux/efi.h
index 2537a24..8710f57 100644
--- a/include/linux/efi.h
+++ b/include/linux/efi.h
@@ -1104,13 +1104,6 @@ enum efi_secureboot_mode 
efi_get_secureboot_mode(efi_get_variable_t *get_var)
return efi_secureboot_mode_enabled;
 }
 
-#ifdef CONFIG_RESET_ATTACK_MITIGATION
-void efi_enable_reset_attack_mitigation(void);
-#else
-static inline void
-efi_enable_reset_attack_mitigation(void) { }
-#endif
-
 #ifdef CONFIG_EFI_EMBEDDED_FIRMWARE
 void efi_check_for_embedded_firmwares(void);
 #else
@@ -1119,8 +1112,6 @@ static inline void efi_check_for_embedded_firmwares(void) 
{ }
 
 efi_status_t efi_random_get_seed(void);
 
-void efi_retrieve_tpm2_eventlog(void);
-
 /*
  * Arch code can implement the following three template macros, avoiding
  * reptition for the void/non-void return cases of {__,}efi_call_virt():


[tip: efi/core] efi: ia64: move IA64-only declarations to new asm/efi.h header

2021-01-27 Thread tip-bot2 for Ard Biesheuvel
The following commit has been merged into the efi/core branch of tip:

Commit-ID: 8ff059b8531f3b98e14f0461859fc7cdd95823e4
Gitweb:
https://git.kernel.org/tip/8ff059b8531f3b98e14f0461859fc7cdd95823e4
Author:Ard Biesheuvel 
AuthorDate:Mon, 18 Jan 2021 13:38:42 +01:00
Committer: Ard Biesheuvel 
CommitterDate: Mon, 18 Jan 2021 13:50:37 +01:00

efi: ia64: move IA64-only declarations to new asm/efi.h header

Move some EFI related declarations that are only referenced on IA64 to
a new asm/efi.h arch header.

Cc: Tony Luck 
Cc: Fenghua Yu 
Signed-off-by: Ard Biesheuvel 
---
 arch/ia64/include/asm/efi.h  | 13 +
 arch/ia64/kernel/efi.c   |  1 +
 arch/ia64/kernel/machine_kexec.c |  1 +
 arch/ia64/kernel/mca.c   |  1 +
 arch/ia64/kernel/smpboot.c   |  1 +
 arch/ia64/kernel/time.c  |  1 +
 arch/ia64/kernel/uncached.c  |  4 +---
 arch/ia64/mm/contig.c|  1 +
 arch/ia64/mm/discontig.c |  1 +
 arch/ia64/mm/init.c  |  1 +
 include/linux/efi.h  |  6 --
 11 files changed, 22 insertions(+), 9 deletions(-)
 create mode 100644 arch/ia64/include/asm/efi.h

diff --git a/arch/ia64/include/asm/efi.h b/arch/ia64/include/asm/efi.h
new file mode 100644
index 000..6a4a50d
--- /dev/null
+++ b/arch/ia64/include/asm/efi.h
@@ -0,0 +1,13 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef _ASM_EFI_H
+#define _ASM_EFI_H
+
+typedef int (*efi_freemem_callback_t) (u64 start, u64 end, void *arg);
+
+void *efi_get_pal_addr(void);
+void efi_map_pal_code(void);
+void efi_memmap_walk(efi_freemem_callback_t, void *);
+void efi_memmap_walk_uc(efi_freemem_callback_t, void *);
+void efi_gettimeofday(struct timespec64 *ts);
+
+#endif
diff --git a/arch/ia64/kernel/efi.c b/arch/ia64/kernel/efi.c
index f932b25..dd7fd75 100644
--- a/arch/ia64/kernel/efi.c
+++ b/arch/ia64/kernel/efi.c
@@ -34,6 +34,7 @@
 #include 
 #include 
 
+#include 
 #include 
 #include 
 #include 
diff --git a/arch/ia64/kernel/machine_kexec.c b/arch/ia64/kernel/machine_kexec.c
index efc9b56..af310dc 100644
--- a/arch/ia64/kernel/machine_kexec.c
+++ b/arch/ia64/kernel/machine_kexec.c
@@ -16,6 +16,7 @@
 #include 
 #include 
 
+#include 
 #include 
 #include 
 #include 
diff --git a/arch/ia64/kernel/mca.c b/arch/ia64/kernel/mca.c
index 2703f77..0fea266 100644
--- a/arch/ia64/kernel/mca.c
+++ b/arch/ia64/kernel/mca.c
@@ -91,6 +91,7 @@
 #include 
 
 #include 
+#include 
 #include 
 #include 
 #include 
diff --git a/arch/ia64/kernel/smpboot.c b/arch/ia64/kernel/smpboot.c
index 093040f..49b4885 100644
--- a/arch/ia64/kernel/smpboot.c
+++ b/arch/ia64/kernel/smpboot.c
@@ -45,6 +45,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
diff --git a/arch/ia64/kernel/time.c b/arch/ia64/kernel/time.c
index ed9fc3d..a37f161 100644
--- a/arch/ia64/kernel/time.c
+++ b/arch/ia64/kernel/time.c
@@ -26,6 +26,7 @@
 #include 
 
 #include 
+#include 
 #include 
 #include 
 #include 
diff --git a/arch/ia64/kernel/uncached.c b/arch/ia64/kernel/uncached.c
index 0750f36..51883a6 100644
--- a/arch/ia64/kernel/uncached.c
+++ b/arch/ia64/kernel/uncached.c
@@ -20,14 +20,12 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
 #include 
 
-
-extern void __init efi_memmap_walk_uc(efi_freemem_callback_t, void *);
-
 struct uncached_pool {
struct gen_pool *pool;
struct mutex add_chunk_mutex;   /* serialize adding a converted chunk */
diff --git a/arch/ia64/mm/contig.c b/arch/ia64/mm/contig.c
index bfc4ecd..62fe80a 100644
--- a/arch/ia64/mm/contig.c
+++ b/arch/ia64/mm/contig.c
@@ -21,6 +21,7 @@
 #include 
 #include 
 
+#include 
 #include 
 #include 
 #include 
diff --git a/arch/ia64/mm/discontig.c b/arch/ia64/mm/discontig.c
index c731113..03b3a02 100644
--- a/arch/ia64/mm/discontig.c
+++ b/arch/ia64/mm/discontig.c
@@ -24,6 +24,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
diff --git a/arch/ia64/mm/init.c b/arch/ia64/mm/init.c
index 9b5acf8..24583a3 100644
--- a/arch/ia64/mm/init.c
+++ b/arch/ia64/mm/init.c
@@ -27,6 +27,7 @@
 #include 
 
 #include 
+#include 
 #include 
 #include 
 #include 
diff --git a/include/linux/efi.h b/include/linux/efi.h
index 763b816..0c31af3 100644
--- a/include/linux/efi.h
+++ b/include/linux/efi.h
@@ -167,8 +167,6 @@ struct capsule_info {
 
 int __efi_capsule_setup_info(struct capsule_info *cap_info);
 
-typedef int (*efi_freemem_callback_t) (u64 start, u64 end, void *arg);
-
 /*
  * Types and defines for Time Services
  */
@@ -605,10 +603,6 @@ efi_guid_to_str(efi_guid_t *guid, char *out)
 }
 
 extern void efi_init (void);
-extern void *efi_get_pal_addr (void);
-extern void efi_map_pal_code (void);
-extern void efi_memmap_walk (efi_freemem_callback_t callback, void *arg);
-extern void efi_gettimeofday (struct timespec64 *ts);
 #ifdef CONFIG_EFI
 extern void efi_enter_virtual_mode (void); /* switch EFI to virtual mode, 
if possible */
 #else


[tip: efi/core] efi/libstub: whitespace cleanup

2021-01-27 Thread tip-bot2 for Ard Biesheuvel
The following commit has been merged into the efi/core branch of tip:

Commit-ID: 2f196059864fb0fe8f60c14a2cb214055b283e08
Gitweb:
https://git.kernel.org/tip/2f196059864fb0fe8f60c14a2cb214055b283e08
Author:Ard Biesheuvel 
AuthorDate:Mon, 02 Nov 2020 17:11:49 +01:00
Committer: Ard Biesheuvel 
CommitterDate: Tue, 19 Jan 2021 17:57:15 +01:00

efi/libstub: whitespace cleanup

Trivial whitespace cleanup.

Signed-off-by: Ard Biesheuvel 
---
 include/linux/efi.h | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/include/linux/efi.h b/include/linux/efi.h
index 0c31af3..2537a24 100644
--- a/include/linux/efi.h
+++ b/include/linux/efi.h
@@ -29,10 +29,10 @@
 #include 
 
 #define EFI_SUCCESS0
-#define EFI_LOAD_ERROR  ( 1 | (1UL << (BITS_PER_LONG-1)))
+#define EFI_LOAD_ERROR ( 1 | (1UL << (BITS_PER_LONG-1)))
 #define EFI_INVALID_PARAMETER  ( 2 | (1UL << (BITS_PER_LONG-1)))
 #define EFI_UNSUPPORTED( 3 | (1UL << (BITS_PER_LONG-1)))
-#define EFI_BAD_BUFFER_SIZE ( 4 | (1UL << (BITS_PER_LONG-1)))
+#define EFI_BAD_BUFFER_SIZE( 4 | (1UL << (BITS_PER_LONG-1)))
 #define EFI_BUFFER_TOO_SMALL   ( 5 | (1UL << (BITS_PER_LONG-1)))
 #define EFI_NOT_READY  ( 6 | (1UL << (BITS_PER_LONG-1)))
 #define EFI_DEVICE_ERROR   ( 7 | (1UL << (BITS_PER_LONG-1)))


[tip: efi/core] efi: x86: clean up previous struct mm switching

2021-01-27 Thread tip-bot2 for Ard Biesheuvel
The following commit has been merged into the efi/core branch of tip:

Commit-ID: 514b1a8477d25a157f65bf52a443f8ffcc2eb54e
Gitweb:
https://git.kernel.org/tip/514b1a8477d25a157f65bf52a443f8ffcc2eb54e
Author:Ard Biesheuvel 
AuthorDate:Tue, 19 Jan 2021 15:05:40 +01:00
Committer: Ard Biesheuvel 
CommitterDate: Tue, 19 Jan 2021 17:57:15 +01:00

efi: x86: clean up previous struct mm switching

EFI on x86_64 keeps track of the process's MM pointer by storing it
in a global struct called 'efi_scratch', which also used to contain
the mixed mode stack pointer. Let's clean this up a little bit, by
getting rid of the struct, and pushing the mm handling into the
callees entirely.

Signed-off-by: Ard Biesheuvel 
---
 arch/x86/include/asm/efi.h | 17 +
 arch/x86/platform/efi/efi_64.c | 27 +++
 2 files changed, 20 insertions(+), 24 deletions(-)

diff --git a/arch/x86/include/asm/efi.h b/arch/x86/include/asm/efi.h
index 5e37e6d..1328b79 100644
--- a/arch/x86/include/asm/efi.h
+++ b/arch/x86/include/asm/efi.h
@@ -95,20 +95,12 @@ extern asmlinkage u64 __efi_call(void *fp, ...);
__efi_call(__VA_ARGS__);\
 })
 
-/*
- * struct efi_scratch - Scratch space used while switching to/from efi_mm
- * @prev_mm:store/restore stolen mm_struct while switching to/from efi_mm
- */
-struct efi_scratch {
-   struct mm_struct*prev_mm;
-} __packed;
-
 #define arch_efi_call_virt_setup() \
 ({ \
efi_sync_low_kernel_mappings(); \
kernel_fpu_begin(); \
firmware_restrict_branch_speculation_start();   \
-   efi_switch_mm(&efi_mm); \
+   efi_enter_mm(); \
 })
 
 #define arch_efi_call_virt(p, f, args...)  \
@@ -116,7 +108,7 @@ struct efi_scratch {
 
 #define arch_efi_call_virt_teardown()  \
 ({ \
-   efi_switch_mm(efi_scratch.prev_mm); \
+   efi_leave_mm(); \
firmware_restrict_branch_speculation_end(); \
kernel_fpu_end();   \
 })
@@ -135,7 +127,6 @@ struct efi_scratch {
 
 #endif /* CONFIG_X86_32 */
 
-extern struct efi_scratch efi_scratch;
 extern int __init efi_memblock_x86_reserve_range(void);
 extern void __init efi_print_memmap(void);
 extern void __init efi_map_region(efi_memory_desc_t *md);
@@ -148,10 +139,12 @@ extern void __init efi_dump_pagetable(void);
 extern void __init efi_apply_memmap_quirks(void);
 extern int __init efi_reuse_config(u64 tables, int nr_tables);
 extern void efi_delete_dummy_variable(void);
-extern void efi_switch_mm(struct mm_struct *mm);
 extern void efi_recover_from_page_fault(unsigned long phys_addr);
 extern void efi_free_boot_services(void);
 
+void efi_enter_mm(void);
+void efi_leave_mm(void);
+
 /* kexec external ABI */
 struct efi_setup_data {
u64 fw_vendor;
diff --git a/arch/x86/platform/efi/efi_64.c b/arch/x86/platform/efi/efi_64.c
index 1d90418..62a6c86 100644
--- a/arch/x86/platform/efi/efi_64.c
+++ b/arch/x86/platform/efi/efi_64.c
@@ -54,10 +54,7 @@
  * 0x___ and limit EFI VA mapping space to 64G.
  */
 static u64 efi_va = EFI_VA_START;
-
-struct efi_scratch efi_scratch;
-
-EXPORT_SYMBOL_GPL(efi_mm);
+static struct mm_struct *efi_prev_mm;
 
 /*
  * We need our own copy of the higher levels of the page tables
@@ -481,11 +478,17 @@ void __init efi_dump_pagetable(void)
  * can not change under us.
  * It should be ensured that there are no concurent calls to this function.
  */
-void efi_switch_mm(struct mm_struct *mm)
+void efi_enter_mm(void)
+{
+   efi_prev_mm = current->active_mm;
+   current->active_mm = &efi_mm;
+   switch_mm(efi_prev_mm, &efi_mm, NULL);
+}
+
+void efi_leave_mm(void)
 {
-   efi_scratch.prev_mm = current->active_mm;
-   current->active_mm = mm;
-   switch_mm(efi_scratch.prev_mm, mm, NULL);
+   current->active_mm = efi_prev_mm;
+   switch_mm(&efi_mm, efi_prev_mm, NULL);
 }
 
 static DEFINE_SPINLOCK(efi_runtime_lock);
@@ -549,12 +552,12 @@ efi_thunk_set_virtual_address_map(unsigned long 
memory_map_size,
efi_sync_low_kernel_mappings();
local_irq_save(flags);
 
-   efi_switch_mm(&efi_mm);
+   efi_enter_mm();
 
status = __efi_thunk(set_virtual_address_map, memory_map_size,
 descriptor_size, descriptor_version, virtual_map);
 
-   efi_switch_mm(efi_scratch.prev_mm);
+   efi_leave_mm();
local_irq_restore(flags);
 
return status;
@

[tip: efi/core] efi: arm: force use of unsigned type for EFI_PHYS_ALIGN

2020-12-15 Thread tip-bot2 for Ard Biesheuvel
The following commit has been merged into the efi/core branch of tip:

Commit-ID: d72c8b0e1cacc39495cd413433d260e8ae59374a
Gitweb:
https://git.kernel.org/tip/d72c8b0e1cacc39495cd413433d260e8ae59374a
Author:Ard Biesheuvel 
AuthorDate:Sun, 13 Dec 2020 16:07:03 +01:00
Committer: Ard Biesheuvel 
CommitterDate: Mon, 14 Dec 2020 16:25:06 +01:00

efi: arm: force use of unsigned type for EFI_PHYS_ALIGN

Ensure that EFI_PHYS_ALIGN is an unsigned type, to prevent spurious
warnings from the type checks in the definition of the max() macro.

Link: https://lore.kernel.org/linux-efi/20201213151306.73558-1-a...@kernel.org
Signed-off-by: Ard Biesheuvel 
---
 arch/arm/include/asm/efi.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm/include/asm/efi.h b/arch/arm/include/asm/efi.h
index abae071..9de7ab2 100644
--- a/arch/arm/include/asm/efi.h
+++ b/arch/arm/include/asm/efi.h
@@ -71,7 +71,7 @@ static inline void efifb_setup_from_dmi(struct screen_info 
*si, const char *opt)
  * here throws off the memory allocation logic, so let's use the lowest power
  * of two greater than 2 MiB and greater than TEXT_OFFSET.
  */
-#define EFI_PHYS_ALIGN max(SZ_2M, roundup_pow_of_two(TEXT_OFFSET))
+#define EFI_PHYS_ALIGN max(UL(SZ_2M), roundup_pow_of_two(TEXT_OFFSET))
 
 /* on ARM, the initrd should be loaded in a lowmem region */
 static inline unsigned long efi_get_max_initrd_addr(unsigned long image_addr)


[tip: efi/core] efi: ia64: disable the capsule loader

2020-12-15 Thread tip-bot2 for Ard Biesheuvel
The following commit has been merged into the efi/core branch of tip:

Commit-ID: e0a6aa30504cb8179d07609fb6386705e8f00663
Gitweb:
https://git.kernel.org/tip/e0a6aa30504cb8179d07609fb6386705e8f00663
Author:Ard Biesheuvel 
AuthorDate:Sun, 13 Dec 2020 09:39:40 +01:00
Committer: Ard Biesheuvel 
CommitterDate: Mon, 14 Dec 2020 16:24:19 +01:00

efi: ia64: disable the capsule loader

EFI capsule loading is a feature that was introduced into EFI long after
its initial introduction on Itanium, and it is highly unlikely that IA64
systems are receiving firmware updates in the first place, let alone
using EFI capsules.

So let's disable capsule support altogether on IA64. This fixes a build
error on IA64 due to a recent change that added an unconditional
include of asm/efi.h, which IA64 does not provide.

While at it, tweak the make rules a bit so that the EFI capsule
component that is always builtin (even if the EFI capsule loader itself
is built as a module) is omitted for all architectures if the module is
not enabled in the build.

Cc: Tony Luck 
Link: https://lore.kernel.org/linux-efi/20201214152200.38353-1-a...@kernel.org
Signed-off-by: Ard Biesheuvel 
---
 drivers/firmware/efi/Kconfig  |  2 +-
 drivers/firmware/efi/Makefile |  5 -
 include/linux/efi.h   | 10 --
 3 files changed, 9 insertions(+), 8 deletions(-)

diff --git a/drivers/firmware/efi/Kconfig b/drivers/firmware/efi/Kconfig
index b452cfa..5ac2a37 100644
--- a/drivers/firmware/efi/Kconfig
+++ b/drivers/firmware/efi/Kconfig
@@ -147,7 +147,7 @@ config EFI_BOOTLOADER_CONTROL
 
 config EFI_CAPSULE_LOADER
tristate "EFI capsule loader"
-   depends on EFI
+   depends on EFI && !IA64
help
  This option exposes a loader interface "/dev/efi_capsule_loader" for
  users to load EFI capsules. This driver requires working runtime
diff --git a/drivers/firmware/efi/Makefile b/drivers/firmware/efi/Makefile
index d6ca2da..467e942 100644
--- a/drivers/firmware/efi/Makefile
+++ b/drivers/firmware/efi/Makefile
@@ -12,7 +12,10 @@ KASAN_SANITIZE_runtime-wrappers.o:= n
 
 obj-$(CONFIG_ACPI_BGRT)+= efi-bgrt.o
 obj-$(CONFIG_EFI)  += efi.o vars.o reboot.o memattr.o tpm.o
-obj-$(CONFIG_EFI)  += capsule.o memmap.o
+obj-$(CONFIG_EFI)  += memmap.o
+ifneq ($(CONFIG_EFI_CAPSULE_LOADER),)
+obj-$(CONFIG_EFI)  += capsule.o
+endif
 obj-$(CONFIG_EFI_PARAMS_FROM_FDT)  += fdtparams.o
 obj-$(CONFIG_EFI_VARS) += efivars.o
 obj-$(CONFIG_EFI_ESRT) += esrt.o
diff --git a/include/linux/efi.h b/include/linux/efi.h
index 1cd5d91..763b816 100644
--- a/include/linux/efi.h
+++ b/include/linux/efi.h
@@ -817,12 +817,6 @@ static inline bool efi_enabled(int feature)
 static inline void
 efi_reboot(enum reboot_mode reboot_mode, const char *__unused) {}
 
-static inline bool
-efi_capsule_pending(int *reset_type)
-{
-   return false;
-}
-
 static inline bool efi_soft_reserve_enabled(void)
 {
return false;
@@ -1038,6 +1032,7 @@ bool efivar_validate(efi_guid_t vendor, efi_char16_t 
*var_name, u8 *data,
 bool efivar_variable_is_removable(efi_guid_t vendor, const char *name,
  size_t len);
 
+#if IS_ENABLED(CONFIG_EFI_CAPSULE_LOADER)
 extern bool efi_capsule_pending(int *reset_type);
 
 extern int efi_capsule_supported(efi_guid_t guid, u32 flags,
@@ -1045,6 +1040,9 @@ extern int efi_capsule_supported(efi_guid_t guid, u32 
flags,
 
 extern int efi_capsule_update(efi_capsule_header_t *capsule,
  phys_addr_t *pages);
+#else
+static inline bool efi_capsule_pending(int *reset_type) { return false; }
+#endif
 
 #ifdef CONFIG_EFI_RUNTIME_MAP
 int efi_runtime_map_init(struct kobject *);


[tip: efi/core] efi: capsule: use atomic kmap for transient sglist mappings

2020-12-10 Thread tip-bot2 for Ard Biesheuvel
The following commit has been merged into the efi/core branch of tip:

Commit-ID: 91c1c092f27da4164d55ca81e0a483108f8a3235
Gitweb:
https://git.kernel.org/tip/91c1c092f27da4164d55ca81e0a483108f8a3235
Author:Ard Biesheuvel 
AuthorDate:Mon, 07 Dec 2020 17:33:33 +01:00
Committer: Ard Biesheuvel 
CommitterDate: Mon, 07 Dec 2020 19:31:43 +01:00

efi: capsule: use atomic kmap for transient sglist mappings

Don't use the heavy-weight kmap() API to create short-lived mappings
of the scatter-gather list entries that are released as soon as the
entries are written. Instead, use kmap_atomic(), which is more suited
to this purpose.

Signed-off-by: Ard Biesheuvel 
---
 drivers/firmware/efi/capsule.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/firmware/efi/capsule.c b/drivers/firmware/efi/capsule.c
index 598b780..43f6fe7 100644
--- a/drivers/firmware/efi/capsule.c
+++ b/drivers/firmware/efi/capsule.c
@@ -244,7 +244,7 @@ int efi_capsule_update(efi_capsule_header_t *capsule, 
phys_addr_t *pages)
for (i = 0; i < sg_count; i++) {
efi_capsule_block_desc_t *sglist;
 
-   sglist = kmap(sg_pages[i]);
+   sglist = kmap_atomic(sg_pages[i]);
 
for (j = 0; j < SGLIST_PER_PAGE && count > 0; j++) {
u64 sz = min_t(u64, imagesize,
@@ -265,7 +265,7 @@ int efi_capsule_update(efi_capsule_header_t *capsule, 
phys_addr_t *pages)
else
sglist[j].data = page_to_phys(sg_pages[i + 1]);
 
-   kunmap(sg_pages[i]);
+   kunmap_atomic(sglist);
}
 
mutex_lock(&capsule_mutex);


[tip: efi/core] efi: stub: get rid of efi_get_max_fdt_addr()

2020-12-10 Thread tip-bot2 for Ard Biesheuvel
The following commit has been merged into the efi/core branch of tip:

Commit-ID: 54649911f31b6e7c2a79a1426ca98259139e4c35
Gitweb:
https://git.kernel.org/tip/54649911f31b6e7c2a79a1426ca98259139e4c35
Author:Ard Biesheuvel 
AuthorDate:Thu, 29 Oct 2020 14:49:01 +01:00
Committer: Ard Biesheuvel 
CommitterDate: Wed, 09 Dec 2020 08:37:27 +01:00

efi: stub: get rid of efi_get_max_fdt_addr()

Now that ARM started following the example of arm64 and RISC-V, and
no longer imposes any restrictions on the placement of the FDT in
memory at boot, we no longer need per-arch implementations of
efi_get_max_fdt_addr() to factor out the differences. So get rid of
it.

Signed-off-by: Ard Biesheuvel 
Reviewed-by: Atish Patra 
Link: https://lore.kernel.org/r/20201029134901.9773-1-a...@kernel.org
---
 arch/arm/include/asm/efi.h  | 6 --
 arch/arm64/include/asm/efi.h| 6 --
 arch/riscv/include/asm/efi.h| 6 --
 drivers/firmware/efi/libstub/efi-stub.c | 1 -
 drivers/firmware/efi/libstub/efistub.h  | 1 -
 drivers/firmware/efi/libstub/fdt.c  | 3 +--
 6 files changed, 1 insertion(+), 22 deletions(-)

diff --git a/arch/arm/include/asm/efi.h b/arch/arm/include/asm/efi.h
index 1536805..abae071 100644
--- a/arch/arm/include/asm/efi.h
+++ b/arch/arm/include/asm/efi.h
@@ -73,12 +73,6 @@ static inline void efifb_setup_from_dmi(struct screen_info 
*si, const char *opt)
  */
 #define EFI_PHYS_ALIGN max(SZ_2M, roundup_pow_of_two(TEXT_OFFSET))
 
-/* on ARM, the FDT should be located in a lowmem region */
-static inline unsigned long efi_get_max_fdt_addr(unsigned long image_addr)
-{
-   return round_down(image_addr, EFI_PHYS_ALIGN) + SZ_512M;
-}
-
 /* on ARM, the initrd should be loaded in a lowmem region */
 static inline unsigned long efi_get_max_initrd_addr(unsigned long image_addr)
 {
diff --git a/arch/arm64/include/asm/efi.h b/arch/arm64/include/asm/efi.h
index 00bd1e1..3578aba 100644
--- a/arch/arm64/include/asm/efi.h
+++ b/arch/arm64/include/asm/efi.h
@@ -64,12 +64,6 @@ efi_status_t __efi_rt_asm_wrapper(void *, const char *, ...);
 #define EFI_KIMG_ALIGN \
(SEGMENT_ALIGN > THREAD_ALIGN ? SEGMENT_ALIGN : THREAD_ALIGN)
 
-/* on arm64, the FDT may be located anywhere in system RAM */
-static inline unsigned long efi_get_max_fdt_addr(unsigned long image_addr)
-{
-   return ULONG_MAX;
-}
-
 /*
  * On arm64, we have to ensure that the initrd ends up in the linear region,
  * which is a 1 GB aligned region of size '1UL << (VA_BITS_MIN - 1)' that is
diff --git a/arch/riscv/include/asm/efi.h b/arch/riscv/include/asm/efi.h
index 7542282..6d98cd9 100644
--- a/arch/riscv/include/asm/efi.h
+++ b/arch/riscv/include/asm/efi.h
@@ -27,12 +27,6 @@ int efi_set_mapping_permissions(struct mm_struct *mm, 
efi_memory_desc_t *md);
 
 #define ARCH_EFI_IRQ_FLAGS_MASK (SR_IE | SR_SPIE)
 
-/* on RISC-V, the FDT may be located anywhere in system RAM */
-static inline unsigned long efi_get_max_fdt_addr(unsigned long image_addr)
-{
-   return ULONG_MAX;
-}
-
 /* Load initrd at enough distance from DRAM start */
 static inline unsigned long efi_get_max_initrd_addr(unsigned long image_addr)
 {
diff --git a/drivers/firmware/efi/libstub/efi-stub.c 
b/drivers/firmware/efi/libstub/efi-stub.c
index 914a343..ec2f398 100644
--- a/drivers/firmware/efi/libstub/efi-stub.c
+++ b/drivers/firmware/efi/libstub/efi-stub.c
@@ -273,7 +273,6 @@ efi_status_t __efiapi efi_pe_entry(efi_handle_t handle,
install_memreserve_table();
 
status = allocate_new_fdt_and_exit_boot(handle, &fdt_addr,
-   
efi_get_max_fdt_addr(image_addr),
initrd_addr, initrd_size,
cmdline_ptr, fdt_addr, 
fdt_size);
if (status != EFI_SUCCESS)
diff --git a/drivers/firmware/efi/libstub/efistub.h 
b/drivers/firmware/efi/libstub/efistub.h
index b8ec29d..b50a6c6 100644
--- a/drivers/firmware/efi/libstub/efistub.h
+++ b/drivers/firmware/efi/libstub/efistub.h
@@ -750,7 +750,6 @@ efi_status_t efi_exit_boot_services(void *handle,
 
 efi_status_t allocate_new_fdt_and_exit_boot(void *handle,
unsigned long *new_fdt_addr,
-   unsigned long max_addr,
u64 initrd_addr, u64 initrd_size,
char *cmdline_ptr,
unsigned long fdt_addr,
diff --git a/drivers/firmware/efi/libstub/fdt.c 
b/drivers/firmware/efi/libstub/fdt.c
index 368cd60..365c3a4 100644
--- a/drivers/firmware/efi/libstub/fdt.c
+++ b/drivers/firmware/efi/libstub/fdt.c
@@ -238,7 +238,6 @@ static efi_status_t exit_boot_func(struct efi_boot_memmap 
*map,
 
 efi_status_t allocate_new_fdt_and_exit_boot(void *handle,
unsigned long *new_fdt_addr,
-   

[tip: efi/core] efi: capsule: clean scatter-gather entries from the D-cache

2020-12-10 Thread tip-bot2 for Ard Biesheuvel
The following commit has been merged into the efi/core branch of tip:

Commit-ID: 4dbe44fb538c59a4adae5abfa9ded2f310250315
Gitweb:
https://git.kernel.org/tip/4dbe44fb538c59a4adae5abfa9ded2f310250315
Author:Ard Biesheuvel 
AuthorDate:Mon, 07 Dec 2020 18:40:53 +01:00
Committer: Ard Biesheuvel 
CommitterDate: Wed, 09 Dec 2020 08:37:27 +01:00

efi: capsule: clean scatter-gather entries from the D-cache

Scatter-gather lists passed to UpdateCapsule() should be cleaned
from the D-cache to ensure that they are visible to the CPU after a
warm reboot before the MMU is enabled. On ARM and arm64 systems, this
implies a D-cache clean by virtual address to the point of coherency.

However, due to the fact that the firmware itself is not able to map
physical addresses back to virtual addresses when running under the OS,
this must be done by the caller.

Signed-off-by: Ard Biesheuvel 
---
 arch/arm/include/asm/efi.h |  5 +
 arch/arm64/include/asm/efi.h   |  5 +
 drivers/firmware/efi/capsule.c | 12 
 3 files changed, 22 insertions(+)

diff --git a/arch/arm/include/asm/efi.h b/arch/arm/include/asm/efi.h
index 3ee4f43..e9a06e1 100644
--- a/arch/arm/include/asm/efi.h
+++ b/arch/arm/include/asm/efi.h
@@ -93,4 +93,9 @@ struct efi_arm_entry_state {
u32 sctlr_after_ebs;
 };
 
+static inline void efi_capsule_flush_cache_range(void *addr, int size)
+{
+   __cpuc_flush_dcache_area(addr, size);
+}
+
 #endif /* _ASM_ARM_EFI_H */
diff --git a/arch/arm64/include/asm/efi.h b/arch/arm64/include/asm/efi.h
index 973b144..00bd1e1 100644
--- a/arch/arm64/include/asm/efi.h
+++ b/arch/arm64/include/asm/efi.h
@@ -141,4 +141,9 @@ static inline void efi_set_pgd(struct mm_struct *mm)
 void efi_virtmap_load(void);
 void efi_virtmap_unload(void);
 
+static inline void efi_capsule_flush_cache_range(void *addr, int size)
+{
+   __flush_dcache_area(addr, size);
+}
+
 #endif /* _ASM_EFI_H */
diff --git a/drivers/firmware/efi/capsule.c b/drivers/firmware/efi/capsule.c
index 43f6fe7..7684302 100644
--- a/drivers/firmware/efi/capsule.c
+++ b/drivers/firmware/efi/capsule.c
@@ -12,6 +12,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 
 typedef struct {
@@ -265,6 +266,17 @@ int efi_capsule_update(efi_capsule_header_t *capsule, 
phys_addr_t *pages)
else
sglist[j].data = page_to_phys(sg_pages[i + 1]);
 
+#if defined(CONFIG_ARM) || defined(CONFIG_ARM64)
+   /*
+* At runtime, the firmware has no way to find out where the
+* sglist elements are mapped, if they are mapped in the first
+* place. Therefore, on architectures that can only perform
+* cache maintenance by virtual address, the firmware is unable
+* to perform this maintenance, and so it is up to the OS to do
+* it instead.
+*/
+   efi_capsule_flush_cache_range(sglist, PAGE_SIZE);
+#endif
kunmap_atomic(sglist);
}
 


[tip: efi/core] efi: arm: reduce minimum alignment of uncompressed kernel

2020-12-10 Thread tip-bot2 for Ard Biesheuvel
The following commit has been merged into the efi/core branch of tip:

Commit-ID: c0249238feefbbb99d517d06ace4338393901b67
Gitweb:
https://git.kernel.org/tip/c0249238feefbbb99d517d06ace4338393901b67
Author:Ard Biesheuvel 
AuthorDate:Thu, 12 Nov 2020 15:42:27 +01:00
Committer: Ard Biesheuvel 
CommitterDate: Wed, 09 Dec 2020 08:37:27 +01:00

efi: arm: reduce minimum alignment of uncompressed kernel

Now that we reduced the minimum relative alignment between PHYS_OFFSET
and PAGE_OFFSET to 2 MiB, we can take this into account when allocating
memory for the decompressed kernel when booting via EFI. This minimizes
the amount of unusable memory we may end up with due to the base of DRAM
being occupied by firmware.

Signed-off-by: Ard Biesheuvel 
---
 arch/arm/include/asm/efi.h | 13 ++---
 1 file changed, 6 insertions(+), 7 deletions(-)

diff --git a/arch/arm/include/asm/efi.h b/arch/arm/include/asm/efi.h
index e9a06e1..1536805 100644
--- a/arch/arm/include/asm/efi.h
+++ b/arch/arm/include/asm/efi.h
@@ -66,13 +66,12 @@ static inline void efifb_setup_from_dmi(struct screen_info 
*si, const char *opt)
 #define MAX_UNCOMP_KERNEL_SIZE SZ_32M
 
 /*
- * phys-to-virt patching requires that the physical to virtual offset fits
- * into the immediate field of an add/sub instruction, which comes down to the
- * 24 least significant bits being zero, and so the offset should be a multiple
- * of 16 MB. Since PAGE_OFFSET itself is a multiple of 16 MB, the physical
- * base should be aligned to 16 MB as well.
+ * phys-to-virt patching requires that the physical to virtual offset is a
+ * multiple of 2 MiB. However, using an alignment smaller than TEXT_OFFSET
+ * here throws off the memory allocation logic, so let's use the lowest power
+ * of two greater than 2 MiB and greater than TEXT_OFFSET.
  */
-#define EFI_PHYS_ALIGN SZ_16M
+#define EFI_PHYS_ALIGN max(SZ_2M, roundup_pow_of_two(TEXT_OFFSET))
 
 /* on ARM, the FDT should be located in a lowmem region */
 static inline unsigned long efi_get_max_fdt_addr(unsigned long image_addr)
@@ -83,7 +82,7 @@ static inline unsigned long efi_get_max_fdt_addr(unsigned 
long image_addr)
 /* on ARM, the initrd should be loaded in a lowmem region */
 static inline unsigned long efi_get_max_initrd_addr(unsigned long image_addr)
 {
-   return round_down(image_addr, EFI_PHYS_ALIGN) + SZ_512M;
+   return round_down(image_addr, SZ_4M) + SZ_512M;
 }
 
 struct efi_arm_entry_state {


[tip: efi/urgent] efivarfs: revert "fix memory leak in efivarfs_create()"

2020-11-27 Thread tip-bot2 for Ard Biesheuvel
The following commit has been merged into the efi/urgent branch of tip:

Commit-ID: ff04f3b6f2e27f8ae28a498416af2a8dd5072b43
Gitweb:
https://git.kernel.org/tip/ff04f3b6f2e27f8ae28a498416af2a8dd5072b43
Author:Ard Biesheuvel 
AuthorDate:Wed, 25 Nov 2020 08:45:55 +01:00
Committer: Ard Biesheuvel 
CommitterDate: Wed, 25 Nov 2020 16:55:02 +01:00

efivarfs: revert "fix memory leak in efivarfs_create()"

The memory leak addressed by commit fe5186cf12e3 is a false positive:
all allocations are recorded in a linked list, and freed when the
filesystem is unmounted. This leads to double frees, and as reported
by David, leads to crashes if SLUB is configured to self destruct when
double frees occur.

So drop the redundant kfree() again, and instead, mark the offending
pointer variable so the allocation is ignored by kmemleak.

Cc: Vamshi K Sthambamkadi 
Fixes: fe5186cf12e3 ("efivarfs: fix memory leak in efivarfs_create()")
Reported-by: David Laight 
Signed-off-by: Ard Biesheuvel 
---
 fs/efivarfs/inode.c | 2 ++
 fs/efivarfs/super.c | 1 -
 2 files changed, 2 insertions(+), 1 deletion(-)

diff --git a/fs/efivarfs/inode.c b/fs/efivarfs/inode.c
index 96c0c86..0297ad9 100644
--- a/fs/efivarfs/inode.c
+++ b/fs/efivarfs/inode.c
@@ -7,6 +7,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 
@@ -103,6 +104,7 @@ static int efivarfs_create(struct inode *dir, struct dentry 
*dentry,
var->var.VariableName[i] = '\0';
 
inode->i_private = var;
+   kmemleak_ignore(var);
 
err = efivar_entry_add(var, &efivarfs_list);
if (err)
diff --git a/fs/efivarfs/super.c b/fs/efivarfs/super.c
index f943fd0..15880a6 100644
--- a/fs/efivarfs/super.c
+++ b/fs/efivarfs/super.c
@@ -21,7 +21,6 @@ LIST_HEAD(efivarfs_list);
 static void efivarfs_evict_inode(struct inode *inode)
 {
clear_inode(inode);
-   kfree(inode->i_private);
 }
 
 static const struct super_operations efivarfs_ops = {


[tip: efi/core] efi: x86/xen: switch to efi_get_secureboot_mode helper

2020-11-17 Thread tip-bot2 for Ard Biesheuvel
The following commit has been merged into the efi/core branch of tip:

Commit-ID: b283477d394ac41ca59ee20eb9293ae9002eb1d7
Gitweb:
https://git.kernel.org/tip/b283477d394ac41ca59ee20eb9293ae9002eb1d7
Author:Ard Biesheuvel 
AuthorDate:Tue, 03 Nov 2020 07:50:04 +01:00
Committer: Ard Biesheuvel 
CommitterDate: Tue, 17 Nov 2020 15:09:32 +01:00

efi: x86/xen: switch to efi_get_secureboot_mode helper

Now that we have a static inline helper to discover the platform's secure
boot mode that can be shared between the EFI stub and the kernel proper,
switch to it, and drop some comments about keeping them in sync manually.

Signed-off-by: Ard Biesheuvel 
---
 arch/x86/xen/efi.c| 37 +-
 drivers/firmware/efi/libstub/secureboot.c |  3 +--
 2 files changed, 9 insertions(+), 31 deletions(-)

diff --git a/arch/x86/xen/efi.c b/arch/x86/xen/efi.c
index 205a9bc..7d7ffb9 100644
--- a/arch/x86/xen/efi.c
+++ b/arch/x86/xen/efi.c
@@ -93,37 +93,22 @@ static efi_system_table_t __init *xen_efi_probe(void)
 
 /*
  * Determine whether we're in secure boot mode.
- *
- * Please keep the logic in sync with
- * drivers/firmware/efi/libstub/secureboot.c:efi_get_secureboot().
  */
 static enum efi_secureboot_mode xen_efi_get_secureboot(void)
 {
-   static efi_guid_t efi_variable_guid = EFI_GLOBAL_VARIABLE_GUID;
static efi_guid_t shim_guid = EFI_SHIM_LOCK_GUID;
+   enum efi_secureboot_mode mode;
efi_status_t status;
-   u8 moksbstate, secboot, setupmode;
+   u8 moksbstate;
unsigned long size;
 
-   size = sizeof(secboot);
-   status = efi.get_variable(L"SecureBoot", &efi_variable_guid,
- NULL, &size, &secboot);
-
-   if (status == EFI_NOT_FOUND)
-   return efi_secureboot_mode_disabled;
-
-   if (status != EFI_SUCCESS)
-   goto out_efi_err;
-
-   size = sizeof(setupmode);
-   status = efi.get_variable(L"SetupMode", &efi_variable_guid,
- NULL, &size, &setupmode);
-
-   if (status != EFI_SUCCESS)
-   goto out_efi_err;
-
-   if (secboot == 0 || setupmode == 1)
-   return efi_secureboot_mode_disabled;
+   mode = efi_get_secureboot_mode(efi.get_variable);
+   if (mode == efi_secureboot_mode_unknown) {
+   pr_err("Could not determine UEFI Secure Boot status.\n");
+   return efi_secureboot_mode_unknown;
+   }
+   if (mode != efi_secureboot_mode_enabled)
+   return mode;
 
/* See if a user has put the shim into insecure mode. */
size = sizeof(moksbstate);
@@ -140,10 +125,6 @@ static enum efi_secureboot_mode 
xen_efi_get_secureboot(void)
  secure_boot_enabled:
pr_info("UEFI Secure Boot is enabled.\n");
return efi_secureboot_mode_enabled;
-
- out_efi_err:
-   pr_err("Could not determine UEFI Secure Boot status.\n");
-   return efi_secureboot_mode_unknown;
 }
 
 void __init xen_efi_init(struct boot_params *boot_params)
diff --git a/drivers/firmware/efi/libstub/secureboot.c 
b/drivers/firmware/efi/libstub/secureboot.c
index af18d86..8a18930 100644
--- a/drivers/firmware/efi/libstub/secureboot.c
+++ b/drivers/firmware/efi/libstub/secureboot.c
@@ -24,9 +24,6 @@ static efi_status_t get_var(efi_char16_t *name, efi_guid_t 
*vendor, u32 *attr,
 
 /*
  * Determine whether we're in secure boot mode.
- *
- * Please keep the logic in sync with
- * arch/x86/xen/efi.c:xen_efi_get_secureboot().
  */
 enum efi_secureboot_mode efi_get_secureboot(void)
 {


[tip: efi/urgent] efi/arm: set HSCTLR Thumb2 bit correctly for HVC calls from HYP

2020-11-17 Thread tip-bot2 for Ard Biesheuvel
The following commit has been merged into the efi/urgent branch of tip:

Commit-ID: fbc81ec5b85d43a4b22e49ec0e643fa7dec2ea40
Gitweb:
https://git.kernel.org/tip/fbc81ec5b85d43a4b22e49ec0e643fa7dec2ea40
Author:Ard Biesheuvel 
AuthorDate:Sat, 03 Oct 2020 17:28:27 +02:00
Committer: Ard Biesheuvel 
CommitterDate: Mon, 26 Oct 2020 08:02:11 +01:00

efi/arm: set HSCTLR Thumb2 bit correctly for HVC calls from HYP

Commit

  db227c19e68db353 ("ARM: 8985/1: efi/decompressor: deal with HYP mode boot 
gracefully")

updated the EFI entry code to permit firmware to invoke the EFI stub
loader in HYP mode, with the MMU either enabled or disabled, neither
of which is permitted by the EFI spec, but which does happen in the
field.

In the MMU on case, we remain in HYP mode as configured by the firmware,
and rely on the fact that any HVC instruction issued in this mode will
be dispatched via the SVC slot in the HYP vector table. However, this
slot will point to a Thumb2 symbol if the kernel is built in Thumb2
mode, and so we have to configure HSCTLR to ensure that the exception
handlers are invoked in Thumb2 mode as well.

Fixes: db227c19e68db353 ("ARM: 8985/1: efi/decompressor: deal with HYP mode 
boot gracefully")
Signed-off-by: Ard Biesheuvel 
---
 arch/arm/boot/compressed/head.S | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/arch/arm/boot/compressed/head.S b/arch/arm/boot/compressed/head.S
index 2e04ec5..caa2732 100644
--- a/arch/arm/boot/compressed/head.S
+++ b/arch/arm/boot/compressed/head.S
@@ -1472,6 +1472,9 @@ ENTRY(efi_enter_kernel)
@ issued from HYP mode take us to the correct handler code. We
@ will disable the MMU before jumping to the kernel proper.
@
+ ARM(  bic r1, r1, #(1 << 30)  ) @ clear HSCTLR.TE
+ THUMB(orr r1, r1, #(1 << 30)  ) @ set HSCTLR.TE
+   mcr p15, 4, r1, c1, c0, 0
adr r0, __hyp_reentry_vectors
mcr p15, 4, r0, c12, c0, 0  @ set HYP vector base (HVBAR)
isb


[tip: efi/core] efi: mokvar: add missing include of asm/early_ioremap.h

2020-10-10 Thread tip-bot2 for Ard Biesheuvel
The following commit has been merged into the efi/core branch of tip:

Commit-ID: cc383a9e245c527d3175e2cf4cced9dbbedbbac6
Gitweb:
https://git.kernel.org/tip/cc383a9e245c527d3175e2cf4cced9dbbedbbac6
Author:Ard Biesheuvel 
AuthorDate:Fri, 02 Oct 2020 10:01:23 +02:00
Committer: Ard Biesheuvel 
CommitterDate: Fri, 02 Oct 2020 10:08:29 +02:00

efi: mokvar: add missing include of asm/early_ioremap.h

Nathan reports that building the new mokvar table code for 32-bit
ARM fails with errors such as

  error: implicit declaration of function 'early_memunmap'
  error: implicit declaration of function 'early_memremap'

This is caused by the lack of an explicit #include of the appropriate
header, and ARM apparently does not inherit that inclusion via another
header file. So add the #include.

Tested-by: Nathan Chancellor 
Signed-off-by: Ard Biesheuvel 
---
 drivers/firmware/efi/mokvar-table.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/firmware/efi/mokvar-table.c 
b/drivers/firmware/efi/mokvar-table.c
index 72a9e17..d8bc013 100644
--- a/drivers/firmware/efi/mokvar-table.c
+++ b/drivers/firmware/efi/mokvar-table.c
@@ -40,6 +40,8 @@
 #include 
 #include 
 
+#include 
+
 /*
  * The LINUX_EFI_MOK_VARIABLE_TABLE_GUID config table is a packed
  * sequence of struct efi_mokvar_table_entry, one for each named


[tip: efi/urgent] efi: Add definition of EFI_MEMORY_CPU_CRYPTO and ability to report it

2020-09-29 Thread tip-bot2 for Ard Biesheuvel
The following commit has been merged into the efi/urgent branch of tip:

Commit-ID: 6277e374b0b07c1a93c829f0a27e38739b3b7a1b
Gitweb:
https://git.kernel.org/tip/6277e374b0b07c1a93c829f0a27e38739b3b7a1b
Author:Ard Biesheuvel 
AuthorDate:Thu, 24 Sep 2020 13:52:24 +02:00
Committer: Ard Biesheuvel 
CommitterDate: Fri, 25 Sep 2020 23:29:04 +02:00

efi: Add definition of EFI_MEMORY_CPU_CRYPTO and ability to report it

Incorporate the definition of EFI_MEMORY_CPU_CRYPTO from the UEFI
specification v2.8, and wire it into our memory map dumping routine
as well.

To make a bit of space in the output buffer, which is provided by
the various callers, shorten the descriptive names of the memory
types.

Reviewed-by: Laszlo Ersek 
Signed-off-by: Ard Biesheuvel 
---
 drivers/firmware/efi/efi.c | 47 ++---
 include/linux/efi.h|  1 +-
 2 files changed, 25 insertions(+), 23 deletions(-)

diff --git a/drivers/firmware/efi/efi.c b/drivers/firmware/efi/efi.c
index 3aa07c3..ebb59e5 100644
--- a/drivers/firmware/efi/efi.c
+++ b/drivers/firmware/efi/efi.c
@@ -714,7 +714,7 @@ void __init efi_systab_report_header(const efi_table_hdr_t 
*systab_hdr,
vendor);
 }
 
-static __initdata char memory_type_name[][20] = {
+static __initdata char memory_type_name[][13] = {
"Reserved",
"Loader Code",
"Loader Data",
@@ -722,14 +722,14 @@ static __initdata char memory_type_name[][20] = {
"Boot Data",
"Runtime Code",
"Runtime Data",
-   "Conventional Memory",
-   "Unusable Memory",
-   "ACPI Reclaim Memory",
-   "ACPI Memory NVS",
-   "Memory Mapped I/O",
-   "MMIO Port Space",
+   "Conventional",
+   "Unusable",
+   "ACPI Reclaim",
+   "ACPI Mem NVS",
+   "MMIO",
+   "MMIO Port",
"PAL Code",
-   "Persistent Memory",
+   "Persistent",
 };
 
 char * __init efi_md_typeattr_format(char *buf, size_t size,
@@ -756,26 +756,27 @@ char * __init efi_md_typeattr_format(char *buf, size_t 
size,
if (attr & ~(EFI_MEMORY_UC | EFI_MEMORY_WC | EFI_MEMORY_WT |
 EFI_MEMORY_WB | EFI_MEMORY_UCE | EFI_MEMORY_RO |
 EFI_MEMORY_WP | EFI_MEMORY_RP | EFI_MEMORY_XP |
-EFI_MEMORY_NV | EFI_MEMORY_SP |
+EFI_MEMORY_NV | EFI_MEMORY_SP | EFI_MEMORY_CPU_CRYPTO |
 EFI_MEMORY_RUNTIME | EFI_MEMORY_MORE_RELIABLE))
snprintf(pos, size, "|attr=0x%016llx]",
 (unsigned long long)attr);
else
snprintf(pos, size,
-
"|%3s|%2s|%2s|%2s|%2s|%2s|%2s|%2s|%3s|%2s|%2s|%2s|%2s]",
-attr & EFI_MEMORY_RUNTIME ? "RUN" : "",
-attr & EFI_MEMORY_MORE_RELIABLE ? "MR" : "",
-attr & EFI_MEMORY_SP  ? "SP"  : "",
-attr & EFI_MEMORY_NV  ? "NV"  : "",
-attr & EFI_MEMORY_XP  ? "XP"  : "",
-attr & EFI_MEMORY_RP  ? "RP"  : "",
-attr & EFI_MEMORY_WP  ? "WP"  : "",
-attr & EFI_MEMORY_RO  ? "RO"  : "",
-attr & EFI_MEMORY_UCE ? "UCE" : "",
-attr & EFI_MEMORY_WB  ? "WB"  : "",
-attr & EFI_MEMORY_WT  ? "WT"  : "",
-attr & EFI_MEMORY_WC  ? "WC"  : "",
-attr & EFI_MEMORY_UC  ? "UC"  : "");
+
"|%3s|%2s|%2s|%2s|%2s|%2s|%2s|%2s|%2s|%3s|%2s|%2s|%2s|%2s]",
+attr & EFI_MEMORY_RUNTIME  ? "RUN" : "",
+attr & EFI_MEMORY_MORE_RELIABLE? "MR"  : "",
+attr & EFI_MEMORY_CPU_CRYPTO   ? "CC"  : "",
+attr & EFI_MEMORY_SP   ? "SP"  : "",
+attr & EFI_MEMORY_NV   ? "NV"  : "",
+attr & EFI_MEMORY_XP   ? "XP"  : "",
+attr & EFI_MEMORY_RP   ? "RP"  : "",
+attr & EFI_MEMORY_WP   ? "WP"  : "",
+attr & EFI_MEMORY_RO   ? "RO"  : "",
+attr & EFI_MEMORY_UCE  ? "UCE" : "",
+attr & EFI_MEMORY_WB   ? "WB"  : "",
+attr & EFI_MEMORY_WT   ? "WT"  : "",
+attr & EFI_MEMORY_WC   ? "WC"  : "",
+attr & EFI_MEMORY_UC   ? "UC"  : "");
return buf;
 }
 
diff --git a/include/linux/efi.h b/include/linux/efi.h
index 73db1ae..f216c02 100644
--- a/include/linux/efi.h
+++ b/include/linux/efi.h
@@ -122,6 +122,7 @@ typedef struct {
((u64)0x0

[tip: efi/urgent] efi/arm64: libstub: Deal gracefully with EFI_RNG_PROTOCOL failure

2020-09-29 Thread tip-bot2 for Ard Biesheuvel
The following commit has been merged into the efi/urgent branch of tip:

Commit-ID: d32de9130f6c79533508e2c7879f18997bfbe2a0
Gitweb:
https://git.kernel.org/tip/d32de9130f6c79533508e2c7879f18997bfbe2a0
Author:Ard Biesheuvel 
AuthorDate:Sat, 26 Sep 2020 10:52:42 +02:00
Committer: Ard Biesheuvel 
CommitterDate: Tue, 29 Sep 2020 15:41:52 +02:00

efi/arm64: libstub: Deal gracefully with EFI_RNG_PROTOCOL failure

Currently, on arm64, we abort on any failure from efi_get_random_bytes()
other than EFI_NOT_FOUND when it comes to setting the physical seed for
KASLR, but ignore such failures when obtaining the seed for virtual
KASLR or for early seeding of the kernel's entropy pool via the config
table. This is inconsistent, and may lead to unexpected boot failures.

So let's permit any failure for the physical seed, and simply report
the error code if it does not equal EFI_NOT_FOUND.

Cc:  # v5.8+
Reported-by: Heinrich Schuchardt 
Signed-off-by: Ard Biesheuvel 
---
 drivers/firmware/efi/libstub/arm64-stub.c | 8 +---
 drivers/firmware/efi/libstub/fdt.c| 4 +---
 2 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/drivers/firmware/efi/libstub/arm64-stub.c 
b/drivers/firmware/efi/libstub/arm64-stub.c
index e5bfac7..04f5d79 100644
--- a/drivers/firmware/efi/libstub/arm64-stub.c
+++ b/drivers/firmware/efi/libstub/arm64-stub.c
@@ -62,10 +62,12 @@ efi_status_t handle_kernel_image(unsigned long *image_addr,
status = efi_get_random_bytes(sizeof(phys_seed),
  (u8 *)&phys_seed);
if (status == EFI_NOT_FOUND) {
-   efi_info("EFI_RNG_PROTOCOL unavailable, no 
randomness supplied\n");
+   efi_info("EFI_RNG_PROTOCOL unavailable, KASLR 
will be disabled\n");
+   efi_nokaslr = true;
} else if (status != EFI_SUCCESS) {
-   efi_err("efi_get_random_bytes() failed\n");
-   return status;
+   efi_err("efi_get_random_bytes() failed (0x%lx), 
KASLR will be disabled\n",
+   status);
+   efi_nokaslr = true;
}
} else {
efi_info("KASLR disabled on kernel command line\n");
diff --git a/drivers/firmware/efi/libstub/fdt.c 
b/drivers/firmware/efi/libstub/fdt.c
index 11ecf3c..368cd60 100644
--- a/drivers/firmware/efi/libstub/fdt.c
+++ b/drivers/firmware/efi/libstub/fdt.c
@@ -136,7 +136,7 @@ static efi_status_t update_fdt(void *orig_fdt, unsigned 
long orig_fdt_size,
if (status)
goto fdt_set_fail;
 
-   if (IS_ENABLED(CONFIG_RANDOMIZE_BASE)) {
+   if (IS_ENABLED(CONFIG_RANDOMIZE_BASE) && !efi_nokaslr) {
efi_status_t efi_status;
 
efi_status = efi_get_random_bytes(sizeof(fdt_val64),
@@ -145,8 +145,6 @@ static efi_status_t update_fdt(void *orig_fdt, unsigned 
long orig_fdt_size,
status = fdt_setprop_var(fdt, node, "kaslr-seed", 
fdt_val64);
if (status)
goto fdt_set_fail;
-   } else if (efi_status != EFI_NOT_FOUND) {
-   return efi_status;
}
}
 


[tip: efi/core] efi: pstore: disentangle from deprecated efivars module

2020-09-29 Thread tip-bot2 for Ard Biesheuvel
The following commit has been merged into the efi/core branch of tip:

Commit-ID: 232f4eb6393f42f7f9418560ae9228e747fc6faf
Gitweb:
https://git.kernel.org/tip/232f4eb6393f42f7f9418560ae9228e747fc6faf
Author:Ard Biesheuvel 
AuthorDate:Wed, 23 Sep 2020 09:56:14 +02:00
Committer: Ard Biesheuvel 
CommitterDate: Tue, 29 Sep 2020 19:40:57 +02:00

efi: pstore: disentangle from deprecated efivars module

The EFI pstore implementation relies on the 'efivars' abstraction,
which encapsulates the EFI variable store in a way that can be
overridden by other backing stores, like the Google SMI one.

On top of that, the EFI pstore implementation also relies on the
efivars.ko module, which is a separate layer built on top of the
'efivars' abstraction that exposes the [deprecated] sysfs entries
for each variable that exists in the backing store.

Since the efivars.ko module is deprecated, and all users appear to
have moved to the efivarfs file system instead, let's prepare for
its removal, by removing EFI pstore's dependency on it.

Signed-off-by: Ard Biesheuvel 
---
 drivers/firmware/efi/Kconfig  |  2 +-
 drivers/firmware/efi/efi-pstore.c | 76 --
 drivers/firmware/efi/efivars.c| 41 +
 include/linux/efi.h   |  4 +--
 4 files changed, 74 insertions(+), 49 deletions(-)

diff --git a/drivers/firmware/efi/Kconfig b/drivers/firmware/efi/Kconfig
index 3939699..dd8d108 100644
--- a/drivers/firmware/efi/Kconfig
+++ b/drivers/firmware/efi/Kconfig
@@ -26,7 +26,7 @@ config EFI_ESRT
 
 config EFI_VARS_PSTORE
tristate "Register efivars backend for pstore"
-   depends on EFI_VARS && PSTORE
+   depends on PSTORE
default y
help
  Say Y here to enable use efivars as a backend to pstore. This
diff --git a/drivers/firmware/efi/efi-pstore.c 
b/drivers/firmware/efi/efi-pstore.c
index feb7fe6..785f5e6 100644
--- a/drivers/firmware/efi/efi-pstore.c
+++ b/drivers/firmware/efi/efi-pstore.c
@@ -8,6 +8,8 @@
 
 #define DUMP_NAME_LEN 66
 
+#define EFIVARS_DATA_SIZE_MAX 1024
+
 static bool efivars_pstore_disable =
IS_ENABLED(CONFIG_EFI_VARS_PSTORE_DEFAULT_DISABLE);
 
@@ -18,6 +20,8 @@ module_param_named(pstore_disable, efivars_pstore_disable, 
bool, 0644);
 EFI_VARIABLE_BOOTSERVICE_ACCESS | \
 EFI_VARIABLE_RUNTIME_ACCESS)
 
+static LIST_HEAD(efi_pstore_list);
+
 static int efi_pstore_open(struct pstore_info *psi)
 {
psi->data = NULL;
@@ -126,7 +130,7 @@ static inline int __efi_pstore_scan_sysfs_exit(struct 
efivar_entry *entry,
if (entry->deleting) {
list_del(&entry->list);
efivar_entry_iter_end();
-   efivar_unregister(entry);
+   kfree(entry);
if (efivar_entry_iter_begin())
return -EINTR;
} else if (turn_off_scanning)
@@ -169,7 +173,7 @@ static int efi_pstore_sysfs_entry_iter(struct pstore_record 
*record)
 {
struct efivar_entry **pos = (struct efivar_entry **)&record->psi->data;
struct efivar_entry *entry, *n;
-   struct list_head *head = &efivar_sysfs_list;
+   struct list_head *head = &efi_pstore_list;
int size = 0;
int ret;
 
@@ -314,12 +318,12 @@ static int efi_pstore_erase_name(const char *name)
if (efivar_entry_iter_begin())
return -EINTR;
 
-   found = __efivar_entry_iter(efi_pstore_erase_func, &efivar_sysfs_list,
+   found = __efivar_entry_iter(efi_pstore_erase_func, &efi_pstore_list,
efi_name, &entry);
efivar_entry_iter_end();
 
if (found && !entry->scanning)
-   efivar_unregister(entry);
+   kfree(entry);
 
return found ? 0 : -ENOENT;
 }
@@ -354,14 +358,76 @@ static struct pstore_info efi_pstore_info = {
.erase  = efi_pstore_erase,
 };
 
+static int efi_pstore_callback(efi_char16_t *name, efi_guid_t vendor,
+  unsigned long name_size, void *data)
+{
+   struct efivar_entry *entry;
+   int ret;
+
+   entry = kzalloc(sizeof(*entry), GFP_KERNEL);
+   if (!entry)
+   return -ENOMEM;
+
+   memcpy(entry->var.VariableName, name, name_size);
+   entry->var.VendorGuid = vendor;
+
+   ret = efivar_entry_add(entry, &efi_pstore_list);
+   if (ret)
+   kfree(entry);
+
+   return ret;
+}
+
+static int efi_pstore_update_entry(efi_char16_t *name, efi_guid_t vendor,
+  unsigned long name_size, void *data)
+{
+   struct efivar_entry *entry = data;
+
+   if (efivar_entry_find(name, vendor, &efi_pstore_list, false))
+   return 0;
+
+   memcpy(entry->var.VariableName, name, name_size);
+   memcpy(&(entry->var.VendorGuid), &vendor, sizeof(efi_guid_t));
+
+   return 1;
+}
+
+static void efi_pstore_update_entries(struct work_struct *work)
+{
+   struct efivar_entry *entry;

[tip: efi/core] efi: gsmi: fix false dependency on CONFIG_EFI_VARS

2020-09-29 Thread tip-bot2 for Ard Biesheuvel
The following commit has been merged into the efi/core branch of tip:

Commit-ID: 9846d86031eeca2fb2867fe4ac9d92803a97e8e4
Gitweb:
https://git.kernel.org/tip/9846d86031eeca2fb2867fe4ac9d92803a97e8e4
Author:Ard Biesheuvel 
AuthorDate:Wed, 23 Sep 2020 10:18:31 +02:00
Committer: Ard Biesheuvel 
CommitterDate: Tue, 29 Sep 2020 19:40:57 +02:00

efi: gsmi: fix false dependency on CONFIG_EFI_VARS

The gsmi code does not actually rely on CONFIG_EFI_VARS, since it only
uses the efivars abstraction that is included unconditionally when
CONFIG_EFI is defined. CONFIG_EFI_VARS controls the inclusion of the
code that exposes the sysfs entries, and which has been deprecated for
some time.

Signed-off-by: Ard Biesheuvel 
---
 drivers/firmware/google/Kconfig | 2 +-
 drivers/firmware/google/gsmi.c  | 8 
 2 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/drivers/firmware/google/Kconfig b/drivers/firmware/google/Kconfig
index a3a6ca6..97968ae 100644
--- a/drivers/firmware/google/Kconfig
+++ b/drivers/firmware/google/Kconfig
@@ -15,7 +15,7 @@ config GOOGLE_SMI
help
  Say Y here if you want to enable SMI callbacks for Google
  platforms.  This provides an interface for writing to and
- clearing the event log.  If EFI_VARS is also enabled this
+ clearing the event log.  If CONFIG_EFI is also enabled this
  driver provides an interface for reading and writing NVRAM
  variables.
 
diff --git a/drivers/firmware/google/gsmi.c b/drivers/firmware/google/gsmi.c
index 5b2011e..7d9367b 100644
--- a/drivers/firmware/google/gsmi.c
+++ b/drivers/firmware/google/gsmi.c
@@ -302,7 +302,7 @@ static int gsmi_exec(u8 func, u8 sub)
return rc;
 }
 
-#ifdef CONFIG_EFI_VARS
+#ifdef CONFIG_EFI
 
 static struct efivars efivars;
 
@@ -483,7 +483,7 @@ static const struct efivar_operations efivar_ops = {
.get_next_variable = gsmi_get_next_variable,
 };
 
-#endif /* CONFIG_EFI_VARS */
+#endif /* CONFIG_EFI */
 
 static ssize_t eventlog_write(struct file *filp, struct kobject *kobj,
   struct bin_attribute *bin_attr,
@@ -1007,7 +1007,7 @@ static __init int gsmi_init(void)
goto out_remove_bin_file;
}
 
-#ifdef CONFIG_EFI_VARS
+#ifdef CONFIG_EFI
ret = efivars_register(&efivars, &efivar_ops, gsmi_kobj);
if (ret) {
printk(KERN_INFO "gsmi: Failed to register efivars\n");
@@ -1047,7 +1047,7 @@ static void __exit gsmi_exit(void)
unregister_die_notifier(&gsmi_die_notifier);
atomic_notifier_chain_unregister(&panic_notifier_list,
 &gsmi_panic_notifier);
-#ifdef CONFIG_EFI_VARS
+#ifdef CONFIG_EFI
efivars_unregister(&efivars);
 #endif
 


[tip: efi/core] efi: efivars: limit availability to X86 builds

2020-09-29 Thread tip-bot2 for Ard Biesheuvel
The following commit has been merged into the efi/core branch of tip:

Commit-ID: 963fabf37f6a94214a823df0a785e653cb8ad6ea
Gitweb:
https://git.kernel.org/tip/963fabf37f6a94214a823df0a785e653cb8ad6ea
Author:Ard Biesheuvel 
AuthorDate:Wed, 23 Sep 2020 10:20:10 +02:00
Committer: Ard Biesheuvel 
CommitterDate: Tue, 29 Sep 2020 19:40:57 +02:00

efi: efivars: limit availability to X86 builds

CONFIG_EFI_VARS controls the code that exposes EFI variables via
sysfs entries, which was deprecated before support for non-Intel
architectures was added to EFI. So let's limit its availability
to Intel architectures for the time being, and hopefully remove
it entirely in the not too distant future.

While at it, let's remove the module alias so that the module is
no longer loaded automatically.

Signed-off-by: Ard Biesheuvel 
---
 Documentation/arm/uefi.rst |  2 +-
 drivers/firmware/efi/Kconfig   | 13 -
 drivers/firmware/efi/efivars.c |  1 -
 3 files changed, 5 insertions(+), 11 deletions(-)

diff --git a/Documentation/arm/uefi.rst b/Documentation/arm/uefi.rst
index f868330..f732f95 100644
--- a/Documentation/arm/uefi.rst
+++ b/Documentation/arm/uefi.rst
@@ -23,7 +23,7 @@ makes it possible for the kernel to support additional 
features:
 For actually enabling [U]EFI support, enable:
 
 - CONFIG_EFI=y
-- CONFIG_EFI_VARS=y or m
+- CONFIG_EFIVAR_FS=y or m
 
 The implementation depends on receiving information about the UEFI environment
 in a Flattened Device Tree (FDT) - so is only available with CONFIG_OF.
diff --git a/drivers/firmware/efi/Kconfig b/drivers/firmware/efi/Kconfig
index 80f5c67..da1887f 100644
--- a/drivers/firmware/efi/Kconfig
+++ b/drivers/firmware/efi/Kconfig
@@ -4,20 +4,15 @@ menu "EFI (Extensible Firmware Interface) Support"
 
 config EFI_VARS
tristate "EFI Variable Support via sysfs"
-   depends on EFI
+   depends on EFI && (X86 || IA64)
default n
help
  If you say Y here, you are able to get EFI (Extensible Firmware
  Interface) variable information via sysfs.  You may read,
  write, create, and destroy EFI variables through this interface.
-
- Note that using this driver in concert with efibootmgr requires
- at least test release version 0.5.0-test3 or later, which is
- available from:
- 

-
- Subsequent efibootmgr releases may be found at:
- 
+ Note that this driver is only retained for compatibility with
+ legacy users: new users should use the efivarfs filesystem
+ instead.
 
 config EFI_ESRT
bool
diff --git a/drivers/firmware/efi/efivars.c b/drivers/firmware/efi/efivars.c
index a76f50e..e6b16b3 100644
--- a/drivers/firmware/efi/efivars.c
+++ b/drivers/firmware/efi/efivars.c
@@ -22,7 +22,6 @@ MODULE_AUTHOR("Matt Domsch ");
 MODULE_DESCRIPTION("sysfs interface to EFI Variables");
 MODULE_LICENSE("GPL");
 MODULE_VERSION(EFIVARS_VERSION);
-MODULE_ALIAS("platform:efivars");
 
 static LIST_HEAD(efivar_sysfs_list);
 


[tip: efi/core] efi: pstore: move workqueue handling out of efivars

2020-09-29 Thread tip-bot2 for Ard Biesheuvel
The following commit has been merged into the efi/core branch of tip:

Commit-ID: c9b51a2dbfe7f47643e133bf48e1bf28f1b85d2a
Gitweb:
https://git.kernel.org/tip/c9b51a2dbfe7f47643e133bf48e1bf28f1b85d2a
Author:Ard Biesheuvel 
AuthorDate:Wed, 23 Sep 2020 10:07:49 +02:00
Committer: Ard Biesheuvel 
CommitterDate: Tue, 29 Sep 2020 19:40:57 +02:00

efi: pstore: move workqueue handling out of efivars

The worker thread that gets kicked off to sync the state of the
EFI variable list is only used by the EFI pstore implementation,
and is defined in its source file. So let's move its scheduling
there as well. Since our efivar_init() scan will bail on duplicate
entries, there is no need to disable the workqueue like we did
before, so we can run it unconditionally.

Signed-off-by: Ard Biesheuvel 
---
 drivers/firmware/efi/efi-pstore.c |  7 +--
 drivers/firmware/efi/vars.c   | 21 -
 include/linux/efi.h   |  3 ---
 3 files changed, 5 insertions(+), 26 deletions(-)

diff --git a/drivers/firmware/efi/efi-pstore.c 
b/drivers/firmware/efi/efi-pstore.c
index 785f5e6..0ef086e 100644
--- a/drivers/firmware/efi/efi-pstore.c
+++ b/drivers/firmware/efi/efi-pstore.c
@@ -21,6 +21,7 @@ module_param_named(pstore_disable, efivars_pstore_disable, 
bool, 0644);
 EFI_VARIABLE_RUNTIME_ACCESS)
 
 static LIST_HEAD(efi_pstore_list);
+static DECLARE_WORK(efivar_work, NULL);
 
 static int efi_pstore_open(struct pstore_info *psi)
 {
@@ -267,8 +268,9 @@ static int efi_pstore_write(struct pstore_record *record)
ret = efivar_entry_set_safe(efi_name, vendor, PSTORE_EFI_ATTRIBUTES,
  preemptible(), record->size, record->psi->buf);
 
-   if (record->reason == KMSG_DUMP_OOPS)
-   efivar_run_worker();
+   if (record->reason == KMSG_DUMP_OOPS && try_module_get(THIS_MODULE))
+   if (!schedule_work(&efivar_work))
+   module_put(THIS_MODULE);
 
return ret;
 };
@@ -412,6 +414,7 @@ static void efi_pstore_update_entries(struct work_struct 
*work)
}
 
kfree(entry);
+   module_put(THIS_MODULE);
 }
 
 static __init int efivars_pstore_init(void)
diff --git a/drivers/firmware/efi/vars.c b/drivers/firmware/efi/vars.c
index 973eef2..ffb12f6 100644
--- a/drivers/firmware/efi/vars.c
+++ b/drivers/firmware/efi/vars.c
@@ -32,10 +32,6 @@ static struct efivars *__efivars;
  */
 static DEFINE_SEMAPHORE(efivars_lock);
 
-static bool efivar_wq_enabled = true;
-DECLARE_WORK(efivar_work, NULL);
-EXPORT_SYMBOL_GPL(efivar_work);
-
 static bool
 validate_device_path(efi_char16_t *var_name, int match, u8 *buffer,
 unsigned long len)
@@ -391,13 +387,6 @@ static void dup_variable_bug(efi_char16_t *str16, 
efi_guid_t *vendor_guid,
size_t i, len8 = len16 / sizeof(efi_char16_t);
char *str8;
 
-   /*
-* Disable the workqueue since the algorithm it uses for
-* detecting new variables won't work with this buggy
-* implementation of GetNextVariableName().
-*/
-   efivar_wq_enabled = false;
-
str8 = kzalloc(len8, GFP_KERNEL);
if (!str8)
return;
@@ -1158,16 +1147,6 @@ struct kobject *efivars_kobject(void)
 EXPORT_SYMBOL_GPL(efivars_kobject);
 
 /**
- * efivar_run_worker - schedule the efivar worker thread
- */
-void efivar_run_worker(void)
-{
-   if (efivar_wq_enabled)
-   schedule_work(&efivar_work);
-}
-EXPORT_SYMBOL_GPL(efivar_run_worker);
-
-/**
  * efivars_register - register an efivars
  * @efivars: efivars to register
  * @ops: efivars operations
diff --git a/include/linux/efi.h b/include/linux/efi.h
index 7066c11..ab8c803 100644
--- a/include/linux/efi.h
+++ b/include/linux/efi.h
@@ -1037,9 +1037,6 @@ bool efivar_validate(efi_guid_t vendor, efi_char16_t 
*var_name, u8 *data,
 bool efivar_variable_is_removable(efi_guid_t vendor, const char *name,
  size_t len);
 
-extern struct work_struct efivar_work;
-void efivar_run_worker(void);
-
 #if defined(CONFIG_EFI_VARS) || defined(CONFIG_EFI_VARS_MODULE)
 int efivars_sysfs_init(void);
 


[tip: efi/core] efi: mokvar-table: fix some issues in new code

2020-09-29 Thread tip-bot2 for Ard Biesheuvel
The following commit has been merged into the efi/core branch of tip:

Commit-ID: b89114cd018cffa5deb7def1844ce1891efd4f96
Gitweb:
https://git.kernel.org/tip/b89114cd018cffa5deb7def1844ce1891efd4f96
Author:Ard Biesheuvel 
AuthorDate:Thu, 24 Sep 2020 17:58:22 +02:00
Committer: Ard Biesheuvel 
CommitterDate: Tue, 29 Sep 2020 19:40:57 +02:00

efi: mokvar-table: fix some issues in new code

Fix a couple of issues in the new mokvar-table handling code, as
pointed out by Arvind and Boris:
- don't bother checking the end of the physical region against the start
  address of the mokvar table,
- ensure that we enter the loop with err = -EINVAL,
- replace size_t with unsigned long to appease pedantic type equality
  checks.

Reviewed-by: Arvind Sankar 
Reviewed-by: Lenny Szubowicz 
Tested-by: Borislav Petkov 
Signed-off-by: Ard Biesheuvel 
---
 drivers/firmware/efi/mokvar-table.c | 25 +++--
 1 file changed, 11 insertions(+), 14 deletions(-)

diff --git a/drivers/firmware/efi/mokvar-table.c 
b/drivers/firmware/efi/mokvar-table.c
index b1cd498..72a9e17 100644
--- a/drivers/firmware/efi/mokvar-table.c
+++ b/drivers/firmware/efi/mokvar-table.c
@@ -98,15 +98,14 @@ static struct kobject *mokvar_kobj;
 void __init efi_mokvar_table_init(void)
 {
efi_memory_desc_t md;
-   u64 end_pa;
void *va = NULL;
-   size_t cur_offset = 0;
-   size_t offset_limit;
-   size_t map_size = 0;
-   size_t map_size_needed = 0;
-   size_t size;
+   unsigned long cur_offset = 0;
+   unsigned long offset_limit;
+   unsigned long map_size = 0;
+   unsigned long map_size_needed = 0;
+   unsigned long size;
struct efi_mokvar_table_entry *mokvar_entry;
-   int err = -EINVAL;
+   int err;
 
if (!efi_enabled(EFI_MEMMAP))
return;
@@ -122,18 +121,16 @@ void __init efi_mokvar_table_init(void)
pr_warn("EFI MOKvar config table is not within the EFI memory 
map\n");
return;
}
-   end_pa = efi_mem_desc_end(&md);
-   if (efi.mokvar_table >= end_pa) {
-   pr_err("EFI memory descriptor containing MOKvar config table is 
invalid\n");
-   return;
-   }
-   offset_limit = end_pa - efi.mokvar_table;
+
+   offset_limit = efi_mem_desc_end(&md) - efi.mokvar_table;
+
/*
 * Validate the MOK config table. Since there is no table header
 * from which we could get the total size of the MOK config table,
 * we compute the total size as we validate each variably sized
 * entry, remapping as necessary.
 */
+   err = -EINVAL;
while (cur_offset + sizeof(*mokvar_entry) <= offset_limit) {
mokvar_entry = va + cur_offset;
map_size_needed = cur_offset + sizeof(*mokvar_entry);
@@ -150,7 +147,7 @@ void __init efi_mokvar_table_init(void)
   offset_limit);
va = early_memremap(efi.mokvar_table, map_size);
if (!va) {
-   pr_err("Failed to map EFI MOKvar config table 
pa=0x%lx, size=%zu.\n",
+   pr_err("Failed to map EFI MOKvar config table 
pa=0x%lx, size=%lu.\n",
   efi.mokvar_table, map_size);
return;
}


[tip: efi/core] efi: efivars: un-export efivars_sysfs_init()

2020-09-29 Thread tip-bot2 for Ard Biesheuvel
The following commit has been merged into the efi/core branch of tip:

Commit-ID: 5d3c8617ccee6387ba73a5dba77fb9dc21cb85f4
Gitweb:
https://git.kernel.org/tip/5d3c8617ccee6387ba73a5dba77fb9dc21cb85f4
Author:Ard Biesheuvel 
AuthorDate:Wed, 23 Sep 2020 10:13:07 +02:00
Committer: Ard Biesheuvel 
CommitterDate: Tue, 29 Sep 2020 19:40:57 +02:00

efi: efivars: un-export efivars_sysfs_init()

efivars_sysfs_init() is only used locally in the source file that
defines it, so make it static and unexport it.

Signed-off-by: Ard Biesheuvel 
---
 drivers/firmware/efi/efivars.c | 3 +--
 include/linux/efi.h| 4 
 2 files changed, 1 insertion(+), 6 deletions(-)

diff --git a/drivers/firmware/efi/efivars.c b/drivers/firmware/efi/efivars.c
index f39321d..a76f50e 100644
--- a/drivers/firmware/efi/efivars.c
+++ b/drivers/firmware/efi/efivars.c
@@ -638,7 +638,7 @@ static void efivars_sysfs_exit(void)
kset_unregister(efivars_kset);
 }
 
-int efivars_sysfs_init(void)
+static int efivars_sysfs_init(void)
 {
struct kobject *parent_kobj = efivars_kobject();
int error = 0;
@@ -666,7 +666,6 @@ int efivars_sysfs_init(void)
 
return 0;
 }
-EXPORT_SYMBOL_GPL(efivars_sysfs_init);
 
 module_init(efivars_sysfs_init);
 module_exit(efivars_sysfs_exit);
diff --git a/include/linux/efi.h b/include/linux/efi.h
index ab8c803..4c8dae0 100644
--- a/include/linux/efi.h
+++ b/include/linux/efi.h
@@ -1037,10 +1037,6 @@ bool efivar_validate(efi_guid_t vendor, efi_char16_t 
*var_name, u8 *data,
 bool efivar_variable_is_removable(efi_guid_t vendor, const char *name,
  size_t len);
 
-#if defined(CONFIG_EFI_VARS) || defined(CONFIG_EFI_VARS_MODULE)
-int efivars_sysfs_init(void);
-
-#endif /* CONFIG_EFI_VARS */
 extern bool efi_capsule_pending(int *reset_type);
 
 extern int efi_capsule_supported(efi_guid_t guid, u32 flags,


[tip: efi/core] efi: remove some false dependencies on CONFIG_EFI_VARS

2020-09-29 Thread tip-bot2 for Ard Biesheuvel
The following commit has been merged into the efi/core branch of tip:

Commit-ID: 5ee70cd60652e85e4e8ced99f58f2fcbab405110
Gitweb:
https://git.kernel.org/tip/5ee70cd60652e85e4e8ced99f58f2fcbab405110
Author:Ard Biesheuvel 
AuthorDate:Wed, 23 Sep 2020 10:27:36 +02:00
Committer: Ard Biesheuvel 
CommitterDate: Tue, 29 Sep 2020 19:40:57 +02:00

efi: remove some false dependencies on CONFIG_EFI_VARS

Remove some false dependencies on CONFIG_EFI_VARS, which only controls
the creation of the sysfs entries, whereas the underlying functionality
that these modules rely on is enabled unconditionally when CONFIG_EFI
is set.

Signed-off-by: Ard Biesheuvel 
---
 drivers/firmware/efi/Kconfig | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/drivers/firmware/efi/Kconfig b/drivers/firmware/efi/Kconfig
index dd8d108..80f5c67 100644
--- a/drivers/firmware/efi/Kconfig
+++ b/drivers/firmware/efi/Kconfig
@@ -137,7 +137,6 @@ config EFI_GENERIC_STUB_INITRD_CMDLINE_LOADER
 
 config EFI_BOOTLOADER_CONTROL
tristate "EFI Bootloader Control"
-   depends on EFI_VARS
default n
help
  This module installs a reboot hook, such that if reboot() is
@@ -281,7 +280,7 @@ config EFI_EARLYCON
 
 config EFI_CUSTOM_SSDT_OVERLAYS
bool "Load custom ACPI SSDT overlay from an EFI variable"
-   depends on EFI_VARS && ACPI
+   depends on EFI && ACPI
default ACPI_TABLE_UPGRADE
help
  Allow loading of an ACPI SSDT overlay from an EFI variable specified


[tip: efi/core] efi/libstub: Export efi_low_alloc_above() to other units

2020-09-18 Thread tip-bot2 for Ard Biesheuvel
The following commit has been merged into the efi/core branch of tip:

Commit-ID: 1a895dbf4b66456bfb7da646cc9b1be3e24f4a1d
Gitweb:
https://git.kernel.org/tip/1a895dbf4b66456bfb7da646cc9b1be3e24f4a1d
Author:Ard Biesheuvel 
AuthorDate:Wed, 09 Sep 2020 16:16:20 +03:00
Committer: Ard Biesheuvel 
CommitterDate: Wed, 16 Sep 2020 18:54:59 +03:00

efi/libstub: Export efi_low_alloc_above() to other units

Permit arm32-stub.c to access efi_low_alloc_above() in a subsequent
patch by giving it external linkage and declaring it in efistub.h.

Reviewed-by: Maxim Uvarov 
Tested-by: Maxim Uvarov 
Signed-off-by: Ard Biesheuvel 
---
 drivers/firmware/efi/libstub/efistub.h  | 3 +++
 drivers/firmware/efi/libstub/relocate.c | 4 ++--
 2 files changed, 5 insertions(+), 2 deletions(-)

diff --git a/drivers/firmware/efi/libstub/efistub.h 
b/drivers/firmware/efi/libstub/efistub.h
index 85050f5..158f86f 100644
--- a/drivers/firmware/efi/libstub/efistub.h
+++ b/drivers/firmware/efi/libstub/efistub.h
@@ -740,6 +740,9 @@ efi_status_t efi_allocate_pages(unsigned long size, 
unsigned long *addr,
 efi_status_t efi_allocate_pages_aligned(unsigned long size, unsigned long 
*addr,
unsigned long max, unsigned long align);
 
+efi_status_t efi_low_alloc_above(unsigned long size, unsigned long align,
+unsigned long *addr, unsigned long min);
+
 efi_status_t efi_relocate_kernel(unsigned long *image_addr,
 unsigned long image_size,
 unsigned long alloc_size,
diff --git a/drivers/firmware/efi/libstub/relocate.c 
b/drivers/firmware/efi/libstub/relocate.c
index 9b1aaf8..8ee9eb2 100644
--- a/drivers/firmware/efi/libstub/relocate.c
+++ b/drivers/firmware/efi/libstub/relocate.c
@@ -20,8 +20,8 @@
  *
  * Return: status code
  */
-static efi_status_t efi_low_alloc_above(unsigned long size, unsigned long 
align,
-   unsigned long *addr, unsigned long min)
+efi_status_t efi_low_alloc_above(unsigned long size, unsigned long align,
+unsigned long *addr, unsigned long min)
 {
unsigned long map_size, desc_size, buff_size;
efi_memory_desc_t *map;


[tip: efi/core] efi/libstub: arm32: Base FDT and initrd placement on image address

2020-09-18 Thread tip-bot2 for Ard Biesheuvel
The following commit has been merged into the efi/core branch of tip:

Commit-ID: 6208857b8f7ebdfe84e1be7573be4552a5896a0d
Gitweb:
https://git.kernel.org/tip/6208857b8f7ebdfe84e1be7573be4552a5896a0d
Author:Ard Biesheuvel 
AuthorDate:Thu, 10 Sep 2020 17:09:45 +03:00
Committer: Ard Biesheuvel 
CommitterDate: Wed, 16 Sep 2020 18:53:42 +03:00

efi/libstub: arm32: Base FDT and initrd placement on image address

The way we use the base of DRAM in the EFI stub is problematic as it
is ill defined what the base of DRAM actually means. There are some
restrictions on the placement of FDT and initrd which are defined in
terms of dram_base, but given that the placement of the kernel in
memory is what defines these boundaries (as on ARM, this is where the
linear region starts), it is better to use the image address in these
cases, and disregard dram_base altogether.

Reviewed-by: Maxim Uvarov 
Tested-by: Maxim Uvarov 
Signed-off-by: Ard Biesheuvel 
---
 arch/arm/include/asm/efi.h| 23 ++
 arch/arm64/include/asm/efi.h  |  5 ++---
 drivers/firmware/efi/libstub/arm32-stub.c |  2 +-
 drivers/firmware/efi/libstub/efi-stub.c   |  4 ++--
 4 files changed, 16 insertions(+), 18 deletions(-)

diff --git a/arch/arm/include/asm/efi.h b/arch/arm/include/asm/efi.h
index 5dcf3c6..3ee4f43 100644
--- a/arch/arm/include/asm/efi.h
+++ b/arch/arm/include/asm/efi.h
@@ -66,25 +66,24 @@ static inline void efifb_setup_from_dmi(struct screen_info 
*si, const char *opt)
 #define MAX_UNCOMP_KERNEL_SIZE SZ_32M
 
 /*
- * The kernel zImage should preferably be located between 32 MB and 128 MB
- * from the base of DRAM. The min address leaves space for a maximal size
- * uncompressed image, and the max address is due to how the zImage 
decompressor
- * picks a destination address.
+ * phys-to-virt patching requires that the physical to virtual offset fits
+ * into the immediate field of an add/sub instruction, which comes down to the
+ * 24 least significant bits being zero, and so the offset should be a multiple
+ * of 16 MB. Since PAGE_OFFSET itself is a multiple of 16 MB, the physical
+ * base should be aligned to 16 MB as well.
  */
-#define ZIMAGE_OFFSET_LIMITSZ_128M
-#define MIN_ZIMAGE_OFFSET  MAX_UNCOMP_KERNEL_SIZE
+#define EFI_PHYS_ALIGN SZ_16M
 
-/* on ARM, the FDT should be located in the first 128 MB of RAM */
-static inline unsigned long efi_get_max_fdt_addr(unsigned long dram_base)
+/* on ARM, the FDT should be located in a lowmem region */
+static inline unsigned long efi_get_max_fdt_addr(unsigned long image_addr)
 {
-   return dram_base + ZIMAGE_OFFSET_LIMIT;
+   return round_down(image_addr, EFI_PHYS_ALIGN) + SZ_512M;
 }
 
 /* on ARM, the initrd should be loaded in a lowmem region */
-static inline unsigned long efi_get_max_initrd_addr(unsigned long dram_base,
-   unsigned long image_addr)
+static inline unsigned long efi_get_max_initrd_addr(unsigned long image_addr)
 {
-   return dram_base + SZ_512M;
+   return round_down(image_addr, EFI_PHYS_ALIGN) + SZ_512M;
 }
 
 struct efi_arm_entry_state {
diff --git a/arch/arm64/include/asm/efi.h b/arch/arm64/include/asm/efi.h
index d4ab3f7..973b144 100644
--- a/arch/arm64/include/asm/efi.h
+++ b/arch/arm64/include/asm/efi.h
@@ -65,7 +65,7 @@ efi_status_t __efi_rt_asm_wrapper(void *, const char *, ...);
(SEGMENT_ALIGN > THREAD_ALIGN ? SEGMENT_ALIGN : THREAD_ALIGN)
 
 /* on arm64, the FDT may be located anywhere in system RAM */
-static inline unsigned long efi_get_max_fdt_addr(unsigned long dram_base)
+static inline unsigned long efi_get_max_fdt_addr(unsigned long image_addr)
 {
return ULONG_MAX;
 }
@@ -80,8 +80,7 @@ static inline unsigned long efi_get_max_fdt_addr(unsigned 
long dram_base)
  * apply to other bootloaders, and are required for some kernel
  * configurations.
  */
-static inline unsigned long efi_get_max_initrd_addr(unsigned long dram_base,
-   unsigned long image_addr)
+static inline unsigned long efi_get_max_initrd_addr(unsigned long image_addr)
 {
return (image_addr & ~(SZ_1G - 1UL)) + (1UL << (VA_BITS_MIN - 1));
 }
diff --git a/drivers/firmware/efi/libstub/arm32-stub.c 
b/drivers/firmware/efi/libstub/arm32-stub.c
index d08e5d5..bcf770c 100644
--- a/drivers/firmware/efi/libstub/arm32-stub.c
+++ b/drivers/firmware/efi/libstub/arm32-stub.c
@@ -252,7 +252,7 @@ efi_status_t handle_kernel_image(unsigned long *image_addr,
efi_status_t status;
 
/* use a 16 MiB aligned base for the decompressed kernel */
-   kernel_base = round_up(dram_base, SZ_16M) + TEXT_OFFSET;
+   kernel_base = round_up(dram_base, EFI_PHYS_ALIGN) + TEXT_OFFSET;
 
/*
 * Note that some platforms (notably, the Raspberry Pi 2) put
diff --git a/drivers/firmware/efi/libstub/efi-stub.c 
b/drivers/firmware/efi/libstub/efi-stub.c
index a5a405d..65a0070 100644

[tip: efi/core] efi/libstub: arm32: Use low allocation for the uncompressed kernel

2020-09-18 Thread tip-bot2 for Ard Biesheuvel
The following commit has been merged into the efi/core branch of tip:

Commit-ID: 762cd288fc4a24a372f36408e69b1885967f94bb
Gitweb:
https://git.kernel.org/tip/762cd288fc4a24a372f36408e69b1885967f94bb
Author:Ard Biesheuvel 
AuthorDate:Wed, 09 Sep 2020 17:11:50 +03:00
Committer: Ard Biesheuvel 
CommitterDate: Wed, 16 Sep 2020 18:55:02 +03:00

efi/libstub: arm32: Use low allocation for the uncompressed kernel

Before commit

  d0f9ca9be11f25ef ("ARM: decompressor: run decompressor in place if loaded via 
UEFI")

we were rather limited in the choice of base address for the uncompressed
kernel, as we were relying on the logic in the decompressor that blindly
rounds down the decompressor execution address to the next multiple of 128
MiB, and decompresses the kernel there. For this reason, we have a lot of
complicated memory region handling code, to ensure that this memory window
is available, even though it could be occupied by reserved regions or
other allocations that may or may not collide with the uncompressed image.

Today, we simply pass the target address for the decompressed image to the
decompressor directly, and so we can choose a suitable window just by
finding a 16 MiB aligned region, while taking TEXT_OFFSET and the region
for the swapper page tables into account.

So let's get rid of the complicated logic, and instead, use the existing
bottom up allocation routine to allocate a suitable window as low as
possible, and carve out a memory region that has the right properties.

Note that this removes any dependencies on the 'dram_base' argument to
handle_kernel_image(), and so this is removed as well. Given that this
was the only remaining use of dram_base, the code that produces it is
removed entirely as well.

Reviewed-by: Maxim Uvarov 
Tested-by: Maxim Uvarov 
Signed-off-by: Ard Biesheuvel 
---
 drivers/firmware/efi/libstub/arm32-stub.c | 178 -
 drivers/firmware/efi/libstub/arm64-stub.c |   1 +-
 drivers/firmware/efi/libstub/efi-stub.c   |  44 +-
 drivers/firmware/efi/libstub/efistub.h|   4 +-
 4 files changed, 38 insertions(+), 189 deletions(-)

diff --git a/drivers/firmware/efi/libstub/arm32-stub.c 
b/drivers/firmware/efi/libstub/arm32-stub.c
index bcf770c..4b5b240 100644
--- a/drivers/firmware/efi/libstub/arm32-stub.c
+++ b/drivers/firmware/efi/libstub/arm32-stub.c
@@ -113,162 +113,58 @@ void free_screen_info(struct screen_info *si)
efi_bs_call(free_pool, si);
 }
 
-static efi_status_t reserve_kernel_base(unsigned long dram_base,
-   unsigned long *reserve_addr,
-   unsigned long *reserve_size)
-{
-   efi_physical_addr_t alloc_addr;
-   efi_memory_desc_t *memory_map;
-   unsigned long nr_pages, map_size, desc_size, buff_size;
-   efi_status_t status;
-   unsigned long l;
-
-   struct efi_boot_memmap map = {
-   .map= &memory_map,
-   .map_size   = &map_size,
-   .desc_size  = &desc_size,
-   .desc_ver   = NULL,
-   .key_ptr= NULL,
-   .buff_size  = &buff_size,
-   };
-
-   /*
-* Reserve memory for the uncompressed kernel image. This is
-* all that prevents any future allocations from conflicting
-* with the kernel. Since we can't tell from the compressed
-* image how much DRAM the kernel actually uses (due to BSS
-* size uncertainty) we allocate the maximum possible size.
-* Do this very early, as prints can cause memory allocations
-* that may conflict with this.
-*/
-   alloc_addr = dram_base + MAX_UNCOMP_KERNEL_SIZE;
-   nr_pages = MAX_UNCOMP_KERNEL_SIZE / EFI_PAGE_SIZE;
-   status = efi_bs_call(allocate_pages, EFI_ALLOCATE_MAX_ADDRESS,
-EFI_BOOT_SERVICES_DATA, nr_pages, &alloc_addr);
-   if (status == EFI_SUCCESS) {
-   if (alloc_addr == dram_base) {
-   *reserve_addr = alloc_addr;
-   *reserve_size = MAX_UNCOMP_KERNEL_SIZE;
-   return EFI_SUCCESS;
-   }
-   /*
-* If we end up here, the allocation succeeded but starts below
-* dram_base. This can only occur if the real base of DRAM is
-* not a multiple of 128 MB, in which case dram_base will have
-* been rounded up. Since this implies that a part of the region
-* was already occupied, we need to fall through to the code
-* below to ensure that the existing allocations don't conflict.
-* For this reason, we use EFI_BOOT_SERVICES_DATA above and not
-* EFI_LOADER_DATA, which we wouldn't able to distinguish from
-* allocations that we want to disallow.
-*/
-   }
-
-   /*
-* If the allocation above failed

[tip: efi/urgent] efi: efibc: check for efivars write capability

2020-09-18 Thread tip-bot2 for Ard Biesheuvel
The following commit has been merged into the efi/urgent branch of tip:

Commit-ID: 46908326c6b801201f1e46f5ed0db6e85bef74ae
Gitweb:
https://git.kernel.org/tip/46908326c6b801201f1e46f5ed0db6e85bef74ae
Author:Ard Biesheuvel 
AuthorDate:Tue, 15 Sep 2020 18:12:09 +03:00
Committer: Ard Biesheuvel 
CommitterDate: Tue, 15 Sep 2020 18:22:47 +03:00

efi: efibc: check for efivars write capability

Branden reports that commit

  f88814cc2578c1 ("efi/efivars: Expose RT service availability via efivars 
abstraction")

regresses UEFI platforms that implement GetVariable but not SetVariable
when booting kernels that have EFIBC (bootloader control) enabled.

The reason is that EFIBC is a user of the efivars abstraction, which was
updated to permit users that rely only on the read capability, but not on
the write capability. EFIBC is in the latter category, so it has to check
explicitly whether efivars supports writes.

Fixes: f88814cc2578c1 ("efi/efivars: Expose RT service availability via efivars 
abstraction")
Tested-by: Branden Sherrell 
Link: 
https://lore.kernel.org/linux-efi/ae217103-c96f-4afc-8417-83ec11962...@gmail.com/
Signed-off-by: Ard Biesheuvel 
---
 drivers/firmware/efi/efibc.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/firmware/efi/efibc.c b/drivers/firmware/efi/efibc.c
index 35dccc8..15a4753 100644
--- a/drivers/firmware/efi/efibc.c
+++ b/drivers/firmware/efi/efibc.c
@@ -84,7 +84,7 @@ static int __init efibc_init(void)
 {
int ret;
 
-   if (!efi_enabled(EFI_RUNTIME_SERVICES))
+   if (!efivars_kobject() || !efivar_supports_writes())
return -ENODEV;
 
ret = register_reboot_notifier(&efibc_reboot_notifier);


[tip: efi/urgent] Documentation: efi: remove description of efi=old_map

2020-08-22 Thread tip-bot2 for Ard Biesheuvel
The following commit has been merged into the efi/urgent branch of tip:

Commit-ID: fb1201aececc59990b75ef59fca93ae4aa1e1444
Gitweb:
https://git.kernel.org/tip/fb1201aececc59990b75ef59fca93ae4aa1e1444
Author:Ard Biesheuvel 
AuthorDate:Mon, 17 Aug 2020 12:00:17 +02:00
Committer: Ard Biesheuvel 
CommitterDate: Thu, 20 Aug 2020 11:18:36 +02:00

Documentation: efi: remove description of efi=old_map

The old EFI runtime region mapping logic that was kept around for some
time has finally been removed entirely, along with the SGI UV1 support
code that was its last remaining user. So remove any mention of the
efi=old_map command line parameter from the docs.

Cc: Jonathan Corbet 
Cc: linux-...@vger.kernel.org
Signed-off-by: Ard Biesheuvel 
---
 Documentation/admin-guide/kernel-parameters.txt | 5 +
 1 file changed, 1 insertion(+), 4 deletions(-)

diff --git a/Documentation/admin-guide/kernel-parameters.txt 
b/Documentation/admin-guide/kernel-parameters.txt
index bdc1f33..a106874 100644
--- a/Documentation/admin-guide/kernel-parameters.txt
+++ b/Documentation/admin-guide/kernel-parameters.txt
@@ -1233,8 +1233,7 @@
efi=[EFI]
Format: { "debug", "disable_early_pci_dma",
  "nochunk", "noruntime", "nosoftreserve",
- "novamap", "no_disable_early_pci_dma",
- "old_map" }
+ "novamap", "no_disable_early_pci_dma" }
debug: enable misc debug output.
disable_early_pci_dma: disable the busmaster bit on all
PCI bridges while in the EFI boot stub.
@@ -1251,8 +1250,6 @@
novamap: do not call SetVirtualAddressMap().
no_disable_early_pci_dma: Leave the busmaster bit set
on all PCI bridges while in the EFI boot stub
-   old_map [X86-64]: switch to the old ioremap-based EFI
-   runtime services mapping. [Needs CONFIG_X86_UV=y]
 
efi_no_storage_paranoia [EFI; X86]
Using this parameter you can use more than 50% of


[tip: efi/urgent] efi/x86: Move 32-bit code into efi_32.c

2020-08-22 Thread tip-bot2 for Ard Biesheuvel
The following commit has been merged into the efi/urgent branch of tip:

Commit-ID: 39ada88f9c862c1ff8929ff67e0d1199c7af73fe
Gitweb:
https://git.kernel.org/tip/39ada88f9c862c1ff8929ff67e0d1199c7af73fe
Author:Ard Biesheuvel 
AuthorDate:Thu, 13 Aug 2020 19:38:17 +02:00
Committer: Ard Biesheuvel 
CommitterDate: Thu, 20 Aug 2020 11:18:36 +02:00

efi/x86: Move 32-bit code into efi_32.c

Now that the old memmap code has been removed, some code that was left
behind in arch/x86/platform/efi/efi.c is only used for 32-bit builds,
which means it can live in efi_32.c as well. So move it over.

Signed-off-by: Ard Biesheuvel 
---
 arch/x86/include/asm/efi.h | 10 +-
 arch/x86/platform/efi/efi.c| 69 +-
 arch/x86/platform/efi/efi_32.c | 44 +
 3 files changed, 37 insertions(+), 86 deletions(-)

diff --git a/arch/x86/include/asm/efi.h b/arch/x86/include/asm/efi.h
index b9c2667..bc9758e 100644
--- a/arch/x86/include/asm/efi.h
+++ b/arch/x86/include/asm/efi.h
@@ -81,11 +81,8 @@ extern unsigned long efi_fw_vendor, efi_config_table;
kernel_fpu_end();   \
 })
 
-
 #define arch_efi_call_virt(p, f, args...)  p->f(args)
 
-#define efi_ioremap(addr, size, type, attr)ioremap_cache(addr, size)
-
 #else /* !CONFIG_X86_32 */
 
 #define EFI_LOADER_SIGNATURE   "EL64"
@@ -125,9 +122,6 @@ struct efi_scratch {
kernel_fpu_end();   \
 })
 
-extern void __iomem *__init efi_ioremap(unsigned long addr, unsigned long size,
-   u32 type, u64 attribute);
-
 #ifdef CONFIG_KASAN
 /*
  * CONFIG_KASAN may redefine memset to __memset.  __memset function is present
@@ -143,17 +137,13 @@ extern void __iomem *__init efi_ioremap(unsigned long 
addr, unsigned long size,
 #endif /* CONFIG_X86_32 */
 
 extern struct efi_scratch efi_scratch;
-extern void __init efi_set_executable(efi_memory_desc_t *md, bool executable);
 extern int __init efi_memblock_x86_reserve_range(void);
 extern void __init efi_print_memmap(void);
-extern void __init efi_memory_uc(u64 addr, unsigned long size);
 extern void __init efi_map_region(efi_memory_desc_t *md);
 extern void __init efi_map_region_fixed(efi_memory_desc_t *md);
 extern void efi_sync_low_kernel_mappings(void);
 extern int __init efi_alloc_page_tables(void);
 extern int __init efi_setup_page_tables(unsigned long pa_memmap, unsigned 
num_pages);
-extern void __init old_map_region(efi_memory_desc_t *md);
-extern void __init runtime_code_page_mkexec(void);
 extern void __init efi_runtime_update_mappings(void);
 extern void __init efi_dump_pagetable(void);
 extern void __init efi_apply_memmap_quirks(void);
diff --git a/arch/x86/platform/efi/efi.c b/arch/x86/platform/efi/efi.c
index f6ea8f1..d37ebe6 100644
--- a/arch/x86/platform/efi/efi.c
+++ b/arch/x86/platform/efi/efi.c
@@ -49,7 +49,6 @@
 #include 
 #include 
 #include 
-#include 
 #include 
 #include 
 #include 
@@ -496,74 +495,6 @@ void __init efi_init(void)
efi_print_memmap();
 }
 
-#if defined(CONFIG_X86_32)
-
-void __init efi_set_executable(efi_memory_desc_t *md, bool executable)
-{
-   u64 addr, npages;
-
-   addr = md->virt_addr;
-   npages = md->num_pages;
-
-   memrange_efi_to_native(&addr, &npages);
-
-   if (executable)
-   set_memory_x(addr, npages);
-   else
-   set_memory_nx(addr, npages);
-}
-
-void __init runtime_code_page_mkexec(void)
-{
-   efi_memory_desc_t *md;
-
-   /* Make EFI runtime service code area executable */
-   for_each_efi_memory_desc(md) {
-   if (md->type != EFI_RUNTIME_SERVICES_CODE)
-   continue;
-
-   efi_set_executable(md, true);
-   }
-}
-
-void __init efi_memory_uc(u64 addr, unsigned long size)
-{
-   unsigned long page_shift = 1UL << EFI_PAGE_SHIFT;
-   u64 npages;
-
-   npages = round_up(size, page_shift) / page_shift;
-   memrange_efi_to_native(&addr, &npages);
-   set_memory_uc(addr, npages);
-}
-
-void __init old_map_region(efi_memory_desc_t *md)
-{
-   u64 start_pfn, end_pfn, end;
-   unsigned long size;
-   void *va;
-
-   start_pfn = PFN_DOWN(md->phys_addr);
-   size  = md->num_pages << PAGE_SHIFT;
-   end   = md->phys_addr + size;
-   end_pfn   = PFN_UP(end);
-
-   if (pfn_range_is_mapped(start_pfn, end_pfn)) {
-   va = __va(md->phys_addr);
-
-   if (!(md->attribute & EFI_MEMORY_WB))
-   efi_memory_uc((u64)(unsigned long)va, size);
-   } else
-   va = efi_ioremap(md->phys_addr, size,
-md->type, md->attribute);
-
-   md->virt_addr = (u64) (unsigned long) va;
-   if (!va)
-   pr_err("ioremap of 0x%llX failed!\n",
-  (unsigned long long)md->phys_addr);
-}
-
-#endif
-
 /* Merge contig

[tip: x86/boot] x86/boot/compressed: Move .got.plt entries out of the .got section

2020-08-14 Thread tip-bot2 for Ard Biesheuvel
The following commit has been merged into the x86/boot branch of tip:

Commit-ID: 262b5cae67a672404da0dcbd009efc1227ad51e4
Gitweb:
https://git.kernel.org/tip/262b5cae67a672404da0dcbd009efc1227ad51e4
Author:Ard Biesheuvel 
AuthorDate:Fri, 31 Jul 2020 16:07:45 -07:00
Committer: Ingo Molnar 
CommitterDate: Fri, 14 Aug 2020 12:52:34 +02:00

x86/boot/compressed: Move .got.plt entries out of the .got section

The .got.plt section contains the part of the GOT which is used by PLT
entries, and which gets updated lazily by the dynamic loader when
function calls are dispatched through those PLT entries.

On fully linked binaries such as the kernel proper or the decompressor,
this never happens, and so in practice, the .got.plt section consists
only of the first 3 magic entries that are meant to point at the _DYNAMIC
section and at the fixup routine in the loader. However, since we don't
use a dynamic loader, those entries are never populated or used.

This means that treating those entries like ordinary GOT entries, and
updating their values based on the actual placement of the executable in
memory is completely pointless, and we can just ignore the .got.plt
section entirely, provided that it has no additional entries beyond
the first 3 ones.

So add an assertion in the linker script to ensure that this assumption
holds, and move the contents out of the [_got, _egot) memory range that
is modified by the GOT fixup routines.

While at it, drop the KEEP(), since it has no effect on the contents
of output sections that are created by the linker itself.

Signed-off-by: Ard Biesheuvel 
Signed-off-by: Arvind Sankar 
Signed-off-by: Kees Cook 
Signed-off-by: Ingo Molnar 
Tested-by: Sedat Dilek 
Tested-by: Nick Desaulniers 
Reviewed-by: Kees Cook 
Acked-by: Arvind Sankar 
Link: https://lore.kernel.org/r/20200731230820.1742553-2-keesc...@chromium.org
---
 arch/x86/boot/compressed/vmlinux.lds.S | 11 ++-
 1 file changed, 10 insertions(+), 1 deletion(-)

diff --git a/arch/x86/boot/compressed/vmlinux.lds.S 
b/arch/x86/boot/compressed/vmlinux.lds.S
index 8f1025d..b17d218 100644
--- a/arch/x86/boot/compressed/vmlinux.lds.S
+++ b/arch/x86/boot/compressed/vmlinux.lds.S
@@ -44,10 +44,13 @@ SECTIONS
}
.got : {
_got = .;
-   KEEP(*(.got.plt))
KEEP(*(.got))
_egot = .;
}
+   .got.plt : {
+   *(.got.plt)
+   }
+
.data : {
_data = . ;
*(.data)
@@ -77,3 +80,9 @@ SECTIONS
 
DISCARDS
 }
+
+#ifdef CONFIG_X86_64
+ASSERT(SIZEOF(.got.plt) == 0 || SIZEOF(.got.plt) == 0x18, "Unexpected GOT/PLT 
entries detected!")
+#else
+ASSERT(SIZEOF(.got.plt) == 0 || SIZEOF(.got.plt) == 0xc, "Unexpected GOT/PLT 
entries detected!")
+#endif


[tip: x86/boot] x86/boot/compressed: Force hidden visibility for all symbol references

2020-08-14 Thread tip-bot2 for Ard Biesheuvel
The following commit has been merged into the x86/boot branch of tip:

Commit-ID: e544ea57ac0734bca752eb2d8635fecbe932c356
Gitweb:
https://git.kernel.org/tip/e544ea57ac0734bca752eb2d8635fecbe932c356
Author:Ard Biesheuvel 
AuthorDate:Fri, 31 Jul 2020 16:07:46 -07:00
Committer: Ingo Molnar 
CommitterDate: Fri, 14 Aug 2020 12:52:34 +02:00

x86/boot/compressed: Force hidden visibility for all symbol references

Eliminate all GOT entries in the decompressor binary, by forcing hidden
visibility for all symbol references, which informs the compiler that
such references will be resolved at link time without the need for
allocating GOT entries.

To ensure that no GOT entries will creep back in, add an assertion to
the decompressor linker script that will fire if the .got section has
a non-zero size.

[Arvind: move hidden.h to include/linux instead of making a copy]

Signed-off-by: Ard Biesheuvel 
Signed-off-by: Arvind Sankar 
Signed-off-by: Kees Cook 
Signed-off-by: Ingo Molnar 
Tested-by: Nick Desaulniers 
Tested-by: Sedat Dilek 
Reviewed-by: Kees Cook 
Acked-by: Arvind Sankar 
Link: https://lore.kernel.org/r/20200731230820.1742553-3-keesc...@chromium.org
---
 arch/x86/boot/compressed/Makefile  |  1 +
 arch/x86/boot/compressed/vmlinux.lds.S |  1 +
 drivers/firmware/efi/libstub/Makefile  |  2 +-
 drivers/firmware/efi/libstub/hidden.h  |  6 --
 include/linux/hidden.h | 19 +++
 5 files changed, 22 insertions(+), 7 deletions(-)
 delete mode 100644 drivers/firmware/efi/libstub/hidden.h
 create mode 100644 include/linux/hidden.h

diff --git a/arch/x86/boot/compressed/Makefile 
b/arch/x86/boot/compressed/Makefile
index 3962f59..7c687a7 100644
--- a/arch/x86/boot/compressed/Makefile
+++ b/arch/x86/boot/compressed/Makefile
@@ -43,6 +43,7 @@ KBUILD_CFLAGS += -Wno-pointer-sign
 KBUILD_CFLAGS += $(call cc-option,-fmacro-prefix-map=$(srctree)/=)
 KBUILD_CFLAGS += -fno-asynchronous-unwind-tables
 KBUILD_CFLAGS += -D__DISABLE_EXPORTS
+KBUILD_CFLAGS += -include $(srctree)/include/linux/hidden.h
 
 KBUILD_AFLAGS  := $(KBUILD_CFLAGS) -D__ASSEMBLY__
 GCOV_PROFILE := n
diff --git a/arch/x86/boot/compressed/vmlinux.lds.S 
b/arch/x86/boot/compressed/vmlinux.lds.S
index b17d218..4bcc943 100644
--- a/arch/x86/boot/compressed/vmlinux.lds.S
+++ b/arch/x86/boot/compressed/vmlinux.lds.S
@@ -81,6 +81,7 @@ SECTIONS
DISCARDS
 }
 
+ASSERT(SIZEOF(.got) == 0, "Unexpected GOT entries detected!")
 #ifdef CONFIG_X86_64
 ASSERT(SIZEOF(.got.plt) == 0 || SIZEOF(.got.plt) == 0x18, "Unexpected GOT/PLT 
entries detected!")
 #else
diff --git a/drivers/firmware/efi/libstub/Makefile 
b/drivers/firmware/efi/libstub/Makefile
index 296b18f..5eefd60 100644
--- a/drivers/firmware/efi/libstub/Makefile
+++ b/drivers/firmware/efi/libstub/Makefile
@@ -26,7 +26,7 @@ cflags-$(CONFIG_ARM)  := $(subst 
$(CC_FLAGS_FTRACE),,$(KBUILD_CFLAGS)) \
 cflags-$(CONFIG_EFI_GENERIC_STUB) += -I$(srctree)/scripts/dtc/libfdt
 
 KBUILD_CFLAGS  := $(cflags-y) -Os -DDISABLE_BRANCH_PROFILING \
-  -include 
$(srctree)/drivers/firmware/efi/libstub/hidden.h \
+  -include $(srctree)/include/linux/hidden.h \
   -D__NO_FORTIFY \
   -ffreestanding \
   -fno-stack-protector \
diff --git a/drivers/firmware/efi/libstub/hidden.h 
b/drivers/firmware/efi/libstub/hidden.h
deleted file mode 100644
index 3493b04..000
--- a/drivers/firmware/efi/libstub/hidden.h
+++ /dev/null
@@ -1,6 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * To prevent the compiler from emitting GOT-indirected (and thus absolute)
- * references to any global symbols, override their visibility as 'hidden'
- */
-#pragma GCC visibility push(hidden)
diff --git a/include/linux/hidden.h b/include/linux/hidden.h
new file mode 100644
index 000..49a17b6
--- /dev/null
+++ b/include/linux/hidden.h
@@ -0,0 +1,19 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * When building position independent code with GCC using the -fPIC option,
+ * (or even the -fPIE one on older versions), it will assume that we are
+ * building a dynamic object (either a shared library or an executable) that
+ * may have symbol references that can only be resolved at load time. For a
+ * variety of reasons (ELF symbol preemption, the CoW footprint of the section
+ * that is modified by the loader), this results in all references to symbols
+ * with external linkage to go via entries in the Global Offset Table (GOT),
+ * which carries absolute addresses which need to be fixed up when the
+ * executable image is loaded at an offset which is different from its link
+ * time offset.
+ *
+ * Fortunately, there is a way to inform the compiler that such symbol
+ * references will be satisfied at link time rather than at load time, by
+ * giving them 'hidden' visibility.
+ */
+
+#pragma GCC visibility push(hid

[tip: x86/boot] x86/boot/compressed: Get rid of GOT fixup code

2020-08-14 Thread tip-bot2 for Ard Biesheuvel
The following commit has been merged into the x86/boot branch of tip:

Commit-ID: 423e4d198a036689de73fd6b073fc4349c4fa1ee
Gitweb:
https://git.kernel.org/tip/423e4d198a036689de73fd6b073fc4349c4fa1ee
Author:Ard Biesheuvel 
AuthorDate:Fri, 31 Jul 2020 16:07:47 -07:00
Committer: Ingo Molnar 
CommitterDate: Fri, 14 Aug 2020 12:52:35 +02:00

x86/boot/compressed: Get rid of GOT fixup code

In a previous patch, we have eliminated GOT entries from the decompressor
binary and added an assertion that the .got section is empty. This means
that the GOT fixup routines that exist in both the 32-bit and 64-bit
startup routines have become dead code, and can be removed.

While at it, drop the KEEP() from the linker script, as it has no effect
on the contents of output sections that are created by the linker itself.

Signed-off-by: Ard Biesheuvel 
Signed-off-by: Arvind Sankar 
Signed-off-by: Kees Cook 
Signed-off-by: Ingo Molnar 
Tested-by: Nick Desaulniers 
Tested-by: Sedat Dilek 
Reviewed-by: Kees Cook 
Acked-by: Arvind Sankar 
Link: https://lore.kernel.org/r/20200731230820.1742553-4-keesc...@chromium.org
---
 arch/x86/boot/compressed/head_32.S | 24 +--
 arch/x86/boot/compressed/head_64.S | 57 +-
 arch/x86/boot/compressed/vmlinux.lds.S |  4 +--
 3 files changed, 5 insertions(+), 80 deletions(-)

diff --git a/arch/x86/boot/compressed/head_32.S 
b/arch/x86/boot/compressed/head_32.S
index 03557f2..39f0bb4 100644
--- a/arch/x86/boot/compressed/head_32.S
+++ b/arch/x86/boot/compressed/head_32.S
@@ -49,16 +49,13 @@
  * Position Independent Executable (PIE) so that linker won't optimize
  * R_386_GOT32X relocation to its fixed symbol address.  Older
  * linkers generate R_386_32 relocations against locally defined symbols,
- * _bss, _ebss, _got, _egot and _end, in PIE.  It isn't wrong, just less
- * optimal than R_386_RELATIVE.  But the x86 kernel fails to properly handle
- * R_386_32 relocations when relocating the kernel.  To generate
- * R_386_RELATIVE relocations, we mark _bss, _ebss, _got, _egot and _end as
- * hidden:
+ * _bss, _ebss and _end, in PIE.  It isn't wrong, just less optimal than
+ * R_386_RELATIVE.  But the x86 kernel fails to properly handle R_386_32
+ * relocations when relocating the kernel.  To generate R_386_RELATIVE
+ * relocations, we mark _bss, _ebss and _end as hidden:
  */
.hidden _bss
.hidden _ebss
-   .hidden _got
-   .hidden _egot
.hidden _end
 
__HEAD
@@ -193,19 +190,6 @@ SYM_FUNC_START_LOCAL_NOALIGN(.Lrelocated)
rep stosl
 
 /*
- * Adjust our own GOT
- */
-   leal_got(%ebx), %edx
-   leal_egot(%ebx), %ecx
-1:
-   cmpl%ecx, %edx
-   jae 2f
-   addl%ebx, (%edx)
-   addl$4, %edx
-   jmp 1b
-2:
-
-/*
  * Do the extraction, and jump to the new kernel..
  */
/* push arguments for extract_kernel: */
diff --git a/arch/x86/boot/compressed/head_64.S 
b/arch/x86/boot/compressed/head_64.S
index 97d37f0..bf1ab30 100644
--- a/arch/x86/boot/compressed/head_64.S
+++ b/arch/x86/boot/compressed/head_64.S
@@ -40,8 +40,6 @@
  */
.hidden _bss
.hidden _ebss
-   .hidden _got
-   .hidden _egot
.hidden _end
 
__HEAD
@@ -354,25 +352,6 @@ SYM_CODE_START(startup_64)
leaqboot_stack_end(%rbx), %rsp
 
/*
-* paging_prepare() and cleanup_trampoline() below can have GOT
-* references. Adjust the table with address we are running at.
-*
-* Zero RAX for adjust_got: the GOT was not adjusted before;
-* there's no adjustment to undo.
-*/
-   xorq%rax, %rax
-
-   /*
-* Calculate the address the binary is loaded at and use it as
-* a GOT adjustment.
-*/
-   call1f
-1: popq%rdi
-   subq$1b, %rdi
-
-   call.Ladjust_got
-
-   /*
 * At this point we are in long mode with 4-level paging enabled,
 * but we might want to enable 5-level paging or vice versa.
 *
@@ -464,21 +443,6 @@ trampoline_return:
pushq   $0
popfq
 
-   /*
-* Previously we've adjusted the GOT with address the binary was
-* loaded at. Now we need to re-adjust for relocation address.
-*
-* Calculate the address the binary is loaded at, so that we can
-* undo the previous GOT adjustment.
-*/
-   call1f
-1: popq%rax
-   subq$1b, %rax
-
-   /* The new adjustment is the relocation address */
-   movq%rbx, %rdi
-   call.Ladjust_got
-
 /*
  * Copy the compressed kernel to the end of our buffer
  * where decompression in place becomes safe.
@@ -556,27 +520,6 @@ SYM_FUNC_START_LOCAL_NOALIGN(.Lrelocated)
jmp *%rax
 SYM_FUNC_END(.Lrelocated)
 
-/*
- * Adjust the global offset table
- *
- * RAX is the previous adjustment of the table to undo (use 0 if it's the

[tip: efi/urgent] efi/efivars: Expose RT service availability via efivars abstraction

2020-07-22 Thread tip-bot2 for Ard Biesheuvel
The following commit has been merged into the efi/urgent branch of tip:

Commit-ID: f88814cc2578c121e6edef686365036db72af0ed
Gitweb:
https://git.kernel.org/tip/f88814cc2578c121e6edef686365036db72af0ed
Author:Ard Biesheuvel 
AuthorDate:Wed, 08 Jul 2020 13:01:57 +03:00
Committer: Ard Biesheuvel 
CommitterDate: Thu, 09 Jul 2020 10:14:29 +03:00

efi/efivars: Expose RT service availability via efivars abstraction

Commit

  bf67fad19e493b ("efi: Use more granular check for availability for variable 
services")

introduced a check into the efivarfs, efi-pstore and other drivers that
aborts loading of the module if not all three variable runtime services
(GetVariable, SetVariable and GetNextVariable) are supported. However, this
results in efivarfs being unavailable entirely if only SetVariable support
is missing, which is only needed if you want to make any modifications.
Also, efi-pstore and the sysfs EFI variable interface could be backed by
another implementation of the 'efivars' abstraction, in which case it is
completely irrelevant which services are supported by the EFI firmware.

So make the generic 'efivars' abstraction dependent on the availibility of
the GetVariable and GetNextVariable EFI runtime services, and add a helper
'efivar_supports_writes()' to find out whether the currently active efivars
abstraction supports writes (and wire it up to the availability of
SetVariable for the generic one).

Then, use the efivar_supports_writes() helper to decide whether to permit
efivarfs to be mounted read-write, and whether to enable efi-pstore or the
sysfs EFI variable interface altogether.

Fixes: bf67fad19e493b ("efi: Use more granular check for availability for 
variable services")
Reported-by: Heinrich Schuchardt 
Acked-by: Ilias Apalodimas 
Tested-by: Ilias Apalodimas 
Signed-off-by: Ard Biesheuvel 
---
 drivers/firmware/efi/efi-pstore.c |  5 +
 drivers/firmware/efi/efi.c| 12 
 drivers/firmware/efi/efivars.c|  5 +
 drivers/firmware/efi/vars.c   |  6 ++
 fs/efivarfs/super.c   |  6 +++---
 include/linux/efi.h   |  1 +
 6 files changed, 20 insertions(+), 15 deletions(-)

diff --git a/drivers/firmware/efi/efi-pstore.c 
b/drivers/firmware/efi/efi-pstore.c
index c2f1d4e..feb7fe6 100644
--- a/drivers/firmware/efi/efi-pstore.c
+++ b/drivers/firmware/efi/efi-pstore.c
@@ -356,10 +356,7 @@ static struct pstore_info efi_pstore_info = {
 
 static __init int efivars_pstore_init(void)
 {
-   if (!efi_rt_services_supported(EFI_RT_SUPPORTED_VARIABLE_SERVICES))
-   return 0;
-
-   if (!efivars_kobject())
+   if (!efivars_kobject() || !efivar_supports_writes())
return 0;
 
if (efivars_pstore_disable)
diff --git a/drivers/firmware/efi/efi.c b/drivers/firmware/efi/efi.c
index 5114cae..fdd1db0 100644
--- a/drivers/firmware/efi/efi.c
+++ b/drivers/firmware/efi/efi.c
@@ -176,11 +176,13 @@ static struct efivar_operations generic_ops;
 static int generic_ops_register(void)
 {
generic_ops.get_variable = efi.get_variable;
-   generic_ops.set_variable = efi.set_variable;
-   generic_ops.set_variable_nonblocking = efi.set_variable_nonblocking;
generic_ops.get_next_variable = efi.get_next_variable;
generic_ops.query_variable_store = efi_query_variable_store;
 
+   if (efi_rt_services_supported(EFI_RT_SUPPORTED_SET_VARIABLE)) {
+   generic_ops.set_variable = efi.set_variable;
+   generic_ops.set_variable_nonblocking = 
efi.set_variable_nonblocking;
+   }
return efivars_register(&generic_efivars, &generic_ops, efi_kobj);
 }
 
@@ -382,7 +384,8 @@ static int __init efisubsys_init(void)
return -ENOMEM;
}
 
-   if (efi_rt_services_supported(EFI_RT_SUPPORTED_VARIABLE_SERVICES)) {
+   if (efi_rt_services_supported(EFI_RT_SUPPORTED_GET_VARIABLE |
+ EFI_RT_SUPPORTED_GET_NEXT_VARIABLE_NAME)) 
{
efivar_ssdt_load();
error = generic_ops_register();
if (error)
@@ -416,7 +419,8 @@ static int __init efisubsys_init(void)
 err_remove_group:
sysfs_remove_group(efi_kobj, &efi_subsys_attr_group);
 err_unregister:
-   if (efi_rt_services_supported(EFI_RT_SUPPORTED_VARIABLE_SERVICES))
+   if (efi_rt_services_supported(EFI_RT_SUPPORTED_GET_VARIABLE |
+ EFI_RT_SUPPORTED_GET_NEXT_VARIABLE_NAME))
generic_ops_unregister();
 err_put:
kobject_put(efi_kobj);
diff --git a/drivers/firmware/efi/efivars.c b/drivers/firmware/efi/efivars.c
index 26528a4..dcea137 100644
--- a/drivers/firmware/efi/efivars.c
+++ b/drivers/firmware/efi/efivars.c
@@ -680,11 +680,8 @@ int efivars_sysfs_init(void)
struct kobject *parent_kobj = efivars_kobject();
int error = 0;
 
-   if (!efi_rt_services_supported(EFI_RT_SUPPORTED_VARIABLE_SERVICES))
-   return -ENODE

[tip: efi/urgent] efi: Revert "efi/x86: Fix build with gcc 4"

2020-07-22 Thread tip-bot2 for Ard Biesheuvel
The following commit has been merged into the efi/urgent branch of tip:

Commit-ID: 769e0fe1171e95d90ea5a2d6d0b2bdc7d5d2e7b2
Gitweb:
https://git.kernel.org/tip/769e0fe1171e95d90ea5a2d6d0b2bdc7d5d2e7b2
Author:Ard Biesheuvel 
AuthorDate:Thu, 09 Jul 2020 09:59:57 +03:00
Committer: Ard Biesheuvel 
CommitterDate: Thu, 09 Jul 2020 10:14:29 +03:00

efi: Revert "efi/x86: Fix build with gcc 4"

This reverts commit 5435f73d5c4a1b75, which is no longer needed now
that the minimum GCC version has been bumped to v4.9

Signed-off-by: Ard Biesheuvel 
---
 drivers/firmware/efi/libstub/Makefile | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/drivers/firmware/efi/libstub/Makefile 
b/drivers/firmware/efi/libstub/Makefile
index 4cce372..75daaf2 100644
--- a/drivers/firmware/efi/libstub/Makefile
+++ b/drivers/firmware/efi/libstub/Makefile
@@ -6,8 +6,7 @@
 # enabled, even if doing so doesn't break the build.
 #
 cflags-$(CONFIG_X86_32):= -march=i386
-cflags-$(CONFIG_X86_64):= -mcmodel=small \
-  $(call cc-option,-maccumulate-outgoing-args)
+cflags-$(CONFIG_X86_64):= -mcmodel=small
 cflags-$(CONFIG_X86)   += -m$(BITS) -D__KERNEL__ \
   -fPIC -fno-strict-aliasing -mno-red-zone \
   -mno-mmx -mno-sse -fshort-wchar \


[tip: efi/urgent] efi/libstub: arm: Print CPU boot mode and MMU state at boot

2020-06-19 Thread tip-bot2 for Ard Biesheuvel
The following commit has been merged into the efi/urgent branch of tip:

Commit-ID: 2a55280a3675203496d302463b941834228b9875
Gitweb:
https://git.kernel.org/tip/2a55280a3675203496d302463b941834228b9875
Author:Ard Biesheuvel 
AuthorDate:Sun, 07 Jun 2020 15:41:35 +02:00
Committer: Ard Biesheuvel 
CommitterDate: Wed, 17 Jun 2020 15:29:11 +02:00

efi/libstub: arm: Print CPU boot mode and MMU state at boot

On 32-bit ARM, we may boot at HYP mode, or with the MMU and caches off
(or both), even though the EFI spec does not actually support this.
While booting at HYP mode is something we might tolerate, fiddling
with the caches is a more serious issue, as disabling the caches is
tricky to do safely from C code, and running without the Dcache makes
it impossible to support unaligned memory accesses, which is another
explicit requirement imposed by the EFI spec.

So take note of the CPU mode and MMU state in the EFI stub diagnostic
output so that we can easily diagnose any issues that may arise from
this. E.g.,

  EFI stub: Entering in SVC mode with MMU enabled

Also, capture the CPSR and SCTLR system register values at EFI stub
entry, and after ExitBootServices() returns, and check whether the
MMU and Dcache were disabled at any point. If this is the case, a
diagnostic message like the following will be emitted:

  efi: [Firmware Bug]: EFI stub was entered with MMU and Dcache disabled, 
please fix your firmware!
  efi: CPSR at EFI stub entry: 0x61d3
  efi: SCTLR at EFI stub entry   : 0x00c51838
  efi: CPSR after ExitBootServices() : 0x61d3
  efi: SCTLR after ExitBootServices(): 0x00c50838

Signed-off-by: Ard Biesheuvel 
Reviewed-by: Leif Lindholm 
---
 arch/arm/include/asm/efi.h|  7 +++-
 drivers/firmware/efi/arm-init.c   | 34 +-
 drivers/firmware/efi/libstub/arm32-stub.c | 54 +-
 drivers/firmware/efi/libstub/efi-stub.c   |  3 +-
 drivers/firmware/efi/libstub/efistub.h|  2 +-
 include/linux/efi.h   |  1 +-
 6 files changed, 98 insertions(+), 3 deletions(-)

diff --git a/arch/arm/include/asm/efi.h b/arch/arm/include/asm/efi.h
index 84dc0ba..5dcf3c6 100644
--- a/arch/arm/include/asm/efi.h
+++ b/arch/arm/include/asm/efi.h
@@ -87,4 +87,11 @@ static inline unsigned long efi_get_max_initrd_addr(unsigned 
long dram_base,
return dram_base + SZ_512M;
 }
 
+struct efi_arm_entry_state {
+   u32 cpsr_before_ebs;
+   u32 sctlr_before_ebs;
+   u32 cpsr_after_ebs;
+   u32 sctlr_after_ebs;
+};
+
 #endif /* _ASM_ARM_EFI_H */
diff --git a/drivers/firmware/efi/arm-init.c b/drivers/firmware/efi/arm-init.c
index 6f4baf7..71c445d 100644
--- a/drivers/firmware/efi/arm-init.c
+++ b/drivers/firmware/efi/arm-init.c
@@ -52,9 +52,11 @@ static phys_addr_t __init efi_to_phys(unsigned long addr)
 }
 
 static __initdata unsigned long screen_info_table = EFI_INVALID_TABLE_ADDR;
+static __initdata unsigned long cpu_state_table = EFI_INVALID_TABLE_ADDR;
 
 static const efi_config_table_type_t arch_tables[] __initconst = {
{LINUX_EFI_ARM_SCREEN_INFO_TABLE_GUID, &screen_info_table},
+   {LINUX_EFI_ARM_CPU_STATE_TABLE_GUID, &cpu_state_table},
{}
 };
 
@@ -240,9 +242,37 @@ void __init efi_init(void)
 
init_screen_info();
 
+#ifdef CONFIG_ARM
/* ARM does not permit early mappings to persist across paging_init() */
-   if (IS_ENABLED(CONFIG_ARM))
-   efi_memmap_unmap();
+   efi_memmap_unmap();
+
+   if (cpu_state_table != EFI_INVALID_TABLE_ADDR) {
+   struct efi_arm_entry_state *state;
+   bool dump_state = true;
+
+   state = early_memremap_ro(cpu_state_table,
+ sizeof(struct efi_arm_entry_state));
+   if (state == NULL) {
+   pr_warn("Unable to map CPU entry state table.\n");
+   return;
+   }
+
+   if ((state->sctlr_before_ebs & 1) == 0)
+   pr_warn(FW_BUG "EFI stub was entered with MMU and 
Dcache disabled, please fix your firmware!\n");
+   else if ((state->sctlr_after_ebs & 1) == 0)
+   pr_warn(FW_BUG "ExitBootServices() returned with MMU 
and Dcache disabled, please fix your firmware!\n");
+   else
+   dump_state = false;
+
+   if (dump_state || efi_enabled(EFI_DBG)) {
+   pr_info("CPSR at EFI stub entry: 0x%08x\n", 
state->cpsr_before_ebs);
+   pr_info("SCTLR at EFI stub entry   : 0x%08x\n", 
state->sctlr_before_ebs);
+   pr_info("CPSR after ExitBootServices() : 0x%08x\n", 
state->cpsr_after_ebs);
+   pr_info("SCTLR after ExitBootServices(): 0x%08x\n", 
state->sctlr_after_ebs);
+   }
+   early_memunmap(state, sizeof(struct efi_arm_entry_state));
+   }
+#endif
 }
 

[tip: efi/urgent] efi/libstub: arm: Omit arch specific config table matching array on arm64

2020-06-19 Thread tip-bot2 for Ard Biesheuvel
The following commit has been merged into the efi/urgent branch of tip:

Commit-ID: 62956be8f95b93e9f91ffe2e5aa9c0e411af5a14
Gitweb:
https://git.kernel.org/tip/62956be8f95b93e9f91ffe2e5aa9c0e411af5a14
Author:Ard Biesheuvel 
AuthorDate:Tue, 16 Jun 2020 12:53:30 +02:00
Committer: Ard Biesheuvel 
CommitterDate: Wed, 17 Jun 2020 15:29:11 +02:00

efi/libstub: arm: Omit arch specific config table matching array on arm64

On arm64, the EFI stub is built into the kernel proper, and so the stub
can refer to its symbols directly. Therefore, the practice of using EFI
configuration tables to pass information between them is never needed,
so we can omit any code consuming such tables when building for arm64.

Signed-off-by: Ard Biesheuvel 
Reviewed-by: Leif Lindholm 
---
 drivers/firmware/efi/arm-init.c | 6 --
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/drivers/firmware/efi/arm-init.c b/drivers/firmware/efi/arm-init.c
index c697e70..6f4baf7 100644
--- a/drivers/firmware/efi/arm-init.c
+++ b/drivers/firmware/efi/arm-init.c
@@ -62,7 +62,8 @@ static void __init init_screen_info(void)
 {
struct screen_info *si;
 
-   if (screen_info_table != EFI_INVALID_TABLE_ADDR) {
+   if (IS_ENABLED(CONFIG_ARM) &&
+   screen_info_table != EFI_INVALID_TABLE_ADDR) {
si = early_memremap_ro(screen_info_table, sizeof(*si));
if (!si) {
pr_err("Could not map screen_info config table\n");
@@ -116,7 +117,8 @@ static int __init uefi_init(u64 efi_system_table)
goto out;
}
retval = efi_config_parse_tables(config_tables, systab->nr_tables,
-arch_tables);
+IS_ENABLED(CONFIG_ARM) ? arch_tables
+   : NULL);
 
early_memunmap(config_tables, table_size);
 out:


[tip: efi/urgent] efi/libstub: Fix missing-prototype warning for skip_spaces()

2020-06-19 Thread tip-bot2 for Ard Biesheuvel
The following commit has been merged into the efi/urgent branch of tip:

Commit-ID: 24552d10339f13d2174e013002da3ed90e26adda
Gitweb:
https://git.kernel.org/tip/24552d10339f13d2174e013002da3ed90e26adda
Author:Ard Biesheuvel 
AuthorDate:Mon, 15 Jun 2020 12:31:14 +02:00
Committer: Ard Biesheuvel 
CommitterDate: Mon, 15 Jun 2020 19:43:58 +02:00

efi/libstub: Fix missing-prototype warning for skip_spaces()

Include  into skip_spaces.c to silence a compiler
warning about a missing prototype.

Signed-off-by: Ard Biesheuvel 
---
 drivers/firmware/efi/libstub/skip_spaces.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/firmware/efi/libstub/skip_spaces.c 
b/drivers/firmware/efi/libstub/skip_spaces.c
index a700b3c..159fb4e 100644
--- a/drivers/firmware/efi/libstub/skip_spaces.c
+++ b/drivers/firmware/efi/libstub/skip_spaces.c
@@ -1,6 +1,7 @@
 // SPDX-License-Identifier: GPL-2.0
 
 #include 
+#include 
 #include 
 
 char *skip_spaces(const char *str)


[tip: efi/urgent] efivar/ssdt: Don't iterate over EFI vars if no SSDT override was specified

2019-10-07 Thread tip-bot2 for Ard Biesheuvel
The following commit has been merged into the efi/urgent branch of tip:

Commit-ID: c05f8f92b701576b615f30aac31fabdc0648649b
Gitweb:
https://git.kernel.org/tip/c05f8f92b701576b615f30aac31fabdc0648649b
Author:Ard Biesheuvel 
AuthorDate:Wed, 02 Oct 2019 18:58:59 +02:00
Committer: Ingo Molnar 
CommitterDate: Mon, 07 Oct 2019 15:24:35 +02:00

efivar/ssdt: Don't iterate over EFI vars if no SSDT override was specified

The kernel command line option efivar_ssdt= allows the name to be
specified of an EFI variable containing an ACPI SSDT table that should
be loaded into memory by the OS, and treated as if it was provided by
the firmware.

Currently, that code will always iterate over the EFI variables and
compare each name with the provided name, even if the command line
option wasn't set to begin with.

So bail early when no variable name was provided. This works around a
boot regression on the 2012 Mac Pro, as reported by Scott.

Tested-by: Scott Talbert 
Signed-off-by: Ard Biesheuvel 
Cc:  # v4.9+
Cc: Ben Dooks 
Cc: Dave Young 
Cc: Jarkko Sakkinen 
Cc: Jerry Snitselaar 
Cc: Linus Torvalds 
Cc: Lukas Wunner 
Cc: Lyude Paul 
Cc: Matthew Garrett 
Cc: Octavian Purdila 
Cc: Peter Jones 
Cc: Peter Zijlstra 
Cc: Thomas Gleixner 
Cc: linux-...@vger.kernel.org
Cc: linux-integr...@vger.kernel.org
Fixes: 475fb4e8b2f4 ("efi / ACPI: load SSTDs from EFI variables")
Link: https://lkml.kernel.org/r/20191002165904.8819-3-ard.biesheu...@linaro.org
Signed-off-by: Ingo Molnar 
---
 drivers/firmware/efi/efi.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/firmware/efi/efi.c b/drivers/firmware/efi/efi.c
index 8d3e778..69f00f7 100644
--- a/drivers/firmware/efi/efi.c
+++ b/drivers/firmware/efi/efi.c
@@ -267,6 +267,9 @@ static __init int efivar_ssdt_load(void)
void *data;
int ret;
 
+   if (!efivar_ssdt[0])
+   return 0;
+
ret = efivar_init(efivar_ssdt_iter, &entries, true, &entries);
 
list_for_each_entry_safe(entry, aux, &entries, list) {