ARM: vfp: Remove workaround for Feroceon CPUs
authorArd Biesheuvel <ardb@kernel.org>
Mon, 20 Mar 2023 10:01:16 +0000 (11:01 +0100)
committerArd Biesheuvel <ardb@kernel.org>
Wed, 17 May 2023 11:11:38 +0000 (13:11 +0200)
Feroceon CPUs have a non-standard implementation of VFP which reports
synchronous VFP exceptions using the async VFP flag. This requires a
workaround which is difficult to reconcile with other implementations,
making it tricky to support both versions in a single image.

Since this is a v5 CPU, it is not supported by armhf and so the
likelihood that anybody is using this with recent distros/kernels and
rely on the VFP at the same time is extremely low. So let's just disable
VFP support on these cores, so we can remove the workaround.

This will help future development to support v5 and v6 CPUs with a
single kernel image.

Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
Acked-by: Nicolas Pitre <nico@fluxnic.net>
Acked-by: Arnd Bergmann <arnd@arndb.de>
Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
arch/arm/mm/proc-feroceon.S
arch/arm/vfp/vfphw.S
arch/arm/vfp/vfpmodule.c

index 61ce82aca6f0d6033e7357d2ea0f940da8def0c3..072ff9b451f846bf2c57de62cd34649423c944e5 100644 (file)
@@ -56,6 +56,10 @@ ENTRY(cpu_feroceon_proc_init)
        movne   r2, r2, lsr #2                  @ turned into # of sets
        sub     r2, r2, #(1 << 5)
        stmia   r1, {r2, r3}
+#ifdef CONFIG_VFP
+       mov     r1, #1                          @ disable quirky VFP
+       str_l   r1, VFP_arch_feroceon, r2
+#endif
        ret     lr
 
 /*
index a4610d0f321527cc86eee150254c6faeb5649dee..0aeb60ac3b5376a84b30103447f48b99d7e871ac 100644 (file)
@@ -110,7 +110,6 @@ ENTRY(vfp_support_entry)
        beq     vfp_reload_hw           @ then the hw state needs reloading
        VFPFSTMIA r4, r5                @ save the working registers
        VFPFMRX r5, FPSCR               @ current status
-#ifndef CONFIG_CPU_FEROCEON
        tst     r1, #FPEXC_EX           @ is there additional state to save?
        beq     1f
        VFPFMRX r6, FPINST              @ FPINST (only if FPEXC.EX is set)
@@ -118,7 +117,6 @@ ENTRY(vfp_support_entry)
        beq     1f
        VFPFMRX r8, FPINST2             @ FPINST2 if needed (and present)
 1:
-#endif
        stmia   r4, {r1, r5, r6, r8}    @ save FPEXC, FPSCR, FPINST, FPINST2
 vfp_reload_hw:
 
@@ -153,7 +151,6 @@ vfp_reload_hw:
        VFPFLDMIA r10, r5               @ reload the working registers while
                                        @ FPEXC is in a safe state
        ldmia   r10, {r1, r5, r6, r8}   @ load FPEXC, FPSCR, FPINST, FPINST2
-#ifndef CONFIG_CPU_FEROCEON
        tst     r1, #FPEXC_EX           @ is there additional state to restore?
        beq     1f
        VFPFMXR FPINST, r6              @ restore FPINST (only if FPEXC.EX is set)
@@ -161,7 +158,6 @@ vfp_reload_hw:
        beq     1f
        VFPFMXR FPINST2, r8             @ FPINST2 if needed (and present)
 1:
-#endif
        VFPFMXR FPSCR, r5               @ restore status
 
 @ The context stored in the VFP hardware is up to date with this thread
index 08d5dfcf70796eea0f316d7188fca5323014f77a..95628e57807b1e79bac307228724fc0b5362b8f1 100644 (file)
@@ -42,7 +42,11 @@ static bool have_vfp __ro_after_init;
  * Used in startup: set to non-zero if VFP checks fail
  * After startup, holds VFP architecture
  */
-static unsigned int __initdata VFP_arch;
+static unsigned int VFP_arch;
+
+#ifdef CONFIG_CPU_FEROCEON
+extern unsigned int VFP_arch_feroceon __alias(VFP_arch);
+#endif
 
 /*
  * The pointer to the vfpstate structure of the thread which currently
@@ -357,14 +361,12 @@ void VFP_bounce(u32 trigger, u32 fpexc, struct pt_regs *regs)
        }
 
        if (fpexc & FPEXC_EX) {
-#ifndef CONFIG_CPU_FEROCEON
                /*
                 * Asynchronous exception. The instruction is read from FPINST
                 * and the interrupted instruction has to be restarted.
                 */
                trigger = fmrx(FPINST);
                regs->ARM_pc -= 4;
-#endif
        } else if (!(fpexc & FPEXC_DEX)) {
                /*
                 * Illegal combination of bits. It can be caused by an