summaryrefslogtreecommitdiff
path: root/include/linux/rseq.h
diff options
context:
space:
mode:
authorThomas Gleixner <tglx@linutronix.de>2025-10-27 09:45:08 +0100
committerIngo Molnar <mingo@kernel.org>2025-11-04 08:33:33 +0100
commit0f085b41880e3140efa6941ff2b8fd43bac4d659 (patch)
tree441ac375157092ba3b346b5f661acbddda7185dd /include/linux/rseq.h
parenteaa9088d568c84afd72fa32dbe01833aef861d0d (diff)
downloadlinux-next-0f085b41880e3140efa6941ff2b8fd43bac4d659.tar.gz
linux-next-0f085b41880e3140efa6941ff2b8fd43bac4d659.zip
rseq: Provide and use rseq_set_ids()
Provide a new and straight forward implementation to set the IDs (CPU ID, Node ID and MM CID), which can be later inlined into the fast path. It does all operations in one scoped_user_rw_access() section and retrieves also the critical section member (rseq::cs_rseq) from user space to avoid another user..begin/end() pair. This is in preparation for optimizing the fast path to avoid extra work when not required. On rseq registration set the CPU ID fields to RSEQ_CPU_ID_UNINITIALIZED and node and MM CID to zero. That's the same as the kernel internal reset values. That makes the debug validation in the exit code work correctly on the first exit to user space. Use it to replace the whole related zoo in rseq.c Signed-off-by: Thomas Gleixner <tglx@linutronix.de> Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org> Signed-off-by: Ingo Molnar <mingo@kernel.org> Reviewed-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com> Link: https://patch.msgid.link/20251027084307.393972266@linutronix.de
Diffstat (limited to 'include/linux/rseq.h')
-rw-r--r--include/linux/rseq.h16
1 files changed, 11 insertions, 5 deletions
diff --git a/include/linux/rseq.h b/include/linux/rseq.h
index 7f347c3a4af8..92f9cd49489b 100644
--- a/include/linux/rseq.h
+++ b/include/linux/rseq.h
@@ -5,6 +5,8 @@
#ifdef CONFIG_RSEQ
#include <linux/sched.h>
+#include <uapi/linux/rseq.h>
+
void __rseq_handle_notify_resume(struct ksignal *sig, struct pt_regs *regs);
static inline void rseq_handle_notify_resume(struct pt_regs *regs)
@@ -48,7 +50,7 @@ static inline void rseq_virt_userspace_exit(void)
static inline void rseq_reset(struct task_struct *t)
{
memset(&t->rseq, 0, sizeof(t->rseq));
- t->rseq.ids.cpu_cid = ~0ULL;
+ t->rseq.ids.cpu_id = RSEQ_CPU_ID_UNINITIALIZED;
}
static inline void rseq_execve(struct task_struct *t)
@@ -59,15 +61,19 @@ static inline void rseq_execve(struct task_struct *t)
/*
* If parent process has a registered restartable sequences area, the
* child inherits. Unregister rseq for a clone with CLONE_VM set.
+ *
+ * On fork, keep the IDs (CPU, MMCID) of the parent, which avoids a fault
+ * on the COW page on exit to user space, when the child stays on the same
+ * CPU as the parent. That's obviously not guaranteed, but in overcommit
+ * scenarios it is more likely and optimizes for the fork/exec case without
+ * taking the fault.
*/
static inline void rseq_fork(struct task_struct *t, u64 clone_flags)
{
- if (clone_flags & CLONE_VM) {
+ if (clone_flags & CLONE_VM)
rseq_reset(t);
- } else {
+ else
t->rseq = current->rseq;
- t->rseq.ids.cpu_cid = ~0ULL;
- }
}
#else /* CONFIG_RSEQ */