From: Ard Biesheuvel <ardb@kernel.org>
To: linux-arm-kernel@lists.infradead.org, linux@armlinux.org.uk
Cc: Ard Biesheuvel <ardb@kernel.org>,
Frederic Weisbecker <frederic@kernel.org>,
Guenter Roeck <linux@roeck-us.net>,
Peter Zijlstra <peterz@infradead.org>,
Linus Walleij <linus.walleij@linaro.org>,
Arnd Bergmann <arnd@arndb.de>
Subject: [PATCH v4 09/12] ARM: vfp: Use undef hook for handling VFP exceptions
Date: Mon, 20 Mar 2023 14:18:42 +0100 [thread overview]
Message-ID: <20230320131845.3138015-10-ardb@kernel.org> (raw)
In-Reply-To: <20230320131845.3138015-1-ardb@kernel.org>
Now that the VFP support code has been reimplemented as a C function
that takes a struct pt_regs pointer and an opcode, we can use the
existing undef_hook framework to deal with undef exceptions triggered by
VFP instructions instead of having special handling in assembler.
Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
---
arch/arm/kernel/entry-armv.S | 53 ----------------
arch/arm/vfp/Makefile | 2 +-
arch/arm/vfp/entry.S | 31 ----------
arch/arm/vfp/vfpmodule.c | 65 ++++++++++----------
4 files changed, 32 insertions(+), 119 deletions(-)
diff --git a/arch/arm/kernel/entry-armv.S b/arch/arm/kernel/entry-armv.S
index cae8e31ce2cbde41..b4586a3447822774 100644
--- a/arch/arm/kernel/entry-armv.S
+++ b/arch/arm/kernel/entry-armv.S
@@ -557,13 +557,6 @@ ENDPROC(__und_usr)
* co-processor instructions. However, we have to watch out
* for the ARM6/ARM7 SWI bug.
*
- * NEON is a special case that has to be handled here. Not all
- * NEON instructions are co-processor instructions, so we have
- * to make a special case of checking for them. Plus, there's
- * five groups of them, so we have a table of mask/opcode pairs
- * to check against, and if any match then we branch off into the
- * NEON handler code.
- *
* Emulators may wish to make use of the following registers:
* r0 = instruction opcode (32-bit ARM or two 16-bit Thumb)
* r2 = PC value to resume execution after successful emulation
@@ -575,25 +568,8 @@ ENDPROC(__und_usr)
@
@ Fall-through from Thumb-2 __und_usr
@
-#ifdef CONFIG_NEON
- get_thread_info r10 @ get current thread
- adr r6, .LCneon_thumb_opcodes
- b 2f
-#endif
call_fpe:
get_thread_info r10 @ get current thread
-#ifdef CONFIG_NEON
- adr r6, .LCneon_arm_opcodes
-2: ldr r5, [r6], #4 @ mask value
- ldr r7, [r6], #4 @ opcode bits matching in mask
- cmp r5, #0 @ end mask?
- beq 1f
- and r8, r0, r5
- cmp r8, r7 @ NEON instruction?
- bne 2b
- b do_vfp @ let VFP handler handle this
-1:
-#endif
tst r0, #0x08000000 @ only CDP/CPRT/LDC/STC have bit 27
tstne r0, #0x04000000 @ bit 26 set on both ARM and Thumb-2
reteq lr
@@ -621,42 +597,13 @@ call_fpe:
ret.w lr @ CP#7
ret.w lr @ CP#8
ret.w lr @ CP#9
-#ifdef CONFIG_VFP
- W(b) do_vfp @ CP#10 (VFP)
- W(b) do_vfp @ CP#11 (VFP)
-#else
ret.w lr @ CP#10 (VFP)
ret.w lr @ CP#11 (VFP)
-#endif
ret.w lr @ CP#12
ret.w lr @ CP#13
ret.w lr @ CP#14 (Debug)
ret.w lr @ CP#15 (Control)
-#ifdef CONFIG_NEON
- .align 6
-
-.LCneon_arm_opcodes:
- .word 0xfe000000 @ mask
- .word 0xf2000000 @ opcode
-
- .word 0xff100000 @ mask
- .word 0xf4000000 @ opcode
-
- .word 0x00000000 @ mask
- .word 0x00000000 @ opcode
-
-.LCneon_thumb_opcodes:
- .word 0xef000000 @ mask
- .word 0xef000000 @ opcode
-
- .word 0xff100000 @ mask
- .word 0xf9000000 @ opcode
-
- .word 0x00000000 @ mask
- .word 0x00000000 @ opcode
-#endif
-
do_fpe:
add r10, r10, #TI_FPSTATE @ r10 = workspace
ldr_va pc, fp_enter, tmp=r4 @ Call FP module USR entry point
diff --git a/arch/arm/vfp/Makefile b/arch/arm/vfp/Makefile
index 749901a72d6dc6c4..dfd64bc2b2fbdd06 100644
--- a/arch/arm/vfp/Makefile
+++ b/arch/arm/vfp/Makefile
@@ -8,4 +8,4 @@
# ccflags-y := -DDEBUG
# asflags-y := -DDEBUG
-obj-y += vfpmodule.o entry.o vfphw.o vfpsingle.o vfpdouble.o
+obj-y += vfpmodule.o vfphw.o vfpsingle.o vfpdouble.o
diff --git a/arch/arm/vfp/entry.S b/arch/arm/vfp/entry.S
deleted file mode 100644
index 547c94c62cd3a66a..0000000000000000
--- a/arch/arm/vfp/entry.S
+++ /dev/null
@@ -1,31 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-only */
-/*
- * linux/arch/arm/vfp/entry.S
- *
- * Copyright (C) 2004 ARM Limited.
- * Written by Deep Blue Solutions Limited.
- */
-#include <linux/init.h>
-#include <linux/linkage.h>
-#include <asm/thread_info.h>
-#include <asm/vfpmacros.h>
-#include <asm/assembler.h>
-#include <asm/asm-offsets.h>
-
-@ VFP entry point.
-@
-@ r0 = instruction opcode (32-bit ARM or two 16-bit Thumb)
-@ r2 = PC value to resume execution after successful emulation
-@ r9 = normal "successful" return address
-@ r10 = this threads thread_info structure
-@ lr = unrecognised instruction return address
-@ IRQs enabled.
-@
-ENTRY(do_vfp)
- mov r1, r0 @ pass trigger opcode via R1
- mov r0, sp @ pass struct pt_regs via R0
- bl vfp_support_entry @ dispatch the VFP exception
- cmp r0, #0 @ handled successfully?
- reteq r9 @ then use R9 as return address
- ret lr @ pass to undef handler
-ENDPROC(do_vfp)
diff --git a/arch/arm/vfp/vfpmodule.c b/arch/arm/vfp/vfpmodule.c
index 6db7d20c467ff843..5f65cf8375134af3 100644
--- a/arch/arm/vfp/vfpmodule.c
+++ b/arch/arm/vfp/vfpmodule.c
@@ -641,8 +641,6 @@ static int vfp_starting_cpu(unsigned int unused)
return 0;
}
-#ifdef CONFIG_KERNEL_MODE_NEON
-
static int vfp_kmode_exception(struct pt_regs *regs, unsigned int instr)
{
/*
@@ -666,14 +664,14 @@ static int vfp_kmode_exception(struct pt_regs *regs, unsigned int instr)
}
/*
- * vfp_support_entry - Handle VFP exception from user mode
+ * vfp_support_entry - Handle VFP exception
*
* @regs: pt_regs structure holding the register state at exception entry
* @trigger: The opcode of the instruction that triggered the exception
*
* Returns 0 if the exception was handled, or an error code otherwise.
*/
-asmlinkage int vfp_support_entry(struct pt_regs *regs, u32 trigger)
+static int vfp_support_entry(struct pt_regs *regs, u32 trigger)
{
struct thread_info *ti = current_thread_info();
u32 fpexc;
@@ -681,6 +679,9 @@ asmlinkage int vfp_support_entry(struct pt_regs *regs, u32 trigger)
if (unlikely(!have_vfp))
return -ENODEV;
+ if (!user_mode(regs))
+ return vfp_kmode_exception(regs, trigger);
+
local_bh_disable();
fpexc = fmrx(FPEXC);
@@ -746,7 +747,6 @@ asmlinkage int vfp_support_entry(struct pt_regs *regs, u32 trigger)
* replay the instruction that trapped.
*/
fmxr(FPEXC, fpexc);
- regs->ARM_pc -= 4;
} else {
/* Check for synchronous or asynchronous exceptions */
if (!(fpexc & (FPEXC_EX | FPEXC_DEX))) {
@@ -767,54 +767,47 @@ asmlinkage int vfp_support_entry(struct pt_regs *regs, u32 trigger)
fpexc |= FPEXC_DEX;
}
}
-bounce: VFP_bounce(trigger, fpexc, regs);
+bounce: regs->ARM_pc += 4;
+ VFP_bounce(trigger, fpexc, regs);
}
local_bh_enable();
return 0;
}
-static struct undef_hook vfp_kmode_exception_hook[] = {{
+static struct undef_hook neon_support_hook[] = {{
.instr_mask = 0xfe000000,
.instr_val = 0xf2000000,
- .cpsr_mask = MODE_MASK | PSR_T_BIT,
- .cpsr_val = SVC_MODE,
- .fn = vfp_kmode_exception,
+ .cpsr_mask = PSR_T_BIT,
+ .cpsr_val = 0,
+ .fn = vfp_support_entry,
}, {
.instr_mask = 0xff100000,
.instr_val = 0xf4000000,
- .cpsr_mask = MODE_MASK | PSR_T_BIT,
- .cpsr_val = SVC_MODE,
- .fn = vfp_kmode_exception,
+ .cpsr_mask = PSR_T_BIT,
+ .cpsr_val = 0,
+ .fn = vfp_support_entry,
}, {
.instr_mask = 0xef000000,
.instr_val = 0xef000000,
- .cpsr_mask = MODE_MASK | PSR_T_BIT,
- .cpsr_val = SVC_MODE | PSR_T_BIT,
- .fn = vfp_kmode_exception,
+ .cpsr_mask = PSR_T_BIT,
+ .cpsr_val = PSR_T_BIT,
+ .fn = vfp_support_entry,
}, {
.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,
+ .cpsr_mask = PSR_T_BIT,
+ .cpsr_val = PSR_T_BIT,
+ .fn = vfp_support_entry,
}};
-static int __init vfp_kmode_exception_hook_init(void)
-{
- int i;
+static struct undef_hook vfp_support_hook = {
+ .instr_mask = 0x0c000e00,
+ .instr_val = 0x0c000a00,
+ .fn = vfp_support_entry,
+};
- for (i = 0; i < ARRAY_SIZE(vfp_kmode_exception_hook); i++)
- register_undef_hook(&vfp_kmode_exception_hook[i]);
- return 0;
-}
-subsys_initcall(vfp_kmode_exception_hook_init);
+#ifdef CONFIG_KERNEL_MODE_NEON
/*
* Kernel-side NEON support functions
@@ -919,8 +912,11 @@ static int __init vfp_init(void)
* for NEON if the hardware has the MVFR registers.
*/
if (IS_ENABLED(CONFIG_NEON) &&
- (fmrx(MVFR1) & 0x000fff00) == 0x00011100)
+ (fmrx(MVFR1) & 0x000fff00) == 0x00011100) {
elf_hwcap |= HWCAP_NEON;
+ for (int i = 0; i < ARRAY_SIZE(neon_support_hook); i++)
+ register_undef_hook(&neon_support_hook[i]);
+ }
if (IS_ENABLED(CONFIG_VFPv3)) {
u32 mvfr0 = fmrx(MVFR0);
@@ -989,6 +985,7 @@ static int __init vfp_init(void)
have_vfp = true;
+ register_undef_hook(&vfp_support_hook);
thread_register_notifier(&vfp_notifier_block);
vfp_pm_init();
--
2.39.2
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
next prev parent reply other threads:[~2023-03-20 13:20 UTC|newest]
Thread overview: 38+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-03-20 13:18 [PATCH v4 00/12] ARM: vfp: Switch to C API to en/disable softirqs Ard Biesheuvel
2023-03-20 13:18 ` [PATCH v4 01/12] ARM: vfp: Pass thread_info pointer to vfp_support_entry Ard Biesheuvel
2023-03-20 13:18 ` [PATCH v4 02/12] ARM: vfp: Pass successful return address via register R3 Ard Biesheuvel
2023-03-20 13:18 ` [PATCH v4 03/12] ARM: vfp: Fix broken softirq handling with instrumentation enabled Ard Biesheuvel
2023-04-09 14:29 ` Linux regression tracking (Thorsten Leemhuis)
2023-04-09 14:29 ` Linux regression tracking (Thorsten Leemhuis)
2023-04-10 20:15 ` Guenter Roeck
2023-04-10 20:15 ` Guenter Roeck
2023-03-20 13:18 ` [PATCH v4 04/12] ARM: entry: Fix iWMMXT TIF flag handling Ard Biesheuvel
2023-03-20 13:18 ` Ard Biesheuvel
2023-03-21 14:32 ` Linus Walleij
2023-03-21 14:32 ` Linus Walleij
2023-03-21 19:19 ` Nicolas Pitre
2023-03-21 19:19 ` Nicolas Pitre
2023-03-21 19:32 ` Ard Biesheuvel
2023-03-21 19:32 ` Ard Biesheuvel
2023-03-20 13:18 ` [PATCH v4 05/12] ARM: vfp: Record VFP bounces as perf emulation faults Ard Biesheuvel
2023-03-21 14:33 ` Linus Walleij
2023-03-20 13:18 ` [PATCH v4 06/12] ARM: vfp: Remove workaround for Feroceon CPUs Ard Biesheuvel
2023-03-21 14:44 ` Linus Walleij
2023-03-21 15:42 ` Ard Biesheuvel
2023-03-21 20:40 ` Linus Walleij
2023-03-22 7:26 ` Arnd Bergmann
2023-03-21 20:00 ` Nicolas Pitre
2023-03-20 13:18 ` [PATCH v4 07/12] ARM: vfp: Reimplement VFP exception entry in C code Ard Biesheuvel
2023-03-20 13:18 ` [PATCH v4 08/12] ARM: kernel: Get rid of thread_info::used_cp[] array Ard Biesheuvel
2023-03-21 14:58 ` Linus Walleij
2023-03-20 13:18 ` Ard Biesheuvel [this message]
2023-03-21 14:59 ` [PATCH v4 09/12] ARM: vfp: Use undef hook for handling VFP exceptions Linus Walleij
2023-03-21 15:41 ` Ard Biesheuvel
2023-03-20 13:18 ` [PATCH v4 10/12] ARM: entry: Disregard Thumb undef exception in coproc dispatch Ard Biesheuvel
2023-03-21 15:05 ` Linus Walleij
2023-03-20 13:18 ` [PATCH v4 11/12] ARM: iwmmxt: Use undef hook to enable coprocessor for task Ard Biesheuvel
2023-03-21 15:06 ` Linus Walleij
2023-03-20 13:18 ` [PATCH v4 12/12] ARM: entry: Make asm coproc dispatch code NWFPE only Ard Biesheuvel
2023-03-21 15:11 ` Linus Walleij
2023-03-23 2:44 ` [PATCH v4 00/12] ARM: vfp: Switch to C API to en/disable softirqs Guenter Roeck
2023-03-23 8:33 ` Ard Biesheuvel
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20230320131845.3138015-10-ardb@kernel.org \
--to=ardb@kernel.org \
--cc=arnd@arndb.de \
--cc=frederic@kernel.org \
--cc=linus.walleij@linaro.org \
--cc=linux-arm-kernel@lists.infradead.org \
--cc=linux@armlinux.org.uk \
--cc=linux@roeck-us.net \
--cc=peterz@infradead.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.