]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
rseq: Implement sys_rseq_slice_yield()
authorThomas Gleixner <tglx@linutronix.de>
Mon, 15 Dec 2025 16:52:15 +0000 (17:52 +0100)
committerPeter Zijlstra <peterz@infradead.org>
Thu, 22 Jan 2026 10:11:17 +0000 (11:11 +0100)
Provide a new syscall which has the only purpose to yield the CPU after the
kernel granted a time slice extension.

sched_yield() is not suitable for that because it unconditionally
schedules, but the end of the time slice extension is not required to
schedule when the task was already preempted. This also allows to have a
strict check for termination to catch user space invoking random syscalls
including sched_yield() from a time slice extension region.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Reviewed-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
Acked-by: Arnd Bergmann <arnd@arndb.de>
Link: https://patch.msgid.link/20251215155708.929634896@linutronix.de
22 files changed:
arch/alpha/kernel/syscalls/syscall.tbl
arch/arm/tools/syscall.tbl
arch/arm64/tools/syscall_32.tbl
arch/m68k/kernel/syscalls/syscall.tbl
arch/microblaze/kernel/syscalls/syscall.tbl
arch/mips/kernel/syscalls/syscall_n32.tbl
arch/mips/kernel/syscalls/syscall_n64.tbl
arch/mips/kernel/syscalls/syscall_o32.tbl
arch/parisc/kernel/syscalls/syscall.tbl
arch/powerpc/kernel/syscalls/syscall.tbl
arch/s390/kernel/syscalls/syscall.tbl
arch/sh/kernel/syscalls/syscall.tbl
arch/sparc/kernel/syscalls/syscall.tbl
arch/x86/entry/syscalls/syscall_32.tbl
arch/x86/entry/syscalls/syscall_64.tbl
arch/xtensa/kernel/syscalls/syscall.tbl
include/linux/rseq_types.h
include/linux/syscalls.h
include/uapi/asm-generic/unistd.h
kernel/rseq.c
kernel/sys_ni.c
scripts/syscall.tbl

index 3fed97478058eb315307823e68ae18019b7cdd23..f31b7afffc34596ee43be883d52da67a6f17a176 100644 (file)
 578    common  file_getattr                    sys_file_getattr
 579    common  file_setattr                    sys_file_setattr
 580    common  listns                          sys_listns
+581    common  rseq_slice_yield                sys_rseq_slice_yield
index fd09afae72a24255a883dd2bc51b1679d29d265e..94351e22bfcf76834c6e4cc2184d1388ad3b169c 100644 (file)
 468    common  file_getattr                    sys_file_getattr
 469    common  file_setattr                    sys_file_setattr
 470    common  listns                          sys_listns
+471    common  rseq_slice_yield                sys_rseq_slice_yield
index 8cdfe5d4dac9b9dd4e9de7a1c75b6cb267f30fd1..62d93d88e0fef81fcf60b7897b131f04b20c49db 100644 (file)
 468    common  file_getattr                    sys_file_getattr
 469    common  file_setattr                    sys_file_setattr
 470    common  listns                          sys_listns
+471    common  rseq_slice_yield                sys_rseq_slice_yield
index 871a5d67bf4164b09f3a9bccd7d3125ce8a7b24e..2489342571014c5f0b3d695e32a6de3de56192d8 100644 (file)
 468    common  file_getattr                    sys_file_getattr
 469    common  file_setattr                    sys_file_setattr
 470    common  listns                          sys_listns
+471    common  rseq_slice_yield                sys_rseq_slice_yield
index 022fc85d94b3384a44aae5d5cdec64a07c072a1c..223d2630362724dfc9fd9de4281c19777dccfb3f 100644 (file)
 468    common  file_getattr                    sys_file_getattr
 469    common  file_setattr                    sys_file_setattr
 470    common  listns                          sys_listns
+471    common  rseq_slice_yield                sys_rseq_slice_yield
index 8cedc83c3266ec4abc477656a5f84cad549654e5..7430714e2b8f863f757feb7ef91a8fbf09be8007 100644 (file)
 468    n32     file_getattr                    sys_file_getattr
 469    n32     file_setattr                    sys_file_setattr
 470    n32     listns                          sys_listns
+471    n32     rseq_slice_yield                sys_rseq_slice_yield
index 9b92bddf06b572d0437b59cd76e6e6852c7d85be..630aab9e542592bbef061594d27aed99b2134f28 100644 (file)
 468    n64     file_getattr                    sys_file_getattr
 469    n64     file_setattr                    sys_file_setattr
 470    n64     listns                          sys_listns
+471    n64     rseq_slice_yield                sys_rseq_slice_yield
index f810b8a557168ec4c46d1a996d32c3088d3d0046..128653112284b2f9fc93958c50b172d91e69e4de 100644 (file)
 468    o32     file_getattr                    sys_file_getattr
 469    o32     file_setattr                    sys_file_setattr
 470    o32     listns                          sys_listns
+471    o32     rseq_slice_yield                sys_rseq_slice_yield
index 39bdacaa530b171781bbc82145344f2bdf733b59..f6e2d0379d57c99ea3d155358cd1648b432da4de 100644 (file)
 468    common  file_getattr                    sys_file_getattr
 469    common  file_setattr                    sys_file_setattr
 470    common  listns                          sys_listns
+471    common  rseq_slice_yield                sys_rseq_slice_yield
index ec4458cdb97b69a6213125d367d42f763234df52..4fcc7c58a105dc9fbf6a4b486ceda155c49d21c0 100644 (file)
 468    common  file_getattr                    sys_file_getattr
 469    common  file_setattr                    sys_file_setattr
 470    common  listns                          sys_listns
+471    nospu   rseq_slice_yield                sys_rseq_slice_yield
index 417ed16b3c63ac8b5e69638105f152971582c413..09a7ef04d9791a8e32217edddd2591f11b48b118 100644 (file)
 468    common  file_getattr                    sys_file_getattr
 469    common  file_setattr                    sys_file_setattr
 470    common  listns                          sys_listns
+471    common  rseq_slice_yield                sys_rseq_slice_yield
index 969c11325adeb24e5b954c940a2be0e88edcf975..70b315cbe710c24836e26ee461af93d289a62361 100644 (file)
 468    common  file_getattr                    sys_file_getattr
 469    common  file_setattr                    sys_file_setattr
 470    common  listns                          sys_listns
+471    common  rseq_slice_yield                sys_rseq_slice_yield
index 39aa26b6a50be7e02ba2400b797d128f8c6d3499..d5b1a7198410886884e3b0e8b846ae995037b377 100644 (file)
 468    common  file_getattr                    sys_file_getattr
 469    common  file_setattr                    sys_file_setattr
 470    common  listns                          sys_listns
+471    common  rseq_slice_yield                sys_rseq_slice_yield
index e979a3eac7a355de54b6b05265db7473a46b6ff5..f832ebd2d79b000aead9a0aed58fcbda8bf09ece 100644 (file)
 468    i386    file_getattr            sys_file_getattr
 469    i386    file_setattr            sys_file_setattr
 470    i386    listns                  sys_listns
+471    i386    rseq_slice_yield        sys_rseq_slice_yield
index 8a4ac4841be6e54250bffb8de630a28b30a8ba5a..524155d655da15478e81117a7b547cf3b172ad82 100644 (file)
 468    common  file_getattr            sys_file_getattr
 469    common  file_setattr            sys_file_setattr
 470    common  listns                  sys_listns
+471    common  rseq_slice_yield        sys_rseq_slice_yield
 
 #
 # Due to a historical design error, certain syscalls are numbered differently
index 438a3b1704022b39f9c25fcd27151b0a54e7be01..a9bca4e484decfb9d7fe1c05a85ca0595a8494c8 100644 (file)
 468    common  file_getattr                    sys_file_getattr
 469    common  file_setattr                    sys_file_setattr
 470    common  listns                          sys_listns
+471    common  rseq_slice_yield                sys_rseq_slice_yield
index 67e40c059b1b16423bf293ced73bcaf277154c8f..8c540e775161660c811803256c82a445f6dfe420 100644 (file)
@@ -89,9 +89,11 @@ union rseq_slice_state {
 /**
  * struct rseq_slice - Status information for rseq time slice extension
  * @state:     Time slice extension state
+ * @yielded:   Indicator for rseq_slice_yield()
  */
 struct rseq_slice {
        union rseq_slice_state  state;
+       u8                      yielded;
 };
 
 /**
index cf84d98964b2f434cfa4946bab54ebf49c71df1c..6c8a570cf44a8f05e6fbaab495e1720bc7f76d08 100644 (file)
@@ -961,6 +961,7 @@ asmlinkage long sys_statx(int dfd, const char __user *path, unsigned flags,
                          unsigned mask, struct statx __user *buffer);
 asmlinkage long sys_rseq(struct rseq __user *rseq, uint32_t rseq_len,
                         int flags, uint32_t sig);
+asmlinkage long sys_rseq_slice_yield(void);
 asmlinkage long sys_open_tree(int dfd, const char __user *path, unsigned flags);
 asmlinkage long sys_open_tree_attr(int dfd, const char __user *path,
                                   unsigned flags,
index 942370b3f5d252305832d105615f1628fa0ad304..a627acc8fb5fead80aeb95f4dfebff16a79cedf5 100644 (file)
@@ -860,8 +860,11 @@ __SYSCALL(__NR_file_setattr, sys_file_setattr)
 #define __NR_listns 470
 __SYSCALL(__NR_listns, sys_listns)
 
+#define __NR_rseq_slice_yield 471
+__SYSCALL(__NR_rseq_slice_yield, sys_rseq_slice_yield)
+
 #undef __NR_syscalls
-#define __NR_syscalls 471
+#define __NR_syscalls 472
 
 /*
  * 32 bit systems traditionally used different
index 09848bb14ec2bd3e451195d9f9eb0d9aee88d40f..d8e1992edffa7831d817a44e991f4371b5f959a4 100644 (file)
@@ -553,6 +553,27 @@ die:
        return -EFAULT;
 }
 
+/**
+ * sys_rseq_slice_yield - yield the current processor side effect free if a
+ *                       task granted with a time slice extension is done with
+ *                       the critical work before being forced out.
+ *
+ * Return: 1 if the task successfully yielded the CPU within the granted slice.
+ *         0 if the slice extension was either never granted or was revoked by
+ *          going over the granted extension, using a syscall other than this one
+ *          or being scheduled out earlier due to a subsequent interrupt.
+ *
+ * The syscall does not schedule because the syscall entry work immediately
+ * relinquishes the CPU and schedules if required.
+ */
+SYSCALL_DEFINE0(rseq_slice_yield)
+{
+       int yielded = !!current->rseq.slice.yielded;
+
+       current->rseq.slice.yielded = 0;
+       return yielded;
+}
+
 static int __init rseq_slice_cmdline(char *str)
 {
        bool on;
index bf5d05c635ffd525afcb42fd780a0ab198e1eebe..add3032da16f509af34bb36a916ede711630d507 100644 (file)
@@ -390,6 +390,7 @@ COND_SYSCALL(setuid16);
 
 /* restartable sequence */
 COND_SYSCALL(rseq);
+COND_SYSCALL(rseq_slice_yield);
 
 COND_SYSCALL(uretprobe);
 COND_SYSCALL(uprobe);
index e74868be513cfb042280bc9496da374f50d9e5cb..7a42b32b65776773b8117a5e2d6131acfdf4e505 100644 (file)
 468    common  file_getattr                    sys_file_getattr
 469    common  file_setattr                    sys_file_setattr
 470    common  listns                          sys_listns
+471    common  rseq_slice_yield                sys_rseq_slice_yield