mirror of
https://github.com/llvm/llvm-project.git
synced 2025-04-18 18:56:43 +00:00
[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
This commit is contained in:
parent
cef07169ec
commit
b191056f44
@ -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)
|
||||
|
@ -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) {
|
||||
|
@ -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.
|
||||
|
Loading…
x
Reference in New Issue
Block a user