diff --git a/shared/source/os_interface/linux/ioctl_helper.h b/shared/source/os_interface/linux/ioctl_helper.h index ed628089ca..47a4632254 100644 --- a/shared/source/os_interface/linux/ioctl_helper.h +++ b/shared/source/os_interface/linux/ioctl_helper.h @@ -56,6 +56,16 @@ struct DistanceInfo { int32_t distance; }; +struct VmBindParams { + uint32_t vmId; + uint32_t handle; + uint64_t start; + uint64_t offset; + uint64_t length; + uint64_t flags; + uint64_t extensions; +}; + using MemRegionsVec = StackVec; class IoctlHelper { @@ -100,6 +110,8 @@ class IoctlHelper { virtual void fillVmBindExtSyncFence(const std::unique_ptr &vmBindExtSyncFence, uint64_t fenceAddress, uint64_t fenceValue, uint64_t nextExtension) = 0; virtual std::optional getCopyClassSaturatePCIECapability() = 0; virtual std::optional getCopyClassSaturateLinkCapability() = 0; + virtual int vmBind(Drm *drm, const VmBindParams &vmBindParams) = 0; + virtual int vmUnbind(Drm *drm, const VmBindParams &vmBindParams) = 0; }; class IoctlHelperUpstream : public IoctlHelper { @@ -139,6 +151,8 @@ class IoctlHelperUpstream : public IoctlHelper { void fillVmBindExtSyncFence(const std::unique_ptr &vmBindExtSyncFence, uint64_t fenceAddress, uint64_t fenceValue, uint64_t nextExtension) override; std::optional getCopyClassSaturatePCIECapability() override; std::optional getCopyClassSaturateLinkCapability() override; + int vmBind(Drm *drm, const VmBindParams &vmBindParams) override; + int vmUnbind(Drm *drm, const VmBindParams &vmBindParams) override; }; template @@ -193,6 +207,8 @@ class IoctlHelperPrelim20 : public IoctlHelper { void fillVmBindExtSyncFence(const std::unique_ptr &vmBindExtSyncFence, uint64_t fenceAddress, uint64_t fenceValue, uint64_t nextExtension) override; std::optional getCopyClassSaturatePCIECapability() override; std::optional getCopyClassSaturateLinkCapability() override; + int vmBind(Drm *drm, const VmBindParams &vmBindParams) override; + int vmUnbind(Drm *drm, const VmBindParams &vmBindParams) override; }; } // namespace NEO diff --git a/shared/source/os_interface/linux/ioctl_helper_prelim.cpp b/shared/source/os_interface/linux/ioctl_helper_prelim.cpp index 351b12801a..2520e823bb 100644 --- a/shared/source/os_interface/linux/ioctl_helper_prelim.cpp +++ b/shared/source/os_interface/linux/ioctl_helper_prelim.cpp @@ -426,4 +426,25 @@ std::optional IoctlHelperPrelim20::getCopyClassSaturateLinkCapability( return PRELIM_I915_COPY_CLASS_CAP_SATURATE_LINK; } +prelim_drm_i915_gem_vm_bind translateVmBindParamsToPrelimStruct(const VmBindParams &vmBindParams) { + prelim_drm_i915_gem_vm_bind vmBind{}; + vmBind.vm_id = vmBindParams.vmId; + vmBind.handle = vmBindParams.handle; + vmBind.start = vmBindParams.start; + vmBind.offset = vmBindParams.offset; + vmBind.length = vmBindParams.length; + vmBind.flags = vmBindParams.flags; + vmBind.extensions = vmBindParams.extensions; + return vmBind; +} + +int IoctlHelperPrelim20::vmBind(Drm *drm, const VmBindParams &vmBindParams) { + auto prelimVmBind = translateVmBindParamsToPrelimStruct(vmBindParams); + return IoctlHelper::ioctl(drm, PRELIM_DRM_IOCTL_I915_GEM_VM_BIND, &prelimVmBind); +} + +int IoctlHelperPrelim20::vmUnbind(Drm *drm, const VmBindParams &vmBindParams) { + auto prelimVmBind = translateVmBindParamsToPrelimStruct(vmBindParams); + return IoctlHelper::ioctl(drm, PRELIM_DRM_IOCTL_I915_GEM_VM_UNBIND, &prelimVmBind); +} } // namespace NEO diff --git a/shared/source/os_interface/linux/ioctl_helper_upstream.cpp b/shared/source/os_interface/linux/ioctl_helper_upstream.cpp index 6fb938d513..9dbbbd04ed 100644 --- a/shared/source/os_interface/linux/ioctl_helper_upstream.cpp +++ b/shared/source/os_interface/linux/ioctl_helper_upstream.cpp @@ -189,4 +189,10 @@ std::optional IoctlHelperUpstream::getCopyClassSaturateLinkCapability( return std::nullopt; } +int IoctlHelperUpstream::vmBind(Drm *drm, const VmBindParams &vmBindParams) { + return 0; +} +int IoctlHelperUpstream::vmUnbind(Drm *drm, const VmBindParams &vmBindParams) { + return 0; +} } // namespace NEO diff --git a/shared/test/common/libult/linux/drm_mock_prelim_context.cpp b/shared/test/common/libult/linux/drm_mock_prelim_context.cpp index 0b78f5af58..00e41f4ee5 100644 --- a/shared/test/common/libult/linux/drm_mock_prelim_context.cpp +++ b/shared/test/common/libult/linux/drm_mock_prelim_context.cpp @@ -78,6 +78,14 @@ int DrmMockPrelimContext::handlePrelimRequest(unsigned long request, void *arg) } allocNumWays += cacheReserveArg->num_ways; } break; + case PRELIM_DRM_IOCTL_I915_GEM_VM_BIND: { + vmBindCalled++; + return vmBindReturn; + } break; + case PRELIM_DRM_IOCTL_I915_GEM_VM_UNBIND: { + vmUnbindCalled++; + return vmUnbindReturn; + } break; default: return -1; diff --git a/shared/test/common/libult/linux/drm_mock_prelim_context.h b/shared/test/common/libult/linux/drm_mock_prelim_context.h index 66e4238dbd..afa553c60c 100644 --- a/shared/test/common/libult/linux/drm_mock_prelim_context.h +++ b/shared/test/common/libult/linux/drm_mock_prelim_context.h @@ -28,6 +28,12 @@ struct DrmMockPrelimContext { int vmBindQueryValue{0}; int vmBindQueryReturn{0}; + size_t vmBindCalled{0}; + int vmBindReturn{0}; + + size_t vmUnbindCalled{0}; + int vmUnbindReturn{0}; + int hasPageFaultQueryValue{0}; int hasPageFaultQueryReturn{0}; diff --git a/shared/test/unit_test/os_interface/linux/drm_with_prelim_tests.cpp b/shared/test/unit_test/os_interface/linux/drm_with_prelim_tests.cpp index 35eb8bfa92..8c3186738e 100644 --- a/shared/test/unit_test/os_interface/linux/drm_with_prelim_tests.cpp +++ b/shared/test/unit_test/os_interface/linux/drm_with_prelim_tests.cpp @@ -75,6 +75,38 @@ TEST(IoctlHelperPrelimTest, whenGettingVmBindAvailabilityThenProperValueIsReturn } } +TEST(IoctlHelperPrelimTest, whenVmBindIsCalledThenProperValueIsReturnedBasedOnIoctlResult) { + auto executionEnvironment = std::make_unique(); + DrmQueryMock drm{*executionEnvironment->rootDeviceEnvironments[0]}; + + IoctlHelperPrelim20 ioctlHelper{}; + + VmBindParams vmBindParams{}; + + for (auto &ioctlValue : {0, EINVAL}) { + drm.context.vmBindReturn = ioctlValue; + drm.context.vmBindCalled = 0u; + EXPECT_EQ(ioctlValue, ioctlHelper.vmBind(&drm, vmBindParams)); + EXPECT_EQ(1u, drm.context.vmBindCalled); + } +} + +TEST(IoctlHelperPrelimTest, whenVmUnbindIsCalledThenProperValueIsReturnedBasedOnIoctlResult) { + auto executionEnvironment = std::make_unique(); + DrmQueryMock drm{*executionEnvironment->rootDeviceEnvironments[0]}; + + IoctlHelperPrelim20 ioctlHelper{}; + + VmBindParams vmBindParams{}; + + for (auto &ioctlValue : {0, EINVAL}) { + drm.context.vmUnbindReturn = ioctlValue; + drm.context.vmUnbindCalled = 0u; + EXPECT_EQ(ioctlValue, ioctlHelper.vmUnbind(&drm, vmBindParams)); + EXPECT_EQ(1u, drm.context.vmUnbindCalled); + } +} + TEST_F(IoctlHelperPrelimFixture, givenPrelimsWhenCreateGemExtThenReturnSuccess) { auto ioctlHelper = drm->getIoctlHelper(); uint32_t handle = 0; diff --git a/shared/test/unit_test/os_interface/linux/ioctl_helper_tests_upstream.cpp b/shared/test/unit_test/os_interface/linux/ioctl_helper_tests_upstream.cpp index 03cc4a2c4d..1748553d59 100644 --- a/shared/test/unit_test/os_interface/linux/ioctl_helper_tests_upstream.cpp +++ b/shared/test/unit_test/os_interface/linux/ioctl_helper_tests_upstream.cpp @@ -272,3 +272,23 @@ TEST(IoctlHelperTestsUpstream, givenNullptrWhenFillVmBindSyncFenceThenNothingThr auto vmBindExtSyncFence = ioctlHelper.createVmBindExtSyncFence(); EXPECT_NO_THROW(ioctlHelper.fillVmBindExtSyncFence(vmBindExtSyncFence, 0u, 0u, 0u)); } + +TEST(IoctlHelperTestsUpstream, whenVmBindIsCalledThenZeroIsReturned) { + auto executionEnvironment = std::make_unique(); + auto drm = std::make_unique(*executionEnvironment->rootDeviceEnvironments[0]); + ASSERT_NE(nullptr, drm); + + VmBindParams vmBindParams{}; + IoctlHelperUpstream ioctlHelper{}; + EXPECT_EQ(0, ioctlHelper.vmBind(drm.get(), vmBindParams)); +} + +TEST(IoctlHelperTestsUpstream, whenVmUnbindIsCalledThenZeroIsReturned) { + auto executionEnvironment = std::make_unique(); + auto drm = std::make_unique(*executionEnvironment->rootDeviceEnvironments[0]); + ASSERT_NE(nullptr, drm); + + IoctlHelperUpstream ioctlHelper{}; + VmBindParams vmBindParams{}; + EXPECT_EQ(0, ioctlHelper.vmUnbind(drm.get(), vmBindParams)); +}