[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