gvisor.dev/gvisor@v0.0.0-20240520182842-f9d4d51c7e0f/pkg/abi/linux/rseq.go (about)

     1  // Copyright 2019 The gVisor Authors.
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //     http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  package linux
    16  
    17  // Flags passed to rseq(2).
    18  //
    19  // Defined in include/uapi/linux/rseq.h.
    20  const (
    21  	// RSEQ_FLAG_UNREGISTER unregisters the current thread.
    22  	RSEQ_FLAG_UNREGISTER = 1 << 0
    23  )
    24  
    25  // Critical section flags used in RSeqCriticalSection.Flags and RSeq.Flags.
    26  //
    27  // Defined in include/uapi/linux/rseq.h.
    28  const (
    29  	// RSEQ_CS_FLAG_NO_RESTART_ON_PREEMPT inhibits restart on preemption.
    30  	RSEQ_CS_FLAG_NO_RESTART_ON_PREEMPT = 1 << 0
    31  
    32  	// RSEQ_CS_FLAG_NO_RESTART_ON_SIGNAL inhibits restart on signal
    33  	// delivery.
    34  	RSEQ_CS_FLAG_NO_RESTART_ON_SIGNAL = 1 << 1
    35  
    36  	// RSEQ_CS_FLAG_NO_RESTART_ON_MIGRATE inhibits restart on CPU
    37  	// migration.
    38  	RSEQ_CS_FLAG_NO_RESTART_ON_MIGRATE = 1 << 2
    39  )
    40  
    41  // RSeqCriticalSection describes a restartable sequences critical section. It
    42  // is equivalent to struct rseq_cs, defined in include/uapi/linux/rseq.h.
    43  //
    44  // In userspace, this structure is always aligned to 32 bytes.
    45  //
    46  // +marshal
    47  type RSeqCriticalSection struct {
    48  	// Version is the version of this structure. Version 0 is defined here.
    49  	Version uint32
    50  
    51  	// Flags are the critical section flags, defined above.
    52  	Flags uint32
    53  
    54  	// Start is the start address of the critical section.
    55  	Start uint64
    56  
    57  	// PostCommitOffset is the offset from Start of the first instruction
    58  	// outside of the critical section.
    59  	PostCommitOffset uint64
    60  
    61  	// Abort is the abort address. It must be outside the critical section,
    62  	// and the 4 bytes prior must match the abort signature.
    63  	Abort uint64
    64  }
    65  
    66  const (
    67  	// SizeOfRSeqCriticalSection is the size of RSeqCriticalSection.
    68  	SizeOfRSeqCriticalSection = 32
    69  
    70  	// SizeOfRSeqSignature is the size of the signature immediately
    71  	// preceding RSeqCriticalSection.Abort.
    72  	SizeOfRSeqSignature = 4
    73  )
    74  
    75  // Special values for RSeq.CPUID, defined in include/uapi/linux/rseq.h.
    76  const (
    77  	// RSEQ_CPU_ID_UNINITIALIZED indicates that this thread has not
    78  	// performed rseq initialization.
    79  	RSEQ_CPU_ID_UNINITIALIZED = ^uint32(0) // -1
    80  
    81  	// RSEQ_CPU_ID_REGISTRATION_FAILED indicates that rseq initialization
    82  	// failed.
    83  	RSEQ_CPU_ID_REGISTRATION_FAILED = ^uint32(1) // -2
    84  )
    85  
    86  // RSeq is the thread-local restartable sequences config/status. It
    87  // is equivalent to struct rseq, defined in include/uapi/linux/rseq.h.
    88  //
    89  // In userspace, this structure is always aligned to 32 bytes.
    90  type RSeq struct {
    91  	// CPUIDStart contains the current CPU ID if rseq is initialized.
    92  	//
    93  	// This field should only be read by the thread which registered this
    94  	// structure, and must be read atomically.
    95  	CPUIDStart uint32
    96  
    97  	// CPUID contains the current CPU ID or one of the CPU ID special
    98  	// values defined above.
    99  	//
   100  	// This field should only be read by the thread which registered this
   101  	// structure, and must be read atomically.
   102  	CPUID uint32
   103  
   104  	// RSeqCriticalSection is a pointer to the current RSeqCriticalSection
   105  	// block, or NULL. It is reset to NULL by the kernel on restart or
   106  	// non-restarting preempt/signal.
   107  	//
   108  	// This field should only be written by the thread which registered
   109  	// this structure, and must be written atomically.
   110  	RSeqCriticalSection uint64
   111  
   112  	// Flags are the critical section flags that apply to all critical
   113  	// sections on this thread, defined above.
   114  	Flags uint32
   115  }
   116  
   117  const (
   118  	// SizeOfRSeq is the size of RSeq.
   119  	//
   120  	// Note that RSeq is naively 24 bytes. However, it has 32-byte
   121  	// alignment, which in C increases sizeof to 32. That is the size that
   122  	// the Linux kernel uses.
   123  	SizeOfRSeq = 32
   124  
   125  	// AlignOfRSeq is the standard alignment of RSeq.
   126  	AlignOfRSeq = 32
   127  
   128  	// OffsetOfRSeqCriticalSection is the offset of RSeqCriticalSection in RSeq.
   129  	OffsetOfRSeqCriticalSection = 8
   130  )