cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

fsgs.rst (7161B)


      1.. SPDX-License-Identifier: GPL-2.0
      2
      3Using FS and GS segments in user space applications
      4===================================================
      5
      6The x86 architecture supports segmentation. Instructions which access
      7memory can use segment register based addressing mode. The following
      8notation is used to address a byte within a segment:
      9
     10  Segment-register:Byte-address
     11
     12The segment base address is added to the Byte-address to compute the
     13resulting virtual address which is accessed. This allows to access multiple
     14instances of data with the identical Byte-address, i.e. the same code. The
     15selection of a particular instance is purely based on the base-address in
     16the segment register.
     17
     18In 32-bit mode the CPU provides 6 segments, which also support segment
     19limits. The limits can be used to enforce address space protections.
     20
     21In 64-bit mode the CS/SS/DS/ES segments are ignored and the base address is
     22always 0 to provide a full 64bit address space. The FS and GS segments are
     23still functional in 64-bit mode.
     24
     25Common FS and GS usage
     26------------------------------
     27
     28The FS segment is commonly used to address Thread Local Storage (TLS). FS
     29is usually managed by runtime code or a threading library. Variables
     30declared with the '__thread' storage class specifier are instantiated per
     31thread and the compiler emits the FS: address prefix for accesses to these
     32variables. Each thread has its own FS base address so common code can be
     33used without complex address offset calculations to access the per thread
     34instances. Applications should not use FS for other purposes when they use
     35runtimes or threading libraries which manage the per thread FS.
     36
     37The GS segment has no common use and can be used freely by
     38applications. GCC and Clang support GS based addressing via address space
     39identifiers.
     40
     41Reading and writing the FS/GS base address
     42------------------------------------------
     43
     44There exist two mechanisms to read and write the FS/GS base address:
     45
     46 - the arch_prctl() system call
     47
     48 - the FSGSBASE instruction family
     49
     50Accessing FS/GS base with arch_prctl()
     51--------------------------------------
     52
     53 The arch_prctl(2) based mechanism is available on all 64-bit 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
     69Accessing 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
     90FSGSBASE 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
    125FSGSBASE instructions compiler support
    126^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    127
    128GCC version 4.6.4 and newer provide instrinsics for the FSGSBASE
    129instructions. Clang 5 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
    138To utilize these instrinsics <immintrin.h> must be included in the source
    139code and the compiler option -mfsgsbase has to be added.
    140
    141Compiler support for FS/GS based addressing
    142-------------------------------------------
    143
    144GCC version 6 and newer provide support for FS/GS based addressing via
    145Named Address Spaces. GCC implements the following address space
    146identifiers for x86:
    147
    148  ========= ====================================
    149  __seg_fs  Variable is addressed relative to FS
    150  __seg_gs  Variable is addressed relative to GS
    151  ========= ====================================
    152
    153The preprocessor symbols __SEG_FS and __SEG_GS are defined when these
    154address spaces are supported. Code which implements fallback modes should
    155check 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 base 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 base to point to data1 */
    175  _writegsbase_u64(&data1);
    176  /* ptr still addresses offset 0! */
    177  printf("data1 = %ld\n", *ptr);
    178
    179
    180Clang does not provide the GCC address space identifiers, but it provides
    181address spaces via an attribute based mechanism in Clang 2.6 and newer
    182versions:
    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
    189FS/GS based addressing with inline assembly
    190-------------------------------------------
    191
    192In case the compiler does not support address spaces, inline assembly can
    193be 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