]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
5.4-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sat, 20 Mar 2021 11:04:17 +0000 (12:04 +0100)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sat, 20 Mar 2021 11:04:17 +0000 (12:04 +0100)
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

queue-5.4/arm-9030-1-entry-omit-fp-emulation-for-und-exceptions-taken-in-kernel-mode.patch [new file with mode: 0644]
queue-5.4/arm-9044-1-vfp-use-undef-hook-for-vfp-support-detection.patch [new file with mode: 0644]
queue-5.4/series

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 (file)
index 0000000..59a9536
--- /dev/null
@@ -0,0 +1,175 @@
+From foo@baz Sat Mar 20 12:03:58 PM CET 2021
+From: Ard Biesheuvel <ardb@kernel.org>
+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 <ardb@kernel.org>
+
+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 <ardb@kernel.org>
+Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
+Signed-off-by: Nick Desaulniers <ndesaulniers@google.com>
+Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
+Reviewed-by: Nick Desaulniers <ndesaulniers@google.com>
+Cc: Dmitry Osipenko <digetx@gmail.com>
+Cc: Kees Cook <keescook@chromium.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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 <asm/cputype.h>
+ #include <asm/system_info.h>
+ #include <asm/thread_notify.h>
++#include <asm/traps.h>
+ #include <asm/vfp.h>
+ #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 (file)
index 0000000..03fde74
--- /dev/null
@@ -0,0 +1,125 @@
+From foo@baz Sat Mar 20 12:03:58 PM CET 2021
+From: Ard Biesheuvel <ardb@kernel.org>
+Date: Tue, 16 Mar 2021 09:59:18 -0700
+Subject: ARM: 9044/1: vfp: use undef hook for VFP support detection
+
+From: Ard Biesheuvel <ardb@kernel.org>
+
+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" <bot@kernelci.org>
+Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
+Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
+Signed-off-by: Nick Desaulniers <ndesaulniers@google.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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: ");
index 2213cf98c4db8c4ef0765c7ad9d2304655ee93df..91cafebbcd2b6f40378f4cc6a76282c4eb6f8e7a 100644 (file)
@@ -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