[compiler-rt] b191056 - [compiler-rt][hwasan] Support for new Intel LAM API

Vitaly Buka via llvm-commits llvm-commits at lists.llvm.org
Wed Jul 13 19:11:18 PDT 2022


Author: Alexander Potapenko
Date: 2022-07-13T19:11:13-07:00
New Revision: b191056f44701a91c7cd7282e3ba82512d56391a

URL: https://github.com/llvm/llvm-project/commit/b191056f44701a91c7cd7282e3ba82512d56391a
DIFF: https://github.com/llvm/llvm-project/commit/b191056f44701a91c7cd7282e3ba82512d56391a.diff

LOG: [compiler-rt][hwasan] Support for new Intel LAM API

New version of Intel LAM patches
(https://lore.kernel.org/linux-mm/20220712231328.5294-1-kirill.shutemov@linux.intel.com/)
uses a different interface based on arch_prctl():
 - arch_prctl(ARCH_GET_UNTAG_MASK, &mask) returns the current mask for
   untagging the pointers. We use it to detect kernel LAM support.
 - arch_prctl(ARCH_ENABLE_TAGGED_ADDR, nr_bits) enables pointer tagging
   for the current process.

Because __NR_arch_prctl is defined in different headers, and no other
platforms need it at the moment, we only declare internal_arch_prctl()
on x86_64.

Reviewed By: vitalybuka

Differential Revision: https://reviews.llvm.org/D129645

Added: 
    

Modified: 
    compiler-rt/lib/hwasan/hwasan_linux.cpp
    compiler-rt/lib/sanitizer_common/sanitizer_linux.cpp
    compiler-rt/lib/sanitizer_common/sanitizer_linux.h

Removed: 
    


################################################################################
diff  --git a/compiler-rt/lib/hwasan/hwasan_linux.cpp b/compiler-rt/lib/hwasan/hwasan_linux.cpp
index ba9e23621cc2a..dcab473d8ad19 100644
--- a/compiler-rt/lib/hwasan/hwasan_linux.cpp
+++ b/compiler-rt/lib/hwasan/hwasan_linux.cpp
@@ -114,11 +114,21 @@ void InitializeOsSupport() {
 #  define PR_SET_TAGGED_ADDR_CTRL 55
 #  define PR_GET_TAGGED_ADDR_CTRL 56
 #  define PR_TAGGED_ADDR_ENABLE (1UL << 0)
+#  define ARCH_GET_UNTAG_MASK     0x4001
+#  define ARCH_ENABLE_TAGGED_ADDR 0x4002
   // Check we're running on a kernel that can use the tagged address ABI.
   int local_errno = 0;
-  if (internal_iserror(internal_prctl(PR_GET_TAGGED_ADDR_CTRL, 0, 0, 0, 0),
+  bool has_abi;
+#  if defined(__x86_64__)
+  has_abi = (internal_iserror(internal_arch_prctl(ARCH_GET_UNTAG_MASK, 0),
                        &local_errno) &&
-      local_errno == EINVAL) {
+      local_errno == EINVAL);
+#  else
+  has_abi = (internal_iserror(internal_prctl(PR_GET_TAGGED_ADDR_CTRL, 0, 0, 0, 0),
+                       &local_errno) &&
+      local_errno == EINVAL);
+#  endif
+  if (has_abi) {
 #  if SANITIZER_ANDROID || defined(HWASAN_ALIASING_MODE)
     // Some older Android kernels have the tagged pointer ABI on
     // unconditionally, and hence don't have the tagged-addr prctl while still
@@ -142,17 +152,11 @@ void InitializeOsSupport() {
        !internal_prctl(PR_GET_TAGGED_ADDR_CTRL, 0, 0, 0, 0))) {
 #  if defined(__x86_64__) && !defined(HWASAN_ALIASING_MODE)
     // Try the new prctl API for Intel LAM.  The API is based on a currently
-    // unsubmitted patch to the Linux kernel (as of May 2021) and is thus
+    // unsubmitted patch to the Linux kernel (as of July 2022) and is thus
     // subject to change.  Patch is here:
-    // https://lore.kernel.org/linux-mm/20210205151631.43511-12-kirill.shutemov@linux.intel.com/
-    int tag_bits = kTagBits;
-    int tag_shift = kAddressTagShift;
+    // https://lore.kernel.org/linux-mm/20220712231328.5294-1-kirill.shutemov@linux.intel.com/
     if (!internal_iserror(
-            internal_prctl(PR_SET_TAGGED_ADDR_CTRL, PR_TAGGED_ADDR_ENABLE,
-                           reinterpret_cast<unsigned long>(&tag_bits),
-                           reinterpret_cast<unsigned long>(&tag_shift), 0))) {
-      CHECK_EQ(tag_bits, kTagBits);
-      CHECK_EQ(tag_shift, kAddressTagShift);
+            internal_arch_prctl(ARCH_ENABLE_TAGGED_ADDR, kTagBits))) {
       return;
     }
 #  endif  // defined(__x86_64__) && !defined(HWASAN_ALIASING_MODE)

diff  --git a/compiler-rt/lib/sanitizer_common/sanitizer_linux.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_linux.cpp
index 86e2676a6acd1..be37fd7f68b31 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_linux.cpp
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_linux.cpp
@@ -763,6 +763,13 @@ uptr internal_lseek(fd_t fd, OFF_T offset, int whence) {
 uptr internal_prctl(int option, uptr arg2, uptr arg3, uptr arg4, uptr arg5) {
   return internal_syscall(SYSCALL(prctl), option, arg2, arg3, arg4, arg5);
 }
+# if defined(__x86_64__)
+#include <asm/unistd_64.h>
+// Currently internal_arch_prctl() is only needed on x86_64.
+uptr internal_arch_prctl(int option, uptr arg2) {
+  return internal_syscall(__NR_arch_prctl, option, arg2);
+}
+# endif
 #endif
 
 uptr internal_sigaltstack(const void *ss, void *oss) {

diff  --git a/compiler-rt/lib/sanitizer_common/sanitizer_linux.h b/compiler-rt/lib/sanitizer_common/sanitizer_linux.h
index 45d8c921da12c..761c57d1b8eb8 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_linux.h
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_linux.h
@@ -69,6 +69,9 @@ uptr internal_clock_gettime(__sanitizer_clockid_t clk_id, void *tp);
 // Linux-only syscalls.
 #if SANITIZER_LINUX
 uptr internal_prctl(int option, uptr arg2, uptr arg3, uptr arg4, uptr arg5);
+#    if defined(__x86_64__)
+uptr internal_arch_prctl(int option, uptr arg2);
+#    endif
 // Used only by sanitizer_stoptheworld. Signal handlers that are actually used
 // (like the process-wide error reporting SEGV handler) must use
 // internal_sigaction instead.


        


More information about the llvm-commits mailing list