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

Reply via email to