diff --git a/opencl/source/sharings/d3d/d3d_texture.cpp b/opencl/source/sharings/d3d/d3d_texture.cpp index 9dcfb9bda9..dbbce2940c 100644 --- a/opencl/source/sharings/d3d/d3d_texture.cpp +++ b/opencl/source/sharings/d3d/d3d_texture.cpp @@ -69,7 +69,12 @@ Image *D3DTexture::create2d(Context *context, D3DTexture2d *d3dTexture, cl_ if (textureDesc.MiscFlags & D3DResourceFlags::MISC_SHARED_NTHANDLE) { sharingFcns->getSharedNTHandle(textureStaging, &sharedHandle); - alloc = memoryManager->createGraphicsAllocationFromNTHandle(sharedHandle, rootDeviceIndex); + if (memoryManager->verifyHandle(toOsHandle(sharedHandle), rootDeviceIndex, true)) { + alloc = memoryManager->createGraphicsAllocationFromNTHandle(sharedHandle, rootDeviceIndex); + } else { + err.set(CL_INVALID_D3D11_RESOURCE_KHR); + return nullptr; + } } else { sharingFcns->getSharedHandle(textureStaging, &sharedHandle); AllocationProperties allocProperties(rootDeviceIndex, @@ -78,9 +83,17 @@ Image *D3DTexture::create2d(Context *context, D3DTexture2d *d3dTexture, cl_ GraphicsAllocation::AllocationType::SHARED_IMAGE, false, // isMultiStorageAllocation context->getDeviceBitfieldForAllocation()); - alloc = memoryManager->createGraphicsAllocationFromSharedHandle(toOsHandle(sharedHandle), allocProperties, false); + if (memoryManager->verifyHandle(toOsHandle(sharedHandle), rootDeviceIndex, false)) { + alloc = memoryManager->createGraphicsAllocationFromSharedHandle(toOsHandle(sharedHandle), allocProperties, false); + } else { + err.set(CL_INVALID_D3D11_RESOURCE_KHR); + return nullptr; + } + } + if (alloc == nullptr) { + err.set(CL_OUT_OF_HOST_MEMORY); + return nullptr; } - DEBUG_BREAK_IF(!alloc); updateImgInfoAndDesc(alloc->getDefaultGmm(), imgInfo, imagePlane, arrayIndex); @@ -141,7 +154,12 @@ Image *D3DTexture::create3d(Context *context, D3DTexture3d *d3dTexture, cl_ if (textureDesc.MiscFlags & D3DResourceFlags::MISC_SHARED_NTHANDLE) { sharingFcns->getSharedNTHandle(textureStaging, &sharedHandle); - alloc = memoryManager->createGraphicsAllocationFromNTHandle(sharedHandle, rootDeviceIndex); + if (memoryManager->verifyHandle(toOsHandle(sharedHandle), rootDeviceIndex, true)) { + alloc = memoryManager->createGraphicsAllocationFromNTHandle(sharedHandle, rootDeviceIndex); + } else { + err.set(CL_INVALID_D3D11_RESOURCE_KHR); + return nullptr; + } } else { sharingFcns->getSharedHandle(textureStaging, &sharedHandle); AllocationProperties allocProperties(rootDeviceIndex, @@ -150,9 +168,17 @@ Image *D3DTexture::create3d(Context *context, D3DTexture3d *d3dTexture, cl_ GraphicsAllocation::AllocationType::SHARED_IMAGE, false, // isMultiStorageAllocation context->getDeviceBitfieldForAllocation()); - alloc = memoryManager->createGraphicsAllocationFromSharedHandle(toOsHandle(sharedHandle), allocProperties, false); + if (memoryManager->verifyHandle(toOsHandle(sharedHandle), rootDeviceIndex, false)) { + alloc = memoryManager->createGraphicsAllocationFromSharedHandle(toOsHandle(sharedHandle), allocProperties, false); + } else { + err.set(CL_INVALID_D3D11_RESOURCE_KHR); + return nullptr; + } + } + if (alloc == nullptr) { + err.set(CL_OUT_OF_HOST_MEMORY); + return nullptr; } - DEBUG_BREAK_IF(!alloc); updateImgInfoAndDesc(alloc->getDefaultGmm(), imgInfo, ImagePlane::NO_PLANE, 0u); diff --git a/opencl/test/unit_test/command_queue/command_queue_hw_tests.cpp b/opencl/test/unit_test/command_queue/command_queue_hw_tests.cpp index 04eccb2083..7325f403a1 100644 --- a/opencl/test/unit_test/command_queue/command_queue_hw_tests.cpp +++ b/opencl/test/unit_test/command_queue/command_queue_hw_tests.cpp @@ -957,8 +957,8 @@ HWTEST_F(CommandQueueHwTest, givenEventWithRecordedCommandWhenSubmitCommandIsCal EXPECT_EQ(CompletionStamp::notReady, neoEvent.peekTaskCount()); std::thread t([&]() { - while (!go) - ; + while (!go) { + } neoEvent.updateTaskCount(77u, 0); }); diff --git a/opencl/test/unit_test/d3d_sharing/d3d_tests_part1.cpp b/opencl/test/unit_test/d3d_sharing/d3d_tests_part1.cpp index 4980a6da2a..5a0896d99f 100644 --- a/opencl/test/unit_test/d3d_sharing/d3d_tests_part1.cpp +++ b/opencl/test/unit_test/d3d_sharing/d3d_tests_part1.cpp @@ -156,6 +156,62 @@ TYPED_TEST_P(D3DTests, givenNV12FormatAndEvenPlaneWhen2dCreatedThenSetPlaneParam EXPECT_EQ(2u, mockGmmResInfo->arrayIndexPassedToGetOffset); } +TYPED_TEST_P(D3DTests, givenSharedObjectFromInvalidContextWhen2dCreatedThenReturnCorrectCode) { + this->mockSharingFcns->mockTexture2dDesc.Format = DXGI_FORMAT_NV12; + this->mockSharingFcns->mockTexture2dDesc.MiscFlags = D3DResourceFlags::MISC_SHARED; + EXPECT_CALL(*this->mockSharingFcns, getTexture2dDesc(_, _)) + .Times(1) + .WillOnce(SetArgPointee<0>(this->mockSharingFcns->mockTexture2dDesc)); + cl_int retCode = 0; + mockMM.get()->verifyValue = false; + auto image = std::unique_ptr(D3DTexture::create2d(this->context, reinterpret_cast(&this->dummyD3DTexture), CL_MEM_READ_WRITE, 4, &retCode)); + mockMM.get()->verifyValue = true; + EXPECT_EQ(nullptr, image.get()); + EXPECT_EQ(retCode, CL_INVALID_D3D11_RESOURCE_KHR); +} + +TYPED_TEST_P(D3DTests, givenSharedObjectFromInvalidContextAndNTHandleWhen2dCreatedThenReturnCorrectCode) { + this->mockSharingFcns->mockTexture2dDesc.Format = DXGI_FORMAT_NV12; + this->mockSharingFcns->mockTexture2dDesc.MiscFlags = D3DResourceFlags::MISC_SHARED_NTHANDLE; + EXPECT_CALL(*this->mockSharingFcns, getTexture2dDesc(_, _)) + .Times(1) + .WillOnce(SetArgPointee<0>(this->mockSharingFcns->mockTexture2dDesc)); + cl_int retCode = 0; + mockMM.get()->verifyValue = false; + auto image = std::unique_ptr(D3DTexture::create2d(this->context, reinterpret_cast(&this->dummyD3DTexture), CL_MEM_READ_WRITE, 4, &retCode)); + mockMM.get()->verifyValue = true; + EXPECT_EQ(nullptr, image.get()); + EXPECT_EQ(retCode, CL_INVALID_D3D11_RESOURCE_KHR); +} + +TYPED_TEST_P(D3DTests, givenSharedObjectAndAlocationFailedWhen2dCreatedThenReturnCorrectCode) { + this->mockSharingFcns->mockTexture2dDesc.Format = DXGI_FORMAT_NV12; + this->mockSharingFcns->mockTexture2dDesc.MiscFlags = D3DResourceFlags::MISC_SHARED; + EXPECT_CALL(*this->mockSharingFcns, getTexture2dDesc(_, _)) + .Times(1) + .WillOnce(SetArgPointee<0>(this->mockSharingFcns->mockTexture2dDesc)); + cl_int retCode = 0; + mockMM.get()->failAlloc = true; + auto image = std::unique_ptr(D3DTexture::create2d(this->context, reinterpret_cast(&this->dummyD3DTexture), CL_MEM_READ_WRITE, 4, &retCode)); + mockMM.get()->failAlloc = false; + EXPECT_EQ(nullptr, image.get()); + EXPECT_EQ(retCode, CL_OUT_OF_HOST_MEMORY); +} + +TYPED_TEST_P(D3DTests, givenSharedObjectAndNTHandleAndAllocationFailedWhen2dCreatedThenReturnCorrectCode) { + this->mockSharingFcns->mockTexture2dDesc.Format = DXGI_FORMAT_NV12; + this->mockSharingFcns->mockTexture2dDesc.MiscFlags = D3DResourceFlags::MISC_SHARED_NTHANDLE; + EXPECT_CALL(*this->mockSharingFcns, getTexture2dDesc(_, _)) + .Times(1) + .WillOnce(SetArgPointee<0>(this->mockSharingFcns->mockTexture2dDesc)); + cl_int retCode = 0; + mockMM.get()->failAlloc = true; + auto image = std::unique_ptr(D3DTexture::create2d(this->context, reinterpret_cast(&this->dummyD3DTexture), CL_MEM_READ_WRITE, 4, &retCode)); + mockMM.get()->failAlloc = false; + EXPECT_EQ(nullptr, image.get()); + EXPECT_EQ(retCode, CL_OUT_OF_HOST_MEMORY); +} + TYPED_TEST_P(D3DTests, givenNV12FormatAndOddPlaneWhen2dCreatedThenSetPlaneParams) { this->mockSharingFcns->mockTexture2dDesc.Format = DXGI_FORMAT_NV12; EXPECT_CALL(*this->mockSharingFcns, getTexture2dDesc(_, _)) @@ -692,6 +748,10 @@ REGISTER_TYPED_TEST_CASE_P(D3DTests, givenWriteOnlyFormatWhenLookingForSurfaceFormatThenReturnValidFormat, givenReadWriteFormatWhenLookingForSurfaceFormatThenReturnValidFormat, givenNV12FormatAndEvenPlaneWhen2dCreatedThenSetPlaneParams, + givenSharedObjectFromInvalidContextWhen2dCreatedThenReturnCorrectCode, + givenSharedObjectFromInvalidContextAndNTHandleWhen2dCreatedThenReturnCorrectCode, + givenSharedObjectAndAlocationFailedWhen2dCreatedThenReturnCorrectCode, + givenSharedObjectAndNTHandleAndAllocationFailedWhen2dCreatedThenReturnCorrectCode, givenP010FormatAndEvenPlaneWhen2dCreatedThenSetPlaneParams, givenP016FormatAndEvenPlaneWhen2dCreatedThenSetPlaneParams, givenNV12FormatAndOddPlaneWhen2dCreatedThenSetPlaneParams, diff --git a/opencl/test/unit_test/d3d_sharing/d3d_tests_part2.cpp b/opencl/test/unit_test/d3d_sharing/d3d_tests_part2.cpp index 7fca935cc9..0bfca93188 100644 --- a/opencl/test/unit_test/d3d_sharing/d3d_tests_part2.cpp +++ b/opencl/test/unit_test/d3d_sharing/d3d_tests_part2.cpp @@ -462,6 +462,78 @@ TYPED_TEST_P(D3DTests, givenD3DTexture3dWhenOclImageIsCreatedThenSharedImageAllo EXPECT_EQ(GraphicsAllocation::AllocationType::SHARED_IMAGE, image->getGraphicsAllocation(rootDeviceIndex)->getAllocationType()); } +TYPED_TEST_P(D3DTests, givenSharedObjectFromInvalidContextWhen3dCreatedThenReturnCorrectCode) { + this->mockSharingFcns->mockTexture3dDesc.MiscFlags = D3DResourceFlags::MISC_SHARED; + + EXPECT_CALL(*this->mockSharingFcns, getTexture3dDesc(_, _)) + .Times(1) + .WillOnce(SetArgPointee<0>(this->mockSharingFcns->mockTexture3dDesc)); + EXPECT_CALL(*this->mockSharingFcns, createTexture3d(_, _, _)) + .Times(1) + .WillOnce(SetArgPointee<0>(reinterpret_cast(&this->dummyD3DTextureStaging))); + + cl_int retCode = 0; + mockMM.get()->verifyValue = false; + auto image = std::unique_ptr(D3DTexture::create3d(this->context, reinterpret_cast(&this->dummyD3DTexture), CL_MEM_READ_WRITE, 1, &retCode)); + mockMM.get()->verifyValue = true; + EXPECT_EQ(nullptr, image.get()); + EXPECT_EQ(retCode, CL_INVALID_D3D11_RESOURCE_KHR); +} + +TYPED_TEST_P(D3DTests, givenSharedObjectFromInvalidContextAndNTHandleWhen3dCreatedThenReturnCorrectCode) { + this->mockSharingFcns->mockTexture3dDesc.MiscFlags = D3DResourceFlags::MISC_SHARED_NTHANDLE; + + EXPECT_CALL(*this->mockSharingFcns, getTexture3dDesc(_, _)) + .Times(1) + .WillOnce(SetArgPointee<0>(this->mockSharingFcns->mockTexture3dDesc)); + EXPECT_CALL(*this->mockSharingFcns, createTexture3d(_, _, _)) + .Times(1) + .WillOnce(SetArgPointee<0>(reinterpret_cast(&this->dummyD3DTextureStaging))); + + cl_int retCode = 0; + mockMM.get()->verifyValue = false; + auto image = std::unique_ptr(D3DTexture::create3d(this->context, reinterpret_cast(&this->dummyD3DTexture), CL_MEM_READ_WRITE, 1, &retCode)); + mockMM.get()->verifyValue = true; + EXPECT_EQ(nullptr, image.get()); + EXPECT_EQ(retCode, CL_INVALID_D3D11_RESOURCE_KHR); +} + +TYPED_TEST_P(D3DTests, givenSharedObjectAndAlocationFailedWhen3dCreatedThenReturnCorrectCode) { + this->mockSharingFcns->mockTexture3dDesc.MiscFlags = D3DResourceFlags::MISC_SHARED; + + EXPECT_CALL(*this->mockSharingFcns, getTexture3dDesc(_, _)) + .Times(1) + .WillOnce(SetArgPointee<0>(this->mockSharingFcns->mockTexture3dDesc)); + EXPECT_CALL(*this->mockSharingFcns, createTexture3d(_, _, _)) + .Times(1) + .WillOnce(SetArgPointee<0>(reinterpret_cast(&this->dummyD3DTextureStaging))); + + cl_int retCode = 0; + mockMM.get()->failAlloc = true; + auto image = std::unique_ptr(D3DTexture::create3d(this->context, reinterpret_cast(&this->dummyD3DTexture), CL_MEM_READ_WRITE, 1, &retCode)); + mockMM.get()->failAlloc = false; + EXPECT_EQ(nullptr, image.get()); + EXPECT_EQ(retCode, CL_OUT_OF_HOST_MEMORY); +} + +TYPED_TEST_P(D3DTests, givenSharedObjectAndNTHandleAndAllocationFailedWhen3dCreatedThenReturnCorrectCode) { + this->mockSharingFcns->mockTexture3dDesc.MiscFlags = D3DResourceFlags::MISC_SHARED_NTHANDLE; + + EXPECT_CALL(*this->mockSharingFcns, getTexture3dDesc(_, _)) + .Times(1) + .WillOnce(SetArgPointee<0>(this->mockSharingFcns->mockTexture3dDesc)); + EXPECT_CALL(*this->mockSharingFcns, createTexture3d(_, _, _)) + .Times(1) + .WillOnce(SetArgPointee<0>(reinterpret_cast(&this->dummyD3DTextureStaging))); + + cl_int retCode = 0; + mockMM.get()->failAlloc = true; + auto image = std::unique_ptr(D3DTexture::create3d(this->context, reinterpret_cast(&this->dummyD3DTexture), CL_MEM_READ_WRITE, 1, &retCode)); + mockMM.get()->failAlloc = false; + EXPECT_EQ(nullptr, image.get()); + EXPECT_EQ(retCode, CL_OUT_OF_HOST_MEMORY); +} + REGISTER_TYPED_TEST_CASE_P(D3DTests, givenSharedResourceBufferAndInteropUserSyncEnabledWhenReleaseIsCalledThenDontDoExplicitFinish, givenNonSharedResourceBufferAndInteropUserSyncDisabledWhenReleaseIsCalledThenDoExplicitFinishTwice, @@ -480,7 +552,11 @@ REGISTER_TYPED_TEST_CASE_P(D3DTests, givenPlaneWhenFindYuvSurfaceCalledThenReturnValidImgFormat, GivenForced32BitAddressingWhenCreatingBufferThenBufferHas32BitAllocation, givenD3DTexture2dWhenOclImageIsCreatedThenSharedImageAllocationTypeIsSet, - givenD3DTexture3dWhenOclImageIsCreatedThenSharedImageAllocationTypeIsSet); + givenD3DTexture3dWhenOclImageIsCreatedThenSharedImageAllocationTypeIsSet, + givenSharedObjectFromInvalidContextWhen3dCreatedThenReturnCorrectCode, + givenSharedObjectFromInvalidContextAndNTHandleWhen3dCreatedThenReturnCorrectCode, + givenSharedObjectAndAlocationFailedWhen3dCreatedThenReturnCorrectCode, + givenSharedObjectAndNTHandleAndAllocationFailedWhen3dCreatedThenReturnCorrectCode); INSTANTIATE_TYPED_TEST_CASE_P(D3DSharingTests, D3DTests, D3DTypes); diff --git a/opencl/test/unit_test/fixtures/d3d_test_fixture.h b/opencl/test/unit_test/fixtures/d3d_test_fixture.h index e0df20ade3..373c812a2e 100644 --- a/opencl/test/unit_test/fixtures/d3d_test_fixture.h +++ b/opencl/test/unit_test/fixtures/d3d_test_fixture.h @@ -45,19 +45,30 @@ class D3DTests : public PlatformFixture, public ::testing::Test { class MockMM : public OsAgnosticMemoryManager { public: using OsAgnosticMemoryManager::OsAgnosticMemoryManager; + bool failAlloc = false; GraphicsAllocation *createGraphicsAllocationFromSharedHandle(osHandle handle, const AllocationProperties &properties, bool requireSpecificBitness) override { + if (failAlloc) { + return nullptr; + } auto alloc = OsAgnosticMemoryManager::createGraphicsAllocationFromSharedHandle(handle, properties, requireSpecificBitness); alloc->setDefaultGmm(forceGmm); gmmOwnershipPassed = true; return alloc; } GraphicsAllocation *createGraphicsAllocationFromNTHandle(void *handle, uint32_t rootDeviceIndex) override { + if (failAlloc) { + return nullptr; + } AllocationProperties properties(rootDeviceIndex, true, 0, GraphicsAllocation::AllocationType::INTERNAL_HOST_MEMORY, false, false, 0); auto alloc = OsAgnosticMemoryManager::createGraphicsAllocationFromSharedHandle(toOsHandle(handle), properties, false); alloc->setDefaultGmm(forceGmm); gmmOwnershipPassed = true; return alloc; } + + bool verifyValue = true; + bool verifyHandle(osHandle handle, uint32_t rootDeviceIndex, bool) { return verifyValue; } + bool mapAuxGpuVA(GraphicsAllocation *graphicsAllocation) override { mapAuxGpuVACalled++; return mapAuxGpuVaRetValue; diff --git a/opencl/test/unit_test/memory_manager/memory_manager_tests.cpp b/opencl/test/unit_test/memory_manager/memory_manager_tests.cpp index b5fac5b045..a761e880ef 100644 --- a/opencl/test/unit_test/memory_manager/memory_manager_tests.cpp +++ b/opencl/test/unit_test/memory_manager/memory_manager_tests.cpp @@ -1302,6 +1302,13 @@ TEST(OsAgnosticMemoryManager, givenOsAgnosticMemoryManagerWhenGpuAddressIsReserv memoryManager.freeGpuAddress(addressRange, 0); } +TEST(OsAgnosticMemoryManager, givenOsAgnosticMemoryManagerWhenVerifyHandleThenReturnTrue) { + MockExecutionEnvironment executionEnvironment; + OsAgnosticMemoryManager memoryManager(executionEnvironment); + osHandle testOSHandle = 1; + EXPECT_TRUE(memoryManager.verifyHandle(testOSHandle, 0, 0)); +} + TEST(OsAgnosticMemoryManager, givenMemoryManagerWhenGpuAddressIsSetThenAllocationWithSpecifiedGpuAddressInSystemMemoryIsCreated) { MockExecutionEnvironment executionEnvironment(defaultHwInfo.get()); auto memoryManager = new OsAgnosticMemoryManager(executionEnvironment); diff --git a/opencl/test/unit_test/mocks/mock_wddm.h b/opencl/test/unit_test/mocks/mock_wddm.h index 75362eafce..a9b49467a0 100644 --- a/opencl/test/unit_test/mocks/mock_wddm.h +++ b/opencl/test/unit_test/mocks/mock_wddm.h @@ -98,6 +98,17 @@ class WddmMock : public Wddm { } } + uint32_t counterVerifyNTHandle = 0; + uint32_t counterVerifySharedHandle = 0; + bool verifyNTHandle(HANDLE handle) override { + ++counterVerifyNTHandle; + return Wddm::verifyNTHandle(handle); + } + bool verifySharedHandle(D3DKMT_HANDLE osHandle) override { + ++counterVerifySharedHandle; + return Wddm::verifySharedHandle(osHandle); + } + void resetGdi(Gdi *gdi); WddmMockHelpers::MakeResidentCall makeResidentResult; diff --git a/opencl/test/unit_test/os_interface/windows/wddm_memory_manager_tests.cpp b/opencl/test/unit_test/os_interface/windows/wddm_memory_manager_tests.cpp index bce7fbbfbd..307145b9ba 100644 --- a/opencl/test/unit_test/os_interface/windows/wddm_memory_manager_tests.cpp +++ b/opencl/test/unit_test/os_interface/windows/wddm_memory_manager_tests.cpp @@ -1419,6 +1419,24 @@ TEST_F(MockWddmMemoryManagerTest, givenValidateAllocationFunctionWhenItIsCalledW memoryManager.freeGraphicsMemory(wddmAlloc); } +TEST_F(MockWddmMemoryManagerTest, givenWddmMemoryManagerWhenVerifySharedHandleThenVerifySharedHandleIsCalled) { + wddm->init(); + MockWddmMemoryManager memoryManager(*executionEnvironment); + osHandle handle = 1; + memoryManager.verifyHandle(handle, 0, false); + EXPECT_EQ(0, wddm->counterVerifyNTHandle); + EXPECT_EQ(1, wddm->counterVerifySharedHandle); +} + +TEST_F(MockWddmMemoryManagerTest, givenWddmMemoryManagerWhenVerifyNTHandleThenVerifyNTHandleIsCalled) { + wddm->init(); + MockWddmMemoryManager memoryManager(*executionEnvironment); + osHandle handle = 1; + memoryManager.verifyHandle(handle, 0, true); + EXPECT_EQ(1, wddm->counterVerifyNTHandle); + EXPECT_EQ(0, wddm->counterVerifySharedHandle); +} + TEST_F(MockWddmMemoryManagerTest, givenEnabled64kbpagesWhenCreatingGraphicsMemoryForBufferWithoutHostPtrThen64kbAdressIsAllocated) { DebugManagerStateRestore dbgRestore; wddm->init(); diff --git a/shared/source/memory_manager/memory_manager.h b/shared/source/memory_manager/memory_manager.h index 62a9c38835..1800d8f748 100644 --- a/shared/source/memory_manager/memory_manager.h +++ b/shared/source/memory_manager/memory_manager.h @@ -75,6 +75,7 @@ class MemoryManager { MOCKABLE_VIRTUAL GraphicsAllocation *allocateGraphicsMemoryInPreferredPool(const AllocationProperties &properties, const void *hostPtr); + virtual bool verifyHandle(osHandle handle, uint32_t rootDeviceIndex, bool) { return true; } virtual GraphicsAllocation *createGraphicsAllocationFromSharedHandle(osHandle handle, const AllocationProperties &properties, bool requireSpecificBitness) = 0; virtual GraphicsAllocation *createGraphicsAllocationFromNTHandle(void *handle, uint32_t rootDeviceIndex) = 0; diff --git a/shared/source/os_interface/windows/wddm/wddm.cpp b/shared/source/os_interface/windows/wddm/wddm.cpp index 5171467f40..bdb4bdf483 100644 --- a/shared/source/os_interface/windows/wddm/wddm.cpp +++ b/shared/source/os_interface/windows/wddm/wddm.cpp @@ -604,6 +604,13 @@ bool Wddm::destroyAllocations(const D3DKMT_HANDLE *handles, uint32_t allocationC return status == STATUS_SUCCESS; } +bool Wddm::verifySharedHandle(D3DKMT_HANDLE osHandle) { + D3DKMT_QUERYRESOURCEINFO QueryResourceInfo = {0}; + QueryResourceInfo.hDevice = device; + QueryResourceInfo.hGlobalShare = osHandle; + auto status = getGdi()->queryResourceInfo(&QueryResourceInfo); + return status == STATUS_SUCCESS; +} bool Wddm::openSharedHandle(D3DKMT_HANDLE handle, WddmAllocation *alloc) { D3DKMT_QUERYRESOURCEINFO QueryResourceInfo = {0}; @@ -646,6 +653,14 @@ bool Wddm::openSharedHandle(D3DKMT_HANDLE handle, WddmAllocation *alloc) { return true; } +bool Wddm::verifyNTHandle(HANDLE handle) { + D3DKMT_QUERYRESOURCEINFOFROMNTHANDLE queryResourceInfoFromNtHandle = {}; + queryResourceInfoFromNtHandle.hDevice = device; + queryResourceInfoFromNtHandle.hNtHandle = handle; + auto status = getGdi()->queryResourceInfoFromNtHandle(&queryResourceInfoFromNtHandle); + return status == STATUS_SUCCESS; +} + bool Wddm::openNTHandle(HANDLE handle, WddmAllocation *alloc) { D3DKMT_QUERYRESOURCEINFOFROMNTHANDLE queryResourceInfoFromNtHandle = {}; queryResourceInfoFromNtHandle.hDevice = device; diff --git a/shared/source/os_interface/windows/wddm/wddm.h b/shared/source/os_interface/windows/wddm/wddm.h index a3cda0420d..7fee96f744 100644 --- a/shared/source/os_interface/windows/wddm/wddm.h +++ b/shared/source/os_interface/windows/wddm/wddm.h @@ -66,7 +66,9 @@ class Wddm { MOCKABLE_VIRTUAL bool createAllocation64k(const Gmm *gmm, D3DKMT_HANDLE &outHandle); MOCKABLE_VIRTUAL NTSTATUS createAllocationsAndMapGpuVa(OsHandleStorage &osHandles); MOCKABLE_VIRTUAL bool destroyAllocations(const D3DKMT_HANDLE *handles, uint32_t allocationCount, D3DKMT_HANDLE resourceHandle); + MOCKABLE_VIRTUAL bool verifySharedHandle(D3DKMT_HANDLE osHandle); MOCKABLE_VIRTUAL bool openSharedHandle(D3DKMT_HANDLE handle, WddmAllocation *alloc); + MOCKABLE_VIRTUAL bool verifyNTHandle(HANDLE handle); bool openNTHandle(HANDLE handle, WddmAllocation *alloc); MOCKABLE_VIRTUAL void *lockResource(const D3DKMT_HANDLE &handle, bool applyMakeResidentPriorToLock, size_t size); MOCKABLE_VIRTUAL void unlockResource(const D3DKMT_HANDLE &handle); diff --git a/shared/source/os_interface/windows/wddm_memory_manager.cpp b/shared/source/os_interface/windows/wddm_memory_manager.cpp index 52ee4b173e..9924567274 100644 --- a/shared/source/os_interface/windows/wddm_memory_manager.cpp +++ b/shared/source/os_interface/windows/wddm_memory_manager.cpp @@ -292,6 +292,12 @@ GraphicsAllocation *WddmMemoryManager::allocate32BitGraphicsMemoryImpl(const All return wddmAllocation.release(); } +bool WddmMemoryManager::verifyHandle(osHandle handle, uint32_t rootDeviceIndex, bool ntHandle) { + bool status = ntHandle ? getWddm(rootDeviceIndex).verifyNTHandle(reinterpret_cast(static_cast(handle))) + : getWddm(rootDeviceIndex).verifySharedHandle(handle); + return status; +} + GraphicsAllocation *WddmMemoryManager::createAllocationFromHandle(osHandle handle, bool requireSpecificBitness, bool ntHandle, GraphicsAllocation::AllocationType allocationType, uint32_t rootDeviceIndex) { auto allocation = std::make_unique(rootDeviceIndex, allocationType, nullptr, 0, handle, MemoryPool::SystemCpuInaccessible); diff --git a/shared/source/os_interface/windows/wddm_memory_manager.h b/shared/source/os_interface/windows/wddm_memory_manager.h index 2308f3eafd..4c897b9a68 100644 --- a/shared/source/os_interface/windows/wddm_memory_manager.h +++ b/shared/source/os_interface/windows/wddm_memory_manager.h @@ -63,6 +63,7 @@ class WddmMemoryManager : public MemoryManager { AddressRange reserveGpuAddress(size_t size, uint32_t rootDeviceIndex) override { return AddressRange{0, 0}; }; void freeGpuAddress(AddressRange addressRange, uint32_t rootDeviceIndex) override{}; + bool verifyHandle(osHandle handle, uint32_t rootDeviceIndex, bool ntHandle) override; protected: GraphicsAllocation *createGraphicsAllocation(OsHandleStorage &handleStorage, const AllocationData &allocationData) override; diff --git a/shared/test/unit_test/os_interface/windows/wddm_tests.cpp b/shared/test/unit_test/os_interface/windows/wddm_tests.cpp index d59705df04..fce4894944 100644 --- a/shared/test/unit_test/os_interface/windows/wddm_tests.cpp +++ b/shared/test/unit_test/os_interface/windows/wddm_tests.cpp @@ -39,4 +39,29 @@ TEST_F(WddmTests, whenInitializingWddmThenSetMinAddressToCorrectValue) { ASSERT_EQ(expectedMinAddress, wddm->getWddmMinAddress()); } +TEST_F(WddmTests, givenWddmWhenPassesCorrectHandleToVerifySharedHandleThenReturnTrue) { + init(); + D3DKMT_HANDLE handle = 1u; + EXPECT_TRUE(wddm->verifySharedHandle(handle)); +} + +TEST_F(WddmTests, givenWddmWhenPassesIncorrectHandleToVerifySharedHandleThenReturnFalse) { + init(); + D3DKMT_HANDLE handle = 0u; + EXPECT_FALSE(wddm->verifySharedHandle(handle)); +} + +TEST_F(WddmTests, givenWddmWhenPassesCorrectHandleToVerifyNTHandleThenReturnTrue) { + init(); + uint32_t temp = 0; + HANDLE handle = &temp; + EXPECT_TRUE(wddm->verifyNTHandle(handle)); +} + +TEST_F(WddmTests, givenWddmWhenPassesIncorrectHandleToVerifyNTHandleThenReturnFalse) { + init(); + HANDLE handle = nullptr; + EXPECT_FALSE(wddm->verifyNTHandle(handle)); +} + } // namespace NEO