Skip to content

Commit ee9ba99

Browse files
AllanZynekbenzie
andauthored
[DeviceMSAN] Check use-of-uninitialized value on static local memory (#17054)
Support sanitizing local memory (address space 3 pointers) - Added "-msan-spir-locals" and "-msan-spir-privates" to enable MSan on local and private memory - Disable some unsupported devices to pass pre ci --------- Co-authored-by: Kenneth Benzie (Benie) <[email protected]>
1 parent af5b684 commit ee9ba99

File tree

15 files changed

+817
-189
lines changed

15 files changed

+817
-189
lines changed

libdevice/sanitizer/msan_rtl.cpp

Lines changed: 139 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -13,39 +13,48 @@
1313
#include "spirv_vars.h"
1414

1515
DeviceGlobal<void *> __MsanLaunchInfo;
16+
#define GetMsanLaunchInfo \
17+
((__SYCL_GLOBAL__ MsanLaunchInfo *)__MsanLaunchInfo.get())
18+
19+
namespace {
1620

1721
constexpr int MSAN_REPORT_NONE = 0;
1822
constexpr int MSAN_REPORT_START = 1;
1923
constexpr int MSAN_REPORT_FINISH = 2;
2024

21-
static const __SYCL_CONSTANT__ char __msan_print_warning_return[] =
22-
"[kernel] !!! msan warning return\n";
25+
constexpr uptr PVC_DEVICE_USM_MASK = 0xff00'0000'0000'0000ULL;
26+
constexpr uptr PVC_DEVICE_USM_BEGIN = 0xff00'0000'0000'0000ULL;
27+
constexpr uptr PVC_DEVICE_USM_END = 0xff00'ffff'ffff'ffffULL;
2328

24-
static const __SYCL_CONSTANT__ char __msan_print_shadow[] =
25-
"[kernel] __msan_get_shadow(addr=%p, as=%d) = %p: %02X\n";
29+
constexpr uptr DG2_DEVICE_USM_MASK = 0xffff'0000'0000'0000ULL;
30+
constexpr uptr DG2_DEVICE_USM_BEGIN = 0xffff'8000'0000'0000ULL;
31+
constexpr uptr DG2_DEVICE_USM_END = 0xffff'ffff'ffff'ffffULL;
2632

27-
static const __SYCL_CONSTANT__ char __msan_print_warning_nolaunchinfo[] =
28-
"[kernel] !!! __mem_warning_nolaunchinfo\n";
33+
const __SYCL_CONSTANT__ char __msan_print_shadow[] =
34+
"[kernel] __msan_get_shadow(addr=%p, as=%d) = %p: %02X\n";
2935

30-
static const __SYCL_CONSTANT__ char __msan_print_launchinfo[] =
36+
const __SYCL_CONSTANT__ char __msan_print_launchinfo[] =
3137
"[kernel] !!! launchinfo %p (GlobalShadow=%p)\n";
3238

33-
static const __SYCL_CONSTANT__ char __msan_print_report[] =
34-
"[kernel] %d bytes uninitialized at kernel %s\n";
35-
36-
static const __SYCL_CONSTANT__ char __msan_print_unsupport_device_type[] =
39+
const __SYCL_CONSTANT__ char __msan_print_unsupport_device_type[] =
3740
"[kernel] Unsupport device type: %d\n";
3841

39-
static const __SYCL_CONSTANT__ char __msan_print_generic_to[] =
42+
const __SYCL_CONSTANT__ char __msan_print_generic_to[] =
4043
"[kernel] %p(4) - %p(%d)\n";
4144

45+
const __SYCL_CONSTANT__ char __msan_print_func_beg[] =
46+
"[kernel] ===== %s() begin\n";
47+
48+
const __SYCL_CONSTANT__ char __msan_print_func_end[] =
49+
"[kernel] ===== %s() end\n";
50+
51+
} // namespace
52+
4253
#if defined(__SPIR__) || defined(__SPIRV__)
4354

4455
#define MSAN_DEBUG(X) \
4556
do { \
46-
auto launch_info = \
47-
(__SYCL_GLOBAL__ const MsanLaunchInfo *)__MsanLaunchInfo.get(); \
48-
if (launch_info->Debug) { \
57+
if (GetMsanLaunchInfo->Debug) { \
4958
X; \
5059
} \
5160
} while (false)
@@ -74,8 +83,7 @@ void __msan_internal_report_save(const uint32_t size,
7483
const int Expected = MSAN_REPORT_NONE;
7584
int Desired = MSAN_REPORT_START;
7685

77-
auto &SanitizerReport =
78-
((__SYCL_GLOBAL__ MsanLaunchInfo *)__MsanLaunchInfo.get())->Report;
86+
auto &SanitizerReport = GetMsanLaunchInfo->Report;
7987

8088
if (atomicCompareAndSet(&SanitizerReport.Flag, Desired, Expected) ==
8189
Expected) {
@@ -126,8 +134,7 @@ void __msan_report_error(const uint32_t size,
126134
const char __SYCL_CONSTANT__ *func) {
127135
__msan_internal_report_save(size, file, line, func);
128136

129-
auto launch = (__SYCL_GLOBAL__ MsanLaunchInfo *)__MsanLaunchInfo.get();
130-
if (!launch->IsRecover) {
137+
if (!GetMsanLaunchInfo->IsRecover) {
131138
__devicelib_exit();
132139
}
133140
}
@@ -141,7 +148,7 @@ inline uptr __msan_get_shadow_dg2(uptr addr, uint32_t as) {
141148
ConvertGenericPointer(addr, as);
142149
}
143150

144-
if (as != ADDRESS_SPACE_GLOBAL || !(addr & 0xffff'0000'0000'0000ULL))
151+
if (as != ADDRESS_SPACE_GLOBAL || !(addr & DG2_DEVICE_USM_MASK))
145152
return (uptr)((__SYCL_GLOBAL__ MsanLaunchInfo *)__MsanLaunchInfo.get())
146153
->CleanShadow;
147154

@@ -151,9 +158,9 @@ inline uptr __msan_get_shadow_dg2(uptr addr, uint32_t as) {
151158
auto shadow_end = ((__SYCL_GLOBAL__ MsanLaunchInfo *)__MsanLaunchInfo.get())
152159
->GlobalShadowOffsetEnd;
153160
if (addr < shadow_begin) {
154-
return addr + (shadow_begin - 0xffff'8000'0000'0000ULL);
161+
return addr + (shadow_begin - DG2_DEVICE_USM_BEGIN);
155162
} else {
156-
return addr - (0xffff'ffff'ffff'ffffULL - shadow_end);
163+
return addr - (DG2_DEVICE_USM_END - shadow_end);
157164
}
158165
}
159166

@@ -162,20 +169,33 @@ inline uptr __msan_get_shadow_pvc(uptr addr, uint32_t as) {
162169
ConvertGenericPointer(addr, as);
163170
}
164171

165-
if (as != ADDRESS_SPACE_GLOBAL || !(addr & 0xFF00000000000000))
166-
return (uptr)((__SYCL_GLOBAL__ MsanLaunchInfo *)__MsanLaunchInfo.get())
167-
->CleanShadow;
168-
169172
// Device USM only
170-
auto shadow_begin = ((__SYCL_GLOBAL__ MsanLaunchInfo *)__MsanLaunchInfo.get())
171-
->GlobalShadowOffset;
172-
auto shadow_end = ((__SYCL_GLOBAL__ MsanLaunchInfo *)__MsanLaunchInfo.get())
173-
->GlobalShadowOffsetEnd;
174-
if (addr < shadow_begin) {
175-
return addr + (shadow_begin - 0xff00'0000'0000'0000ULL);
176-
} else {
177-
return addr - (0xff00'ffff'ffff'ffffULL - shadow_end);
173+
if (as == ADDRESS_SPACE_GLOBAL && (addr & PVC_DEVICE_USM_MASK)) {
174+
auto shadow_begin = GetMsanLaunchInfo->GlobalShadowOffset;
175+
auto shadow_end = GetMsanLaunchInfo->GlobalShadowOffsetEnd;
176+
if (addr < shadow_begin) {
177+
return addr + (shadow_begin - PVC_DEVICE_USM_BEGIN);
178+
} else {
179+
return addr - (PVC_DEVICE_USM_END - shadow_end);
180+
}
181+
} else if (as == ADDRESS_SPACE_LOCAL) {
182+
// The size of SLM is 128KB on PVC
183+
constexpr unsigned SLM_SIZE = 128 * 1024;
184+
// work-group linear id
185+
const auto wg_lid =
186+
__spirv_BuiltInWorkgroupId.x * __spirv_BuiltInNumWorkgroups.y *
187+
__spirv_BuiltInNumWorkgroups.z +
188+
__spirv_BuiltInWorkgroupId.y * __spirv_BuiltInNumWorkgroups.z +
189+
__spirv_BuiltInWorkgroupId.z;
190+
191+
const auto shadow_offset = GetMsanLaunchInfo->LocalShadowOffset;
192+
193+
if (shadow_offset != 0) {
194+
return shadow_offset + (wg_lid * SLM_SIZE) + (addr & (SLM_SIZE - 1));
195+
}
178196
}
197+
198+
return GetMsanLaunchInfo->CleanShadow;
179199
}
180200

181201
} // namespace
@@ -184,7 +204,7 @@ inline uptr __msan_get_shadow_pvc(uptr addr, uint32_t as) {
184204
DEVICE_EXTERN_C_NOINLINE void __msan_maybe_warning_##size( \
185205
type s, u32 o, const char __SYCL_CONSTANT__ *file, uint32_t line, \
186206
const char __SYCL_CONSTANT__ *func) { \
187-
if (!__MsanLaunchInfo.get()) \
207+
if (!GetMsanLaunchInfo) \
188208
return; \
189209
if (UNLIKELY(s)) { \
190210
__msan_report_error(size, file, line, func); \
@@ -209,33 +229,32 @@ __msan_warning_noreturn(const char __SYCL_CONSTANT__ *file, uint32_t line,
209229
__devicelib_exit();
210230
}
211231

232+
// For mapping detail, ref to
233+
// "unified-runtime/source/loader/layers/sanitizer/msan/msan_shadow.hpp"
212234
DEVICE_EXTERN_C_NOINLINE uptr __msan_get_shadow(uptr addr, uint32_t as) {
213235
// Return clean shadow (0s) by default
214-
uptr shadow_ptr =
215-
(uptr)((__SYCL_GLOBAL__ MsanLaunchInfo *)__MsanLaunchInfo.get())
216-
->CleanShadow;
236+
uptr shadow_ptr = GetMsanLaunchInfo->CleanShadow;
217237

218-
if (!__MsanLaunchInfo.get())
238+
if (!GetMsanLaunchInfo)
219239
return shadow_ptr;
220240

221-
auto launch_info = (__SYCL_GLOBAL__ MsanLaunchInfo *)__MsanLaunchInfo.get();
222-
MSAN_DEBUG(__spirv_ocl_printf(__msan_print_launchinfo, (void *)launch_info,
223-
launch_info->GlobalShadowOffset));
241+
MSAN_DEBUG(__spirv_ocl_printf(__msan_print_launchinfo, GetMsanLaunchInfo,
242+
GetMsanLaunchInfo->GlobalShadowOffset));
224243

225244
#if defined(__LIBDEVICE_PVC__)
226245
shadow_ptr = __msan_get_shadow_pvc(addr, as);
227246
#elif defined(__LIBDEVICE_CPU__)
228247
shadow_ptr = __msan_get_shadow_cpu(addr);
229248
#else
230-
if (LIKELY(launch_info->DeviceTy == DeviceType::CPU)) {
249+
if (LIKELY(GetMsanLaunchInfo->DeviceTy == DeviceType::CPU)) {
231250
shadow_ptr = __msan_get_shadow_cpu(addr);
232-
} else if (launch_info->DeviceTy == DeviceType::GPU_PVC) {
251+
} else if (GetMsanLaunchInfo->DeviceTy == DeviceType::GPU_PVC) {
233252
shadow_ptr = __msan_get_shadow_pvc(addr, as);
234-
} else if (launch_info->DeviceTy == DeviceType::GPU_DG2) {
253+
} else if (GetMsanLaunchInfo->DeviceTy == DeviceType::GPU_DG2) {
235254
shadow_ptr = __msan_get_shadow_dg2(addr, as);
236255
} else {
237256
MSAN_DEBUG(__spirv_ocl_printf(__msan_print_unsupport_device_type,
238-
launch_info->DeviceTy));
257+
GetMsanLaunchInfo->DeviceTy));
239258
}
240259
#endif
241260

@@ -245,15 +264,22 @@ DEVICE_EXTERN_C_NOINLINE uptr __msan_get_shadow(uptr addr, uint32_t as) {
245264
return shadow_ptr;
246265
}
247266

267+
static __SYCL_CONSTANT__ const char __mem_memset[] =
268+
"[kernel] memset(beg=%p, shadow_beg=%p, shadow_end=%p)\n";
269+
248270
#define MSAN_MEMSET(as) \
249271
DEVICE_EXTERN_C_NOINLINE \
250272
__attribute__((address_space(as))) void *__msan_memset_p##as( \
251273
__attribute__((address_space(as))) char *dest, int val, size_t size) { \
274+
MSAN_DEBUG(__spirv_ocl_printf(__msan_print_func_beg, "__msan_memset")); \
252275
uptr shadow = __msan_get_shadow((uptr)dest, as); \
253276
for (size_t i = 0; i < size; i++) { \
254277
dest[i] = val; \
255278
((__SYCL_GLOBAL__ char *)shadow)[i] = 0; \
256279
} \
280+
MSAN_DEBUG( \
281+
__spirv_ocl_printf(__mem_memset, dest, shadow, shadow + size - 1)); \
282+
MSAN_DEBUG(__spirv_ocl_printf(__msan_print_func_end, "__msan_memset")); \
257283
return dest; \
258284
}
259285

@@ -324,4 +350,71 @@ MSAN_MEMCPY(1)
324350
MSAN_MEMCPY(3)
325351
MSAN_MEMCPY(4)
326352

353+
///
354+
/// Initialize shdadow memory of local memory
355+
///
356+
357+
static __SYCL_CONSTANT__ const char __mem_set_shadow_local[] =
358+
"[kernel] set_shadow_local(beg=%p, end=%p, val:%02X)\n";
359+
360+
DEVICE_EXTERN_C_NOINLINE void __msan_poison_shadow_static_local(uptr ptr,
361+
size_t size) {
362+
// Update shadow memory of local memory only on first work-item
363+
if (__spirv_LocalInvocationId_x() + __spirv_LocalInvocationId_y() +
364+
__spirv_LocalInvocationId_z() ==
365+
0) {
366+
if (!GetMsanLaunchInfo)
367+
return;
368+
369+
MSAN_DEBUG(__spirv_ocl_printf(__msan_print_func_beg,
370+
"__msan_poison_shadow_static_local"));
371+
372+
auto shadow_address = __msan_get_shadow(ptr, ADDRESS_SPACE_LOCAL);
373+
if (shadow_address == GetMsanLaunchInfo->CleanShadow)
374+
return;
375+
376+
for (size_t i = 0; i < size; ++i) {
377+
((__SYCL_GLOBAL__ u8 *)shadow_address)[i] = 0xff;
378+
}
379+
380+
MSAN_DEBUG(__spirv_ocl_printf(__mem_set_shadow_local, shadow_address,
381+
shadow_address + size, 0xff));
382+
MSAN_DEBUG(__spirv_ocl_printf(__msan_print_func_end,
383+
"__msan_poison_shadow_static_local"));
384+
}
385+
}
386+
387+
DEVICE_EXTERN_C_NOINLINE void __msan_unpoison_shadow_static_local(uptr ptr,
388+
size_t size) {
389+
// Update shadow memory of local memory only on first work-item
390+
if (__spirv_LocalInvocationId_x() + __spirv_LocalInvocationId_y() +
391+
__spirv_LocalInvocationId_z() ==
392+
0) {
393+
if (!GetMsanLaunchInfo)
394+
return;
395+
396+
MSAN_DEBUG(__spirv_ocl_printf(__msan_print_func_beg,
397+
"__msan_unpoison_shadow_static_local"));
398+
399+
auto shadow_address = __msan_get_shadow(ptr, ADDRESS_SPACE_LOCAL);
400+
if (shadow_address == GetMsanLaunchInfo->CleanShadow)
401+
return;
402+
403+
for (size_t i = 0; i < size; ++i) {
404+
((__SYCL_GLOBAL__ u8 *)shadow_address)[i] = 0;
405+
}
406+
407+
MSAN_DEBUG(__spirv_ocl_printf(__mem_set_shadow_local, shadow_address,
408+
shadow_address + size, 0));
409+
MSAN_DEBUG(__spirv_ocl_printf(__msan_print_func_end,
410+
"__msan_unpoison_shadow_static_local"));
411+
}
412+
}
413+
414+
DEVICE_EXTERN_C_INLINE void __msan_barrier() {
415+
__spirv_ControlBarrier(__spv::Scope::Workgroup, __spv::Scope::Workgroup,
416+
__spv::MemorySemanticsMask::SequentiallyConsistent |
417+
__spv::MemorySemanticsMask::WorkgroupMemory);
418+
}
419+
327420
#endif // __SPIR__ || __SPIRV__

0 commit comments

Comments
 (0)