From: Greg Kroah-Hartman Date: Sat, 20 Mar 2021 11:04:17 +0000 (+0100) Subject: 5.4-stable patches X-Git-Tag: v4.4.263~87 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=7b39ccc698513ca6e897fd71b6ade6d9db65e9eb;p=thirdparty%2Fkernel%2Fstable-queue.git 5.4-stable patches added patches: arm-9030-1-entry-omit-fp-emulation-for-und-exceptions-taken-in-kernel-mode.patch arm-9044-1-vfp-use-undef-hook-for-vfp-support-detection.patch --- diff --git a/queue-5.4/arm-9030-1-entry-omit-fp-emulation-for-und-exceptions-taken-in-kernel-mode.patch b/queue-5.4/arm-9030-1-entry-omit-fp-emulation-for-und-exceptions-taken-in-kernel-mode.patch new file mode 100644 index 00000000000..59a95366147 --- /dev/null +++ b/queue-5.4/arm-9030-1-entry-omit-fp-emulation-for-und-exceptions-taken-in-kernel-mode.patch @@ -0,0 +1,175 @@ +From foo@baz Sat Mar 20 12:03:58 PM CET 2021 +From: Ard Biesheuvel +Date: Mon, 15 Mar 2021 16:19:52 -0700 +Subject: ARM: 9030/1: entry: omit FP emulation for UND exceptions taken in kernel mode + +From: Ard Biesheuvel + +commit f77ac2e378be9dd61eb88728f0840642f045d9d1 upstream. + +There are a couple of problems with the exception entry code that deals +with FP exceptions (which are reported as UND exceptions) when building +the kernel in Thumb2 mode: +- the conditional branch to vfp_kmode_exception in vfp_support_entry() + may be out of range for its target, depending on how the linker decides + to arrange the sections; +- when the UND exception is taken in kernel mode, the emulation handling + logic is entered via the 'call_fpe' label, which means we end up using + the wrong value/mask pairs to match and detect the NEON opcodes. + +Since UND exceptions in kernel mode are unlikely to occur on a hot path +(as opposed to the user mode version which is invoked for VFP support +code and lazy restore), we can use the existing undef hook machinery for +any kernel mode instruction emulation that is needed, including calling +the existing vfp_kmode_exception() routine for unexpected cases. So drop +the call to call_fpe, and instead, install an undef hook that will get +called for NEON and VFP instructions that trigger an UND exception in +kernel mode. + +While at it, make sure that the PC correction is accurate for the +execution mode where the exception was taken, by checking the PSR +Thumb bit. + +[nd: fix conflict in arch/arm/vfp/vfphw.S due to missing + commit 2cbd1cc3dcd3 ("ARM: 8991/1: use VFP assembler mnemonics if + available")] + +Fixes: eff8728fe698 ("vmlinux.lds.h: Add PGO and AutoFDO input sections") +Signed-off-by: Ard Biesheuvel +Signed-off-by: Russell King +Signed-off-by: Nick Desaulniers +Reviewed-by: Linus Walleij +Reviewed-by: Nick Desaulniers +Cc: Dmitry Osipenko +Cc: Kees Cook +Signed-off-by: Greg Kroah-Hartman +--- + arch/arm/kernel/entry-armv.S | 25 +-------------------- + arch/arm/vfp/vfphw.S | 5 ---- + arch/arm/vfp/vfpmodule.c | 49 +++++++++++++++++++++++++++++++++++++++++-- + 3 files changed, 49 insertions(+), 30 deletions(-) + +--- a/arch/arm/kernel/entry-armv.S ++++ b/arch/arm/kernel/entry-armv.S +@@ -252,31 +252,10 @@ __und_svc: + #else + svc_entry + #endif +- @ +- @ call emulation code, which returns using r9 if it has emulated +- @ the instruction, or the more conventional lr if we are to treat +- @ this as a real undefined instruction +- @ +- @ r0 - instruction +- @ +-#ifndef CONFIG_THUMB2_KERNEL +- ldr r0, [r4, #-4] +-#else +- mov r1, #2 +- ldrh r0, [r4, #-2] @ Thumb instruction at LR - 2 +- cmp r0, #0xe800 @ 32-bit instruction if xx >= 0 +- blo __und_svc_fault +- ldrh r9, [r4] @ bottom 16 bits +- add r4, r4, #2 +- str r4, [sp, #S_PC] +- orr r0, r9, r0, lsl #16 +-#endif +- badr r9, __und_svc_finish +- mov r2, r4 +- bl call_fpe + + mov r1, #4 @ PC correction to apply +-__und_svc_fault: ++ THUMB( tst r5, #PSR_T_BIT ) @ exception taken in Thumb mode? ++ THUMB( movne r1, #2 ) @ if so, fix up PC correction + mov r0, sp @ struct pt_regs *regs + bl __und_fault + +--- a/arch/arm/vfp/vfphw.S ++++ b/arch/arm/vfp/vfphw.S +@@ -78,11 +78,6 @@ + ENTRY(vfp_support_entry) + DBGSTR3 "instr %08x pc %08x state %p", r0, r2, r10 + +- ldr r3, [sp, #S_PSR] @ Neither lazy restore nor FP exceptions +- and r3, r3, #MODE_MASK @ are supported in kernel mode +- teq r3, #USR_MODE +- bne vfp_kmode_exception @ Returns through lr +- + VFPFMRX r1, FPEXC @ Is the VFP enabled? + DBGSTR1 "fpexc %08x", r1 + tst r1, #FPEXC_EN +--- a/arch/arm/vfp/vfpmodule.c ++++ b/arch/arm/vfp/vfpmodule.c +@@ -23,6 +23,7 @@ + #include + #include + #include ++#include + #include + + #include "vfpinstr.h" +@@ -642,7 +643,9 @@ static int vfp_starting_cpu(unsigned int + return 0; + } + +-void vfp_kmode_exception(void) ++#ifdef CONFIG_KERNEL_MODE_NEON ++ ++static int vfp_kmode_exception(struct pt_regs *regs, unsigned int instr) + { + /* + * If we reach this point, a floating point exception has been raised +@@ -660,9 +663,51 @@ void vfp_kmode_exception(void) + pr_crit("BUG: unsupported FP instruction in kernel mode\n"); + else + pr_crit("BUG: FP instruction issued in kernel mode with FP unit disabled\n"); ++ pr_crit("FPEXC == 0x%08x\n", fmrx(FPEXC)); ++ return 1; + } + +-#ifdef CONFIG_KERNEL_MODE_NEON ++static struct undef_hook vfp_kmode_exception_hook[] = {{ ++ .instr_mask = 0xfe000000, ++ .instr_val = 0xf2000000, ++ .cpsr_mask = MODE_MASK | PSR_T_BIT, ++ .cpsr_val = SVC_MODE, ++ .fn = vfp_kmode_exception, ++}, { ++ .instr_mask = 0xff100000, ++ .instr_val = 0xf4000000, ++ .cpsr_mask = MODE_MASK | PSR_T_BIT, ++ .cpsr_val = SVC_MODE, ++ .fn = vfp_kmode_exception, ++}, { ++ .instr_mask = 0xef000000, ++ .instr_val = 0xef000000, ++ .cpsr_mask = MODE_MASK | PSR_T_BIT, ++ .cpsr_val = SVC_MODE | PSR_T_BIT, ++ .fn = vfp_kmode_exception, ++}, { ++ .instr_mask = 0xff100000, ++ .instr_val = 0xf9000000, ++ .cpsr_mask = MODE_MASK | PSR_T_BIT, ++ .cpsr_val = SVC_MODE | PSR_T_BIT, ++ .fn = vfp_kmode_exception, ++}, { ++ .instr_mask = 0x0c000e00, ++ .instr_val = 0x0c000a00, ++ .cpsr_mask = MODE_MASK, ++ .cpsr_val = SVC_MODE, ++ .fn = vfp_kmode_exception, ++}}; ++ ++static int __init vfp_kmode_exception_hook_init(void) ++{ ++ int i; ++ ++ for (i = 0; i < ARRAY_SIZE(vfp_kmode_exception_hook); i++) ++ register_undef_hook(&vfp_kmode_exception_hook[i]); ++ return 0; ++} ++core_initcall(vfp_kmode_exception_hook_init); + + /* + * Kernel-side NEON support functions diff --git a/queue-5.4/arm-9044-1-vfp-use-undef-hook-for-vfp-support-detection.patch b/queue-5.4/arm-9044-1-vfp-use-undef-hook-for-vfp-support-detection.patch new file mode 100644 index 00000000000..03fde7430a5 --- /dev/null +++ b/queue-5.4/arm-9044-1-vfp-use-undef-hook-for-vfp-support-detection.patch @@ -0,0 +1,125 @@ +From foo@baz Sat Mar 20 12:03:58 PM CET 2021 +From: Ard Biesheuvel +Date: Tue, 16 Mar 2021 09:59:18 -0700 +Subject: ARM: 9044/1: vfp: use undef hook for VFP support detection + +From: Ard Biesheuvel + +commit 3cce9d44321e460e7c88cdec4e4537a6e9ad7c0d upstream. + +Commit f77ac2e378be9dd6 ("ARM: 9030/1: entry: omit FP emulation for UND +exceptions taken in kernel mode") failed to take into account that there +is in fact a case where we relied on this code path: during boot, the +VFP detection code issues a read of FPSID, which will trigger an undef +exception on cores that lack VFP support. + +So let's reinstate this logic using an undef hook which is registered +only for the duration of the initcall to vpf_init(), and which sets +VFP_arch to a non-zero value - as before - if no VFP support is present. + +Fixes: f77ac2e378be9dd6 ("ARM: 9030/1: entry: omit FP emulation for UND ...") +Reported-by: "kernelci.org bot" +Signed-off-by: Ard Biesheuvel +Signed-off-by: Russell King +Signed-off-by: Nick Desaulniers +Signed-off-by: Greg Kroah-Hartman +--- + arch/arm/vfp/entry.S | 17 ----------------- + arch/arm/vfp/vfpmodule.c | 25 ++++++++++++++++++++----- + 2 files changed, 20 insertions(+), 22 deletions(-) + +--- a/arch/arm/vfp/entry.S ++++ b/arch/arm/vfp/entry.S +@@ -37,20 +37,3 @@ ENDPROC(vfp_null_entry) + .align 2 + .LCvfp: + .word vfp_vector +- +-@ This code is called if the VFP does not exist. It needs to flag the +-@ failure to the VFP initialisation code. +- +- __INIT +-ENTRY(vfp_testing_entry) +- dec_preempt_count_ti r10, r4 +- ldr r0, VFP_arch_address +- str r0, [r0] @ set to non-zero value +- ret r9 @ we have handled the fault +-ENDPROC(vfp_testing_entry) +- +- .align 2 +-VFP_arch_address: +- .word VFP_arch +- +- __FINIT +--- a/arch/arm/vfp/vfpmodule.c ++++ b/arch/arm/vfp/vfpmodule.c +@@ -32,7 +32,6 @@ + /* + * Our undef handlers (in entry.S) + */ +-asmlinkage void vfp_testing_entry(void); + asmlinkage void vfp_support_entry(void); + asmlinkage void vfp_null_entry(void); + +@@ -43,7 +42,7 @@ asmlinkage void (*vfp_vector)(void) = vf + * Used in startup: set to non-zero if VFP checks fail + * After startup, holds VFP architecture + */ +-unsigned int VFP_arch; ++static unsigned int __initdata VFP_arch; + + /* + * The pointer to the vfpstate structure of the thread which currently +@@ -437,7 +436,7 @@ static void vfp_enable(void *unused) + * present on all CPUs within a SMP complex. Needs to be called prior to + * vfp_init(). + */ +-void vfp_disable(void) ++void __init vfp_disable(void) + { + if (VFP_arch) { + pr_debug("%s: should be called prior to vfp_init\n", __func__); +@@ -707,7 +706,7 @@ static int __init vfp_kmode_exception_ho + register_undef_hook(&vfp_kmode_exception_hook[i]); + return 0; + } +-core_initcall(vfp_kmode_exception_hook_init); ++subsys_initcall(vfp_kmode_exception_hook_init); + + /* + * Kernel-side NEON support functions +@@ -753,6 +752,21 @@ EXPORT_SYMBOL(kernel_neon_end); + + #endif /* CONFIG_KERNEL_MODE_NEON */ + ++static int __init vfp_detect(struct pt_regs *regs, unsigned int instr) ++{ ++ VFP_arch = UINT_MAX; /* mark as not present */ ++ regs->ARM_pc += 4; ++ return 0; ++} ++ ++static struct undef_hook vfp_detect_hook __initdata = { ++ .instr_mask = 0x0c000e00, ++ .instr_val = 0x0c000a00, ++ .cpsr_mask = MODE_MASK, ++ .cpsr_val = SVC_MODE, ++ .fn = vfp_detect, ++}; ++ + /* + * VFP support code initialisation. + */ +@@ -773,10 +787,11 @@ static int __init vfp_init(void) + * The handler is already setup to just log calls, so + * we just need to read the VFPSID register. + */ +- vfp_vector = vfp_testing_entry; ++ register_undef_hook(&vfp_detect_hook); + barrier(); + vfpsid = fmrx(FPSID); + barrier(); ++ unregister_undef_hook(&vfp_detect_hook); + vfp_vector = vfp_null_entry; + + pr_info("VFP support v0.3: "); diff --git a/queue-5.4/series b/queue-5.4/series index 2213cf98c4d..91cafebbcd2 100644 --- a/queue-5.4/series +++ b/queue-5.4/series @@ -6,3 +6,5 @@ alsa-hda-generic-fix-the-micmute-led-init-state.patch alsa-hda-realtek-apply-headset-mic-quirks-for-xiaomi-redmibook-air.patch revert-pm-runtime-update-device-status-before-letting-suppliers-suspend.patch s390-vtime-fix-increased-steal-time-accounting.patch +arm-9030-1-entry-omit-fp-emulation-for-und-exceptions-taken-in-kernel-mode.patch +arm-9044-1-vfp-use-undef-hook-for-vfp-support-detection.patch