fsgs.rst 7.0 KB

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