Skip to content

Commit 39bfe1b

Browse files
author
Salinas, David
authored
[ASan] Intercept rocr api's 'hsa_amd_vmem_address_reserve_align' and … (llvm#4111)
2 parents 844cf36 + 7861d81 commit 39bfe1b

File tree

6 files changed

+132
-23
lines changed

6 files changed

+132
-23
lines changed

compiler-rt/lib/asan/asan_allocator.cpp

Lines changed: 60 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1304,6 +1304,9 @@ DECLARE_REAL(hsa_status_t, hsa_amd_ipc_memory_attach,
13041304
const hsa_amd_ipc_memory_t *handle, size_t len, uint32_t num_agents,
13051305
const hsa_agent_t *mapping_agents, void **mapped_ptr)
13061306
DECLARE_REAL(hsa_status_t, hsa_amd_ipc_memory_detach, void *mapped_ptr)
1307+
DECLARE_REAL(hsa_status_t, hsa_amd_vmem_address_reserve_align, void** ptr,
1308+
size_t size, uint64_t address, uint64_t alignment, uint64_t flags)
1309+
DECLARE_REAL(hsa_status_t, hsa_amd_vmem_address_free, void* ptr, size_t size);
13071310

13081311
namespace __asan {
13091312

@@ -1332,21 +1335,17 @@ hsa_status_t asan_hsa_amd_memory_pool_free(
13321335
if (p) {
13331336
instance.Deallocate(ptr, 0, 0, stack, FROM_MALLOC);
13341337
return HSA_STATUS_SUCCESS;
1335-
} else {
1336-
return REAL(hsa_amd_memory_pool_free)(ptr);
13371338
}
1339+
return REAL(hsa_amd_memory_pool_free)(ptr);
13381340
}
13391341

13401342
hsa_status_t asan_hsa_amd_agents_allow_access(
13411343
uint32_t num_agents, const hsa_agent_t *agents, const uint32_t *flags,
13421344
const void *ptr,
13431345
BufferedStackTrace *stack) {
13441346
void *p = get_allocator().GetBlockBegin(ptr);
1345-
if (p) {
1346-
return REAL(hsa_amd_agents_allow_access)(num_agents, agents, flags, p);
1347-
} else {
1348-
return REAL(hsa_amd_agents_allow_access)(num_agents, agents, flags, ptr);
1349-
}
1347+
return REAL(hsa_amd_agents_allow_access)(num_agents, agents, flags,
1348+
p ? p : ptr);
13501349
}
13511350

13521351
// For asan allocator, kMetadataSize is 0 and maximum redzone size is 2048. This
@@ -1394,5 +1393,59 @@ hsa_status_t asan_hsa_amd_ipc_memory_detach(void *mapped_ptr) {
13941393
reinterpret_cast<void *>(reinterpret_cast<uptr>(mapped_ptr) - kPageSize_);
13951394
return REAL(hsa_amd_ipc_memory_detach)(mapped_ptr_);
13961395
}
1396+
1397+
hsa_status_t asan_hsa_amd_vmem_address_reserve_align(
1398+
void** ptr, size_t size, uint64_t address, uint64_t alignment,
1399+
uint64_t flags, BufferedStackTrace* stack) {
1400+
// Bypass the tracking for a fixed address since it cannot be supported.
1401+
// Reasons:
1402+
// 1. Address may not meet the alignment/page-size requirement.
1403+
// 2. Requested range overlaps an existing reserved/mapped range.
1404+
// 3. Insufficient VA space to honor that exact placement.
1405+
if (address)
1406+
return REAL(hsa_amd_vmem_address_reserve_align)(ptr, size, address,
1407+
alignment, flags);
1408+
1409+
if (alignment < kPageSize_)
1410+
alignment = kPageSize_;
1411+
1412+
if (UNLIKELY(!IsPowerOfTwo(alignment))) {
1413+
errno = errno_EINVAL;
1414+
return HSA_STATUS_ERROR_INVALID_ARGUMENT;
1415+
}
1416+
1417+
AmdgpuAllocationInfo aa_info;
1418+
aa_info.alloc_func =
1419+
reinterpret_cast<void*>(asan_hsa_amd_vmem_address_reserve_align);
1420+
aa_info.memory_pool = {0};
1421+
aa_info.size = size;
1422+
aa_info.flags64 = flags;
1423+
aa_info.address = 0;
1424+
aa_info.alignment = alignment;
1425+
aa_info.ptr = nullptr;
1426+
SetErrnoOnNull(*ptr = instance.Allocate(size, alignment, stack, FROM_MALLOC,
1427+
false, &aa_info));
1428+
1429+
return aa_info.status;
1430+
}
1431+
1432+
hsa_status_t asan_hsa_amd_vmem_address_free(void* ptr, size_t size,
1433+
BufferedStackTrace* stack) {
1434+
if (UNLIKELY(!IsAligned(reinterpret_cast<uptr>(ptr), kPageSize_))) {
1435+
errno = errno_EINVAL;
1436+
return HSA_STATUS_ERROR_INVALID_ARGUMENT;
1437+
}
1438+
if (size == 0) {
1439+
errno = errno_EINVAL;
1440+
return HSA_STATUS_ERROR_INVALID_ARGUMENT;
1441+
}
1442+
1443+
void* p = get_allocator().GetBlockBegin(ptr);
1444+
if (p) {
1445+
instance.Deallocate(ptr, 0, 0, stack, FROM_MALLOC);
1446+
return HSA_STATUS_SUCCESS;
1447+
}
1448+
return REAL(hsa_amd_vmem_address_free)(ptr, size);
1449+
}
13971450
} // namespace __asan
13981451
#endif

compiler-rt/lib/asan/asan_allocator.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -320,6 +320,13 @@ hsa_status_t asan_hsa_amd_ipc_memory_attach(
320320
const hsa_agent_t* mapping_agents, void** mapped_ptr);
321321
hsa_status_t asan_hsa_amd_ipc_memory_detach(
322322
void* mapped_ptr);
323+
hsa_status_t asan_hsa_amd_vmem_address_reserve_align(void** ptr, size_t size,
324+
uint64_t address,
325+
uint64_t alignment,
326+
uint64_t flags,
327+
BufferedStackTrace* stack);
328+
hsa_status_t asan_hsa_amd_vmem_address_free(void* ptr, size_t size,
329+
BufferedStackTrace* stack);
323330
} // namespace __asan
324331
#endif
325332

compiler-rt/lib/asan/asan_interceptors.cpp

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -897,6 +897,22 @@ INTERCEPTOR(hsa_status_t, hsa_amd_ipc_memory_detach, void* mapped_ptr) {
897897
return asan_hsa_amd_ipc_memory_detach(mapped_ptr);
898898
}
899899

900+
INTERCEPTOR(hsa_status_t, hsa_amd_vmem_address_reserve_align, void** ptr,
901+
size_t size, uint64_t address, uint64_t alignment, uint64_t flags) {
902+
AsanInitFromRtl();
903+
ENSURE_HSA_INITED();
904+
GET_STACK_TRACE_MALLOC;
905+
return asan_hsa_amd_vmem_address_reserve_align(ptr, size, address, alignment,
906+
flags, &stack);
907+
}
908+
909+
INTERCEPTOR(hsa_status_t, hsa_amd_vmem_address_free, void* ptr, size_t size) {
910+
AsanInitFromRtl();
911+
ENSURE_HSA_INITED();
912+
GET_STACK_TRACE_FREE;
913+
return asan_hsa_amd_vmem_address_free(ptr, size, &stack);
914+
}
915+
900916
void InitializeAmdgpuInterceptors() {
901917
ASAN_INTERCEPT_FUNC(hsa_memory_copy);
902918
ASAN_INTERCEPT_FUNC(hsa_amd_memory_pool_allocate);
@@ -909,6 +925,8 @@ void InitializeAmdgpuInterceptors() {
909925
ASAN_INTERCEPT_FUNC(hsa_amd_ipc_memory_create);
910926
ASAN_INTERCEPT_FUNC(hsa_amd_ipc_memory_attach);
911927
ASAN_INTERCEPT_FUNC(hsa_amd_ipc_memory_detach);
928+
ASAN_INTERCEPT_FUNC(hsa_amd_vmem_address_reserve_align);
929+
ASAN_INTERCEPT_FUNC(hsa_amd_vmem_address_free);
912930
}
913931

914932
void ENSURE_HSA_INITED() {

compiler-rt/lib/sanitizer_common/sanitizer_allocator_amdgpu.cpp

Lines changed: 36 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,11 @@ struct HsaMemoryFunctions {
2222
void *(*alloc)(size_t),
2323
uint32_t *num_agents_accessible,
2424
hsa_agent_t **accessible);
25+
hsa_status_t (*vmem_address_reserve_align)(void** ptr, size_t size,
26+
uint64_t address,
27+
uint64_t alignment,
28+
uint64_t flags);
29+
hsa_status_t (*vmem_address_free)(void* ptr, size_t size);
2530
};
2631

2732
static HsaMemoryFunctions hsa_amd;
@@ -37,31 +42,49 @@ bool AmdgpuMemFuncs::Init() {
3742
RTLD_NEXT, "hsa_amd_memory_pool_free");
3843
hsa_amd.pointer_info = (decltype(hsa_amd.pointer_info))dlsym(
3944
RTLD_NEXT, "hsa_amd_pointer_info");
45+
hsa_amd.vmem_address_reserve_align =
46+
(decltype(hsa_amd.vmem_address_reserve_align))dlsym(
47+
RTLD_NEXT, "hsa_amd_vmem_address_reserve_align");
48+
hsa_amd.vmem_address_free = (decltype(hsa_amd.vmem_address_free))dlsym(
49+
RTLD_NEXT, "hsa_amd_vmem_address_free");
4050
if (!hsa_amd.memory_pool_allocate || !hsa_amd.memory_pool_free ||
41-
!hsa_amd.pointer_info)
51+
!hsa_amd.pointer_info || !hsa_amd.vmem_address_reserve_align ||
52+
!hsa_amd.vmem_address_free)
4253
return false;
43-
else
44-
return true;
54+
return true;
4555
}
4656

4757
void *AmdgpuMemFuncs::Allocate(uptr size, uptr alignment,
4858
DeviceAllocationInfo *da_info) {
4959
AmdgpuAllocationInfo *aa_info =
5060
reinterpret_cast<AmdgpuAllocationInfo *>(da_info);
51-
52-
aa_info->status = hsa_amd.memory_pool_allocate(aa_info->memory_pool, size,
53-
aa_info->flags, &aa_info->ptr);
61+
if (!aa_info->memory_pool.handle) {
62+
aa_info->status = hsa_amd.vmem_address_reserve_align(
63+
&aa_info->ptr, size, aa_info->address, aa_info->alignment,
64+
aa_info->flags64);
65+
} else {
66+
aa_info->status = hsa_amd.memory_pool_allocate(
67+
aa_info->memory_pool, size, aa_info->flags, &aa_info->ptr);
68+
}
5469
if (aa_info->status != HSA_STATUS_SUCCESS)
5570
return nullptr;
5671

5772
return aa_info->ptr;
5873
}
5974

6075
void AmdgpuMemFuncs::Deallocate(void *p) {
61-
UNUSED hsa_status_t status = hsa_amd.memory_pool_free(p);
76+
DevicePointerInfo DevPtrInfo;
77+
if (AmdgpuMemFuncs::GetPointerInfo(reinterpret_cast<uptr>(p), &DevPtrInfo)) {
78+
if (DevPtrInfo.type == HSA_EXT_POINTER_TYPE_HSA) {
79+
UNUSED hsa_status_t status = hsa_amd.memory_pool_free(p);
80+
} else if (DevPtrInfo.type == HSA_EXT_POINTER_TYPE_RESERVED_ADDR) {
81+
UNUSED hsa_status_t status =
82+
hsa_amd.vmem_address_free(p, DevPtrInfo.map_size);
83+
}
84+
}
6285
}
6386

64-
bool AmdgpuMemFuncs::GetPointerInfo(uptr ptr, DevivePointerInfo *ptr_info) {
87+
bool AmdgpuMemFuncs::GetPointerInfo(uptr ptr, DevicePointerInfo* ptr_info) {
6588
hsa_amd_pointer_info_t info;
6689
info.size = sizeof(hsa_amd_pointer_info_t);
6790
hsa_status_t status =
@@ -70,8 +93,12 @@ bool AmdgpuMemFuncs::GetPointerInfo(uptr ptr, DevivePointerInfo *ptr_info) {
7093
if (status != HSA_STATUS_SUCCESS)
7194
return false;
7295

73-
ptr_info->map_beg = reinterpret_cast<uptr>(info.agentBaseAddress);
96+
if (info.type == HSA_EXT_POINTER_TYPE_RESERVED_ADDR)
97+
ptr_info->map_beg = reinterpret_cast<uptr>(info.hostBaseAddress);
98+
else if (info.type == HSA_EXT_POINTER_TYPE_HSA)
99+
ptr_info->map_beg = reinterpret_cast<uptr>(info.agentBaseAddress);
74100
ptr_info->map_size = info.sizeInBytes;
101+
ptr_info->type = reinterpret_cast<hsa_amd_pointer_type_t>(info.type);
75102

76103
return true;
77104
}

compiler-rt/lib/sanitizer_common/sanitizer_allocator_amdgpu.h

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ class AmdgpuMemFuncs {
2020
static void *Allocate(uptr size, uptr alignment,
2121
DeviceAllocationInfo *da_info);
2222
static void Deallocate(void *p);
23-
static bool GetPointerInfo(uptr ptr, DevivePointerInfo *ptr_info);
23+
static bool GetPointerInfo(uptr ptr, DevicePointerInfo* ptr_info);
2424
static uptr GetPageSize();
2525
};
2626

@@ -32,8 +32,11 @@ struct AmdgpuAllocationInfo : public DeviceAllocationInfo {
3232
hsa_status_t status;
3333
void *alloc_func;
3434
hsa_amd_memory_pool_t memory_pool;
35-
size_t size;
36-
uint32_t flags;
35+
u64 alignment;
36+
u64 address;
37+
u64 flags64;
38+
usize size;
39+
u32 flags;
3740
void *ptr;
3841
};
3942
#endif // SANITIZER_AMDGPU

compiler-rt/lib/sanitizer_common/sanitizer_allocator_device.h

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,8 @@ struct DeviceAllocationInfo {
3131
DeviceAllocationType type_;
3232
};
3333

34-
struct DevivePointerInfo {
34+
struct DevicePointerInfo {
35+
u64 type;
3536
uptr map_beg;
3637
uptr map_size;
3738
};
@@ -165,7 +166,7 @@ class DeviceAllocatorT {
165166
: nullptr;
166167
}
167168

168-
void *GetBlockBegin(const void *ptr) const {
169+
void* GetBlockBegin(const void* ptr) const {
169170
Header header;
170171
if (!mem_funcs_inited_) return nullptr;
171172
uptr p = reinterpret_cast<uptr>(ptr);
@@ -182,7 +183,7 @@ class DeviceAllocatorT {
182183
if (!nearest_chunk)
183184
return nullptr;
184185
if (p != nearest_chunk) {
185-
Header *h = GetHeader(nearest_chunk, &header);
186+
Header* h = GetHeader(nearest_chunk, &header);
186187
CHECK_GE(nearest_chunk, h->map_beg);
187188
CHECK_LT(nearest_chunk, h->map_beg + h->map_size);
188189
CHECK_LE(nearest_chunk, p);
@@ -297,7 +298,7 @@ class DeviceAllocatorT {
297298
return mem_funcs_inited_;
298299
}
299300

300-
typedef DevivePointerInfo Header;
301+
typedef DevicePointerInfo Header;
301302

302303
Header *GetHeaderAnyPointer(uptr p, Header* h) const {
303304
CHECK(IsAligned(p, page_size_));

0 commit comments

Comments
 (0)