fix: add check for SVM allocated host ptr in clCreateBuffer

Related-To: NEO-13988

Signed-off-by: Alicja Lukaszewicz <alicja.lukaszewicz@intel.com>
This commit is contained in:
Alicja Lukaszewicz 2025-02-14 16:50:28 +00:00 committed by Compute-Runtime-Automation
parent c2387954e9
commit 52ac3d8cf0
2 changed files with 77 additions and 1 deletions

View File

@ -144,6 +144,21 @@ cl_mem Buffer::validateInputAndCreateBuffer(cl_context context,
return nullptr; return nullptr;
} }
if (expectHostPtr) {
auto svmAlloc = pContext->getSVMAllocsManager()->getSVMAlloc(hostPtr);
if (svmAlloc) {
auto rootDeviceIndex = pDevice->getRootDeviceIndex();
auto allocationEndAddress = svmAlloc->gpuAllocations.getGraphicsAllocation(rootDeviceIndex)->getGpuAddress() + svmAlloc->size;
auto bufferEndAddress = castToUint64(hostPtr) + size;
if ((size > svmAlloc->size) || (bufferEndAddress > allocationEndAddress)) {
retVal = CL_INVALID_BUFFER_SIZE;
return nullptr;
}
}
}
// create the buffer // create the buffer
Buffer *pBuffer = nullptr; Buffer *pBuffer = nullptr;

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (C) 2018-2024 Intel Corporation * Copyright (C) 2018-2025 Intel Corporation
* *
* SPDX-License-Identifier: MIT * SPDX-License-Identifier: MIT
* *
@ -284,6 +284,67 @@ TEST_F(ClCreateBufferTests, GivenBufferSizeOverMaxMemAllocSizeWhenCreateBufferWi
EXPECT_EQ(nullptr, buffer); EXPECT_EQ(nullptr, buffer);
} }
TEST_F(ClCreateBufferTests, GivenValidHostPointerAndSizeOverSVMAllocSizeWhenCreatingBufferThenInvalidBufferSizeErrorIsReturned) {
const ClDeviceInfo &devInfo = pDevice->getDeviceInfo();
if (devInfo.svmCapabilities != 0) {
size_t size = 10;
const cl_mem_flags flags[] = {CL_MEM_USE_HOST_PTR, CL_MEM_COPY_HOST_PTR};
cl_char *data = static_cast<cl_char *>(clSVMAlloc(pContext, CL_MEM_READ_WRITE, size, 0));
for (const auto &flag : flags) {
cl_mem buffer = clCreateBuffer(pContext, flag, 2 * size, data, &retVal);
EXPECT_EQ(CL_INVALID_BUFFER_SIZE, retVal);
EXPECT_EQ(nullptr, buffer);
}
clSVMFree(pContext, data);
}
}
TEST_F(ClCreateBufferTests, GivenValidHostPointerAndSizeWithinSVMAllocSizeWhenCreatingBufferThenSuccessIsReturned) {
const ClDeviceInfo &devInfo = pDevice->getDeviceInfo();
if (devInfo.svmCapabilities != 0) {
size_t size = 10;
const cl_mem_flags flags[] = {CL_MEM_USE_HOST_PTR, CL_MEM_COPY_HOST_PTR};
cl_char *data = static_cast<cl_char *>(clSVMAlloc(pContext, CL_MEM_READ_WRITE, size, 0));
for (const auto &flag : flags) {
cl_mem buffer = clCreateBuffer(pContext, flag, size, data, &retVal);
EXPECT_EQ(CL_SUCCESS, retVal);
EXPECT_NE(nullptr, buffer);
retVal = clReleaseMemObject(buffer);
EXPECT_EQ(CL_SUCCESS, retVal);
}
clSVMFree(pContext, data);
}
}
TEST_F(ClCreateBufferTests, GivenValidHostPointerAndSVMAllocWhenOffsetAndSizeReachOutOfBoundWhenCreatingBufferThenInvalidBufferSizeIsReturned) {
const ClDeviceInfo &devInfo = pDevice->getDeviceInfo();
if (devInfo.svmCapabilities != 0) {
size_t size = 1024;
size_t offset = 1020;
const cl_mem_flags flags[] = {CL_MEM_USE_HOST_PTR, CL_MEM_COPY_HOST_PTR};
cl_char *data = static_cast<cl_char *>(clSVMAlloc(pContext, CL_MEM_READ_WRITE, size, 0));
for (const auto &flag : flags) {
cl_mem buffer = clCreateBuffer(pContext, flag, size, (cl_char *)(data + offset), &retVal);
EXPECT_EQ(CL_INVALID_BUFFER_SIZE, retVal);
EXPECT_EQ(nullptr, buffer);
}
clSVMFree(pContext, data);
}
}
TEST_F(ClCreateBufferTests, GivenBufferSizeOverMaxMemAllocSizeAndClMemAllowUnrestirctedSizeFlagWhenCreatingBufferThenClSuccessIsReturned) { TEST_F(ClCreateBufferTests, GivenBufferSizeOverMaxMemAllocSizeAndClMemAllowUnrestirctedSizeFlagWhenCreatingBufferThenClSuccessIsReturned) {
auto pDevice = pContext->getDevice(0); auto pDevice = pContext->getDevice(0);
uint64_t bigSize = MemoryConstants::gigaByte * 5; uint64_t bigSize = MemoryConstants::gigaByte * 5;