The arm64 test machine boot failed when using hulk_defconfig after d63c76835476 ("arm64: efi: Execute runtime services from a dedicated stack"), revert this patch set first for weekly release.
Wei Li (11): Revert "arm64: efi: Make efi_rt_lock a raw_spinlock" Revert "efi: rt-wrapper: Add missing include" Revert "arm64: efi: Recover from synchronous exceptions occurring in firmware" Revert "arm64: efi: Execute runtime services from a dedicated stack" Revert "efi: fix userspace infinite retry read efivars after EFI runtime services page fault" Revert "arm64: efi: Restore register x18 if it was corrupted" Revert "x86/efi: fix a -Wtype-limits compilation warning" Revert "efi: Fix build error due to enum collision between efi.h and ima.h" Revert "efi: Fix debugobjects warning on 'efi_rts_work'" Revert "efi/x86: Handle page faults occurring while running EFI runtime services" Revert "efi: Make efi_rts_work accessible to efi page fault handler"
arch/arm64/include/asm/efi.h | 12 --- arch/arm64/kernel/efi-rt-wrapper.S | 49 +---------- arch/arm64/kernel/efi.c | 50 ----------- arch/arm64/mm/fault.c | 4 - arch/x86/include/asm/efi.h | 1 - arch/x86/mm/fault.c | 9 -- arch/x86/platform/efi/quirks.c | 78 ----------------- drivers/firmware/efi/runtime-wrappers.c | 109 +++++++++++++++--------- include/linux/efi.h | 42 --------- 9 files changed, 70 insertions(+), 284 deletions(-)
hulk inclusion category: bugfix bugzilla: https://gitee.com/openeuler/kernel/issues/I80QRY CVE: NA
--------------------------------
This reverts commit 213aa9a96141dff62378d075c452fc5e5ff72628.
Signed-off-by: Wei Li liwei391@huawei.com --- arch/arm64/include/asm/efi.h | 6 +++--- arch/arm64/kernel/efi.c | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/arch/arm64/include/asm/efi.h b/arch/arm64/include/asm/efi.h index 647ea987da0e..3cc753db9035 100644 --- a/arch/arm64/include/asm/efi.h +++ b/arch/arm64/include/asm/efi.h @@ -34,7 +34,7 @@ int efi_set_mapping_permissions(struct mm_struct *mm, efi_memory_desc_t *md); ({ \ efi_virtmap_load(); \ __efi_fpsimd_begin(); \ - raw_spin_lock(&efi_rt_lock); \ + spin_lock(&efi_rt_lock); \ })
#define arch_efi_call_virt(p, f, args...) \ @@ -46,12 +46,12 @@ int efi_set_mapping_permissions(struct mm_struct *mm, efi_memory_desc_t *md);
#define arch_efi_call_virt_teardown() \ ({ \ - raw_spin_unlock(&efi_rt_lock); \ + spin_unlock(&efi_rt_lock); \ __efi_fpsimd_end(); \ efi_virtmap_unload(); \ })
-extern raw_spinlock_t efi_rt_lock; +extern spinlock_t efi_rt_lock; efi_status_t __efi_rt_asm_wrapper(void *, const char *, ...);
#define ARCH_EFI_IRQ_FLAGS_MASK (PSR_D_BIT | PSR_A_BIT | PSR_I_BIT | PSR_F_BIT) diff --git a/arch/arm64/kernel/efi.c b/arch/arm64/kernel/efi.c index b2a3d5f5d36f..923970fb0394 100644 --- a/arch/arm64/kernel/efi.c +++ b/arch/arm64/kernel/efi.c @@ -133,7 +133,7 @@ asmlinkage efi_status_t efi_handle_corrupted_x18(efi_status_t s, const char *f) return s; }
-DEFINE_RAW_SPINLOCK(efi_rt_lock); +DEFINE_SPINLOCK(efi_rt_lock);
asmlinkage u64 *efi_rt_stack_top __ro_after_init;
hulk inclusion category: bugfix bugzilla: https://gitee.com/openeuler/kernel/issues/I80QRY CVE: NA
--------------------------------
This reverts commit f0e7f15fe27f499de2c2eabed1efb9c7d4e617d5.
Signed-off-by: Wei Li liwei391@huawei.com --- arch/arm64/kernel/efi-rt-wrapper.S | 1 - 1 file changed, 1 deletion(-)
diff --git a/arch/arm64/kernel/efi-rt-wrapper.S b/arch/arm64/kernel/efi-rt-wrapper.S index a9ae26e176f1..6bbc35e61ce1 100644 --- a/arch/arm64/kernel/efi-rt-wrapper.S +++ b/arch/arm64/kernel/efi-rt-wrapper.S @@ -7,7 +7,6 @@ */
#include <linux/linkage.h> -#include <asm/assembler.h>
ENTRY(__efi_rt_asm_wrapper) stp x29, x30, [sp, #-112]!
hulk inclusion category: bugfix bugzilla: https://gitee.com/openeuler/kernel/issues/I80QRY CVE: NA
--------------------------------
This reverts commit 7c55f3f97afa71cde005b5ed89bf7944c6f7c9ec.
Signed-off-by: Wei Li liwei391@huawei.com --- arch/arm64/include/asm/efi.h | 9 ------- arch/arm64/kernel/efi-rt-wrapper.S | 32 ++++--------------------- arch/arm64/kernel/efi.c | 22 ----------------- arch/arm64/mm/fault.c | 4 ---- drivers/firmware/efi/runtime-wrappers.c | 1 - 5 files changed, 5 insertions(+), 63 deletions(-)
diff --git a/arch/arm64/include/asm/efi.h b/arch/arm64/include/asm/efi.h index 3cc753db9035..9e780a68883c 100644 --- a/arch/arm64/include/asm/efi.h +++ b/arch/arm64/include/asm/efi.h @@ -11,20 +11,11 @@ #include <asm/neon.h> #include <asm/ptrace.h> #include <asm/tlbflush.h> -#include <linux/efi.h>
#ifdef CONFIG_EFI extern void efi_init(void); - -bool efi_runtime_fixup_exception(struct pt_regs *regs, const char *msg); #else #define efi_init() - -static inline -bool efi_runtime_fixup_exception(struct pt_regs *regs, const char *msg) -{ - return false; -} #endif
int efi_create_mapping(struct mm_struct *mm, efi_memory_desc_t *md); diff --git a/arch/arm64/kernel/efi-rt-wrapper.S b/arch/arm64/kernel/efi-rt-wrapper.S index 6bbc35e61ce1..27e946550bbc 100644 --- a/arch/arm64/kernel/efi-rt-wrapper.S +++ b/arch/arm64/kernel/efi-rt-wrapper.S @@ -9,7 +9,7 @@ #include <linux/linkage.h>
ENTRY(__efi_rt_asm_wrapper) - stp x29, x30, [sp, #-112]! + stp x29, x30, [sp, #-32]! mov x29, sp
/* @@ -19,21 +19,11 @@ ENTRY(__efi_rt_asm_wrapper) */ stp x1, x18, [sp, #16]
- /* - * Preserve all callee saved registers and preserve the stack pointer - * value at the base of the EFI runtime stack so we can recover from - * synchronous exceptions occurring while executing the firmware - * routines. - */ - stp x19, x20, [sp, #32] - stp x21, x22, [sp, #48] - stp x23, x24, [sp, #64] - stp x25, x26, [sp, #80] - stp x27, x28, [sp, #96] - ldr_l x16, efi_rt_stack_top mov sp, x16 - stp x18, x29, [sp, #-16]! +#ifdef CONFIG_SHADOW_CALL_STACK + str x18, [sp, #-16]! +#endif
/* * We are lucky enough that no EFI runtime services take more than @@ -51,7 +41,7 @@ ENTRY(__efi_rt_asm_wrapper) mov sp, x29 ldp x1, x2, [sp, #16] cmp x2, x18 - ldp x29, x30, [sp], #112 + ldp x29, x30, [sp], #32 b.ne 0f ret 0: @@ -69,15 +59,3 @@ ENTRY(__efi_rt_asm_wrapper)
b efi_handle_corrupted_x18 // tail call ENDPROC(__efi_rt_asm_wrapper) - -ENTRY(__efi_rt_asm_recover) - mov sp, x30 - - ldp x19, x20, [sp, #32] - ldp x21, x22, [sp, #48] - ldp x23, x24, [sp, #64] - ldp x25, x26, [sp, #80] - ldp x27, x28, [sp, #96] - ldp x29, x30, [sp], #112 - ret -ENDPROC(__efi_rt_asm_recover) diff --git a/arch/arm64/kernel/efi.c b/arch/arm64/kernel/efi.c index 923970fb0394..fb7f5e9e8114 100644 --- a/arch/arm64/kernel/efi.c +++ b/arch/arm64/kernel/efi.c @@ -137,28 +137,6 @@ DEFINE_SPINLOCK(efi_rt_lock);
asmlinkage u64 *efi_rt_stack_top __ro_after_init;
-asmlinkage efi_status_t __efi_rt_asm_recover(void); - -bool efi_runtime_fixup_exception(struct pt_regs *regs, const char *msg) -{ - /* Check whether the exception occurred while running the firmware */ - if (current_work() != &efi_rts_work.work || regs->pc >= TASK_SIZE_64) - return false; - - pr_err(FW_BUG "Unable to handle %s in EFI runtime service\n", msg); - add_taint(TAINT_FIRMWARE_WORKAROUND, LOCKDEP_STILL_OK); - clear_bit(EFI_RUNTIME_SERVICES, &efi.flags); - - regs->regs[0] = EFI_ABORTED; - regs->regs[30] = efi_rt_stack_top[-1]; - regs->pc = (u64)__efi_rt_asm_recover; - - if (IS_ENABLED(CONFIG_SHADOW_CALL_STACK)) - regs->regs[18] = efi_rt_stack_top[-2]; - - return true; -} - /* EFI requires 8 KiB of stack space for runtime services */ static_assert(THREAD_SIZE >= SZ_8K);
diff --git a/arch/arm64/mm/fault.c b/arch/arm64/mm/fault.c index a3c33ccecd83..96bfdade877a 100644 --- a/arch/arm64/mm/fault.c +++ b/arch/arm64/mm/fault.c @@ -37,7 +37,6 @@ #include <asm/bug.h> #include <asm/cmpxchg.h> #include <asm/cpufeature.h> -#include <asm/efi.h> #include <asm/exception.h> #include <asm/daifflags.h> #include <asm/debug-monitors.h> @@ -333,9 +332,6 @@ static void __do_kernel_fault(unsigned long addr, unsigned int esr, msg = "paging request"; }
- if (efi_runtime_fixup_exception(regs, msg)) - return; - die_kernel_fault(msg, addr, esr, regs); }
diff --git a/drivers/firmware/efi/runtime-wrappers.c b/drivers/firmware/efi/runtime-wrappers.c index cba62aded6d1..f40c0e215f84 100644 --- a/drivers/firmware/efi/runtime-wrappers.c +++ b/drivers/firmware/efi/runtime-wrappers.c @@ -85,7 +85,6 @@ struct efi_runtime_work efi_rts_work; else \ pr_err("Failed to queue work to efi_rts_wq.\n"); \ \ - WARN_ON_ONCE(efi_rts_work.status == EFI_ABORTED); \ exit: \ efi_rts_work.efi_rts_id = EFI_NONE; \ efi_rts_work.status; \
hulk inclusion category: bugfix bugzilla: https://gitee.com/openeuler/kernel/issues/I80QRY CVE: NA
--------------------------------
This reverts commit d63c76835476f9cb183af549d790dc7893cd07b8.
Signed-off-by: Wei Li liwei391@huawei.com --- arch/arm64/include/asm/efi.h | 3 --- arch/arm64/kernel/efi-rt-wrapper.S | 13 +------------ arch/arm64/kernel/efi.c | 28 ---------------------------- 3 files changed, 1 insertion(+), 43 deletions(-)
diff --git a/arch/arm64/include/asm/efi.h b/arch/arm64/include/asm/efi.h index 9e780a68883c..d3cb42fd51ec 100644 --- a/arch/arm64/include/asm/efi.h +++ b/arch/arm64/include/asm/efi.h @@ -25,7 +25,6 @@ int efi_set_mapping_permissions(struct mm_struct *mm, efi_memory_desc_t *md); ({ \ efi_virtmap_load(); \ __efi_fpsimd_begin(); \ - spin_lock(&efi_rt_lock); \ })
#define arch_efi_call_virt(p, f, args...) \ @@ -37,12 +36,10 @@ int efi_set_mapping_permissions(struct mm_struct *mm, efi_memory_desc_t *md);
#define arch_efi_call_virt_teardown() \ ({ \ - spin_unlock(&efi_rt_lock); \ __efi_fpsimd_end(); \ efi_virtmap_unload(); \ })
-extern spinlock_t efi_rt_lock; efi_status_t __efi_rt_asm_wrapper(void *, const char *, ...);
#define ARCH_EFI_IRQ_FLAGS_MASK (PSR_D_BIT | PSR_A_BIT | PSR_I_BIT | PSR_F_BIT) diff --git a/arch/arm64/kernel/efi-rt-wrapper.S b/arch/arm64/kernel/efi-rt-wrapper.S index 27e946550bbc..e02329e79ee1 100644 --- a/arch/arm64/kernel/efi-rt-wrapper.S +++ b/arch/arm64/kernel/efi-rt-wrapper.S @@ -19,12 +19,6 @@ ENTRY(__efi_rt_asm_wrapper) */ stp x1, x18, [sp, #16]
- ldr_l x16, efi_rt_stack_top - mov sp, x16 -#ifdef CONFIG_SHADOW_CALL_STACK - str x18, [sp, #-16]! -#endif - /* * We are lucky enough that no EFI runtime services take more than * 5 arguments, so all are passed in registers rather than via the @@ -38,7 +32,6 @@ ENTRY(__efi_rt_asm_wrapper) mov x4, x6 blr x8
- mov sp, x29 ldp x1, x2, [sp, #16] cmp x2, x18 ldp x29, x30, [sp], #32 @@ -52,10 +45,6 @@ ENTRY(__efi_rt_asm_wrapper) * called with preemption disabled and a separate shadow stack is used * for interrupts. */ -#ifdef CONFIG_SHADOW_CALL_STACK - ldr_l x18, efi_rt_stack_top - ldr x18, [x18, #-16] -#endif - + mov x18, x2 b efi_handle_corrupted_x18 // tail call ENDPROC(__efi_rt_asm_wrapper) diff --git a/arch/arm64/kernel/efi.c b/arch/arm64/kernel/efi.c index fb7f5e9e8114..4f9acb5fbe97 100644 --- a/arch/arm64/kernel/efi.c +++ b/arch/arm64/kernel/efi.c @@ -132,31 +132,3 @@ asmlinkage efi_status_t efi_handle_corrupted_x18(efi_status_t s, const char *f) pr_err_ratelimited(FW_BUG "register x18 corrupted by EFI %s\n", f); return s; } - -DEFINE_SPINLOCK(efi_rt_lock); - -asmlinkage u64 *efi_rt_stack_top __ro_after_init; - -/* EFI requires 8 KiB of stack space for runtime services */ -static_assert(THREAD_SIZE >= SZ_8K); - -static int __init arm64_efi_rt_init(void) -{ - void *p; - - if (!efi_enabled(EFI_RUNTIME_SERVICES)) - return 0; - - p = __vmalloc_node(THREAD_SIZE, THREAD_ALIGN, GFP_KERNEL, - PAGE_KERNEL, 0, - NUMA_NO_NODE, &&l); -l: if (!p) { - pr_warn("Failed to allocate EFI runtime stack\n"); - clear_bit(EFI_RUNTIME_SERVICES, &efi.flags); - return -ENOMEM; - } - - efi_rt_stack_top = p + THREAD_SIZE; - return 0; -} -core_initcall(arm64_efi_rt_init);
hulk inclusion category: bugfix bugzilla: https://gitee.com/openeuler/kernel/issues/I80QRY CVE: NA
--------------------------------
This reverts commit f5f7537c9af36d6eb10cb6ca7ca92842847d214f.
Signed-off-by: Wei Li liwei391@huawei.com --- drivers/firmware/efi/runtime-wrappers.c | 1 - 1 file changed, 1 deletion(-)
diff --git a/drivers/firmware/efi/runtime-wrappers.c b/drivers/firmware/efi/runtime-wrappers.c index f40c0e215f84..3e8b3e3b8757 100644 --- a/drivers/firmware/efi/runtime-wrappers.c +++ b/drivers/firmware/efi/runtime-wrappers.c @@ -63,7 +63,6 @@ struct efi_runtime_work efi_rts_work; \ if (!efi_enabled(EFI_RUNTIME_SERVICES)) { \ pr_warn_once("EFI Runtime Services are disabled!\n"); \ - efi_rts_work.status = EFI_DEVICE_ERROR; \ goto exit; \ } \ \
hulk inclusion category: bugfix bugzilla: https://gitee.com/openeuler/kernel/issues/I80QRY CVE: NA
--------------------------------
This reverts commit 1928ac07d3de3fe15eb6fe6ad3f1c1370dba3d9e.
Signed-off-by: Wei Li liwei391@huawei.com --- arch/arm64/kernel/efi-rt-wrapper.S | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-)
diff --git a/arch/arm64/kernel/efi-rt-wrapper.S b/arch/arm64/kernel/efi-rt-wrapper.S index e02329e79ee1..05235ebb336d 100644 --- a/arch/arm64/kernel/efi-rt-wrapper.S +++ b/arch/arm64/kernel/efi-rt-wrapper.S @@ -37,14 +37,5 @@ ENTRY(__efi_rt_asm_wrapper) ldp x29, x30, [sp], #32 b.ne 0f ret -0: - /* - * With CONFIG_SHADOW_CALL_STACK, the kernel uses x18 to store a - * shadow stack pointer, which we need to restore before returning to - * potentially instrumented code. This is safe because the wrapper is - * called with preemption disabled and a separate shadow stack is used - * for interrupts. - */ - mov x18, x2 - b efi_handle_corrupted_x18 // tail call +0: b efi_handle_corrupted_x18 // tail call ENDPROC(__efi_rt_asm_wrapper)
hulk inclusion category: bugfix bugzilla: https://gitee.com/openeuler/kernel/issues/I80QRY CVE: NA
--------------------------------
This reverts commit 3a3a00dcf508dbf9552094675db7c4ba1793e0cf.
Signed-off-by: Wei Li liwei391@huawei.com --- arch/x86/platform/efi/quirks.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/x86/platform/efi/quirks.c b/arch/x86/platform/efi/quirks.c index d80603886a29..b21d8ebf694c 100644 --- a/arch/x86/platform/efi/quirks.c +++ b/arch/x86/platform/efi/quirks.c @@ -683,7 +683,7 @@ void efi_recover_from_page_fault(unsigned long phys_addr) * Address range 0x0000 - 0x0fff is always mapped in the efi_pgd, so * page faulting on these addresses isn't expected. */ - if (phys_addr <= 0x0fff) + if (phys_addr >= 0x0000 && phys_addr <= 0x0fff) return;
/*
hulk inclusion category: bugfix bugzilla: https://gitee.com/openeuler/kernel/issues/I80QRY CVE: NA
--------------------------------
This reverts commit 684683269ea8d9a0e0e6672df47dd92d752f90c6.
Signed-off-by: Wei Li liwei391@huawei.com --- arch/x86/platform/efi/quirks.c | 4 +-- drivers/firmware/efi/runtime-wrappers.c | 48 ++++++++++++------------- include/linux/efi.h | 26 +++++++------- 3 files changed, 39 insertions(+), 39 deletions(-)
diff --git a/arch/x86/platform/efi/quirks.c b/arch/x86/platform/efi/quirks.c index b21d8ebf694c..bd4806267456 100644 --- a/arch/x86/platform/efi/quirks.c +++ b/arch/x86/platform/efi/quirks.c @@ -676,7 +676,7 @@ void efi_recover_from_page_fault(unsigned long phys_addr) * "efi_mm" cannot be used to check if the page fault had occurred * in the firmware context because efi=old_map doesn't use efi_pgd. */ - if (efi_rts_work.efi_rts_id == EFI_NONE) + if (efi_rts_work.efi_rts_id == NONE) return;
/* @@ -701,7 +701,7 @@ void efi_recover_from_page_fault(unsigned long phys_addr) * because this case occurs *very* rarely and hence could be improved * on a need by basis. */ - if (efi_rts_work.efi_rts_id == EFI_RESET_SYSTEM) { + if (efi_rts_work.efi_rts_id == RESET_SYSTEM) { pr_info("efi_reset_system() buggy! Reboot through BIOS\n"); machine_real_restart(MRR_BIOS); return; diff --git a/drivers/firmware/efi/runtime-wrappers.c b/drivers/firmware/efi/runtime-wrappers.c index 3e8b3e3b8757..d901951208b4 100644 --- a/drivers/firmware/efi/runtime-wrappers.c +++ b/drivers/firmware/efi/runtime-wrappers.c @@ -85,7 +85,7 @@ struct efi_runtime_work efi_rts_work; pr_err("Failed to queue work to efi_rts_wq.\n"); \ \ exit: \ - efi_rts_work.efi_rts_id = EFI_NONE; \ + efi_rts_work.efi_rts_id = NONE; \ efi_rts_work.status; \ })
@@ -188,50 +188,50 @@ static void efi_call_rts(struct work_struct *work) arg5 = efi_rts_work.arg5;
switch (efi_rts_work.efi_rts_id) { - case EFI_GET_TIME: + case GET_TIME: status = efi_call_virt(get_time, (efi_time_t *)arg1, (efi_time_cap_t *)arg2); break; - case EFI_SET_TIME: + case SET_TIME: status = efi_call_virt(set_time, (efi_time_t *)arg1); break; - case EFI_GET_WAKEUP_TIME: + case GET_WAKEUP_TIME: status = efi_call_virt(get_wakeup_time, (efi_bool_t *)arg1, (efi_bool_t *)arg2, (efi_time_t *)arg3); break; - case EFI_SET_WAKEUP_TIME: + case SET_WAKEUP_TIME: status = efi_call_virt(set_wakeup_time, *(efi_bool_t *)arg1, (efi_time_t *)arg2); break; - case EFI_GET_VARIABLE: + case GET_VARIABLE: status = efi_call_virt(get_variable, (efi_char16_t *)arg1, (efi_guid_t *)arg2, (u32 *)arg3, (unsigned long *)arg4, (void *)arg5); break; - case EFI_GET_NEXT_VARIABLE: + case GET_NEXT_VARIABLE: status = efi_call_virt(get_next_variable, (unsigned long *)arg1, (efi_char16_t *)arg2, (efi_guid_t *)arg3); break; - case EFI_SET_VARIABLE: + case SET_VARIABLE: status = efi_call_virt(set_variable, (efi_char16_t *)arg1, (efi_guid_t *)arg2, *(u32 *)arg3, *(unsigned long *)arg4, (void *)arg5); break; - case EFI_QUERY_VARIABLE_INFO: + case QUERY_VARIABLE_INFO: status = efi_call_virt(query_variable_info, *(u32 *)arg1, (u64 *)arg2, (u64 *)arg3, (u64 *)arg4); break; - case EFI_GET_NEXT_HIGH_MONO_COUNT: + case GET_NEXT_HIGH_MONO_COUNT: status = efi_call_virt(get_next_high_mono_count, (u32 *)arg1); break; - case EFI_UPDATE_CAPSULE: + case UPDATE_CAPSULE: status = efi_call_virt(update_capsule, (efi_capsule_header_t **)arg1, *(unsigned long *)arg2, *(unsigned long *)arg3); break; - case EFI_QUERY_CAPSULE_CAPS: + case QUERY_CAPSULE_CAPS: status = efi_call_virt(query_capsule_caps, (efi_capsule_header_t **)arg1, *(unsigned long *)arg2, (u64 *)arg3, @@ -255,7 +255,7 @@ static efi_status_t virt_efi_get_time(efi_time_t *tm, efi_time_cap_t *tc)
if (down_interruptible(&efi_runtime_lock)) return EFI_ABORTED; - status = efi_queue_work(EFI_GET_TIME, tm, tc, NULL, NULL, NULL); + status = efi_queue_work(GET_TIME, tm, tc, NULL, NULL, NULL); up(&efi_runtime_lock); return status; } @@ -266,7 +266,7 @@ static efi_status_t virt_efi_set_time(efi_time_t *tm)
if (down_interruptible(&efi_runtime_lock)) return EFI_ABORTED; - status = efi_queue_work(EFI_SET_TIME, tm, NULL, NULL, NULL, NULL); + status = efi_queue_work(SET_TIME, tm, NULL, NULL, NULL, NULL); up(&efi_runtime_lock); return status; } @@ -279,7 +279,7 @@ static efi_status_t virt_efi_get_wakeup_time(efi_bool_t *enabled,
if (down_interruptible(&efi_runtime_lock)) return EFI_ABORTED; - status = efi_queue_work(EFI_GET_WAKEUP_TIME, enabled, pending, tm, NULL, + status = efi_queue_work(GET_WAKEUP_TIME, enabled, pending, tm, NULL, NULL); up(&efi_runtime_lock); return status; @@ -291,7 +291,7 @@ static efi_status_t virt_efi_set_wakeup_time(efi_bool_t enabled, efi_time_t *tm)
if (down_interruptible(&efi_runtime_lock)) return EFI_ABORTED; - status = efi_queue_work(EFI_SET_WAKEUP_TIME, &enabled, tm, NULL, NULL, + status = efi_queue_work(SET_WAKEUP_TIME, &enabled, tm, NULL, NULL, NULL); up(&efi_runtime_lock); return status; @@ -307,7 +307,7 @@ static efi_status_t virt_efi_get_variable(efi_char16_t *name,
if (down_interruptible(&efi_runtime_lock)) return EFI_ABORTED; - status = efi_queue_work(EFI_GET_VARIABLE, name, vendor, attr, data_size, + status = efi_queue_work(GET_VARIABLE, name, vendor, attr, data_size, data); up(&efi_runtime_lock); return status; @@ -321,7 +321,7 @@ static efi_status_t virt_efi_get_next_variable(unsigned long *name_size,
if (down_interruptible(&efi_runtime_lock)) return EFI_ABORTED; - status = efi_queue_work(EFI_GET_NEXT_VARIABLE, name_size, name, vendor, + status = efi_queue_work(GET_NEXT_VARIABLE, name_size, name, vendor, NULL, NULL); up(&efi_runtime_lock); return status; @@ -337,7 +337,7 @@ static efi_status_t virt_efi_set_variable(efi_char16_t *name,
if (down_interruptible(&efi_runtime_lock)) return EFI_ABORTED; - status = efi_queue_work(EFI_SET_VARIABLE, name, vendor, &attr, &data_size, + status = efi_queue_work(SET_VARIABLE, name, vendor, &attr, &data_size, data); up(&efi_runtime_lock); return status; @@ -372,7 +372,7 @@ static efi_status_t virt_efi_query_variable_info(u32 attr,
if (down_interruptible(&efi_runtime_lock)) return EFI_ABORTED; - status = efi_queue_work(EFI_QUERY_VARIABLE_INFO, &attr, storage_space, + status = efi_queue_work(QUERY_VARIABLE_INFO, &attr, storage_space, remaining_space, max_variable_size, NULL); up(&efi_runtime_lock); return status; @@ -404,7 +404,7 @@ static efi_status_t virt_efi_get_next_high_mono_count(u32 *count)
if (down_interruptible(&efi_runtime_lock)) return EFI_ABORTED; - status = efi_queue_work(EFI_GET_NEXT_HIGH_MONO_COUNT, count, NULL, NULL, + status = efi_queue_work(GET_NEXT_HIGH_MONO_COUNT, count, NULL, NULL, NULL, NULL); up(&efi_runtime_lock); return status; @@ -420,7 +420,7 @@ static void virt_efi_reset_system(int reset_type, "could not get exclusive access to the firmware\n"); return; } - efi_rts_work.efi_rts_id = EFI_RESET_SYSTEM; + efi_rts_work.efi_rts_id = RESET_SYSTEM; __efi_call_virt(reset_system, reset_type, status, data_size, data); up(&efi_runtime_lock); } @@ -436,7 +436,7 @@ static efi_status_t virt_efi_update_capsule(efi_capsule_header_t **capsules,
if (down_interruptible(&efi_runtime_lock)) return EFI_ABORTED; - status = efi_queue_work(EFI_UPDATE_CAPSULE, capsules, &count, &sg_list, + status = efi_queue_work(UPDATE_CAPSULE, capsules, &count, &sg_list, NULL, NULL); up(&efi_runtime_lock); return status; @@ -454,7 +454,7 @@ static efi_status_t virt_efi_query_capsule_caps(efi_capsule_header_t **capsules,
if (down_interruptible(&efi_runtime_lock)) return EFI_ABORTED; - status = efi_queue_work(EFI_QUERY_CAPSULE_CAPS, capsules, &count, + status = efi_queue_work(QUERY_CAPSULE_CAPS, capsules, &count, max_size, reset_type, NULL); up(&efi_runtime_lock); return status; diff --git a/include/linux/efi.h b/include/linux/efi.h index 8fbab420b265..e691426def2d 100644 --- a/include/linux/efi.h +++ b/include/linux/efi.h @@ -1690,19 +1690,19 @@ extern int efi_tpm_eventlog_init(void); * fault happened while executing an efi runtime service. */ enum efi_rts_ids { - EFI_NONE, - EFI_GET_TIME, - EFI_SET_TIME, - EFI_GET_WAKEUP_TIME, - EFI_SET_WAKEUP_TIME, - EFI_GET_VARIABLE, - EFI_GET_NEXT_VARIABLE, - EFI_SET_VARIABLE, - EFI_QUERY_VARIABLE_INFO, - EFI_GET_NEXT_HIGH_MONO_COUNT, - EFI_RESET_SYSTEM, - EFI_UPDATE_CAPSULE, - EFI_QUERY_CAPSULE_CAPS, + NONE, + GET_TIME, + SET_TIME, + GET_WAKEUP_TIME, + SET_WAKEUP_TIME, + GET_VARIABLE, + GET_NEXT_VARIABLE, + SET_VARIABLE, + QUERY_VARIABLE_INFO, + GET_NEXT_HIGH_MONO_COUNT, + RESET_SYSTEM, + UPDATE_CAPSULE, + QUERY_CAPSULE_CAPS, };
/*
hulk inclusion category: bugfix bugzilla: https://gitee.com/openeuler/kernel/issues/I80QRY CVE: NA
--------------------------------
This reverts commit 8b1b60589bd87f4ea35a923c6cb5e26cc55433a6.
Signed-off-by: Wei Li liwei391@huawei.com --- drivers/firmware/efi/runtime-wrappers.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/firmware/efi/runtime-wrappers.c b/drivers/firmware/efi/runtime-wrappers.c index d901951208b4..7ac5e4fdf458 100644 --- a/drivers/firmware/efi/runtime-wrappers.c +++ b/drivers/firmware/efi/runtime-wrappers.c @@ -67,7 +67,7 @@ struct efi_runtime_work efi_rts_work; } \ \ init_completion(&efi_rts_work.efi_rts_comp); \ - INIT_WORK(&efi_rts_work.work, efi_call_rts); \ + INIT_WORK_ONSTACK(&efi_rts_work.work, efi_call_rts); \ efi_rts_work.arg1 = _arg1; \ efi_rts_work.arg2 = _arg2; \ efi_rts_work.arg3 = _arg3; \
hulk inclusion category: bugfix bugzilla: https://gitee.com/openeuler/kernel/issues/I80QRY CVE: NA
--------------------------------
This reverts commit f0c06317189db11e7f4f8c794c2031b6807c71b0.
Signed-off-by: Wei Li liwei391@huawei.com --- arch/x86/include/asm/efi.h | 1 - arch/x86/mm/fault.c | 9 --- arch/x86/platform/efi/quirks.c | 78 ------------------------- drivers/firmware/efi/runtime-wrappers.c | 8 --- include/linux/efi.h | 8 +-- 5 files changed, 1 insertion(+), 103 deletions(-)
diff --git a/arch/x86/include/asm/efi.h b/arch/x86/include/asm/efi.h index eea57447ee56..00aa9de5abbb 100644 --- a/arch/x86/include/asm/efi.h +++ b/arch/x86/include/asm/efi.h @@ -137,7 +137,6 @@ 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);
struct efi_setup_data { u64 fw_vendor; diff --git a/arch/x86/mm/fault.c b/arch/x86/mm/fault.c index a9d03d3bacec..52c8cbbd5a65 100644 --- a/arch/x86/mm/fault.c +++ b/arch/x86/mm/fault.c @@ -16,7 +16,6 @@ #include <linux/prefetch.h> /* prefetchw */ #include <linux/context_tracking.h> /* exception_enter(), ... */ #include <linux/uaccess.h> /* faulthandler_disabled() */ -#include <linux/efi.h> /* efi_recover_from_page_fault()*/ #include <linux/mm_types.h>
#include <asm/cpufeature.h> /* boot_cpu_has, ... */ @@ -26,7 +25,6 @@ #include <asm/vsyscall.h> /* emulate_vsyscall */ #include <asm/vm86.h> /* struct vm86 */ #include <asm/mmu_context.h> /* vma_pkey() */ -#include <asm/efi.h> /* efi_recover_from_page_fault()*/
#define CREATE_TRACE_POINTS #include <asm/trace/exceptions.h> @@ -807,13 +805,6 @@ no_context(struct pt_regs *regs, unsigned long error_code, if (is_errata93(regs, address)) return;
- /* - * Buggy firmware could access regions which might page fault, try to - * recover from such faults. - */ - if (IS_ENABLED(CONFIG_EFI)) - efi_recover_from_page_fault(address); - /* * Oops. The kernel tried to access some bad page. We'll have to * terminate things with extreme prejudice: diff --git a/arch/x86/platform/efi/quirks.c b/arch/x86/platform/efi/quirks.c index bd4806267456..006eb09e9587 100644 --- a/arch/x86/platform/efi/quirks.c +++ b/arch/x86/platform/efi/quirks.c @@ -16,7 +16,6 @@ #include <asm/efi.h> #include <asm/uv/uv.h> #include <asm/cpu_device_id.h> -#include <asm/reboot.h>
#define EFI_MIN_RESERVE 5120
@@ -654,80 +653,3 @@ int efi_capsule_setup_info(struct capsule_info *cap_info, void *kbuff, }
#endif - -/* - * If any access by any efi runtime service causes a page fault, then, - * 1. If it's efi_reset_system(), reboot through BIOS. - * 2. If any other efi runtime service, then - * a. Return error status to the efi caller process. - * b. Disable EFI Runtime Services forever and - * c. Freeze efi_rts_wq and schedule new process. - * - * @return: Returns, if the page fault is not handled. This function - * will never return if the page fault is handled successfully. - */ -void efi_recover_from_page_fault(unsigned long phys_addr) -{ - if (!IS_ENABLED(CONFIG_X86_64)) - return; - - /* - * Make sure that an efi runtime service caused the page fault. - * "efi_mm" cannot be used to check if the page fault had occurred - * in the firmware context because efi=old_map doesn't use efi_pgd. - */ - if (efi_rts_work.efi_rts_id == NONE) - return; - - /* - * Address range 0x0000 - 0x0fff is always mapped in the efi_pgd, so - * page faulting on these addresses isn't expected. - */ - if (phys_addr >= 0x0000 && phys_addr <= 0x0fff) - return; - - /* - * Print stack trace as it might be useful to know which EFI Runtime - * Service is buggy. - */ - WARN(1, FW_BUG "Page fault caused by firmware at PA: 0x%lx\n", - phys_addr); - - /* - * Buggy efi_reset_system() is handled differently from other EFI - * Runtime Services as it doesn't use efi_rts_wq. Although, - * native_machine_emergency_restart() says that machine_real_restart() - * could fail, it's better not to compilcate this fault handler - * because this case occurs *very* rarely and hence could be improved - * on a need by basis. - */ - if (efi_rts_work.efi_rts_id == RESET_SYSTEM) { - pr_info("efi_reset_system() buggy! Reboot through BIOS\n"); - machine_real_restart(MRR_BIOS); - return; - } - - /* - * Before calling EFI Runtime Service, the kernel has switched the - * calling process to efi_mm. Hence, switch back to task_mm. - */ - arch_efi_call_virt_teardown(); - - /* Signal error status to the efi caller process */ - efi_rts_work.status = EFI_ABORTED; - complete(&efi_rts_work.efi_rts_comp); - - clear_bit(EFI_RUNTIME_SERVICES, &efi.flags); - pr_info("Froze efi_rts_wq and disabled EFI Runtime Services\n"); - - /* - * Call schedule() in an infinite loop, so that any spurious wake ups - * will never run efi_rts_wq again. - */ - for (;;) { - set_current_state(TASK_IDLE); - schedule(); - } - - return; -} diff --git a/drivers/firmware/efi/runtime-wrappers.c b/drivers/firmware/efi/runtime-wrappers.c index 7ac5e4fdf458..0c3481b80578 100644 --- a/drivers/firmware/efi/runtime-wrappers.c +++ b/drivers/firmware/efi/runtime-wrappers.c @@ -61,11 +61,6 @@ struct efi_runtime_work efi_rts_work; ({ \ efi_rts_work.status = EFI_ABORTED; \ \ - if (!efi_enabled(EFI_RUNTIME_SERVICES)) { \ - pr_warn_once("EFI Runtime Services are disabled!\n"); \ - goto exit; \ - } \ - \ init_completion(&efi_rts_work.efi_rts_comp); \ INIT_WORK_ONSTACK(&efi_rts_work.work, efi_call_rts); \ efi_rts_work.arg1 = _arg1; \ @@ -84,8 +79,6 @@ struct efi_runtime_work efi_rts_work; else \ pr_err("Failed to queue work to efi_rts_wq.\n"); \ \ -exit: \ - efi_rts_work.efi_rts_id = NONE; \ efi_rts_work.status; \ })
@@ -420,7 +413,6 @@ static void virt_efi_reset_system(int reset_type, "could not get exclusive access to the firmware\n"); return; } - efi_rts_work.efi_rts_id = RESET_SYSTEM; __efi_call_virt(reset_system, reset_type, status, data_size, data); up(&efi_runtime_lock); } diff --git a/include/linux/efi.h b/include/linux/efi.h index e691426def2d..4d0be16f04c3 100644 --- a/include/linux/efi.h +++ b/include/linux/efi.h @@ -1684,13 +1684,8 @@ struct linux_efi_tpm_eventlog {
extern int efi_tpm_eventlog_init(void);
-/* - * efi_runtime_service() function identifiers. - * "NONE" is used by efi_recover_from_page_fault() to check if the page - * fault happened while executing an efi runtime service. - */ +/* efi_runtime_service() function identifiers */ enum efi_rts_ids { - NONE, GET_TIME, SET_TIME, GET_WAKEUP_TIME, @@ -1700,7 +1695,6 @@ enum efi_rts_ids { SET_VARIABLE, QUERY_VARIABLE_INFO, GET_NEXT_HIGH_MONO_COUNT, - RESET_SYSTEM, UPDATE_CAPSULE, QUERY_CAPSULE_CAPS, };
hulk inclusion category: bugfix bugzilla: https://gitee.com/openeuler/kernel/issues/I80QRY CVE: NA
--------------------------------
This reverts commit 8066fc13747cd2806610651492023cac1fc81282.
Signed-off-by: Wei Li liwei391@huawei.com --- drivers/firmware/efi/runtime-wrappers.c | 53 ++++++++++++++++++++----- include/linux/efi.h | 36 ----------------- 2 files changed, 44 insertions(+), 45 deletions(-)
diff --git a/drivers/firmware/efi/runtime-wrappers.c b/drivers/firmware/efi/runtime-wrappers.c index 0c3481b80578..cec6558bf33a 100644 --- a/drivers/firmware/efi/runtime-wrappers.c +++ b/drivers/firmware/efi/runtime-wrappers.c @@ -45,7 +45,39 @@ #define __efi_call_virt(f, args...) \ __efi_call_virt_pointer(efi.systab->runtime, f, args)
-struct efi_runtime_work efi_rts_work; +/* efi_runtime_service() function identifiers */ +enum efi_rts_ids { + GET_TIME, + SET_TIME, + GET_WAKEUP_TIME, + SET_WAKEUP_TIME, + GET_VARIABLE, + GET_NEXT_VARIABLE, + SET_VARIABLE, + QUERY_VARIABLE_INFO, + GET_NEXT_HIGH_MONO_COUNT, + UPDATE_CAPSULE, + QUERY_CAPSULE_CAPS, +}; + +/* + * efi_runtime_work: Details of EFI Runtime Service work + * @arg<1-5>: EFI Runtime Service function arguments + * @status: Status of executing EFI Runtime Service + * @efi_rts_id: EFI Runtime Service function identifier + * @efi_rts_comp: Struct used for handling completions + */ +struct efi_runtime_work { + void *arg1; + void *arg2; + void *arg3; + void *arg4; + void *arg5; + efi_status_t status; + struct work_struct work; + enum efi_rts_ids efi_rts_id; + struct completion efi_rts_comp; +};
/* * efi_queue_work: Queue efi_runtime_service() and wait until it's done @@ -59,6 +91,7 @@ struct efi_runtime_work efi_rts_work; */ #define efi_queue_work(_rts, _arg1, _arg2, _arg3, _arg4, _arg5) \ ({ \ + struct efi_runtime_work efi_rts_work; \ efi_rts_work.status = EFI_ABORTED; \ \ init_completion(&efi_rts_work.efi_rts_comp); \ @@ -171,16 +204,18 @@ extern struct semaphore __efi_uv_runtime_lock __alias(efi_runtime_lock); */ static void efi_call_rts(struct work_struct *work) { + struct efi_runtime_work *efi_rts_work; void *arg1, *arg2, *arg3, *arg4, *arg5; efi_status_t status = EFI_NOT_FOUND;
- arg1 = efi_rts_work.arg1; - arg2 = efi_rts_work.arg2; - arg3 = efi_rts_work.arg3; - arg4 = efi_rts_work.arg4; - arg5 = efi_rts_work.arg5; + efi_rts_work = container_of(work, struct efi_runtime_work, work); + arg1 = efi_rts_work->arg1; + arg2 = efi_rts_work->arg2; + arg3 = efi_rts_work->arg3; + arg4 = efi_rts_work->arg4; + arg5 = efi_rts_work->arg5;
- switch (efi_rts_work.efi_rts_id) { + switch (efi_rts_work->efi_rts_id) { case GET_TIME: status = efi_call_virt(get_time, (efi_time_t *)arg1, (efi_time_cap_t *)arg2); @@ -238,8 +273,8 @@ static void efi_call_rts(struct work_struct *work) */ pr_err("Requested executing invalid EFI Runtime Service.\n"); } - efi_rts_work.status = status; - complete(&efi_rts_work.efi_rts_comp); + efi_rts_work->status = status; + complete(&efi_rts_work->efi_rts_comp); }
static efi_status_t virt_efi_get_time(efi_time_t *tm, efi_time_cap_t *tc) diff --git a/include/linux/efi.h b/include/linux/efi.h index 4d0be16f04c3..b90423d1128b 100644 --- a/include/linux/efi.h +++ b/include/linux/efi.h @@ -1684,42 +1684,6 @@ struct linux_efi_tpm_eventlog {
extern int efi_tpm_eventlog_init(void);
-/* efi_runtime_service() function identifiers */ -enum efi_rts_ids { - GET_TIME, - SET_TIME, - GET_WAKEUP_TIME, - SET_WAKEUP_TIME, - GET_VARIABLE, - GET_NEXT_VARIABLE, - SET_VARIABLE, - QUERY_VARIABLE_INFO, - GET_NEXT_HIGH_MONO_COUNT, - UPDATE_CAPSULE, - QUERY_CAPSULE_CAPS, -}; - -/* - * efi_runtime_work: Details of EFI Runtime Service work - * @arg<1-5>: EFI Runtime Service function arguments - * @status: Status of executing EFI Runtime Service - * @efi_rts_id: EFI Runtime Service function identifier - * @efi_rts_comp: Struct used for handling completions - */ -struct efi_runtime_work { - void *arg1; - void *arg2; - void *arg3; - void *arg4; - void *arg5; - efi_status_t status; - struct work_struct work; - enum efi_rts_ids efi_rts_id; - struct completion efi_rts_comp; -}; - -extern struct efi_runtime_work efi_rts_work; - /* Workqueue to queue EFI Runtime Services */ extern struct workqueue_struct *efi_rts_wq;
反馈: 您发送到kernel@openeuler.org的补丁/补丁集,已成功转换为PR! PR链接地址: https://gitee.com/openeuler/kernel/pulls/2206 邮件列表地址:https://mailweb.openeuler.org/hyperkitty/list/kernel@openeuler.org/message/Q...
FeedBack: The patch(es) which you have sent to kernel@openeuler.org mailing list has been converted to a pull request successfully! Pull request link: https://gitee.com/openeuler/kernel/pulls/2206 Mailing list address: https://mailweb.openeuler.org/hyperkitty/list/kernel@openeuler.org/message/Q...