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

selftests/rseq: introduce own copy of rseq uapi header

The Linux kernel rseq uapi header has a broken layout for the
rseq_cs.ptr field on 32-bit little endian architectures. The entire
rseq_cs.ptr field is planned for removal, leaving only the 64-bit
rseq_cs.ptr64 field available.

Both glibc and librseq use their own copy of the Linux kernel uapi
header, where they introduce proper union fields to access to the 32-bit
low order bits of the rseq_cs pointer on 32-bit architectures.

Introduce a copy of the Linux kernel uapi headers in the Linux kernel
selftests.

Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Link: https://lkml.kernel.org/r/20220124171253.22072-2-mathieu.desnoyers@efficios.com

authored by

Mathieu Desnoyers and committed by
Peter Zijlstra
5c105d55 ec244453

+161 -14
+151
tools/testing/selftests/rseq/rseq-abi.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0+ WITH Linux-syscall-note */ 2 + #ifndef _RSEQ_ABI_H 3 + #define _RSEQ_ABI_H 4 + 5 + /* 6 + * rseq-abi.h 7 + * 8 + * Restartable sequences system call API 9 + * 10 + * Copyright (c) 2015-2022 Mathieu Desnoyers <mathieu.desnoyers@efficios.com> 11 + */ 12 + 13 + #include <linux/types.h> 14 + #include <asm/byteorder.h> 15 + 16 + enum rseq_abi_cpu_id_state { 17 + RSEQ_ABI_CPU_ID_UNINITIALIZED = -1, 18 + RSEQ_ABI_CPU_ID_REGISTRATION_FAILED = -2, 19 + }; 20 + 21 + enum rseq_abi_flags { 22 + RSEQ_ABI_FLAG_UNREGISTER = (1 << 0), 23 + }; 24 + 25 + enum rseq_abi_cs_flags_bit { 26 + RSEQ_ABI_CS_FLAG_NO_RESTART_ON_PREEMPT_BIT = 0, 27 + RSEQ_ABI_CS_FLAG_NO_RESTART_ON_SIGNAL_BIT = 1, 28 + RSEQ_ABI_CS_FLAG_NO_RESTART_ON_MIGRATE_BIT = 2, 29 + }; 30 + 31 + enum rseq_abi_cs_flags { 32 + RSEQ_ABI_CS_FLAG_NO_RESTART_ON_PREEMPT = 33 + (1U << RSEQ_ABI_CS_FLAG_NO_RESTART_ON_PREEMPT_BIT), 34 + RSEQ_ABI_CS_FLAG_NO_RESTART_ON_SIGNAL = 35 + (1U << RSEQ_ABI_CS_FLAG_NO_RESTART_ON_SIGNAL_BIT), 36 + RSEQ_ABI_CS_FLAG_NO_RESTART_ON_MIGRATE = 37 + (1U << RSEQ_ABI_CS_FLAG_NO_RESTART_ON_MIGRATE_BIT), 38 + }; 39 + 40 + /* 41 + * struct rseq_abi_cs is aligned on 4 * 8 bytes to ensure it is always 42 + * contained within a single cache-line. It is usually declared as 43 + * link-time constant data. 44 + */ 45 + struct rseq_abi_cs { 46 + /* Version of this structure. */ 47 + __u32 version; 48 + /* enum rseq_abi_cs_flags */ 49 + __u32 flags; 50 + __u64 start_ip; 51 + /* Offset from start_ip. */ 52 + __u64 post_commit_offset; 53 + __u64 abort_ip; 54 + } __attribute__((aligned(4 * sizeof(__u64)))); 55 + 56 + /* 57 + * struct rseq_abi is aligned on 4 * 8 bytes to ensure it is always 58 + * contained within a single cache-line. 59 + * 60 + * A single struct rseq_abi per thread is allowed. 61 + */ 62 + struct rseq_abi { 63 + /* 64 + * Restartable sequences cpu_id_start field. Updated by the 65 + * kernel. Read by user-space with single-copy atomicity 66 + * semantics. This field should only be read by the thread which 67 + * registered this data structure. Aligned on 32-bit. Always 68 + * contains a value in the range of possible CPUs, although the 69 + * value may not be the actual current CPU (e.g. if rseq is not 70 + * initialized). This CPU number value should always be compared 71 + * against the value of the cpu_id field before performing a rseq 72 + * commit or returning a value read from a data structure indexed 73 + * using the cpu_id_start value. 74 + */ 75 + __u32 cpu_id_start; 76 + /* 77 + * Restartable sequences cpu_id field. Updated by the kernel. 78 + * Read by user-space with single-copy atomicity semantics. This 79 + * field should only be read by the thread which registered this 80 + * data structure. Aligned on 32-bit. Values 81 + * RSEQ_CPU_ID_UNINITIALIZED and RSEQ_CPU_ID_REGISTRATION_FAILED 82 + * have a special semantic: the former means "rseq uninitialized", 83 + * and latter means "rseq initialization failed". This value is 84 + * meant to be read within rseq critical sections and compared 85 + * with the cpu_id_start value previously read, before performing 86 + * the commit instruction, or read and compared with the 87 + * cpu_id_start value before returning a value loaded from a data 88 + * structure indexed using the cpu_id_start value. 89 + */ 90 + __u32 cpu_id; 91 + /* 92 + * Restartable sequences rseq_cs field. 93 + * 94 + * Contains NULL when no critical section is active for the current 95 + * thread, or holds a pointer to the currently active struct rseq_cs. 96 + * 97 + * Updated by user-space, which sets the address of the currently 98 + * active rseq_cs at the beginning of assembly instruction sequence 99 + * block, and set to NULL by the kernel when it restarts an assembly 100 + * instruction sequence block, as well as when the kernel detects that 101 + * it is preempting or delivering a signal outside of the range 102 + * targeted by the rseq_cs. Also needs to be set to NULL by user-space 103 + * before reclaiming memory that contains the targeted struct rseq_cs. 104 + * 105 + * Read and set by the kernel. Set by user-space with single-copy 106 + * atomicity semantics. This field should only be updated by the 107 + * thread which registered this data structure. Aligned on 64-bit. 108 + */ 109 + union { 110 + __u64 ptr64; 111 + 112 + /* 113 + * The "arch" field provides architecture accessor for 114 + * the ptr field based on architecture pointer size and 115 + * endianness. 116 + */ 117 + struct { 118 + #ifdef __LP64__ 119 + __u64 ptr; 120 + #elif defined(__BYTE_ORDER) ? (__BYTE_ORDER == __BIG_ENDIAN) : defined(__BIG_ENDIAN) 121 + __u32 padding; /* Initialized to zero. */ 122 + __u32 ptr; 123 + #else 124 + __u32 ptr; 125 + __u32 padding; /* Initialized to zero. */ 126 + #endif 127 + } arch; 128 + } rseq_cs; 129 + 130 + /* 131 + * Restartable sequences flags field. 132 + * 133 + * This field should only be updated by the thread which 134 + * registered this data structure. Read by the kernel. 135 + * Mainly used for single-stepping through rseq critical sections 136 + * with debuggers. 137 + * 138 + * - RSEQ_ABI_CS_FLAG_NO_RESTART_ON_PREEMPT 139 + * Inhibit instruction sequence block restart on preemption 140 + * for this thread. 141 + * - RSEQ_ABI_CS_FLAG_NO_RESTART_ON_SIGNAL 142 + * Inhibit instruction sequence block restart on signal 143 + * delivery for this thread. 144 + * - RSEQ_ABI_CS_FLAG_NO_RESTART_ON_MIGRATE 145 + * Inhibit instruction sequence block restart on migration for 146 + * this thread. 147 + */ 148 + __u32 flags; 149 + } __attribute__((aligned(4 * sizeof(__u64)))); 150 + 151 + #endif /* _RSEQ_ABI_H */
+7 -7
tools/testing/selftests/rseq/rseq.c
··· 30 30 #include "../kselftest.h" 31 31 #include "rseq.h" 32 32 33 - __thread volatile struct rseq __rseq_abi = { 34 - .cpu_id = RSEQ_CPU_ID_UNINITIALIZED, 33 + __thread volatile struct rseq_abi __rseq_abi = { 34 + .cpu_id = RSEQ_ABI_CPU_ID_UNINITIALIZED, 35 35 }; 36 36 37 37 /* ··· 66 66 abort(); 67 67 } 68 68 69 - static int sys_rseq(volatile struct rseq *rseq_abi, uint32_t rseq_len, 69 + static int sys_rseq(volatile struct rseq_abi *rseq_abi, uint32_t rseq_len, 70 70 int flags, uint32_t sig) 71 71 { 72 72 return syscall(__NR_rseq, rseq_abi, rseq_len, flags, sig); ··· 86 86 } 87 87 if (__rseq_refcount++) 88 88 goto end; 89 - rc = sys_rseq(&__rseq_abi, sizeof(struct rseq), 0, RSEQ_SIG); 89 + rc = sys_rseq(&__rseq_abi, sizeof(struct rseq_abi), 0, RSEQ_SIG); 90 90 if (!rc) { 91 91 assert(rseq_current_cpu_raw() >= 0); 92 92 goto end; 93 93 } 94 94 if (errno != EBUSY) 95 - __rseq_abi.cpu_id = RSEQ_CPU_ID_REGISTRATION_FAILED; 95 + __rseq_abi.cpu_id = RSEQ_ABI_CPU_ID_REGISTRATION_FAILED; 96 96 ret = -1; 97 97 __rseq_refcount--; 98 98 end: ··· 114 114 } 115 115 if (--__rseq_refcount) 116 116 goto end; 117 - rc = sys_rseq(&__rseq_abi, sizeof(struct rseq), 118 - RSEQ_FLAG_UNREGISTER, RSEQ_SIG); 117 + rc = sys_rseq(&__rseq_abi, sizeof(struct rseq_abi), 118 + RSEQ_ABI_FLAG_UNREGISTER, RSEQ_SIG); 119 119 if (!rc) 120 120 goto end; 121 121 __rseq_refcount = 1;
+3 -7
tools/testing/selftests/rseq/rseq.h
··· 16 16 #include <errno.h> 17 17 #include <stdio.h> 18 18 #include <stdlib.h> 19 - #include <linux/rseq.h> 19 + #include "rseq-abi.h" 20 20 21 21 /* 22 22 * Empty code injection macros, override when testing. ··· 43 43 #define RSEQ_INJECT_FAILED 44 44 #endif 45 45 46 - extern __thread volatile struct rseq __rseq_abi; 46 + extern __thread volatile struct rseq_abi __rseq_abi; 47 47 extern int __rseq_handled; 48 48 49 49 #define rseq_likely(x) __builtin_expect(!!(x), 1) ··· 139 139 140 140 static inline void rseq_clear_rseq_cs(void) 141 141 { 142 - #ifdef __LP64__ 143 - __rseq_abi.rseq_cs.ptr = 0; 144 - #else 145 - __rseq_abi.rseq_cs.ptr.ptr32 = 0; 146 - #endif 142 + __rseq_abi.rseq_cs.arch.ptr = 0; 147 143 } 148 144 149 145 /*