From 39f1b650433d3ccf1c921152d352a9728bb08f6e Mon Sep 17 00:00:00 2001 From: Tharo Date: Tue, 28 Apr 2026 10:19:13 -0600 Subject: [PATCH] [HWASAN] [RISC-V] Update EnableTaggingAbi for RISC-V linux. (#176616) Cherry-picked from LLVM commit: 32d21326f3b60874fd72bbe509c06dbe5b729a32 Enabling pointer tagging in the userspace ABI for RISC-V kernels differs to that of Aarch64. It requires requesting a particular number of masked pointer bits, an error is returned if the platform could not accommodate the request: https://docs.kernel.org/arch/riscv/uabi.html#pointer-masking While experimenting with enabling RISC-V HWASAN on GCC I was hitting the error > HWAddressSanitizer failed to enable tagged address syscall ABI when attempting to run instrumented programs in the spike simulator running kernel release 6.18. This patch successfully allows the tagged address syscall ABI to be enabled by the support runtime. --- libsanitizer/hwasan/hwasan.h | 9 ++++++++- libsanitizer/hwasan/hwasan_linux.cpp | 16 ++++++++++++++-- 2 files changed, 22 insertions(+), 3 deletions(-) diff --git a/libsanitizer/hwasan/hwasan.h b/libsanitizer/hwasan/hwasan.h index 1ae463f845c..9201ed04526 100644 --- a/libsanitizer/hwasan/hwasan.h +++ b/libsanitizer/hwasan/hwasan.h @@ -57,11 +57,18 @@ constexpr unsigned kTaggableRegionCheckShift = // Tags are done in upper bits using Intel LAM. constexpr unsigned kAddressTagShift = 57; constexpr unsigned kTagBits = 6; -#else +#elif defined(__aarch64__) // TBI (Top Byte Ignore) feature of AArch64: bits [63:56] are ignored in address // translation and can be used to store a tag. constexpr unsigned kAddressTagShift = 56; constexpr unsigned kTagBits = 8; +#elif SANITIZER_RISCV64 +// Pointer Masking extension for RISC-V: Top PMLEN (16 or 7) bits are ignored in +// address translation and can be used to store a tag. +constexpr unsigned kAddressTagShift = 56; +constexpr unsigned kTagBits = 8; +#else +# error Architecture not supported #endif // defined(HWASAN_ALIASING_MODE) // Mask for extracting tag bits from the lower 8 bits. diff --git a/libsanitizer/hwasan/hwasan_linux.cpp b/libsanitizer/hwasan/hwasan_linux.cpp index 68651d3d39d..716a8d47ae1 100644 --- a/libsanitizer/hwasan/hwasan_linux.cpp +++ b/libsanitizer/hwasan/hwasan_linux.cpp @@ -134,6 +134,7 @@ static void MaybeDieIfNoTaggingAbi(const char *message) { # define PR_SET_TAGGED_ADDR_CTRL 55 # define PR_GET_TAGGED_ADDR_CTRL 56 # define PR_TAGGED_ADDR_ENABLE (1UL << 0) +# define PR_PMLEN_SHIFT 24 # define ARCH_GET_UNTAG_MASK 0x4001 # define ARCH_ENABLE_TAGGED_ADDR 0x4002 # define ARCH_GET_MAX_TAG_BITS 0x4003 @@ -182,7 +183,7 @@ static bool EnableTaggingAbi() { if (mask & kAddressTagMask) return false; return true; -# else +# elif defined(__aarch64__) // Enable ARM TBI tagging for the process. If for some reason tagging is not // supported, prctl(PR_SET_TAGGED_ADDR_CTRL, PR_TAGGED_ADDR_ENABLE) returns // -EINVAL. @@ -194,7 +195,18 @@ static bool EnableTaggingAbi() { PR_TAGGED_ADDR_ENABLE) return false; return true; -# endif // __x86_64__ +# elif SANITIZER_RISCV64 + // Enable RISC-V address tagging via pointer masking. + uptr req = kTagBits << PR_PMLEN_SHIFT | PR_TAGGED_ADDR_ENABLE; + if (internal_iserror(internal_prctl(PR_SET_TAGGED_ADDR_CTRL, req, 0, 0, 0))) + return false; + uptr rsp = internal_prctl(PR_GET_TAGGED_ADDR_CTRL, 0, 0, 0, 0); + if (internal_iserror(rsp)) + return false; + return rsp & PR_TAGGED_ADDR_ENABLE; +# else +# error Architecture not supported +# endif // __x86_64__ } void InitializeOsSupport() {