380c0b5ccca2ac68b9c47b313312f18aef5dccbc
[sfrench/cifs-2.6.git] / Documentation / x86 / x86_64 / fsgs.rst
1 .. SPDX-License-Identifier: GPL-2.0
2
3 Using FS and GS segments in user space applications
4 ===================================================
5
6 The x86 architecture supports segmentation. Instructions which access
7 memory can use segment register based addressing mode. The following
8 notation is used to address a byte within a segment:
9
10   Segment-register:Byte-address
11
12 The segment base address is added to the Byte-address to compute the
13 resulting virtual address which is accessed. This allows to access multiple
14 instances of data with the identical Byte-address, i.e. the same code. The
15 selection of a particular instance is purely based on the base-address in
16 the segment register.
17
18 In 32-bit mode the CPU provides 6 segments, which also support segment
19 limits. The limits can be used to enforce address space protections.
20
21 In 64-bit mode the CS/SS/DS/ES segments are ignored and the base address is
22 always 0 to provide a full 64bit address space. The FS and GS segments are
23 still functional in 64-bit mode.
24
25 Common FS and GS usage
26 ------------------------------
27
28 The FS segment is commonly used to address Thread Local Storage (TLS). FS
29 is usually managed by runtime code or a threading library. Variables
30 declared with the '__thread' storage class specifier are instantiated per
31 thread and the compiler emits the FS: address prefix for accesses to these
32 variables. Each thread has its own FS base address so common code can be
33 used without complex address offset calculations to access the per thread
34 instances. Applications should not use FS for other purposes when they use
35 runtimes or threading libraries which manage the per thread FS.
36
37 The GS segment has no common use and can be used freely by
38 applications. GCC and Clang support GS based addressing via address space
39 identifiers.
40
41 Reading and writing the FS/GS base address
42 ------------------------------------------
43
44 There exist two mechanisms to read and write the FS/FS base address:
45
46  - the arch_prctl() system call
47
48  - the FSGSBASE instruction family
49
50 Accessing FS/GS base with arch_prctl()
51 --------------------------------------
52
53  The arch_prctl(2) based mechanism is available on all 64bit CPUs and all
54  kernel versions.
55
56  Reading the base:
57
58    arch_prctl(ARCH_GET_FS, &fsbase);
59    arch_prctl(ARCH_GET_GS, &gsbase);
60
61  Writing the base:
62
63    arch_prctl(ARCH_SET_FS, fsbase);
64    arch_prctl(ARCH_SET_GS, gsbase);
65
66  The ARCH_SET_GS prctl may be disabled depending on kernel configuration
67  and security settings.
68
69 Accessing FS/GS base with the FSGSBASE instructions
70 ---------------------------------------------------
71
72  With the Ivy Bridge CPU generation Intel introduced a new set of
73  instructions to access the FS and GS base registers directly from user
74  space. These instructions are also supported on AMD Family 17H CPUs. The
75  following instructions are available:
76
77   =============== ===========================
78   RDFSBASE %reg   Read the FS base register
79   RDGSBASE %reg   Read the GS base register
80   WRFSBASE %reg   Write the FS base register
81   WRGSBASE %reg   Write the GS base register
82   =============== ===========================
83
84  The instructions avoid the overhead of the arch_prctl() syscall and allow
85  more flexible usage of the FS/GS addressing modes in user space
86  applications. This does not prevent conflicts between threading libraries
87  and runtimes which utilize FS and applications which want to use it for
88  their own purpose.
89
90 FSGSBASE instructions enablement
91 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
92  The instructions are enumerated in CPUID leaf 7, bit 0 of EBX. If
93  available /proc/cpuinfo shows 'fsgsbase' in the flag entry of the CPUs.
94
95  The availability of the instructions does not enable them
96  automatically. The kernel has to enable them explicitly in CR4. The
97  reason for this is that older kernels make assumptions about the values in
98  the GS register and enforce them when GS base is set via
99  arch_prctl(). Allowing user space to write arbitrary values to GS base
100  would violate these assumptions and cause malfunction.
101
102  On kernels which do not enable FSGSBASE the execution of the FSGSBASE
103  instructions will fault with a #UD exception.
104
105  The kernel provides reliable information about the enabled state in the
106  ELF AUX vector. If the HWCAP2_FSGSBASE bit is set in the AUX vector, the
107  kernel has FSGSBASE instructions enabled and applications can use them.
108  The following code example shows how this detection works::
109
110    #include <sys/auxv.h>
111    #include <elf.h>
112
113    /* Will be eventually in asm/hwcap.h */
114    #ifndef HWCAP2_FSGSBASE
115    #define HWCAP2_FSGSBASE        (1 << 1)
116    #endif
117
118    ....
119
120    unsigned val = getauxval(AT_HWCAP2);
121
122    if (val & HWCAP2_FSGSBASE)
123         printf("FSGSBASE enabled\n");
124
125 FSGSBASE instructions compiler support
126 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
127
128 GCC version 4.6.4 and newer provide instrinsics for the FSGSBASE
129 instructions. Clang supports them as well.
130
131   =================== ===========================
132   _readfsbase_u64()   Read the FS base register
133   _readfsbase_u64()   Read the GS base register
134   _writefsbase_u64()  Write the FS base register
135   _writegsbase_u64()  Write the GS base register
136   =================== ===========================
137
138 To utilize these instrinsics <immintrin.h> must be included in the source
139 code and the compiler option -mfsgsbase has to be added.
140
141 Compiler support for FS/GS based addressing
142 -------------------------------------------
143
144 GCC version 6 and newer provide support for FS/GS based addressing via
145 Named Address Spaces. GCC implements the following address space
146 identifiers for x86:
147
148   ========= ====================================
149   __seg_fs  Variable is addressed relative to FS
150   __seg_gs  Variable is addressed relative to GS
151   ========= ====================================
152
153 The preprocessor symbols __SEG_FS and __SEG_GS are defined when these
154 address spaces are supported. Code which implements fallback modes should
155 check whether these symbols are defined. Usage example::
156
157   #ifdef __SEG_GS
158
159   long data0 = 0;
160   long data1 = 1;
161
162   long __seg_gs *ptr;
163
164   /* Check whether FSGSBASE is enabled by the kernel (HWCAP2_FSGSBASE) */
165   ....
166
167   /* Set GS to point to data0 */
168   _writegsbase_u64(&data0);
169
170   /* Access offset 0 of GS */
171   ptr = 0;
172   printf("data0 = %ld\n", *ptr);
173
174   /* Set GS to point to data1 */
175   _writegsbase_u64(&data1);
176   /* ptr still addresses offset 0! */
177   printf("data1 = %ld\n", *ptr);
178
179
180 Clang does not provide the GCC address space identifiers, but it provides
181 address spaces via an attribute based mechanism in Clang 5 and newer
182 versions:
183
184  ==================================== =====================================
185   __attribute__((address_space(256))  Variable is addressed relative to GS
186   __attribute__((address_space(257))  Variable is addressed relative to FS
187  ==================================== =====================================
188
189 FS/GS based addressing with inline assembly
190 -------------------------------------------
191
192 In case the compiler does not support address spaces, inline assembly can
193 be used for FS/GS based addressing mode::
194
195         mov %fs:offset, %reg
196         mov %gs:offset, %reg
197
198         mov %reg, %fs:offset
199         mov %reg, %gs:offset