1d7822b1eSMathieu Desnoyers /* SPDX-License-Identifier: GPL-2.0+ WITH Linux-syscall-note */ 2d7822b1eSMathieu Desnoyers #ifndef _UAPI_LINUX_RSEQ_H 3d7822b1eSMathieu Desnoyers #define _UAPI_LINUX_RSEQ_H 4d7822b1eSMathieu Desnoyers 5d7822b1eSMathieu Desnoyers /* 6d7822b1eSMathieu Desnoyers * linux/rseq.h 7d7822b1eSMathieu Desnoyers * 8d7822b1eSMathieu Desnoyers * Restartable sequences system call API 9d7822b1eSMathieu Desnoyers * 10d7822b1eSMathieu Desnoyers * Copyright (c) 2015-2018 Mathieu Desnoyers <mathieu.desnoyers@efficios.com> 11d7822b1eSMathieu Desnoyers */ 12d7822b1eSMathieu Desnoyers 13d7822b1eSMathieu Desnoyers #include <linux/types.h> 14ec9c82e0SMathieu Desnoyers #include <asm/byteorder.h> 15d7822b1eSMathieu Desnoyers 16d7822b1eSMathieu Desnoyers enum rseq_cpu_id_state { 17d7822b1eSMathieu Desnoyers RSEQ_CPU_ID_UNINITIALIZED = -1, 18d7822b1eSMathieu Desnoyers RSEQ_CPU_ID_REGISTRATION_FAILED = -2, 19d7822b1eSMathieu Desnoyers }; 20d7822b1eSMathieu Desnoyers 21d7822b1eSMathieu Desnoyers enum rseq_flags { 22d7822b1eSMathieu Desnoyers RSEQ_FLAG_UNREGISTER = (1 << 0), 23d7822b1eSMathieu Desnoyers }; 24d7822b1eSMathieu Desnoyers 25d7822b1eSMathieu Desnoyers enum rseq_cs_flags_bit { 26d7822b1eSMathieu Desnoyers RSEQ_CS_FLAG_NO_RESTART_ON_PREEMPT_BIT = 0, 27d7822b1eSMathieu Desnoyers RSEQ_CS_FLAG_NO_RESTART_ON_SIGNAL_BIT = 1, 28d7822b1eSMathieu Desnoyers RSEQ_CS_FLAG_NO_RESTART_ON_MIGRATE_BIT = 2, 29d7822b1eSMathieu Desnoyers }; 30d7822b1eSMathieu Desnoyers 31d7822b1eSMathieu Desnoyers enum rseq_cs_flags { 32d7822b1eSMathieu Desnoyers RSEQ_CS_FLAG_NO_RESTART_ON_PREEMPT = 33d7822b1eSMathieu Desnoyers (1U << RSEQ_CS_FLAG_NO_RESTART_ON_PREEMPT_BIT), 34d7822b1eSMathieu Desnoyers RSEQ_CS_FLAG_NO_RESTART_ON_SIGNAL = 35d7822b1eSMathieu Desnoyers (1U << RSEQ_CS_FLAG_NO_RESTART_ON_SIGNAL_BIT), 36d7822b1eSMathieu Desnoyers RSEQ_CS_FLAG_NO_RESTART_ON_MIGRATE = 37d7822b1eSMathieu Desnoyers (1U << RSEQ_CS_FLAG_NO_RESTART_ON_MIGRATE_BIT), 38d7822b1eSMathieu Desnoyers }; 39d7822b1eSMathieu Desnoyers 40d7822b1eSMathieu Desnoyers /* 41d7822b1eSMathieu Desnoyers * struct rseq_cs is aligned on 4 * 8 bytes to ensure it is always 42d7822b1eSMathieu Desnoyers * contained within a single cache-line. It is usually declared as 43d7822b1eSMathieu Desnoyers * link-time constant data. 44d7822b1eSMathieu Desnoyers */ 45d7822b1eSMathieu Desnoyers struct rseq_cs { 46d7822b1eSMathieu Desnoyers /* Version of this structure. */ 47d7822b1eSMathieu Desnoyers __u32 version; 48d7822b1eSMathieu Desnoyers /* enum rseq_cs_flags */ 49d7822b1eSMathieu Desnoyers __u32 flags; 50e96d7135SMathieu Desnoyers __u64 start_ip; 51d7822b1eSMathieu Desnoyers /* Offset from start_ip. */ 52e96d7135SMathieu Desnoyers __u64 post_commit_offset; 53e96d7135SMathieu Desnoyers __u64 abort_ip; 54d7822b1eSMathieu Desnoyers } __attribute__((aligned(4 * sizeof(__u64)))); 55d7822b1eSMathieu Desnoyers 56d7822b1eSMathieu Desnoyers /* 57d7822b1eSMathieu Desnoyers * struct rseq is aligned on 4 * 8 bytes to ensure it is always 58d7822b1eSMathieu Desnoyers * contained within a single cache-line. 59d7822b1eSMathieu Desnoyers * 60d7822b1eSMathieu Desnoyers * A single struct rseq per thread is allowed. 61d7822b1eSMathieu Desnoyers */ 62d7822b1eSMathieu Desnoyers struct rseq { 63d7822b1eSMathieu Desnoyers /* 64d7822b1eSMathieu Desnoyers * Restartable sequences cpu_id_start field. Updated by the 650fb9a1abSMathieu Desnoyers * kernel. Read by user-space with single-copy atomicity 660fb9a1abSMathieu Desnoyers * semantics. This field should only be read by the thread which 670fb9a1abSMathieu Desnoyers * registered this data structure. Aligned on 32-bit. Always 680fb9a1abSMathieu Desnoyers * contains a value in the range of possible CPUs, although the 690fb9a1abSMathieu Desnoyers * value may not be the actual current CPU (e.g. if rseq is not 700fb9a1abSMathieu Desnoyers * initialized). This CPU number value should always be compared 710fb9a1abSMathieu Desnoyers * against the value of the cpu_id field before performing a rseq 720fb9a1abSMathieu Desnoyers * commit or returning a value read from a data structure indexed 730fb9a1abSMathieu Desnoyers * using the cpu_id_start value. 74d7822b1eSMathieu Desnoyers */ 75d7822b1eSMathieu Desnoyers __u32 cpu_id_start; 76d7822b1eSMathieu Desnoyers /* 770fb9a1abSMathieu Desnoyers * Restartable sequences cpu_id field. Updated by the kernel. 780fb9a1abSMathieu Desnoyers * Read by user-space with single-copy atomicity semantics. This 790fb9a1abSMathieu Desnoyers * field should only be read by the thread which registered this 800fb9a1abSMathieu Desnoyers * data structure. Aligned on 32-bit. Values 810fb9a1abSMathieu Desnoyers * RSEQ_CPU_ID_UNINITIALIZED and RSEQ_CPU_ID_REGISTRATION_FAILED 820fb9a1abSMathieu Desnoyers * have a special semantic: the former means "rseq uninitialized", 830fb9a1abSMathieu Desnoyers * and latter means "rseq initialization failed". This value is 840fb9a1abSMathieu Desnoyers * meant to be read within rseq critical sections and compared 850fb9a1abSMathieu Desnoyers * with the cpu_id_start value previously read, before performing 860fb9a1abSMathieu Desnoyers * the commit instruction, or read and compared with the 870fb9a1abSMathieu Desnoyers * cpu_id_start value before returning a value loaded from a data 880fb9a1abSMathieu Desnoyers * structure indexed using the cpu_id_start value. 89d7822b1eSMathieu Desnoyers */ 90d7822b1eSMathieu Desnoyers __u32 cpu_id; 91d7822b1eSMathieu Desnoyers /* 92d7822b1eSMathieu Desnoyers * Restartable sequences rseq_cs field. 93d7822b1eSMathieu Desnoyers * 94d7822b1eSMathieu Desnoyers * Contains NULL when no critical section is active for the current 95d7822b1eSMathieu Desnoyers * thread, or holds a pointer to the currently active struct rseq_cs. 96d7822b1eSMathieu Desnoyers * 97d7822b1eSMathieu Desnoyers * Updated by user-space, which sets the address of the currently 98d7822b1eSMathieu Desnoyers * active rseq_cs at the beginning of assembly instruction sequence 99d7822b1eSMathieu Desnoyers * block, and set to NULL by the kernel when it restarts an assembly 100d7822b1eSMathieu Desnoyers * instruction sequence block, as well as when the kernel detects that 101d7822b1eSMathieu Desnoyers * it is preempting or delivering a signal outside of the range 102d7822b1eSMathieu Desnoyers * targeted by the rseq_cs. Also needs to be set to NULL by user-space 103d7822b1eSMathieu Desnoyers * before reclaiming memory that contains the targeted struct rseq_cs. 104d7822b1eSMathieu Desnoyers * 1050fb9a1abSMathieu Desnoyers * Read and set by the kernel. Set by user-space with single-copy 1060fb9a1abSMathieu Desnoyers * atomicity semantics. This field should only be updated by the 1070fb9a1abSMathieu Desnoyers * thread which registered this data structure. Aligned on 64-bit. 108bfdf4e62SMathieu Desnoyers * 109bfdf4e62SMathieu Desnoyers * 32-bit architectures should update the low order bits of the 110bfdf4e62SMathieu Desnoyers * rseq_cs field, leaving the high order bits initialized to 0. 111d7822b1eSMathieu Desnoyers */ 112bfdf4e62SMathieu Desnoyers __u64 rseq_cs; 113ec9c82e0SMathieu Desnoyers 114d7822b1eSMathieu Desnoyers /* 1150fb9a1abSMathieu Desnoyers * Restartable sequences flags field. 116d7822b1eSMathieu Desnoyers * 1170fb9a1abSMathieu Desnoyers * This field should only be updated by the thread which 1180fb9a1abSMathieu Desnoyers * registered this data structure. Read by the kernel. 1190fb9a1abSMathieu Desnoyers * Mainly used for single-stepping through rseq critical sections 1200fb9a1abSMathieu Desnoyers * with debuggers. 1210fb9a1abSMathieu Desnoyers * 122d7822b1eSMathieu Desnoyers * - RSEQ_CS_FLAG_NO_RESTART_ON_PREEMPT 1230fb9a1abSMathieu Desnoyers * Inhibit instruction sequence block restart on preemption 1240fb9a1abSMathieu Desnoyers * for this thread. 125d7822b1eSMathieu Desnoyers * - RSEQ_CS_FLAG_NO_RESTART_ON_SIGNAL 1260fb9a1abSMathieu Desnoyers * Inhibit instruction sequence block restart on signal 1270fb9a1abSMathieu Desnoyers * delivery for this thread. 128d7822b1eSMathieu Desnoyers * - RSEQ_CS_FLAG_NO_RESTART_ON_MIGRATE 1290fb9a1abSMathieu Desnoyers * Inhibit instruction sequence block restart on migration for 1300fb9a1abSMathieu Desnoyers * this thread. 131d7822b1eSMathieu Desnoyers */ 132d7822b1eSMathieu Desnoyers __u32 flags; 133317c8194SMathieu Desnoyers 134317c8194SMathieu Desnoyers /* 135cbae6bacSMathieu Desnoyers * Restartable sequences node_id field. Updated by the kernel. Read by 136cbae6bacSMathieu Desnoyers * user-space with single-copy atomicity semantics. This field should 137cbae6bacSMathieu Desnoyers * only be read by the thread which registered this data structure. 138cbae6bacSMathieu Desnoyers * Aligned on 32-bit. Contains the current NUMA node ID. 139cbae6bacSMathieu Desnoyers */ 140cbae6bacSMathieu Desnoyers __u32 node_id; 141cbae6bacSMathieu Desnoyers 142cbae6bacSMathieu Desnoyers /* 143*f7b01bb0SMathieu Desnoyers * Restartable sequences mm_cid field. Updated by the kernel. Read by 144*f7b01bb0SMathieu Desnoyers * user-space with single-copy atomicity semantics. This field should 145*f7b01bb0SMathieu Desnoyers * only be read by the thread which registered this data structure. 146*f7b01bb0SMathieu Desnoyers * Aligned on 32-bit. Contains the current thread's concurrency ID 147*f7b01bb0SMathieu Desnoyers * (allocated uniquely within a memory map). 148*f7b01bb0SMathieu Desnoyers */ 149*f7b01bb0SMathieu Desnoyers __u32 mm_cid; 150*f7b01bb0SMathieu Desnoyers 151*f7b01bb0SMathieu Desnoyers /* 152317c8194SMathieu Desnoyers * Flexible array member at end of structure, after last feature field. 153317c8194SMathieu Desnoyers */ 154317c8194SMathieu Desnoyers char end[]; 155d7822b1eSMathieu Desnoyers } __attribute__((aligned(4 * sizeof(__u64)))); 156d7822b1eSMathieu Desnoyers 157d7822b1eSMathieu Desnoyers #endif /* _UAPI_LINUX_RSEQ_H */ 158