From fa7711020636da4ec931bcbb7a17786cb1420505 Mon Sep 17 00:00:00 2001 From: Honglei Huang Date: Fri, 14 Nov 2025 09:48:11 +0800 Subject: [PATCH 1/2] Add slab alignment validation in __ockl_dm_init_v1 The device memory allocator assumes all slabs are 2MB aligned because __ockl_dm_dealloc uses address masking (addr & ~0x1fffffUL) to find slab metadata. If initial_slabs are misaligned, deallocation will compute wrong slab addresses, read garbage metadata, and cause GPU page faults. This patch adds alignment validation in __ockl_dm_init_v1. If the initial slabs base address is not 2MB aligned, the function disables the pre-allocated pool by setting initial_slabs equal to initial_slabs_end, forcing allocation to fall back to devmem_request. Signed-off-by: Honglei Huang --- amd/device-libs/ockl/src/dm.cl | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/amd/device-libs/ockl/src/dm.cl b/amd/device-libs/ockl/src/dm.cl index 9a5970249ad10..6d9c23abeade1 100644 --- a/amd/device-libs/ockl/src/dm.cl +++ b/amd/device-libs/ockl/src/dm.cl @@ -947,9 +947,24 @@ __ockl_dm_init_v1(ulong hp, ulong sp, uint hb, uint nis) if (lid == 0) { __global heap_t *thp = (__global heap_t *)hp; - AS(&thp->initial_slabs, sp, memory_order_relaxed); - thp->initial_slabs_end = sp + ((ulong)nis << 21); - thp->initial_slabs_start = sp; + + // CRITICAL: Verify that initial_slabs pointer is 2MB aligned + // The deallocation code assumes all slabs are 2MB aligned and uses + // address masking (addr & ~0x1fffffUL) to find slab metadata. + // Misaligned slabs will cause memory corruption and crashes. + if ((sp & 0x1fffffUL) != 0) { + // Fatal error: initial slabs base address not 2MB aligned + // Set initial_slabs to end to prevent use of misaligned slabs + // This forces allocation to fall back to devmem_request which + // should provide properly aligned memory + AS(&thp->initial_slabs, sp + ((ulong)nis << 21), memory_order_relaxed); + thp->initial_slabs_end = sp + ((ulong)nis << 21); + thp->initial_slabs_start = sp + ((ulong)nis << 21); + } else { + AS(&thp->initial_slabs, sp, memory_order_relaxed); + thp->initial_slabs_end = sp + ((ulong)nis << 21); + thp->initial_slabs_start = sp; + } } } From c2927bb197a92cabe6433385e6e19f122c9d4ff9 Mon Sep 17 00:00:00 2001 From: Honglei Huang Date: Fri, 14 Nov 2025 09:50:48 +0800 Subject: [PATCH 2/2] Add slab alignment validation in obtain_new_slab The obtain_new_slab function retrieves 2MB slabs from either the pre-allocated pool or via dynamic allocation through devmem_request. However, it did not validate that returned addresses are 2MB aligned. Since __ockl_dm_dealloc uses address masking (addr & ~0x1fffffUL) to locate slab metadata, misaligned slabs cause incorrect address calculations, leading to reading garbage metadata and GPU page faults. This patch adds alignment validation for both pre-allocated and dynamically allocated slabs. If a slab is misaligned, the function releases it (for dynamic allocations) and returns 0 to fail safely rather than causing silent memory corruption. Signed-off-by: Honglei Huang --- amd/device-libs/ockl/src/dm.cl | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/amd/device-libs/ockl/src/dm.cl b/amd/device-libs/ockl/src/dm.cl index 6d9c23abeade1..8aed1bf960138 100644 --- a/amd/device-libs/ockl/src/dm.cl +++ b/amd/device-libs/ockl/src/dm.cl @@ -578,10 +578,29 @@ obtain_new_slab(__global heap_t *hp) ulong se = hp->initial_slabs_end; if (is < se) { is = AFA(&hp->initial_slabs, 1UL << 21, memory_order_relaxed); - if (is < se) + if (is < se) { + // Verify 2MB alignment for pre-allocated slabs + // This is critical because __ockl_dm_dealloc relies on address masking + // to find the slab base address: addr & ~0x1fffffUL + if ((is & 0x1fffffUL) != 0) { + // Fatal error: pre-allocated slab not 2MB aligned + // This will cause memory corruption in dealloc + return 0; + } return is; + } } ulong ret = __ockl_devmem_request(0, 1UL << 21); + + // Verify 2MB alignment for dynamically allocated slabs + // The hostcall implementation must guarantee this alignment + if (ret && (ret & 0x1fffffUL) != 0) { + // Fatal error: dynamically allocated slab not 2MB aligned + // Release the misaligned memory and return failure + __ockl_devmem_request(ret, 0); + return 0; + } + return ret; }