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: 32+ 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-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-21 14:32 ` Linus Walleij
2023-03-21 19:19 ` Nicolas Pitre
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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).