linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v2 0/3] xtensa: add division by zero exception handler
@ 2022-05-14  3:34 Max Filippov
  2022-05-14  3:34 ` [PATCH v2 1/3] xtensa: add trap handler for division by zero Max Filippov
                   ` (2 more replies)
  0 siblings, 3 replies; 4+ messages in thread
From: Max Filippov @ 2022-05-14  3:34 UTC (permalink / raw)
  To: linux-xtensa; +Cc: Chris Zankel, linux-kernel, Max Filippov

Hello,

this series adds handlers for hardware and artificial division by zero
exceptions and improves call0 ABI probing in the presence of unrelated
illegal instructions.

Changes v1->v2:

- split ABI probing improvement from the artificial division by 0
- don't limit artificial division by 0 pattern detection to
  configurations without HW division opcodes, do it always

Max Filippov (3):
  xtensa: add trap handler for division by zero
  xtensa: support artificial division by 0 exception
  xtensa: improve call0 ABI probing

 arch/xtensa/include/asm/thread_info.h |  4 +++
 arch/xtensa/kernel/asm-offsets.c      |  3 ++
 arch/xtensa/kernel/entry.S            |  5 +++
 arch/xtensa/kernel/traps.c            | 50 ++++++++++++++++++++++++++-
 4 files changed, 61 insertions(+), 1 deletion(-)

-- 
2.30.2


^ permalink raw reply	[flat|nested] 4+ messages in thread

* [PATCH v2 1/3] xtensa: add trap handler for division by zero
  2022-05-14  3:34 [PATCH v2 0/3] xtensa: add division by zero exception handler Max Filippov
@ 2022-05-14  3:34 ` Max Filippov
  2022-05-14  3:34 ` [PATCH v2 2/3] xtensa: support artificial division by 0 exception Max Filippov
  2022-05-14  3:34 ` [PATCH v2 3/3] xtensa: improve call0 ABI probing Max Filippov
  2 siblings, 0 replies; 4+ messages in thread
From: Max Filippov @ 2022-05-14  3:34 UTC (permalink / raw)
  To: linux-xtensa; +Cc: Chris Zankel, linux-kernel, Max Filippov

Add c-level handler for the division by zero exception and kill the task
if it was thrown from the kernel space or send SIGFPE otherwise.

Signed-off-by: Max Filippov <jcmvbkbc@gmail.com>
---
 arch/xtensa/kernel/traps.c | 8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/arch/xtensa/kernel/traps.c b/arch/xtensa/kernel/traps.c
index 138a86fbe9d7..24d11b44fa57 100644
--- a/arch/xtensa/kernel/traps.c
+++ b/arch/xtensa/kernel/traps.c
@@ -49,6 +49,7 @@
  */
 
 static void do_illegal_instruction(struct pt_regs *regs);
+static void do_div0(struct pt_regs *regs);
 static void do_interrupt(struct pt_regs *regs);
 #if XTENSA_FAKE_NMI
 static void do_nmi(struct pt_regs *regs);
@@ -95,7 +96,7 @@ static dispatch_init_table_t __initdata dispatch_init_table[] = {
 #ifdef SUPPORT_WINDOWED
 { EXCCAUSE_ALLOCA,		USER|KRNL, fast_alloca },
 #endif
-/* EXCCAUSE_INTEGER_DIVIDE_BY_ZERO unhandled */
+{ EXCCAUSE_INTEGER_DIVIDE_BY_ZERO, 0,	   do_div0 },
 /* EXCCAUSE_PRIVILEGED unhandled */
 #if XCHAL_UNALIGNED_LOAD_EXCEPTION || XCHAL_UNALIGNED_STORE_EXCEPTION
 #ifdef CONFIG_XTENSA_UNALIGNED_USER
@@ -307,6 +308,11 @@ static void do_illegal_instruction(struct pt_regs *regs)
 	force_sig(SIGILL);
 }
 
+static void do_div0(struct pt_regs *regs)
+{
+	__die_if_kernel("Unhandled division by 0 in kernel", regs, SIGKILL);
+	force_sig_fault(SIGFPE, FPE_INTDIV, (void __user *)regs->pc);
+}
 
 /*
  * Handle unaligned memory accesses from user space. Kill task.
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 4+ messages in thread

* [PATCH v2 2/3] xtensa: support artificial division by 0 exception
  2022-05-14  3:34 [PATCH v2 0/3] xtensa: add division by zero exception handler Max Filippov
  2022-05-14  3:34 ` [PATCH v2 1/3] xtensa: add trap handler for division by zero Max Filippov
@ 2022-05-14  3:34 ` Max Filippov
  2022-05-14  3:34 ` [PATCH v2 3/3] xtensa: improve call0 ABI probing Max Filippov
  2 siblings, 0 replies; 4+ messages in thread
From: Max Filippov @ 2022-05-14  3:34 UTC (permalink / raw)
  To: linux-xtensa; +Cc: Chris Zankel, linux-kernel, Max Filippov

On xtensa cores wihout hardware division option division support
functions from libgcc react to division by 0 attempt by executing
illegal instruction followed by the characters 'DIV0'. Recognize this
pattern in illegal instruction exception handler and convert it to
division by 0.

Signed-off-by: Max Filippov <jcmvbkbc@gmail.com>
---
Changes v1->v2:

- split ABI probing improvement from the artificial division by 0
- don't limit artificial division by 0 pattern detection to
  configurations without HW division opcodes, do it always

 arch/xtensa/kernel/traps.c | 30 ++++++++++++++++++++++++++++++
 1 file changed, 30 insertions(+)

diff --git a/arch/xtensa/kernel/traps.c b/arch/xtensa/kernel/traps.c
index 24d11b44fa57..47445b2d4217 100644
--- a/arch/xtensa/kernel/traps.c
+++ b/arch/xtensa/kernel/traps.c
@@ -293,12 +293,42 @@ static void do_interrupt(struct pt_regs *regs)
 	set_irq_regs(old_regs);
 }
 
+static int check_div0(struct pt_regs *regs)
+{
+	u8 buf[7];
+	void *p;
+	static const u8 pattern1[] = {0, 0, 0, 'D', 'I', 'V', '0'};
+#if defined(__XTENSA_EB__)
+	static const u8 pattern2[] = {0xd6, 0x0f, 'D', 'I', 'V', '0'};
+#elif defined(__XTENSA_EL__)
+	static const u8 pattern2[] = {0x6d, 0xf0, 'D', 'I', 'V', '0'};
+#else
+#error Unsupported Xtensa endianness
+#endif
+
+	if (user_mode(regs)) {
+		if (copy_from_user(buf, (void __user *)regs->pc, 7))
+			return 0;
+		p = buf;
+	} else {
+		p = (void *)regs->pc;
+	}
+
+	return memcmp(p, pattern1, sizeof(pattern1)) == 0 ||
+		memcmp(p, pattern2, sizeof(pattern2)) == 0;
+}
+
 /*
  * Illegal instruction. Fatal if in kernel space.
  */
 
 static void do_illegal_instruction(struct pt_regs *regs)
 {
+	if (check_div0(regs)) {
+		do_div0(regs);
+		return;
+	}
+
 	__die_if_kernel("Illegal instruction in kernel", regs, SIGKILL);
 
 	/* If in user mode, send SIGILL signal to current process. */
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 4+ messages in thread

* [PATCH v2 3/3] xtensa: improve call0 ABI probing
  2022-05-14  3:34 [PATCH v2 0/3] xtensa: add division by zero exception handler Max Filippov
  2022-05-14  3:34 ` [PATCH v2 1/3] xtensa: add trap handler for division by zero Max Filippov
  2022-05-14  3:34 ` [PATCH v2 2/3] xtensa: support artificial division by 0 exception Max Filippov
@ 2022-05-14  3:34 ` Max Filippov
  2 siblings, 0 replies; 4+ messages in thread
From: Max Filippov @ 2022-05-14  3:34 UTC (permalink / raw)
  To: linux-xtensa; +Cc: Chris Zankel, linux-kernel, Max Filippov

When call0 userspace ABI support by probing is enabled instructions that
cause illegal instruction exception when PS.WOE is clear are retried
with PS.WOE set before calling c-level exception handler. Record user pc
at which PS.WOE was set in the fast exception handler and clear PS.WOE
in the c-level exception handler if we get there from the same address.

Signed-off-by: Max Filippov <jcmvbkbc@gmail.com>
---
Changes v1->v2:

- split ABI probing improvement from the artificial division by 0

 arch/xtensa/include/asm/thread_info.h |  4 ++++
 arch/xtensa/kernel/asm-offsets.c      |  3 +++
 arch/xtensa/kernel/entry.S            |  5 +++++
 arch/xtensa/kernel/traps.c            | 12 ++++++++++++
 4 files changed, 24 insertions(+)

diff --git a/arch/xtensa/include/asm/thread_info.h b/arch/xtensa/include/asm/thread_info.h
index 52974317a6b6..326db1c1d5d8 100644
--- a/arch/xtensa/include/asm/thread_info.h
+++ b/arch/xtensa/include/asm/thread_info.h
@@ -56,6 +56,10 @@ struct thread_info {
 	/* result of the most recent exclusive store */
 	unsigned long		atomctl8;
 #endif
+#ifdef CONFIG_USER_ABI_CALL0_PROBE
+	/* Address where PS.WOE was enabled by the ABI probing code */
+	unsigned long		ps_woe_fix_addr;
+#endif
 
 	/*
 	 * If i-th bit is set then coprocessor state is loaded into the
diff --git a/arch/xtensa/kernel/asm-offsets.c b/arch/xtensa/kernel/asm-offsets.c
index 9a1db6ffcbf4..da38de20ae59 100644
--- a/arch/xtensa/kernel/asm-offsets.c
+++ b/arch/xtensa/kernel/asm-offsets.c
@@ -88,6 +88,9 @@ int main(void)
 	OFFSET(TI_STSTUS, thread_info, status);
 	OFFSET(TI_CPU, thread_info, cpu);
 	OFFSET(TI_PRE_COUNT, thread_info, preempt_count);
+#ifdef CONFIG_USER_ABI_CALL0_PROBE
+	OFFSET(TI_PS_WOE_FIX_ADDR, thread_info, ps_woe_fix_addr);
+#endif
 
 	/* struct thread_info (offset from start_struct) */
 	DEFINE(THREAD_RA, offsetof (struct task_struct, thread.ra));
diff --git a/arch/xtensa/kernel/entry.S b/arch/xtensa/kernel/entry.S
index 3224b4ceca34..e3eae648ba2e 100644
--- a/arch/xtensa/kernel/entry.S
+++ b/arch/xtensa/kernel/entry.S
@@ -1056,6 +1056,11 @@ ENTRY(fast_illegal_instruction_user)
 	movi	a3, PS_WOE_MASK
 	or	a0, a0, a3
 	wsr	a0, ps
+#ifdef CONFIG_USER_ABI_CALL0_PROBE
+	GET_THREAD_INFO(a3, a2)
+	rsr	a0, epc1
+	s32i	a0, a3, TI_PS_WOE_FIX_ADDR
+#endif
 	l32i	a3, a2, PT_AREG3
 	l32i	a0, a2, PT_AREG0
 	rsr	a2, depc
diff --git a/arch/xtensa/kernel/traps.c b/arch/xtensa/kernel/traps.c
index 47445b2d4217..21c2c30baf69 100644
--- a/arch/xtensa/kernel/traps.c
+++ b/arch/xtensa/kernel/traps.c
@@ -324,6 +324,18 @@ static int check_div0(struct pt_regs *regs)
 
 static void do_illegal_instruction(struct pt_regs *regs)
 {
+#ifdef CONFIG_USER_ABI_CALL0_PROBE
+	/*
+	 * When call0 application encounters an illegal instruction fast
+	 * exception handler will attempt to set PS.WOE and retry failing
+	 * instruction.
+	 * If we get here we know that that instruction is also illegal
+	 * with PS.WOE set, so it's not related to the windowed option
+	 * hence PS.WOE may be cleared.
+	 */
+	if (regs->pc == current_thread_info()->ps_woe_fix_addr)
+		regs->ps &= ~PS_WOE_MASK;
+#endif
 	if (check_div0(regs)) {
 		do_div0(regs);
 		return;
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2022-05-14  3:35 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-05-14  3:34 [PATCH v2 0/3] xtensa: add division by zero exception handler Max Filippov
2022-05-14  3:34 ` [PATCH v2 1/3] xtensa: add trap handler for division by zero Max Filippov
2022-05-14  3:34 ` [PATCH v2 2/3] xtensa: support artificial division by 0 exception Max Filippov
2022-05-14  3:34 ` [PATCH v2 3/3] xtensa: improve call0 ABI probing Max Filippov

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).