This is a mirror of the related patch to the LLVM upstream counterpart: llvm-project commit 32d21326f3b60874fd72bbe509c06dbe5b729a32 https://github.com/llvm/llvm-project/pull/176616.patch
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 This patch successfully allows the tagged address syscall ABI to be enabled by the support runtime. Tested under the spike simulator running kernel release 6.18. Enabling pointer masking in the RISC-V back end to follow. ------ libsanitizer/ChangeLog: * hwasan/hwasan.h: Cherry picked from LLVM commit 32d21326f3b60874fd72bbe509c06dbe5b729a32. * hwasan/hwasan_linux.cpp: Cherry picked from LLVM commit 32d21326f3b60874fd72bbe509c06dbe5b729a32. Signed-off-by: Maximilian Ciric <[email protected]> --- 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 1ae463f84..9201ed045 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 68651d3d3..716a8d47a 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() { -- 2.34.1
