Commit d6200245 authored by Peter Zijlstra's avatar Peter Zijlstra
Browse files

rseq: Allow registering RSEQ with slice extension



Since glibc cares about the number of syscalls required to initialize a new
thread, allow initializing rseq with slice extension on. This avoids having to
do another prctl().

Requested-by: default avatarMathieu Desnoyers <mathieu.desnoyers@efficios.com>
Signed-off-by: default avatarPeter Zijlstra (Intel) <peterz@infradead.org>
Link: https://patch.msgid.link/20260121143207.814193010@infradead.org
parent 830969e7
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -20,6 +20,7 @@ enum rseq_cpu_id_state {

enum rseq_flags {
	RSEQ_FLAG_UNREGISTER			= (1 << 0),
	RSEQ_FLAG_SLICE_EXT_DEFAULT_ON		= (1 << 1),
};

enum rseq_cs_flags_bit {
+10 −2
Original line number Diff line number Diff line
@@ -424,7 +424,7 @@ SYSCALL_DEFINE4(rseq, struct rseq __user *, rseq, u32, rseq_len, int, flags, u32
		return 0;
	}

	if (unlikely(flags))
	if (unlikely(flags & ~(RSEQ_FLAG_SLICE_EXT_DEFAULT_ON)))
		return -EINVAL;

	if (current->rseq.usrptr) {
@@ -459,8 +459,12 @@ SYSCALL_DEFINE4(rseq, struct rseq __user *, rseq, u32, rseq_len, int, flags, u32
	if (!access_ok(rseq, rseq_len))
		return -EFAULT;

	if (IS_ENABLED(CONFIG_RSEQ_SLICE_EXTENSION))
	if (IS_ENABLED(CONFIG_RSEQ_SLICE_EXTENSION)) {
		rseqfl |= RSEQ_CS_FLAG_SLICE_EXT_AVAILABLE;
		if (rseq_slice_extension_enabled() &&
		    (flags & RSEQ_FLAG_SLICE_EXT_DEFAULT_ON))
			rseqfl |= RSEQ_CS_FLAG_SLICE_EXT_ENABLED;
	}

	scoped_user_write_access(rseq, efault) {
		/*
@@ -488,6 +492,10 @@ SYSCALL_DEFINE4(rseq, struct rseq __user *, rseq, u32, rseq_len, int, flags, u32
	current->rseq.len = rseq_len;
	current->rseq.sig = sig;

#ifdef CONFIG_RSEQ_SLICE_EXTENSION
	current->rseq.slice.state.enabled = !!(rseqfl & RSEQ_CS_FLAG_SLICE_EXT_ENABLED);
#endif

	/*
	 * If rseq was previously inactive, and has just been
	 * registered, ensure the cpu_id_start and cpu_id fields