Files
linux/tools/testing/selftests/rseq/rseq-abi.h
Thomas Gleixner d97cb2ef0b selftests/rseq: Make registration flexible for legacy and optimized mode
rseq_register_current_thread() either uses the glibc registered RSEQ region
or registers it's own region with the legacy size of 32 bytes.

That worked so far, but becomes a problem when the kernel implements a
distinction between legacy and performance optimized behavior based on the
registration size as that does not allow to test both modes with the self
test suite.

Add two arguments to the function. One to enforce that the registration is
not using libc provided mode and one to tell the registration to use the
legacy size and not the kernel advertised size.

Rename it and make the original one a inline wrapper which preserves the
existing behavior.

Fixes: 566d8015f7 ("rseq: Avoid CPU/MM CID updates when no event pending")
Signed-off-by: Thomas Gleixner <tglx@kernel.org>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Reviewed-by: Dmitry Vyukov <dvyukov@google.com>
Tested-by: Dmitry Vyukov <dvyukov@google.com>
Link: https://patch.msgid.link/20260428224427.677889423%40kernel.org
Cc: stable@vger.kernel.org
2026-05-05 16:03:11 +02:00

206 lines
6.4 KiB
C

/* SPDX-License-Identifier: GPL-2.0+ WITH Linux-syscall-note */
#ifndef _RSEQ_ABI_H
#define _RSEQ_ABI_H
/*
* rseq-abi.h
*
* Restartable sequences system call API
*
* Copyright (c) 2015-2022 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
*/
#include <linux/types.h>
#include <asm/byteorder.h>
enum rseq_abi_cpu_id_state {
RSEQ_ABI_CPU_ID_UNINITIALIZED = -1,
RSEQ_ABI_CPU_ID_REGISTRATION_FAILED = -2,
};
enum rseq_abi_flags {
RSEQ_ABI_FLAG_UNREGISTER = (1 << 0),
};
enum rseq_abi_cs_flags_bit {
RSEQ_ABI_CS_FLAG_NO_RESTART_ON_PREEMPT_BIT = 0,
RSEQ_ABI_CS_FLAG_NO_RESTART_ON_SIGNAL_BIT = 1,
RSEQ_ABI_CS_FLAG_NO_RESTART_ON_MIGRATE_BIT = 2,
};
enum rseq_abi_cs_flags {
RSEQ_ABI_CS_FLAG_NO_RESTART_ON_PREEMPT =
(1U << RSEQ_ABI_CS_FLAG_NO_RESTART_ON_PREEMPT_BIT),
RSEQ_ABI_CS_FLAG_NO_RESTART_ON_SIGNAL =
(1U << RSEQ_ABI_CS_FLAG_NO_RESTART_ON_SIGNAL_BIT),
RSEQ_ABI_CS_FLAG_NO_RESTART_ON_MIGRATE =
(1U << RSEQ_ABI_CS_FLAG_NO_RESTART_ON_MIGRATE_BIT),
};
/*
* struct rseq_abi_cs is aligned on 4 * 8 bytes to ensure it is always
* contained within a single cache-line. It is usually declared as
* link-time constant data.
*/
struct rseq_abi_cs {
/* Version of this structure. */
__u32 version;
/* enum rseq_abi_cs_flags */
__u32 flags;
__u64 start_ip;
/* Offset from start_ip. */
__u64 post_commit_offset;
__u64 abort_ip;
} __attribute__((aligned(4 * sizeof(__u64))));
/**
* rseq_abi_slice_ctrl - Time slice extension control structure
* @all: Compound value
* @request: Request for a time slice extension
* @granted: Granted time slice extension
*
* @request is set by user space and can be cleared by user space or kernel
* space. @granted is set and cleared by the kernel and must only be read
* by user space.
*/
struct rseq_abi_slice_ctrl {
union {
__u32 all;
struct {
__u8 request;
__u8 granted;
__u16 __reserved;
};
};
};
/*
* struct rseq_abi is aligned on 4 * 8 bytes to ensure it is always
* contained within a single cache-line.
*
* A single struct rseq_abi per thread is allowed.
*/
struct rseq_abi {
/*
* Restartable sequences cpu_id_start field. Updated by the
* kernel. Read by user-space with single-copy atomicity
* semantics. This field should only be read by the thread which
* registered this data structure. Aligned on 32-bit. Always
* contains a value in the range of possible CPUs, although the
* value may not be the actual current CPU (e.g. if rseq is not
* initialized). This CPU number value should always be compared
* against the value of the cpu_id field before performing a rseq
* commit or returning a value read from a data structure indexed
* using the cpu_id_start value.
*/
__u32 cpu_id_start;
/*
* Restartable sequences cpu_id field. Updated by the kernel.
* Read by user-space with single-copy atomicity semantics. This
* field should only be read by the thread which registered this
* data structure. Aligned on 32-bit. Values
* RSEQ_CPU_ID_UNINITIALIZED and RSEQ_CPU_ID_REGISTRATION_FAILED
* have a special semantic: the former means "rseq uninitialized",
* and latter means "rseq initialization failed". This value is
* meant to be read within rseq critical sections and compared
* with the cpu_id_start value previously read, before performing
* the commit instruction, or read and compared with the
* cpu_id_start value before returning a value loaded from a data
* structure indexed using the cpu_id_start value.
*/
__u32 cpu_id;
/*
* Restartable sequences rseq_cs field.
*
* Contains NULL when no critical section is active for the current
* thread, or holds a pointer to the currently active struct rseq_cs.
*
* Updated by user-space, which sets the address of the currently
* active rseq_cs at the beginning of assembly instruction sequence
* block, and set to NULL by the kernel when it restarts an assembly
* instruction sequence block, as well as when the kernel detects that
* it is preempting or delivering a signal outside of the range
* targeted by the rseq_cs. Also needs to be set to NULL by user-space
* before reclaiming memory that contains the targeted struct rseq_cs.
*
* Read and set by the kernel. Set by user-space with single-copy
* atomicity semantics. This field should only be updated by the
* thread which registered this data structure. Aligned on 64-bit.
*/
union {
__u64 ptr64;
/*
* The "arch" field provides architecture accessor for
* the ptr field based on architecture pointer size and
* endianness.
*/
struct {
#ifdef __LP64__
__u64 ptr;
#elif defined(__BYTE_ORDER) ? (__BYTE_ORDER == __BIG_ENDIAN) : defined(__BIG_ENDIAN)
__u32 padding; /* Initialized to zero. */
__u32 ptr;
#else
__u32 ptr;
__u32 padding; /* Initialized to zero. */
#endif
} arch;
} rseq_cs;
/*
* Restartable sequences flags field.
*
* This field should only be updated by the thread which
* registered this data structure. Read by the kernel.
* Mainly used for single-stepping through rseq critical sections
* with debuggers.
*
* - RSEQ_ABI_CS_FLAG_NO_RESTART_ON_PREEMPT
* Inhibit instruction sequence block restart on preemption
* for this thread.
* - RSEQ_ABI_CS_FLAG_NO_RESTART_ON_SIGNAL
* Inhibit instruction sequence block restart on signal
* delivery for this thread.
* - RSEQ_ABI_CS_FLAG_NO_RESTART_ON_MIGRATE
* Inhibit instruction sequence block restart on migration for
* this thread.
*/
__u32 flags;
/*
* Restartable sequences node_id field. Updated by the kernel. Read by
* user-space with single-copy atomicity semantics. This field should
* only be read by the thread which registered this data structure.
* Aligned on 32-bit. Contains the current NUMA node ID.
*/
__u32 node_id;
/*
* Restartable sequences mm_cid field. Updated by the kernel. Read by
* user-space with single-copy atomicity semantics. This field should
* only be read by the thread which registered this data structure.
* Aligned on 32-bit. Contains the current thread's concurrency ID
* (allocated uniquely within a memory map).
*/
__u32 mm_cid;
/*
* Time slice extension control structure. CPU local updates from
* kernel and user space.
*/
struct rseq_abi_slice_ctrl slice_ctrl;
/*
* Place holder to push the size above 32 bytes.
*/
__u8 __reserved;
/*
* Flexible array member at end of structure, after last feature field.
*/
char end[];
} __attribute__((aligned(256)));
#endif /* _RSEQ_ABI_H */