Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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: 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/20251027084306.841964081@linutronix.de

authored by

Thomas Gleixner and committed by
Ingo Molnar
4b7de6df 4fc9225d

+32 -4
+5 -2
include/linux/rseq.h
··· 57 57 static inline void rseq_reset(struct task_struct *t) 58 58 { 59 59 memset(&t->rseq, 0, sizeof(t->rseq)); 60 + t->rseq.ids.cpu_cid = ~0ULL; 60 61 } 61 62 62 63 static inline void rseq_execve(struct task_struct *t) ··· 71 70 */ 72 71 static inline void rseq_fork(struct task_struct *t, u64 clone_flags) 73 72 { 74 - if (clone_flags & CLONE_VM) 73 + if (clone_flags & CLONE_VM) { 75 74 rseq_reset(t); 76 - else 75 + } else { 77 76 t->rseq = current->rseq; 77 + t->rseq.ids.cpu_cid = ~0ULL; 78 + } 78 79 } 79 80 80 81 #else /* CONFIG_RSEQ */
+21
include/linux/rseq_types.h
··· 31 31 }; 32 32 33 33 /** 34 + * struct rseq_ids - Cache for ids, which need to be updated 35 + * @cpu_cid: Compound of @cpu_id and @mm_cid to make the 36 + * compiler emit a single compare on 64-bit 37 + * @cpu_id: The CPU ID which was written last to user space 38 + * @mm_cid: The MM CID which was written last to user space 39 + * 40 + * @cpu_id and @mm_cid are updated when the data is written to user space. 41 + */ 42 + struct rseq_ids { 43 + union { 44 + u64 cpu_cid; 45 + struct { 46 + u32 cpu_id; 47 + u32 mm_cid; 48 + }; 49 + }; 50 + }; 51 + 52 + /** 34 53 * struct rseq_data - Storage for all rseq related data 35 54 * @usrptr: Pointer to the registered user space RSEQ memory 36 55 * @len: Length of the RSEQ region 37 56 * @sig: Signature of critial section abort IPs 38 57 * @event: Storage for event management 58 + * @ids: Storage for cached CPU ID and MM CID 39 59 */ 40 60 struct rseq_data { 41 61 struct rseq __user *usrptr; 42 62 u32 len; 43 63 u32 sig; 44 64 struct rseq_event event; 65 + struct rseq_ids ids; 45 66 }; 46 67 47 68 #else /* CONFIG_RSEQ */
+2 -2
include/trace/events/rseq.h
··· 21 21 ), 22 22 23 23 TP_fast_assign( 24 - __entry->cpu_id = raw_smp_processor_id(); 24 + __entry->cpu_id = t->rseq.ids.cpu_id; 25 25 __entry->node_id = cpu_to_node(__entry->cpu_id); 26 - __entry->mm_cid = task_mm_cid(t); 26 + __entry->mm_cid = t->rseq.ids.mm_cid; 27 27 ), 28 28 29 29 TP_printk("cpu_id=%d node_id=%d mm_cid=%d", __entry->cpu_id,
+4
kernel/rseq.c
··· 184 184 rseq_unsafe_put_user(t, node_id, node_id, efault_end); 185 185 rseq_unsafe_put_user(t, mm_cid, mm_cid, efault_end); 186 186 187 + /* Cache the user space values */ 188 + t->rseq.ids.cpu_id = cpu_id; 189 + t->rseq.ids.mm_cid = mm_cid; 190 + 187 191 /* 188 192 * Additional feature fields added after ORIG_RSEQ_SIZE 189 193 * need to be conditionally updated only if