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