Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[TSAN] add support for riscv64 #68735

Merged
merged 1 commit into from
Oct 12, 2023
Merged

[TSAN] add support for riscv64 #68735

merged 1 commit into from
Oct 12, 2023

Conversation

hiraditya
Copy link
Collaborator

@hiraditya hiraditya commented Oct 10, 2023

Implements for sv39 and sv48 VMA layout.

Userspace only has access to the bottom half of vma range. The top half is used by kernel. There is no dedicated vsyscall or heap segment.
PIE program is allocated to start at TASK_SIZE/3*2. Maximum ASLR is ARCH_MMAP_RND_BITS_MAX+PAGE_SHIFT=24+12=36 Loader, vdso and other libraries are allocated below stack from the top.

Also change RestoreAddr to use 4 bits to accommodate MappingRiscv64_48

Reviewed by: MaskRay, dvyukov, asb, StephenFan, luismarques, jrtc27, hiraditya, vitalybuka

Differential Revision: https://reviews.llvm.org/D145214

D145214 was reverted because one file was missing in the latest commit. Luckily the file was there in the previous commit, probably the author missed uploading that file with latest commit.

@llvmbot llvmbot added clang Clang issues not falling into any other category compiler-rt clang:driver 'clang' and 'clang++' user-facing binaries. Not 'clang-cl' compiler-rt:sanitizer labels Oct 10, 2023
@llvmbot
Copy link
Member

llvmbot commented Oct 10, 2023

@llvm/pr-subscribers-compiler-rt-sanitizer
@llvm/pr-subscribers-clang-driver

@llvm/pr-subscribers-clang

Author: AdityaK (hiraditya)

Changes

Implements for sv39 and sv48 VMA layout.

Userspace only has access to the bottom half of vma range. The top half is used by kernel. There is no dedicated vsyscall or heap segment.
PIE program is allocated to start at TASK_SIZE/3*2. Maximum ASLR is ARCH_MMAP_RND_BITS_MAX+PAGE_SHIFT=24+12=36 Loader, vdso and other libraries are allocated below stack from the top.

Also change RestoreAddr to use 4 bits to accommodate MappingRiscv64_48

Reviewed by: MaskRay, dvyukov, asb, StephenFan, luismarques, jrtc27, hiraditya, vitalybuka

Differential Revision: https://reviews.llvm.org/D145214


Full diff: https://github.com/llvm/llvm-project/pull/68735.diff

11 Files Affected:

  • (modified) clang/lib/Driver/ToolChains/Linux.cpp (+1-1)
  • (modified) compiler-rt/cmake/Modules/AllSupportedArchDefs.cmake (+1-1)
  • (modified) compiler-rt/lib/tsan/rtl/CMakeLists.txt (+4)
  • (modified) compiler-rt/lib/tsan/rtl/tsan_interceptors_posix.cpp (+2)
  • (modified) compiler-rt/lib/tsan/rtl/tsan_platform.h (+75-1)
  • (modified) compiler-rt/lib/tsan/rtl/tsan_platform_linux.cpp (+14)
  • (modified) compiler-rt/lib/tsan/rtl/tsan_rtl.h (+1-1)
  • (added) compiler-rt/lib/tsan/rtl/tsan_rtl_riscv64.S (+203)
  • (modified) compiler-rt/test/tsan/map32bit.cpp (+1)
  • (modified) compiler-rt/test/tsan/mmap_large.cpp (+2-1)
  • (modified) compiler-rt/test/tsan/test.h (+2)
diff --git a/clang/lib/Driver/ToolChains/Linux.cpp b/clang/lib/Driver/ToolChains/Linux.cpp
index 1ba222bf83b1032..735af54f114cef2 100644
--- a/clang/lib/Driver/ToolChains/Linux.cpp
+++ b/clang/lib/Driver/ToolChains/Linux.cpp
@@ -801,7 +801,7 @@ SanitizerMask Linux::getSupportedSanitizers() const {
       IsRISCV64 || IsSystemZ || IsHexagon || IsLoongArch64)
     Res |= SanitizerKind::Leak;
   if (IsX86_64 || IsMIPS64 || IsAArch64 || IsPowerPC64 || IsSystemZ ||
-      IsLoongArch64)
+      IsLoongArch64 || IsRISCV64)
     Res |= SanitizerKind::Thread;
   if (IsX86_64 || IsSystemZ)
     Res |= SanitizerKind::KernelMemory;
diff --git a/compiler-rt/cmake/Modules/AllSupportedArchDefs.cmake b/compiler-rt/cmake/Modules/AllSupportedArchDefs.cmake
index e8ab660c1d83c0c..416777171d2ca75 100644
--- a/compiler-rt/cmake/Modules/AllSupportedArchDefs.cmake
+++ b/compiler-rt/cmake/Modules/AllSupportedArchDefs.cmake
@@ -66,7 +66,7 @@ set(ALL_PROFILE_SUPPORTED_ARCH ${X86} ${X86_64} ${ARM32} ${ARM64} ${PPC32} ${PPC
     ${MIPS32} ${MIPS64} ${S390X} ${SPARC} ${SPARCV9} ${HEXAGON}
     ${RISCV32} ${RISCV64} ${LOONGARCH64})
 set(ALL_TSAN_SUPPORTED_ARCH ${X86_64} ${MIPS64} ${ARM64} ${PPC64} ${S390X}
-    ${LOONGARCH64})
+    ${LOONGARCH64} ${RISCV64})
 set(ALL_UBSAN_SUPPORTED_ARCH ${X86} ${X86_64} ${ARM32} ${ARM64} ${RISCV64}
     ${MIPS32} ${MIPS64} ${PPC64} ${S390X} ${SPARC} ${SPARCV9} ${HEXAGON}
     ${LOONGARCH64})
diff --git a/compiler-rt/lib/tsan/rtl/CMakeLists.txt b/compiler-rt/lib/tsan/rtl/CMakeLists.txt
index 7b18d379e919776..791c0596f65abf7 100644
--- a/compiler-rt/lib/tsan/rtl/CMakeLists.txt
+++ b/compiler-rt/lib/tsan/rtl/CMakeLists.txt
@@ -220,6 +220,10 @@ else()
       set(TSAN_ASM_SOURCES
         tsan_rtl_mips64.S
         )
+    elseif(arch MATCHES "riscv64")
+      set(TSAN_ASM_SOURCES
+        tsan_rtl_riscv64.S
+        )
     elseif(arch MATCHES "s390x")
       set(TSAN_ASM_SOURCES
         tsan_rtl_s390x.S
diff --git a/compiler-rt/lib/tsan/rtl/tsan_interceptors_posix.cpp b/compiler-rt/lib/tsan/rtl/tsan_interceptors_posix.cpp
index 5add97ccd17a3ad..bb10b607278f91a 100644
--- a/compiler-rt/lib/tsan/rtl/tsan_interceptors_posix.cpp
+++ b/compiler-rt/lib/tsan/rtl/tsan_interceptors_posix.cpp
@@ -81,6 +81,8 @@ struct ucontext_t {
 #define PTHREAD_ABI_BASE  "GLIBC_2.17"
 #elif SANITIZER_LOONGARCH64
 #define PTHREAD_ABI_BASE  "GLIBC_2.36"
+#elif SANITIZER_RISCV64
+#define PTHREAD_ABI_BASE  "GLIBC_2.27"
 #endif
 
 extern "C" int pthread_attr_init(void *attr);
diff --git a/compiler-rt/lib/tsan/rtl/tsan_platform.h b/compiler-rt/lib/tsan/rtl/tsan_platform.h
index f0cdaf48eaa3102..43822020c0b4b30 100644
--- a/compiler-rt/lib/tsan/rtl/tsan_platform.h
+++ b/compiler-rt/lib/tsan/rtl/tsan_platform.h
@@ -377,6 +377,71 @@ struct MappingPPC64_47 {
   static const uptr kMidAppMemEnd = 0;
 };
 
+/*
+C/C++ on linux/riscv64 (39-bit VMA)
+0000 0010 00 - 0200 0000 00: main binary                      ( 8 GB)
+0200 0000 00 - 1000 0000 00: -
+1000 0000 00 - 4000 0000 00: shadow memory                    (64 GB)
+4000 0000 00 - 4800 0000 00: metainfo                         (16 GB)
+4800 0000 00 - 5500 0000 00: -
+5500 0000 00 - 5a00 0000 00: main binary (PIE)                (~8 GB)
+5600 0000 00 - 7c00 0000 00: -
+7d00 0000 00 - 7fff ffff ff: libraries and main thread stack  ( 8 GB)
+
+mmap by default allocates from top downwards
+VDSO sits below loader and above dynamic libraries, within HiApp region.
+Heap starts after program region whose position depends on pie or non-pie.
+Disable tracking them since their locations are not fixed.
+*/
+struct MappingRiscv64_39 {
+  static const uptr kLoAppMemBeg   = 0x0000001000ull;
+  static const uptr kLoAppMemEnd   = 0x0200000000ull;
+  static const uptr kShadowBeg     = 0x1000000000ull;
+  static const uptr kShadowEnd     = 0x2000000000ull;
+  static const uptr kMetaShadowBeg = 0x2000000000ull;
+  static const uptr kMetaShadowEnd = 0x2400000000ull;
+  static const uptr kMidAppMemBeg  = 0x2aaaaaa000ull;
+  static const uptr kMidAppMemEnd  = 0x2c00000000ull;
+  static const uptr kHeapMemBeg    = 0x2c00000000ull;
+  static const uptr kHeapMemEnd    = 0x2c00000000ull;
+  static const uptr kHiAppMemBeg   = 0x3c00000000ull;
+  static const uptr kHiAppMemEnd   = 0x3fffffffffull;
+  static const uptr kShadowMsk     = 0x3800000000ull;
+  static const uptr kShadowXor     = 0x0800000000ull;
+  static const uptr kShadowAdd     = 0x0000000000ull;
+  static const uptr kVdsoBeg       = 0x4000000000ull;
+};
+
+/*
+C/C++ on linux/riscv64 (48-bit VMA)
+0000 0000 1000 - 0500 0000 0000: main binary                      ( 5 TB)
+0500 0000 0000 - 2000 0000 0000: -
+2000 0000 0000 - 4000 0000 0000: shadow memory                    (32 TB)
+4000 0000 0000 - 4800 0000 0000: metainfo                         ( 8 TB)
+4800 0000 0000 - 5555 5555 5000: -
+5555 5555 5000 - 5a00 0000 0000: main binary (PIE)                (~5 TB)
+5a00 0000 0000 - 7a00 0000 0000: -
+7a00 0000 0000 - 7fff ffff ffff: libraries and main thread stack  ( 5 TB)
+*/
+struct MappingRiscv64_48 {
+  static const uptr kLoAppMemBeg   = 0x000000001000ull;
+  static const uptr kLoAppMemEnd   = 0x050000000000ull;
+  static const uptr kShadowBeg     = 0x200000000000ull;
+  static const uptr kShadowEnd     = 0x400000000000ull;
+  static const uptr kMetaShadowBeg = 0x400000000000ull;
+  static const uptr kMetaShadowEnd = 0x480000000000ull;
+  static const uptr kMidAppMemBeg  = 0x555555555000ull;
+  static const uptr kMidAppMemEnd  = 0x5a0000000000ull;
+  static const uptr kHeapMemBeg    = 0x5a0000000000ull;
+  static const uptr kHeapMemEnd    = 0x5a0000000000ull;
+  static const uptr kHiAppMemBeg   = 0x7a0000000000ull;
+  static const uptr kHiAppMemEnd   = 0x7fffffffffffull;
+  static const uptr kShadowMsk     = 0x700000000000ull;
+  static const uptr kShadowXor     = 0x100000000000ull;
+  static const uptr kShadowAdd     = 0x000000000000ull;
+  static const uptr kVdsoBeg       = 0x800000000000ull;
+};
+
 /*
 C/C++ on linux/s390x
 While the kernel provides a 64-bit address space, we have to restrict ourselves
@@ -665,6 +730,13 @@ ALWAYS_INLINE auto SelectMapping(Arg arg) {
   }
 #  elif defined(__mips64)
   return Func::template Apply<MappingMips64_40>(arg);
+#  elif SANITIZER_RISCV64
+  switch (vmaSize) {
+    case 39:
+      return Func::template Apply<MappingRiscv64_39>(arg);
+    case 48:
+      return Func::template Apply<MappingRiscv64_48>(arg);
+  }
 #  elif defined(__s390x__)
   return Func::template Apply<MappingS390x>(arg);
 #  else
@@ -686,6 +758,8 @@ void ForEachMapping() {
   Func::template Apply<MappingPPC64_44>();
   Func::template Apply<MappingPPC64_46>();
   Func::template Apply<MappingPPC64_47>();
+  Func::template Apply<MappingRiscv64_39>();
+  Func::template Apply<MappingRiscv64_48>();
   Func::template Apply<MappingS390x>();
   Func::template Apply<MappingGo48>();
   Func::template Apply<MappingGoWindows>();
@@ -894,7 +968,7 @@ struct RestoreAddrImpl {
         Mapping::kMidAppMemEnd, Mapping::kHiAppMemBeg, Mapping::kHiAppMemEnd,
         Mapping::kHeapMemBeg,   Mapping::kHeapMemEnd,
     };
-    const uptr indicator = 0x0e0000000000ull;
+    const uptr indicator = 0x0f0000000000ull;
     const uptr ind_lsb = 1ull << LeastSignificantSetBitIndex(indicator);
     for (uptr i = 0; i < ARRAY_SIZE(ranges); i += 2) {
       uptr beg = ranges[i];
diff --git a/compiler-rt/lib/tsan/rtl/tsan_platform_linux.cpp b/compiler-rt/lib/tsan/rtl/tsan_platform_linux.cpp
index d161fa8d217e8c0..709a4322ed7ddf8 100644
--- a/compiler-rt/lib/tsan/rtl/tsan_platform_linux.cpp
+++ b/compiler-rt/lib/tsan/rtl/tsan_platform_linux.cpp
@@ -267,6 +267,16 @@ void InitializePlatformEarly() {
     Die();
   }
 # endif
+#elif SANITIZER_RISCV64
+  // the bottom half of vma is allocated for userspace
+  vmaSize = vmaSize + 1;
+# if !SANITIZER_GO
+  if (vmaSize != 39 && vmaSize != 48) {
+    Printf("FATAL: ThreadSanitizer: unsupported VMA range\n");
+    Printf("FATAL: Found %zd - Supported 39 and 48\n", vmaSize);
+    Die();
+  }
+# endif
 #endif
 }
 
@@ -399,6 +409,8 @@ static uptr UnmangleLongJmpSp(uptr mangled_sp) {
   return mangled_sp ^ xor_key;
 #elif defined(__mips__)
   return mangled_sp;
+#elif SANITIZER_RISCV64
+  return mangled_sp;
 #elif defined(__s390x__)
   // tcbhead_t.stack_guard
   uptr xor_key = ((uptr *)__builtin_thread_pointer())[5];
@@ -429,6 +441,8 @@ static uptr UnmangleLongJmpSp(uptr mangled_sp) {
 #  define LONG_JMP_SP_ENV_SLOT 1
 # elif defined(__mips64)
 #  define LONG_JMP_SP_ENV_SLOT 1
+# elif SANITIZER_RISCV64
+#  define LONG_JMP_SP_ENV_SLOT 13
 # elif defined(__s390x__)
 #  define LONG_JMP_SP_ENV_SLOT 9
 # else
diff --git a/compiler-rt/lib/tsan/rtl/tsan_rtl.h b/compiler-rt/lib/tsan/rtl/tsan_rtl.h
index a5606dbc7f882e0..e074e6fede5d964 100644
--- a/compiler-rt/lib/tsan/rtl/tsan_rtl.h
+++ b/compiler-rt/lib/tsan/rtl/tsan_rtl.h
@@ -57,7 +57,7 @@ namespace __tsan {
 #if !SANITIZER_GO
 struct MapUnmapCallback;
 #if defined(__mips64) || defined(__aarch64__) || defined(__loongarch__) || \
-    defined(__powerpc__)
+    defined(__powerpc__) || SANITIZER_RISCV64
 
 struct AP32 {
   static const uptr kSpaceBeg = 0;
diff --git a/compiler-rt/lib/tsan/rtl/tsan_rtl_riscv64.S b/compiler-rt/lib/tsan/rtl/tsan_rtl_riscv64.S
new file mode 100644
index 000000000000000..8e6b9b9432ef837
--- /dev/null
+++ b/compiler-rt/lib/tsan/rtl/tsan_rtl_riscv64.S
@@ -0,0 +1,203 @@
+#include "sanitizer_common/sanitizer_asm.h"
+
+.section .text
+
+.comm _ZN14__interception11real_setjmpE,8,8
+.globl ASM_SYMBOL_INTERCEPTOR(setjmp)
+ASM_TYPE_FUNCTION(ASM_SYMBOL_INTERCEPTOR(setjmp))
+ASM_SYMBOL_INTERCEPTOR(setjmp):
+  CFI_STARTPROC
+
+  // Save frame pointer and return address register
+  addi sp, sp, -32
+  sd ra, 24(sp)
+  sd s0, 16(sp)
+  CFI_DEF_CFA_OFFSET (32)
+  CFI_OFFSET (1, -8)
+  CFI_OFFSET (8, -16)
+
+  // Adjust the SP for previous frame
+  addi s0, sp, 32
+  CFI_DEF_CFA_REGISTER (8)
+
+  // Save env parameter
+  sd a0, 8(sp)
+  CFI_OFFSET (10, -24)
+
+  // Obtain SP, first argument to `void __tsan_setjmp(uptr sp)`
+  addi  a0, s0, 0
+
+  // call tsan interceptor
+  call ASM_SYMBOL(__tsan_setjmp)
+
+  // Restore env parameter
+  ld a0, 8(sp)
+  CFI_RESTORE (10)
+
+  // Restore frame/link register
+  ld s0, 16(sp)
+  ld ra, 24(sp)
+  addi sp, sp, 32
+  CFI_RESTORE (8)
+  CFI_RESTORE (1)
+  CFI_DEF_CFA (2, 0)
+
+  // tail jump to libc setjmp
+  la t1, _ZN14__interception11real_setjmpE
+  ld t1, 0(t1)
+  jr t1
+
+  CFI_ENDPROC
+ASM_SIZE(ASM_SYMBOL_INTERCEPTOR(setjmp))
+
+.comm _ZN14__interception12real__setjmpE,8,8
+.globl ASM_SYMBOL_INTERCEPTOR(_setjmp)
+ASM_TYPE_FUNCTION(ASM_SYMBOL_INTERCEPTOR(_setjmp))
+ASM_SYMBOL_INTERCEPTOR(_setjmp):
+  CFI_STARTPROC
+
+  // Save frame pointer and return address register
+  addi sp, sp, -32
+  sd ra, 24(sp)
+  sd s0, 16(sp)
+  CFI_DEF_CFA_OFFSET (32)
+  CFI_OFFSET (1, -8)
+  CFI_OFFSET (8, -16)
+
+  // Adjust the SP for previous frame
+  addi s0, sp, 32
+  CFI_DEF_CFA_REGISTER (8)
+
+  // Save env parameter
+  sd a0, 8(sp)
+  CFI_OFFSET (10, -24)
+
+  // Obtain SP, first argument to `void __tsan_setjmp(uptr sp)`
+  addi  a0, s0, 0
+
+  // call tsan interceptor
+  call ASM_SYMBOL(__tsan_setjmp)
+
+  // Restore env parameter
+  ld a0, 8(sp)
+  CFI_RESTORE (10)
+
+  // Restore frame/link register
+  ld s0, 16(sp)
+  ld ra, 24(sp)
+  addi sp, sp, 32
+  CFI_RESTORE (8)
+  CFI_RESTORE (1)
+  CFI_DEF_CFA (2, 0)
+
+  // tail jump to libc setjmp
+  la t1, _ZN14__interception12real__setjmpE
+  ld t1, 0(t1)
+  jr t1
+
+  CFI_ENDPROC
+ASM_SIZE(ASM_SYMBOL_INTERCEPTOR(_setjmp))
+
+.comm _ZN14__interception14real_sigsetjmpE,8,8
+.globl ASM_SYMBOL_INTERCEPTOR(sigsetjmp)
+ASM_TYPE_FUNCTION(ASM_SYMBOL_INTERCEPTOR(sigsetjmp))
+ASM_SYMBOL_INTERCEPTOR(sigsetjmp):
+  CFI_STARTPROC
+
+  // Save frame pointer and return address register
+  addi sp, sp, -32
+  sd ra, 24(sp)
+  sd s0, 16(sp)
+  CFI_DEF_CFA_OFFSET (32)
+  CFI_OFFSET (1, -8)
+  CFI_OFFSET (8, -16)
+
+  // Adjust the SP for previous frame
+  addi s0, sp, 32
+  CFI_DEF_CFA_REGISTER (8)
+
+  // Save env parameter
+  sd a0, 8(sp)
+  sd a1, 0(sp)
+  CFI_OFFSET (10, -24)
+  CFI_OFFSET (11, -32)
+
+  // Obtain SP, first argument to `void __tsan_setjmp(uptr sp)`
+  addi  a0, s0, 0
+
+  // call tsan interceptor
+  call      ASM_SYMBOL(__tsan_setjmp)
+
+  // Restore env parameter
+  ld a0, 8(sp)
+  ld a1, 0(sp)
+  CFI_RESTORE (10)
+  CFI_RESTORE (11)
+
+  // Restore frame/link register
+  ld s0, 16(sp)
+  ld ra, 24(sp)
+  addi sp, sp, 32
+  CFI_RESTORE (8)
+  CFI_RESTORE (1)
+  CFI_DEF_CFA (2, 0)
+
+  // tail jump to libc setjmp
+  la t1, _ZN14__interception14real_sigsetjmpE
+  ld t1, 0(t1)
+  jr t1
+
+  CFI_ENDPROC
+ASM_SIZE(ASM_SYMBOL_INTERCEPTOR(sigsetjmp))
+
+.comm _ZN14__interception16real___sigsetjmpE,8,8
+.globl ASM_SYMBOL_INTERCEPTOR(__sigsetjmp)
+ASM_TYPE_FUNCTION(ASM_SYMBOL_INTERCEPTOR(__sigsetjmp))
+ASM_SYMBOL_INTERCEPTOR(__sigsetjmp):
+  CFI_STARTPROC
+
+  // Save frame pointer and return address register
+  addi sp, sp, -32
+  sd ra, 24(sp)
+  sd s0, 16(sp)
+  CFI_DEF_CFA_OFFSET (32)
+  CFI_OFFSET (1, -8)
+  CFI_OFFSET (8, -16)
+
+  // Adjust the SP for previous frame
+  addi s0, sp, 32
+  CFI_DEF_CFA_REGISTER (8)
+
+  // Save env parameter
+  sd a0, 8(sp)
+  sd a1, 0(sp)
+  CFI_OFFSET (10, -24)
+  CFI_OFFSET (11, -32)
+
+  // Obtain SP, first argument to `void __tsan_setjmp(uptr sp)`
+  addi  a0, s0, 0
+
+  // call tsan interceptor
+  call      ASM_SYMBOL(__tsan_setjmp)
+
+  // Restore env parameter
+  ld a0, 8(sp)
+  ld a1, 0(sp)
+  CFI_RESTORE (10)
+  CFI_RESTORE (11)
+
+  // Restore frame/link register
+  ld s0, 16(sp)
+  ld ra, 24(sp)
+  addi sp, sp, 32
+  CFI_RESTORE (8)
+  CFI_RESTORE (1)
+  CFI_DEF_CFA (2, 0)
+
+  // tail jump to libc setjmp
+  la t1, _ZN14__interception16real___sigsetjmpE
+  ld t1, 0(t1)
+  jr t1
+
+  CFI_ENDPROC
+ASM_SIZE(ASM_SYMBOL_INTERCEPTOR(__sigsetjmp))
diff --git a/compiler-rt/test/tsan/map32bit.cpp b/compiler-rt/test/tsan/map32bit.cpp
index e8bac22647bb558..9c0760f54b73ad0 100644
--- a/compiler-rt/test/tsan/map32bit.cpp
+++ b/compiler-rt/test/tsan/map32bit.cpp
@@ -13,6 +13,7 @@
 // XFAIL: target=powerpc64{{.*}}
 // XFAIL: target=s390x{{.*}}
 // XFAIL: target=loongarch64{{.*}}
+// XFAIL: target=riscv64{{.*}}
 
 // MAP_32BIT doesn't exist on OS X and NetBSD.
 // UNSUPPORTED: darwin,target={{.*netbsd.*}}
diff --git a/compiler-rt/test/tsan/mmap_large.cpp b/compiler-rt/test/tsan/mmap_large.cpp
index 85ebe7f76b02364..a6aca720bf8a101 100644
--- a/compiler-rt/test/tsan/mmap_large.cpp
+++ b/compiler-rt/test/tsan/mmap_large.cpp
@@ -17,7 +17,8 @@
 int main() {
 #ifdef __x86_64__
   const size_t kLog2Size = 39;
-#elif defined(__mips64) || defined(__aarch64__) || defined(__loongarch_lp64)
+#elif defined(__mips64) || defined(__aarch64__) ||                             \
+    defined(__loongarch_lp64) || (defined(__riscv) && __riscv_xlen == 64)
   const size_t kLog2Size = 32;
 #elif defined(__powerpc64__)
   const size_t kLog2Size = 39;
diff --git a/compiler-rt/test/tsan/test.h b/compiler-rt/test/tsan/test.h
index 7406318243c5787..6fd552465823eda 100644
--- a/compiler-rt/test/tsan/test.h
+++ b/compiler-rt/test/tsan/test.h
@@ -76,6 +76,8 @@ unsigned long long monotonic_clock_ns() {
 const int kPCInc = 1;
 #elif defined(__sparc__) || defined(__mips__)
 const int kPCInc = 8;
+#elif defined(__riscv) && __riscv_xlen == 64
+const int kPCInc = 2;
 #else
 const int kPCInc = 4;
 #endif

@github-actions
Copy link

github-actions bot commented Oct 10, 2023

✅ With the latest revision this PR passed the C/C++ code formatter.

Copy link
Contributor

@zeroomega zeroomega left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM.
Please solve the code-formatting issues complaint by the bots.

@MaskRay
Copy link
Member

MaskRay commented Oct 10, 2023

The review context is on https://reviews.llvm.org/D145214 . Moving it here just causes more confusion.

@alexfanqi is the author of the patch and they can drive a reland.

Copy link
Member

@MaskRay MaskRay left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@hiraditya
Copy link
Collaborator Author

The review context is on https://reviews.llvm.org/D145214 . Moving it here just causes more confusion.

@alexfanqi is the author of the patch and they can drive a reland.

Can you elaborate what is confusing? The patch was already reviewed and accepted. I'm waiting on the author to reply back but I posted here for it to be tested. @alexfanqi asked me to land the patch last time (https://reviews.llvm.org/D145214#4650928)

@alexfanqi
Copy link
Contributor

alexfanqi commented Oct 12, 2023

Sorry. It took some time to reply. Since newer linux kernel supports sv57 and sv48, I tested this again with latest qemu and 6.6 kernel, by passing -cpu rv64,sv48=on to qemu.

Also to note, if we want to support sv57, we could directly copy the aarch64_48 scheme and append 8 bits to its addresses. That gives the maximum application space, a horrific ~2^24 tera byte.

I asked @hiraditya to land for me. Thanks for the help to drive the reland.

Copy link
Contributor

@alexfanqi alexfanqi left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I missed a little piece for sv48 here

--- a/compiler-rt/lib/sanitizer_common/sanitizer_platform.h
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_platform.h
@@ -303,7 +303,7 @@
 #    define SANITIZER_MMAP_RANGE_SIZE FIRST_32_SECOND_64(1ULL << 32, 1ULL << 40)
 #  endif
 #elif SANITIZER_RISCV64
-#  define SANITIZER_MMAP_RANGE_SIZE FIRST_32_SECOND_64(1ULL << 32, 1ULL << 38)
+#  define SANITIZER_MMAP_RANGE_SIZE FIRST_32_SECOND_64(1ULL << 32, 1ULL << 47)
 #elif defined(__aarch64__)
 #  if SANITIZER_APPLE
 #    if SANITIZER_OSX || SANITIZER_IOSSIM

Implements for sv39 and sv48 VMA layout.

Userspace only has access to the bottom half of vma range. The top half is used by kernel.
There is no dedicated vsyscall or heap segment.
PIE program is allocated to start at TASK_SIZE/3*2. Maximum ASLR is ARCH_MMAP_RND_BITS_MAX+PAGE_SHIFT=24+12=36
Loader, vdso and other libraries are allocated below stack from the top.

Also change RestoreAddr to use 4 bits to accommodate MappingRiscv64_48

Reviewed by: MaskRay, dvyukov, asb, StephenFan, luismarques, jrtc27, hiraditya, vitalybuka

Differential Revision: https://reviews.llvm.org/D145214
@hiraditya hiraditya merged commit 46cb8d9 into llvm:main Oct 12, 2023
@hiraditya hiraditya deleted the riscv_tsan branch October 12, 2023 23:03
@MaskRay
Copy link
Member

MaskRay commented Oct 12, 2023

The review context is on reviews.llvm.org/D145214 . Moving it here just causes more confusion.
@alexfanqi is the author of the patch and they can drive a reland.

Can you elaborate what is confusing? The patch was already reviewed and accepted. I'm waiting on the author to reply back but I posted here for it to be tested. @alexfanqi asked me to land the patch last time (reviews.llvm.org/D145214#4650928)

The patch is just a reland of https://reviews.llvm.org/D145214 . Having discussions both there and here is just confusing. AIUI this pull request does not add anything on top of that, but the main author of commit 46cb8d9 is now you with a Co-authored-by: tag attributing Alex Fan. That's what you got when you posted the pull request and merged the pull request via the web UI, instead of letting Alex Fan post the patch here.

@hiraditya
Copy link
Collaborator Author

Ah that's unfortunate.; sorry about that. In my local copy of git log (before merging)

commit 5b85613483861b3734edf9c94be390f2b3b0dd2a (HEAD -> riscv_tsan)
Author: Alex Fan <alex.fan.q@gmail.com>
Date:   Fri Oct 6 12:32:38 2023 -0700

so i thought github would respect that.

harbandana pushed a commit to harbandana/LLVM-REPO that referenced this pull request Jan 29, 2024
harbandana added a commit to harbandana/LLVM-REPO that referenced this pull request Jan 30, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
clang:driver 'clang' and 'clang++' user-facing binaries. Not 'clang-cl' clang Clang issues not falling into any other category compiler-rt:sanitizer compiler-rt
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants