Commit 4b7de6df authored by Thomas Gleixner's avatar Thomas Gleixner Committed by Ingo Molnar
Browse files

rseq: Cache CPU ID and MM CID values



In preparation for rewriting RSEQ exit to user space handling provide
storage to cache the CPU ID and MM CID values which were written to user
space. That prepares for a quick check, which avoids the update when
nothing changed.

Signed-off-by: default avatarThomas Gleixner <tglx@linutronix.de>
Signed-off-by: default avatarPeter Zijlstra (Intel) <peterz@infradead.org>
Signed-off-by: default avatarIngo Molnar <mingo@kernel.org>
Reviewed-by: default avatarMathieu Desnoyers <mathieu.desnoyers@efficios.com>
Link: https://patch.msgid.link/20251027084306.841964081@linutronix.de
parent 4fc9225d
Loading
Loading
Loading
Loading
+5 −2
Original line number Diff line number Diff line
@@ -57,6 +57,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;
}

static inline void rseq_execve(struct task_struct *t)
@@ -70,10 +71,12 @@ static inline void rseq_execve(struct task_struct *t)
 */
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 */
+21 −0
Original line number Diff line number Diff line
@@ -30,18 +30,39 @@ struct rseq_event {
	};
};

/**
 * struct rseq_ids - Cache for ids, which need to be updated
 * @cpu_cid:	Compound of @cpu_id and @mm_cid to make the
 *		compiler emit a single compare on 64-bit
 * @cpu_id:	The CPU ID which was written last to user space
 * @mm_cid:	The MM CID which was written last to user space
 *
 * @cpu_id and @mm_cid are updated when the data is written to user space.
 */
struct rseq_ids {
	union {
		u64		cpu_cid;
		struct {
			u32	cpu_id;
			u32	mm_cid;
		};
	};
};

/**
 * struct rseq_data - Storage for all rseq related data
 * @usrptr:	Pointer to the registered user space RSEQ memory
 * @len:	Length of the RSEQ region
 * @sig:	Signature of critial section abort IPs
 * @event:	Storage for event management
 * @ids:	Storage for cached CPU ID and MM CID
 */
struct rseq_data {
	struct rseq __user		*usrptr;
	u32				len;
	u32				sig;
	struct rseq_event		event;
	struct rseq_ids			ids;
};

#else /* CONFIG_RSEQ */
+2 −2
Original line number Diff line number Diff line
@@ -21,9 +21,9 @@ TRACE_EVENT(rseq_update,
	),

	TP_fast_assign(
		__entry->cpu_id = raw_smp_processor_id();
		__entry->cpu_id = t->rseq.ids.cpu_id;
		__entry->node_id = cpu_to_node(__entry->cpu_id);
		__entry->mm_cid = task_mm_cid(t);
		__entry->mm_cid = t->rseq.ids.mm_cid;
	),

	TP_printk("cpu_id=%d node_id=%d mm_cid=%d", __entry->cpu_id,
+4 −0
Original line number Diff line number Diff line
@@ -184,6 +184,10 @@ static int rseq_update_cpu_node_id(struct task_struct *t)
	rseq_unsafe_put_user(t, node_id, node_id, efault_end);
	rseq_unsafe_put_user(t, mm_cid, mm_cid, efault_end);

	/* Cache the user space values */
	t->rseq.ids.cpu_id = cpu_id;
	t->rseq.ids.mm_cid = mm_cid;

	/*
	 * Additional feature fields added after ORIG_RSEQ_SIZE
	 * need to be conditionally updated only if