xenomai.lists.linux.dev archive mirror
 help / color / mirror / Atom feed
From: Jan Kiszka <jan.kiszka@siemens.com>
To: Xenomai <xenomai@lists.linux.dev>,
	Philippe Gerum <rpm@xenomai.org>,
	Johannes Kirchmair <johannes.kirchmair@sigmatek.at>,
	Richard Weinberger <richard@nod.at>
Subject: [RFC][PATCH] x86: dovetail: Permit to declare a trap handled
Date: Fri, 8 Jul 2022 09:11:03 +0200	[thread overview]
Message-ID: <006148b8-dfa1-1abb-b243-029db08ceb0a@siemens.com> (raw)

From: Jan Kiszka <jan.kiszka@siemens.com>

This allows to skip reporting a trap to Linux when the OOB handler
resolved it directly. The handler can signal this condition by returning
"true". This feature was present in I-pipe as well.

By intention, not all spots of oob_trap_notify are enabled for this.
Debug traps are left out as well as asyncpf in kvm - no use cases from
OOB-perspective.

NOTE: breaks unprepared users, breaks non-x86.

Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
---

I'm happy to add non-x86 support as well if the direction is fine.

And if we introduce that to dovetail, we will have to add some kernel 
version checks to Xenomai so that it does the right thing with the right 
dovetail versions. Feature flags are out of fashion there as far as I 
understood.

 arch/x86/kernel/traps.c  | 38 ++++++++++++++++++++++----------------
 arch/x86/mm/fault.c      |  9 ++++++---
 include/linux/dovetail.h |  9 +++++----
 kernel/dovetail.c        |  9 ++++++---
 4 files changed, 39 insertions(+), 26 deletions(-)

diff --git a/arch/x86/kernel/traps.c b/arch/x86/kernel/traps.c
index 3d04a80a1464..daf222f444f4 100644
--- a/arch/x86/kernel/traps.c
+++ b/arch/x86/kernel/traps.c
@@ -163,10 +163,12 @@ static void show_signal(struct task_struct *tsk, int signr,
 }
 
 static __always_inline
-void mark_trap_entry(int trapnr, struct pt_regs *regs)
+bool mark_trap_entry(int trapnr, struct pt_regs *regs)
 {
-	oob_trap_notify(trapnr, regs);
+	if (oob_trap_notify(trapnr, regs))
+		return false;
 	hard_cond_local_irq_enable();
+	return true;
 }
 
 static __always_inline
@@ -211,9 +213,8 @@ static void do_error_trap(struct pt_regs *regs, long error_code, char *str,
 {
 	RCU_LOCKDEP_WARN(!rcu_is_watching(), "entry code didn't wake RCU");
 
-	mark_trap_entry(trapnr, regs);
-
-	if (notify_die(DIE_TRAP, str, regs, error_code, trapnr, signr) !=
+	if (mark_trap_entry(trapnr, regs) &&
+	    notify_die(DIE_TRAP, str, regs, error_code, trapnr, signr) !=
 			NOTIFY_STOP) {
 		cond_local_irq_enable(regs);
 		do_trap(trapnr, signr, str, regs, error_code, sicode, addr);
@@ -375,10 +376,12 @@ DEFINE_IDTENTRY_RAW(exc_invalid_op)
 		return;
 
 	state = irqentry_enter(regs);
-	mark_trap_entry(X86_TRAP_UD, regs);
+	if (!mark_trap_entry(X86_TRAP_UD, regs))
+		goto mark_exit;
 	instrumentation_begin();
 	handle_invalid_op(regs);
 	instrumentation_end();
+mark_exit:
 	mark_trap_exit(X86_TRAP_UD, regs);
 	irqentry_exit(regs, state);
 }
@@ -411,7 +414,8 @@ DEFINE_IDTENTRY_ERRORCODE(exc_alignment_check)
 {
 	char *str = "alignment check";
 
-	mark_trap_entry(X86_TRAP_AC, regs);
+	if (!mark_trap_entry(X86_TRAP_AC, regs))
+		goto mark_exit;
 
 	if (notify_die(DIE_TRAP, str, regs, error_code, X86_TRAP_AC, SIGBUS) == NOTIFY_STOP)
 		goto mark_exit;
@@ -595,7 +599,8 @@ DEFINE_IDTENTRY_DF(exc_double_fault)
 
 DEFINE_IDTENTRY(exc_bounds)
 {
-	mark_trap_entry(X86_TRAP_BR, regs);
+	if (!mark_trap_entry(X86_TRAP_BR, regs))
+		goto out;
 
 	if (notify_die(DIE_TRAP, "bounds", regs, 0,
 			X86_TRAP_BR, SIGSEGV) == NOTIFY_STOP)
@@ -806,7 +811,8 @@ DEFINE_IDTENTRY_ERRORCODE(exc_general_protection)
 		if (fixup_vdso_exception(regs, X86_TRAP_GP, error_code, 0))
 			goto exit;
 
-		mark_trap_entry(X86_TRAP_GP, regs);
+		if (!mark_trap_entry(X86_TRAP_GP, regs))
+			goto mark_exit;
 		gp_user_force_sig_segv(regs, X86_TRAP_GP, error_code, desc);
 		goto mark_exit;
 	}
@@ -1273,7 +1279,8 @@ static void math_error(struct pt_regs *regs, int trapnr)
 		if (fixup_exception(regs, trapnr, 0, 0))
 			goto exit;
 
-		mark_trap_entry(trapnr, regs);
+		if (!mark_trap_entry(trapnr, regs))
+			goto mark_exit;
 		task->thread.error_code = 0;
 		task->thread.trap_nr = trapnr;
 
@@ -1300,10 +1307,9 @@ static void math_error(struct pt_regs *regs, int trapnr)
 	if (fixup_vdso_exception(regs, trapnr, 0, 0))
 		goto exit;
 
-	mark_trap_entry(trapnr, regs);
-
-	force_sig_fault(SIGFPE, si_code,
-			(void __user *)uprobe_get_trap_addr(regs));
+	if (mark_trap_entry(trapnr, regs))
+		force_sig_fault(SIGFPE, si_code,
+				(void __user *)uprobe_get_trap_addr(regs));
 mark_exit:
 	mark_trap_exit(trapnr, regs);
 exit:
@@ -1416,8 +1422,8 @@ DEFINE_IDTENTRY(exc_device_not_available)
 		 * to kill the task than getting stuck in a never-ending
 		 * loop of #NM faults.
 		 */
-		mark_trap_entry(X86_TRAP_NM, regs);
-		die("unexpected #NM exception", regs, 0);
+		if (mark_trap_entry(X86_TRAP_NM, regs))
+			die("unexpected #NM exception", regs, 0);
 		mark_trap_exit(X86_TRAP_NM, regs);
 	}
 }
diff --git a/arch/x86/mm/fault.c b/arch/x86/mm/fault.c
index 834a6edd0be5..1cffd321878f 100644
--- a/arch/x86/mm/fault.c
+++ b/arch/x86/mm/fault.c
@@ -650,7 +650,8 @@ page_fault_oops(struct pt_regs *regs, unsigned long error_code,
 	 * Do not bother unwinding the notification context on
 	 * CPU/firmware/kernel bug.
 	 */
-	oob_trap_notify(X86_TRAP_PF, regs);
+	if (oob_trap_notify(X86_TRAP_PF, regs))
+		return;
 
 #ifdef CONFIG_VMAP_STACK
 	/*
@@ -890,7 +891,8 @@ __bad_area_nosemaphore(struct pt_regs *regs, unsigned long error_code,
 	if (fixup_vdso_exception(regs, X86_TRAP_PF, error_code, address))
 		return;
 
-	oob_trap_notify(X86_TRAP_PF, regs);
+	if (oob_trap_notify(X86_TRAP_PF, regs))
+		return;
 
 	if (likely(show_unhandled_signals))
 		show_signal_msg(regs, error_code, address, tsk);
@@ -1363,7 +1365,8 @@ void do_user_addr_fault(struct pt_regs *regs,
 	 * event, so that it might switch current to in-band mode if
 	 * need be.
 	 */
-	oob_trap_notify(X86_TRAP_PF, regs);
+	if (oob_trap_notify(X86_TRAP_PF, regs))
+		return;
 
 	perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS, 1, regs, address);
 
diff --git a/include/linux/dovetail.h b/include/linux/dovetail.h
index 6a244a44ab1f..4bd27531f9e5 100644
--- a/include/linux/dovetail.h
+++ b/include/linux/dovetail.h
@@ -58,14 +58,15 @@ void inband_task_init(struct task_struct *p);
 
 int pipeline_syscall(unsigned int nr, struct pt_regs *regs);
 
-void __oob_trap_notify(unsigned int exception,
+bool __oob_trap_notify(unsigned int exception,
 		       struct pt_regs *regs);
 
-static __always_inline void oob_trap_notify(unsigned int exception,
+static __always_inline bool oob_trap_notify(unsigned int exception,
 					struct pt_regs *regs)
 {
 	if (running_oob() && !test_thread_local_flags(_TLF_OOBTRAP))
-		__oob_trap_notify(exception, regs);
+		return __oob_trap_notify(exception, regs);
+	return false;
 }
 
 void __oob_trap_unwind(unsigned int exception,
@@ -248,7 +249,7 @@ static inline void arch_dovetail_exec_prepare(void)
  * Keep the trap helpers as macros, we might not be able to resolve
  * trap numbers if CONFIG_DOVETAIL is off.
  */
-#define oob_trap_notify(__exception, __regs)	do { } while (0)
+#define oob_trap_notify(__exception, __regs)	false
 #define oob_trap_unwind(__exception, __regs)	do { } while (0)
 
 static inline
diff --git a/kernel/dovetail.c b/kernel/dovetail.c
index 79fd75918b37..167dc61dbcce 100644
--- a/kernel/dovetail.c
+++ b/kernel/dovetail.c
@@ -254,14 +254,16 @@ int pipeline_syscall(unsigned int nr, struct pt_regs *regs)
 	return 0; /* pass syscall down to the in-band dispatcher. */
 }
 
-void __weak handle_oob_trap_entry(unsigned int trapnr, struct pt_regs *regs)
+bool __weak handle_oob_trap_entry(unsigned int trapnr, struct pt_regs *regs)
 {
+	return false;
 }
 
-noinstr void __oob_trap_notify(unsigned int exception,
+noinstr bool __oob_trap_notify(unsigned int exception,
 			       struct pt_regs *regs)
 {
 	unsigned long flags;
+	bool handled;
 
 	/*
 	 * We send a notification about exceptions raised over a
@@ -273,10 +275,11 @@ noinstr void __oob_trap_notify(unsigned int exception,
 		set_thread_local_flags(_TLF_OOBTRAP);
 		flags = hard_local_irq_save();
 		instrumentation_begin();
-		handle_oob_trap_entry(exception, regs);
+		handled = handle_oob_trap_entry(exception, regs);
 		instrumentation_end();
 		hard_local_irq_restore(flags);
 	}
+	return handled;
 }
 
 void __weak handle_oob_trap_exit(unsigned int trapnr, struct pt_regs *regs)
-- 
2.35.3

             reply	other threads:[~2022-07-08  7:11 UTC|newest]

Thread overview: 16+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-07-08  7:11 Jan Kiszka [this message]
2022-07-08  7:12 ` [RFC][PATCH] x86: dovetail: Permit to declare a trap handled Jan Kiszka
2022-11-09  7:31   ` Johannes Kirchmair
2022-11-09  9:28     ` Jan Kiszka
2022-11-09 10:06       ` Philippe Gerum
2022-11-09 10:38         ` Jan Kiszka
2022-11-09 11:42           ` Johannes Kirchmair
2022-11-10  9:00             ` Philippe Gerum
2024-02-12 15:04               ` Richard Weinberger
2024-02-12 15:12                 ` Jan Kiszka
2024-02-12 15:14                   ` Richard Weinberger
2024-02-12 16:12                     ` Jan Kiszka
2024-03-28  7:28                       ` Richard Weinberger
2024-04-08 11:59                         ` Jan Kiszka
2022-11-09  7:36 ` Johannes Kirchmair
2022-11-09  9:29   ` Jan Kiszka

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=006148b8-dfa1-1abb-b243-029db08ceb0a@siemens.com \
    --to=jan.kiszka@siemens.com \
    --cc=johannes.kirchmair@sigmatek.at \
    --cc=richard@nod.at \
    --cc=rpm@xenomai.org \
    --cc=xenomai@lists.linux.dev \
    /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 read-only IMAP folder(s) and NNTP newsgroup(s).