From 2f529f9b558ca1c1bd74be7437a84e4711743404 Mon Sep 17 00:00:00 2001
From: hc <hc@nodka.com>
Date: Fri, 01 Nov 2024 02:11:33 +0000
Subject: [PATCH] add xenomai
---
kernel/arch/arm64/kernel/signal.c | 38 +++++++++++++++++++++++++++++++++++++-
1 files changed, 37 insertions(+), 1 deletions(-)
diff --git a/kernel/arch/arm64/kernel/signal.c b/kernel/arch/arm64/kernel/signal.c
index b6fbbd5..3bf8eae 100644
--- a/kernel/arch/arm64/kernel/signal.c
+++ b/kernel/arch/arm64/kernel/signal.c
@@ -11,6 +11,7 @@
#include <linux/errno.h>
#include <linux/kernel.h>
#include <linux/signal.h>
+#include <linux/irq_pipeline.h>
#include <linux/personality.h>
#include <linux/freezer.h>
#include <linux/stddef.h>
@@ -914,19 +915,36 @@
restore_saved_sigmask();
}
+static inline void do_retuser(void)
+{
+ unsigned long thread_flags;
+
+ if (dovetailing()) {
+ thread_flags = current_thread_info()->flags;
+ if (thread_flags & _TIF_RETUSER)
+ inband_retuser_notify();
+ }
+}
+
asmlinkage void do_notify_resume(struct pt_regs *regs,
unsigned long thread_flags)
{
+ WARN_ON_ONCE(irq_pipeline_debug() && running_oob());
+
+ stall_inband();
+
do {
/* Check valid user FS if needed */
addr_limit_user_check();
if (thread_flags & _TIF_NEED_RESCHED) {
/* Unmask Debug and SError for the next task */
- local_daif_restore(DAIF_PROCCTX_NOIRQ);
+ local_daif_restore(irqs_pipelined() ? DAIF_PROCCTX :
+ DAIF_PROCCTX_NOIRQ);
schedule();
} else {
+ unstall_inband();
local_daif_restore(DAIF_PROCCTX);
if (thread_flags & _TIF_UPROBE)
@@ -948,11 +966,29 @@
if (thread_flags & _TIF_FOREIGN_FPSTATE)
fpsimd_restore_current_state();
+
+ do_retuser();
+ /* RETUSER might have switched oob */
+ if (running_oob()) {
+ local_daif_mask();
+ return;
+ }
}
+ /*
+ * Dovetail: we may have restored the fpsimd state for
+ * current with no other opportunity to check for
+ * _TIF_FOREIGN_FPSTATE until we are back running on
+ * el0, so we must not take any interrupt until then,
+ * otherwise we may end up resuming with some OOB
+ * thread's fpsimd state.
+ */
local_daif_mask();
+ stall_inband();
thread_flags = READ_ONCE(current_thread_info()->flags);
} while (thread_flags & _TIF_WORK_MASK);
+
+ unstall_inband();
}
unsigned long __ro_after_init signal_minsigstksz;
--
Gitblit v1.6.2