]> git.ipfire.org Git - thirdparty/glibc.git/commitdiff
i386: Use __seg_gs qualifiers in NPTL accessors
authorUros Bizjak <ubizjak@gmail.com>
Sun, 17 Aug 2025 15:50:47 +0000 (17:50 +0200)
committerH.J. Lu <hjl.tools@gmail.com>
Wed, 20 Aug 2025 18:48:23 +0000 (11:48 -0700)
Use __seg_gs named address space qualifiers to cast NPTL accessors
to %gs: prefixed addresses.  Use volatile access only where
strictly necessary.

Signed-off-by: Uros Bizjak <ubizjak@gmail.com>
Cc: H.J.Lu <hjl.tools@gmail.com>
Cc: Florian Weimer <fweimer@redhat.com>
Cc: Carlos O'Donell <carlos@redhat.com>
Reviewed-by: H.J. Lu <hjl.tools@gmail.com>
sysdeps/i386/nptl/rseq-access.h
sysdeps/i386/nptl/tcb-access.h

index 5e7e09d49450bdb0a0c3aefa5825e47a93d42830..ee78c6198d5acc18249807d21be6efda934c3508 100644 (file)
    License along with the GNU C Library; if not, see
    <https://www.gnu.org/licenses/>.  */
 
-#define __RSEQ_GETMEM(member) \
-  ({ __typeof (RSEQ_SELF()->member) __value;                                 \
-     if (sizeof (__value) == 1)                                                      \
-       asm volatile ("movb %%gs:%P2(%3),%b0"                                 \
-                    : "=q" (__value)                                         \
-                    : "0" (0), "i" (offsetof (struct rseq_area, member)),   \
-                    "r" (__rseq_offset));                                    \
-     else if (sizeof (__value) == 4)                                         \
-       asm volatile ("movl %%gs:%P1(%2),%0"                                  \
-                    : "=r" (__value)                                         \
-                    : "i" (offsetof (struct rseq_area, member)),             \
-                      "r" (__rseq_offset));                                  \
-     else /* 8 */                                                            \
-       {                                                                     \
-        asm volatile  ("movl %%gs:%P1(%2),%%eax\n\t"                         \
-                       "movl %%gs:4+%P1(%2),%%edx"                           \
-                       : "=&A" (__value)                                     \
-                       : "i" (offsetof (struct rseq_area, member)),          \
-                         "r" (__rseq_offset));                               \
-       }                                                                     \
-     __value; })
-
 /* Read member of the RSEQ area directly.  */
 #define RSEQ_GETMEM(member) \
   ({                                                                         \
@@ -45,7 +23,9 @@
                     || sizeof (RSEQ_SELF()->member) == 4                     \
                     || sizeof (RSEQ_SELF()->member) == 8,                    \
                     "size of rseq data");                                    \
-     __RSEQ_GETMEM(member); })
+     (*(__typeof (RSEQ_SELF()->member) __seg_gs *)                           \
+      (__rseq_offset + offsetof (struct rseq_area, member)));                \
+  })
 
 /* Read member of the RSEQ area directly, with single-copy atomicity semantics.
    Static assert for types >= 64 bits since they can't be loaded atomically on
      _Static_assert (sizeof (RSEQ_SELF()->member) == 1                       \
                     || sizeof (RSEQ_SELF()->member) == 4,                    \
                     "size of rseq data");                                    \
-     __RSEQ_GETMEM(member); })
-
-#define __RSEQ_SETMEM(member, value) \
-  ({                                                                         \
-     if (sizeof (RSEQ_SELF()->member) == 1)                                  \
-       asm volatile ("movb %b0,%%gs:%P1(%2)" :                               \
-                    : "iq" (value),                                          \
-                      "i" (offsetof (struct rseq_area, member)),             \
-                      "r" (__rseq_offset));                                  \
-     else if (sizeof (RSEQ_SELF()->member) == 4)                             \
-       asm volatile ("movl %0,%%gs:%P1(%2)" :                                \
-                    : "ir" (value),                                          \
-                      "i" (offsetof (struct rseq_area, member)),             \
-                      "r" (__rseq_offset));                                  \
-     else /* 8 */                                                            \
-       {                                                                     \
-        asm volatile ("movl %%eax,%%gs:%P1(%2)\n\t"                          \
-                      "movl %%edx,%%gs:4+%P1(%2)" :                          \
-                      : "A" ((uint64_t) cast_to_integer (value)),            \
-                        "i" (offsetof (struct rseq_area, member)),           \
-                        "r" (__rseq_offset));                                \
-       }})
+     (*(volatile __typeof (RSEQ_SELF()->member) __seg_gs *)                  \
+      (__rseq_offset + offsetof (struct rseq_area, member)));                \
+  })
 
 /* Set member of the RSEQ area directly.  */
 #define RSEQ_SETMEM(member, value) \
@@ -85,7 +46,9 @@
                     || sizeof (RSEQ_SELF()->member) == 4                     \
                     || sizeof (RSEQ_SELF()->member) == 8,                    \
                     "size of rseq data");                                    \
-     __RSEQ_SETMEM(member, value); })
+     (*(__typeof (RSEQ_SELF()->member) __seg_gs *)                           \
+      (__rseq_offset + offsetof (struct rseq_area, member)) = (value));              \
+  })
 
 /* Set member of the RSEQ area directly, with single-copy atomicity semantics.
    Static assert for types >= 64 bits since they can't be stored atomically on
@@ -95,4 +58,6 @@
      _Static_assert (sizeof (RSEQ_SELF()->member) == 1                       \
                     || sizeof (RSEQ_SELF()->member) == 4,                    \
                     "size of rseq data");                                    \
-     __RSEQ_SETMEM(member, value); })
+     (*(volatile __typeof (RSEQ_SELF()->member) __seg_gs *)                  \
+      (__rseq_offset + offsetof (struct rseq_area, member)) = (value));              \
+  })
index dc84dfeef475c92bf4a3693f8cb61dc5a66bdc63..2a7f9d2a572ea05507c0ed5542205cbd83d8d45a 100644 (file)
 
 /* Read member of the thread descriptor directly.  */
 #define THREAD_GETMEM(descr, member) \
-  ({ __typeof (descr->member) __value;                                       \
-     _Static_assert (sizeof (__value) == 1                                   \
-                    || sizeof (__value) == 4                                 \
-                    || sizeof (__value) == 8,                                \
+  ({                                                                         \
+     _Static_assert (sizeof (descr->member) == 1                                     \
+                    || sizeof (descr->member) == 4                           \
+                    || sizeof (descr->member) == 8,                          \
                     "size of per-thread data");                              \
-     if (sizeof (__value) == 1)                                                      \
-       asm volatile ("movb %%gs:%P2,%b0"                                     \
-                    : "=q" (__value)                                         \
-                    : "0" (0), "i" (offsetof (struct pthread, member)));     \
-     else if (sizeof (__value) == 4)                                         \
-       asm volatile ("movl %%gs:%P1,%0"                                              \
-                    : "=r" (__value)                                         \
-                    : "i" (offsetof (struct pthread, member)));              \
-     else /* 8 */                                                                    \
-       {                                                                     \
-        asm volatile ("movl %%gs:%P1,%%eax\n\t"                              \
-                      "movl %%gs:%P2,%%edx"                                  \
-                      : "=A" (__value)                                       \
-                      : "i" (offsetof (struct pthread, member)),             \
-                        "i" (offsetof (struct pthread, member) + 4));        \
-       }                                                                     \
-     __value; })
+     (*(__typeof (descr->member) __seg_gs *)                                 \
+      offsetof (struct pthread, member));                                    \
+  })
 
-/* THREAD_GETMEM already forces a read.  */
-#define THREAD_GETMEM_VOLATILE(descr, member) THREAD_GETMEM (descr, member)
+#define THREAD_GETMEM_VOLATILE(descr, member) \
+  ({                                                                         \
+     _Static_assert (sizeof (descr->member) == 1                             \
+                    || sizeof (descr->member) == 4                           \
+                    || sizeof (descr->member) == 8,                          \
+                    "size of per-thread data");                              \
+     (*(volatile __typeof (descr->member) __seg_gs *)                        \
+      offsetof (struct pthread, member));                                    \
+  })
 
 /* Same as THREAD_GETMEM, but the member offset can be non-constant.  */
 #define THREAD_GETMEM_NC(descr, member, idx) \
-  ({ __typeof (descr->member[0]) __value;                                    \
-     _Static_assert (sizeof (__value) == 1                                   \
-                    || sizeof (__value) == 4                                 \
-                    || sizeof (__value) == 8,                                \
+  ({                                                                         \
+     _Static_assert (sizeof (descr->member[0]) == 1                          \
+                    || sizeof (descr->member[0]) == 4                        \
+                    || sizeof (descr->member[0]) == 8,                       \
                     "size of per-thread data");                              \
-     if (sizeof (__value) == 1)                                                      \
-       asm volatile ("movb %%gs:%P2(%3),%b0"                                 \
-                    : "=q" (__value)                                         \
-                    : "0" (0), "i" (offsetof (struct pthread, member[0])),   \
-                    "r" (idx));                                              \
-     else if (sizeof (__value) == 4)                                         \
-       asm volatile ("movl %%gs:%P1(,%2,4),%0"                               \
-                    : "=r" (__value)                                         \
-                    : "i" (offsetof (struct pthread, member[0])),            \
-                      "r" (idx));                                            \
-     else /* 8 */                                                            \
-       {                                                                     \
-        asm volatile  ("movl %%gs:%P1(,%2,8),%%eax\n\t"                      \
-                       "movl %%gs:4+%P1(,%2,8),%%edx"                        \
-                       : "=&A" (__value)                                     \
-                       : "i" (offsetof (struct pthread, member[0])),         \
-                         "r" (idx));                                         \
-       }                                                                     \
-     __value; })
-
-
+     (*(__typeof (descr->member[0]) __seg_gs *)                                      \
+      offsetof (struct pthread, member[idx]));                               \
+  })
 
 /* Set member of the thread descriptor directly.  */
 #define THREAD_SETMEM(descr, member, value) \
                     || sizeof (descr->member) == 4                           \
                     || sizeof (descr->member) == 8,                          \
                     "size of per-thread data");                              \
-     if (sizeof (descr->member) == 1)                                        \
-       asm volatile ("movb %b0,%%gs:%P1" :                                   \
-                    : "iq" (value),                                          \
-                      "i" (offsetof (struct pthread, member)));              \
-     else if (sizeof (descr->member) == 4)                                   \
-       asm volatile ("movl %0,%%gs:%P1" :                                    \
-                    : "ir" (value),                                          \
-                      "i" (offsetof (struct pthread, member)));              \
-     else /* 8 */                                                            \
-       {                                                                     \
-        asm volatile ("movl %%eax,%%gs:%P1\n\t"                              \
-                      "movl %%edx,%%gs:%P2" :                                \
-                      : "A" ((uint64_t) cast_to_integer (value)),            \
-                        "i" (offsetof (struct pthread, member)),             \
-                        "i" (offsetof (struct pthread, member) + 4));        \
-       }})
-
+     (*(__typeof (descr->member) __seg_gs *)                                 \
+      offsetof (struct pthread, member) = (value));                          \
+  })
 
 /* Same as THREAD_SETMEM, but the member offset can be non-constant.  */
 #define THREAD_SETMEM_NC(descr, member, idx, value) \
                     || sizeof (descr->member[0]) == 4                        \
                     || sizeof (descr->member[0]) == 8,                       \
                     "size of per-thread data");                              \
-     if (sizeof (descr->member[0]) == 1)                                     \
-       asm volatile ("movb %b0,%%gs:%P1(%2)" :                               \
-                    : "iq" (value),                                          \
-                      "i" (offsetof (struct pthread, member)),               \
-                      "r" (idx));                                            \
-     else if (sizeof (descr->member[0]) == 4)                                \
-       asm volatile ("movl %0,%%gs:%P1(,%2,4)" :                             \
-                    : "ir" (value),                                          \
-                      "i" (offsetof (struct pthread, member)),               \
-                      "r" (idx));                                            \
-     else /* 8 */                                                            \
-       {                                                                     \
-        asm volatile ("movl %%eax,%%gs:%P1(,%2,8)\n\t"                       \
-                      "movl %%edx,%%gs:4+%P1(,%2,8)" :                       \
-                      : "A" ((uint64_t) cast_to_integer (value)),            \
-                        "i" (offsetof (struct pthread, member)),             \
-                        "r" (idx));                                          \
-       }})
+     (*(__typeof (descr->member[0]) __seg_gs *)                                      \
+      offsetof (struct pthread, member[idx]) = (value));                     \
+  })