diff --git a/level_zero/sysman/source/shared/firmware_util/linux/sysman_os_firmware_util_enumeration.cpp b/level_zero/sysman/source/shared/firmware_util/linux/sysman_os_firmware_util_enumeration.cpp index ee7cc5013f..acf2a55ca6 100644 --- a/level_zero/sysman/source/shared/firmware_util/linux/sysman_os_firmware_util_enumeration.cpp +++ b/level_zero/sysman/source/shared/firmware_util/linux/sysman_os_firmware_util_enumeration.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022-2023 Intel Corporation + * Copyright (C) 2022-2024 Intel Corporation * * SPDX-License-Identifier: MIT * @@ -7,8 +7,11 @@ #include "level_zero/sysman/source/shared/firmware_util/sysman_firmware_util_imp.h" +#include + namespace L0 { namespace Sysman { +int FirmwareUtilImp::fwUtilLoadFlags = RTLD_LAZY; std::string FirmwareUtilImp::fwUtilLibraryName = "libigsc.so.0"; } // namespace Sysman } // namespace L0 \ No newline at end of file diff --git a/level_zero/sysman/source/shared/firmware_util/sysman_firmware_util_imp.cpp b/level_zero/sysman/source/shared/firmware_util/sysman_firmware_util_imp.cpp index 62285cb470..2dbebd6c39 100644 --- a/level_zero/sysman/source/shared/firmware_util/sysman_firmware_util_imp.cpp +++ b/level_zero/sysman/source/shared/firmware_util/sysman_firmware_util_imp.cpp @@ -208,6 +208,7 @@ FirmwareUtilImp::~FirmwareUtilImp() { FirmwareUtil *FirmwareUtil::create(uint16_t domain, uint8_t bus, uint8_t device, uint8_t function) { FirmwareUtilImp *pFwUtilImp = new FirmwareUtilImp(domain, bus, device, function); UNRECOVERABLE_IF(nullptr == pFwUtilImp); + NEO::OsLibrary::loadFlagsOverwrite = &FirmwareUtilImp::fwUtilLoadFlags; pFwUtilImp->libraryHandle = NEO::OsLibrary::loadFunc(FirmwareUtilImp::fwUtilLibraryName); if (pFwUtilImp->libraryHandle == nullptr || pFwUtilImp->loadEntryPoints() == false || pFwUtilImp->fwDeviceInit() != ZE_RESULT_SUCCESS) { if (nullptr != pFwUtilImp->libraryHandle) { diff --git a/level_zero/sysman/source/shared/firmware_util/sysman_firmware_util_imp.h b/level_zero/sysman/source/shared/firmware_util/sysman_firmware_util_imp.h index 00848c6fc4..aed5c1fac5 100644 --- a/level_zero/sysman/source/shared/firmware_util/sysman_firmware_util_imp.h +++ b/level_zero/sysman/source/shared/firmware_util/sysman_firmware_util_imp.h @@ -127,6 +127,7 @@ class FirmwareUtilImp : public FirmwareUtil, NEO::NonCopyableOrMovableClass { void getDeviceSupportedFwTypes(std::vector &fwTypes) override; void fwGetMemoryHealthIndicator(zes_mem_health_t *health) override; + static int fwUtilLoadFlags; static std::string fwUtilLibraryName; bool loadEntryPoints(); bool loadEntryPointsExt(); diff --git a/level_zero/sysman/source/shared/firmware_util/windows/sysman_os_firmware_util_enumeration.cpp b/level_zero/sysman/source/shared/firmware_util/windows/sysman_os_firmware_util_enumeration.cpp index 009d32b11c..3d02c87f28 100644 --- a/level_zero/sysman/source/shared/firmware_util/windows/sysman_os_firmware_util_enumeration.cpp +++ b/level_zero/sysman/source/shared/firmware_util/windows/sysman_os_firmware_util_enumeration.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022-2023 Intel Corporation + * Copyright (C) 2022-2024 Intel Corporation * * SPDX-License-Identifier: MIT * @@ -10,5 +10,6 @@ namespace L0 { namespace Sysman { std::string FirmwareUtilImp::fwUtilLibraryName = "igsc.dll"; +int FirmwareUtilImp::fwUtilLoadFlags{}; } // namespace Sysman } // namespace L0 \ No newline at end of file diff --git a/level_zero/sysman/test/unit_tests/sources/firmware_util/CMakeLists.txt b/level_zero/sysman/test/unit_tests/sources/firmware_util/CMakeLists.txt index 47618c3f48..92645995d6 100644 --- a/level_zero/sysman/test/unit_tests/sources/firmware_util/CMakeLists.txt +++ b/level_zero/sysman/test/unit_tests/sources/firmware_util/CMakeLists.txt @@ -1,19 +1,17 @@ # -# Copyright (C) 2022-2023 Intel Corporation +# Copyright (C) 2022-2024 Intel Corporation # # SPDX-License-Identifier: MIT # if(igsc_FOUND) - set(L0_SRCS_SYSMAN_LINUX_FIRMWARE_UTIL_TEST - ${CMAKE_CURRENT_SOURCE_DIR}/CMakeLists.txt - ${CMAKE_CURRENT_SOURCE_DIR}/test_fw_util.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/mock_fw_util_fixture.h - ${CMAKE_CURRENT_SOURCE_DIR}/test_fw_util_helper.cpp + target_sources(${TARGET_NAME} PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR}/CMakeLists.txt + ${CMAKE_CURRENT_SOURCE_DIR}/mock_fw_util_fixture.h + ${CMAKE_CURRENT_SOURCE_DIR}/test_fw_util.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/test_fw_util_helper.cpp ) endif() -target_sources(${TARGET_NAME} PRIVATE - ${L0_SRCS_SYSMAN_LINUX_FIRMWARE_UTIL_TEST} -) +add_subdirectories() diff --git a/level_zero/sysman/test/unit_tests/sources/firmware_util/linux/CMakeLists.txt b/level_zero/sysman/test/unit_tests/sources/firmware_util/linux/CMakeLists.txt new file mode 100644 index 0000000000..24873f925c --- /dev/null +++ b/level_zero/sysman/test/unit_tests/sources/firmware_util/linux/CMakeLists.txt @@ -0,0 +1,14 @@ +# +# Copyright (C) 2024 Intel Corporation +# +# SPDX-License-Identifier: MIT +# + +if(UNIX) + if(igsc_FOUND) + target_sources(${TARGET_NAME} PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR}/CMakeLists.txt + ${CMAKE_CURRENT_SOURCE_DIR}/test_fw_util_linux.cpp + ) + endif() +endif() diff --git a/level_zero/sysman/test/unit_tests/sources/firmware_util/linux/test_fw_util_linux.cpp b/level_zero/sysman/test/unit_tests/sources/firmware_util/linux/test_fw_util_linux.cpp new file mode 100644 index 0000000000..5c649f8b68 --- /dev/null +++ b/level_zero/sysman/test/unit_tests/sources/firmware_util/linux/test_fw_util_linux.cpp @@ -0,0 +1,47 @@ +/* + * Copyright (C) 2022-2024 Intel Corporation + * + * SPDX-License-Identifier: MIT + * + */ + +#include "shared/test/common/helpers/variable_backup.h" +#include "shared/test/common/test_macros/test.h" + +#include "level_zero/sysman/source/shared/firmware_util/sysman_firmware_util_imp.h" +#include "level_zero/sysman/test/unit_tests/sources/firmware_util/mock_fw_util_fixture.h" + +#include + +extern void *(*dlopenFunc)(const char *filename, int flags); + +namespace L0 { +namespace Sysman { +namespace ult { + +static int dlOpenFlags = 0; +static bool dlOpenCalled = false; + +void *mockDlopen(const char *filename, int flags) { + dlOpenCalled = true; + dlOpenFlags = flags; + return nullptr; +} + +TEST(FwUtilTest, GivenLibraryWasSetWhenCreatingFirmwareUtilInterfaceThenLibraryIsLoadedWithDeepbindDisabled) { + VariableBackup dlopenFuncBackup(&dlopenFunc, nullptr); + dlopenFunc = mockDlopen; + VariableBackup dlOpenCalledBackup{&dlOpenCalled, false}; + VariableBackup dlOpenFlagsBackup{&dlOpenFlags, 0}; + + auto flags = RTLD_LAZY; + NEO::OsLibrary::loadFlagsOverwrite = &flags; + L0::Sysman::FirmwareUtil *pFwUtil = L0::Sysman::FirmwareUtil::create(0, 0, 0, 0); + EXPECT_EQ(dlOpenCalled, true); + EXPECT_EQ(dlOpenFlags, RTLD_LAZY); + EXPECT_EQ(pFwUtil, nullptr); +} + +} // namespace ult +} // namespace Sysman +} // namespace L0 diff --git a/level_zero/sysman/test/unit_tests/sources/firmware_util/mock_fw_util_fixture.h b/level_zero/sysman/test/unit_tests/sources/firmware_util/mock_fw_util_fixture.h index 820f1ec39f..84ce9ea49e 100644 --- a/level_zero/sysman/test/unit_tests/sources/firmware_util/mock_fw_util_fixture.h +++ b/level_zero/sysman/test/unit_tests/sources/firmware_util/mock_fw_util_fixture.h @@ -74,4 +74,4 @@ struct MockFwUtilOsLibrary : public OsLibrary { } // namespace ult } // namespace Sysman -} // namespace L0 +} // namespace L0 \ No newline at end of file diff --git a/level_zero/tools/source/sysman/firmware_util/firmware_util_imp.cpp b/level_zero/tools/source/sysman/firmware_util/firmware_util_imp.cpp index 8dddb3d9eb..d9f08db4c5 100644 --- a/level_zero/tools/source/sysman/firmware_util/firmware_util_imp.cpp +++ b/level_zero/tools/source/sysman/firmware_util/firmware_util_imp.cpp @@ -192,6 +192,7 @@ FirmwareUtilImp::~FirmwareUtilImp() { FirmwareUtil *FirmwareUtil::create(uint16_t domain, uint8_t bus, uint8_t device, uint8_t function) { FirmwareUtilImp *pFwUtilImp = new FirmwareUtilImp(domain, bus, device, function); UNRECOVERABLE_IF(nullptr == pFwUtilImp); + NEO::OsLibrary::loadFlagsOverwrite = &FirmwareUtilImp::fwUtilLoadFlags; pFwUtilImp->libraryHandle = NEO::OsLibrary::loadFunc(FirmwareUtilImp::fwUtilLibraryName); if (pFwUtilImp->libraryHandle == nullptr || pFwUtilImp->loadEntryPoints() == false || pFwUtilImp->fwDeviceInit() != ZE_RESULT_SUCCESS) { if (nullptr != pFwUtilImp->libraryHandle) { diff --git a/level_zero/tools/source/sysman/firmware_util/firmware_util_imp.h b/level_zero/tools/source/sysman/firmware_util/firmware_util_imp.h index e2fc99e89f..65dd52eab0 100644 --- a/level_zero/tools/source/sysman/firmware_util/firmware_util_imp.h +++ b/level_zero/tools/source/sysman/firmware_util/firmware_util_imp.h @@ -127,6 +127,7 @@ class FirmwareUtilImp : public FirmwareUtil, NEO::NonCopyableOrMovableClass { ze_result_t fwFlashIafPsc(void *pImage, uint32_t size); ze_result_t fwCallGetstatusExt(uint32_t &supportedTests, uint32_t &ifrApplied, uint32_t &prevErrors, uint32_t &pendingReset); + static int fwUtilLoadFlags; static std::string fwUtilLibraryName; std::string fwDevicePath{}; struct igsc_device_handle fwDeviceHandle = {}; diff --git a/level_zero/tools/source/sysman/firmware_util/linux/os_firmware_util_enumeration.cpp b/level_zero/tools/source/sysman/firmware_util/linux/os_firmware_util_enumeration.cpp index 3ff245a091..14bd7ed378 100644 --- a/level_zero/tools/source/sysman/firmware_util/linux/os_firmware_util_enumeration.cpp +++ b/level_zero/tools/source/sysman/firmware_util/linux/os_firmware_util_enumeration.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Intel Corporation + * Copyright (C) 2022-2024 Intel Corporation * * SPDX-License-Identifier: MIT * @@ -7,6 +7,9 @@ #include "level_zero/tools/source/sysman/firmware_util/firmware_util_imp.h" +#include + namespace L0 { +int FirmwareUtilImp::fwUtilLoadFlags = RTLD_LAZY; std::string FirmwareUtilImp::fwUtilLibraryName = "libigsc.so.0"; -} \ No newline at end of file +} // namespace L0 \ No newline at end of file diff --git a/level_zero/tools/source/sysman/firmware_util/windows/os_firmware_util_enumeration.cpp b/level_zero/tools/source/sysman/firmware_util/windows/os_firmware_util_enumeration.cpp index fc5044a608..1510044c8a 100644 --- a/level_zero/tools/source/sysman/firmware_util/windows/os_firmware_util_enumeration.cpp +++ b/level_zero/tools/source/sysman/firmware_util/windows/os_firmware_util_enumeration.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Intel Corporation + * Copyright (C) 2022-2024 Intel Corporation * * SPDX-License-Identifier: MIT * @@ -9,4 +9,5 @@ namespace L0 { std::string FirmwareUtilImp::fwUtilLibraryName = "igsc.dll"; -} \ No newline at end of file +int FirmwareUtilImp::fwUtilLoadFlags{}; +} // namespace L0 \ No newline at end of file diff --git a/level_zero/tools/test/unit_tests/sources/sysman/firmware_util/CMakeLists.txt b/level_zero/tools/test/unit_tests/sources/sysman/firmware_util/CMakeLists.txt index 2cb072d5c4..f63addeed7 100644 --- a/level_zero/tools/test/unit_tests/sources/sysman/firmware_util/CMakeLists.txt +++ b/level_zero/tools/test/unit_tests/sources/sysman/firmware_util/CMakeLists.txt @@ -1,5 +1,5 @@ # -# Copyright (C) 2022-2023 Intel Corporation +# Copyright (C) 2022-2024 Intel Corporation # # SPDX-License-Identifier: MIT # @@ -13,3 +13,4 @@ if(igsc_FOUND) ) endif() +add_subdirectories() \ No newline at end of file diff --git a/level_zero/tools/test/unit_tests/sources/sysman/firmware_util/linux/CMakeLists.txt b/level_zero/tools/test/unit_tests/sources/sysman/firmware_util/linux/CMakeLists.txt new file mode 100644 index 0000000000..24873f925c --- /dev/null +++ b/level_zero/tools/test/unit_tests/sources/sysman/firmware_util/linux/CMakeLists.txt @@ -0,0 +1,14 @@ +# +# Copyright (C) 2024 Intel Corporation +# +# SPDX-License-Identifier: MIT +# + +if(UNIX) + if(igsc_FOUND) + target_sources(${TARGET_NAME} PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR}/CMakeLists.txt + ${CMAKE_CURRENT_SOURCE_DIR}/test_fw_util_linux.cpp + ) + endif() +endif() diff --git a/level_zero/tools/test/unit_tests/sources/sysman/firmware_util/linux/test_fw_util_linux.cpp b/level_zero/tools/test/unit_tests/sources/sysman/firmware_util/linux/test_fw_util_linux.cpp new file mode 100644 index 0000000000..5c649f8b68 --- /dev/null +++ b/level_zero/tools/test/unit_tests/sources/sysman/firmware_util/linux/test_fw_util_linux.cpp @@ -0,0 +1,47 @@ +/* + * Copyright (C) 2022-2024 Intel Corporation + * + * SPDX-License-Identifier: MIT + * + */ + +#include "shared/test/common/helpers/variable_backup.h" +#include "shared/test/common/test_macros/test.h" + +#include "level_zero/sysman/source/shared/firmware_util/sysman_firmware_util_imp.h" +#include "level_zero/sysman/test/unit_tests/sources/firmware_util/mock_fw_util_fixture.h" + +#include + +extern void *(*dlopenFunc)(const char *filename, int flags); + +namespace L0 { +namespace Sysman { +namespace ult { + +static int dlOpenFlags = 0; +static bool dlOpenCalled = false; + +void *mockDlopen(const char *filename, int flags) { + dlOpenCalled = true; + dlOpenFlags = flags; + return nullptr; +} + +TEST(FwUtilTest, GivenLibraryWasSetWhenCreatingFirmwareUtilInterfaceThenLibraryIsLoadedWithDeepbindDisabled) { + VariableBackup dlopenFuncBackup(&dlopenFunc, nullptr); + dlopenFunc = mockDlopen; + VariableBackup dlOpenCalledBackup{&dlOpenCalled, false}; + VariableBackup dlOpenFlagsBackup{&dlOpenFlags, 0}; + + auto flags = RTLD_LAZY; + NEO::OsLibrary::loadFlagsOverwrite = &flags; + L0::Sysman::FirmwareUtil *pFwUtil = L0::Sysman::FirmwareUtil::create(0, 0, 0, 0); + EXPECT_EQ(dlOpenCalled, true); + EXPECT_EQ(dlOpenFlags, RTLD_LAZY); + EXPECT_EQ(pFwUtil, nullptr); +} + +} // namespace ult +} // namespace Sysman +} // namespace L0 diff --git a/shared/source/os_interface/linux/os_library_linux.cpp b/shared/source/os_interface/linux/os_library_linux.cpp index b67b796335..cf4848934c 100644 --- a/shared/source/os_interface/linux/os_library_linux.cpp +++ b/shared/source/os_interface/linux/os_library_linux.cpp @@ -43,6 +43,8 @@ OsLibrary::OsLibrary(const std::string &name, std::string *errorValue) { auto dlopenFlag = RTLD_LAZY | RTLD_DEEPBIND; /* Background: https://github.com/intel/compute-runtime/issues/122 */ #endif + dlopenFlag = OsLibrary::loadFlagsOverwrite ? *OsLibrary::loadFlagsOverwrite : dlopenFlag; + OsLibrary::loadFlagsOverwrite = nullptr; adjustLibraryFlags(dlopenFlag); this->handle = SysCalls::dlopen(name.c_str(), dlopenFlag); if (!this->handle && (errorValue != nullptr)) { diff --git a/shared/source/os_interface/os_library.cpp b/shared/source/os_interface/os_library.cpp index 37218f18c2..eeed34ede6 100644 --- a/shared/source/os_interface/os_library.cpp +++ b/shared/source/os_interface/os_library.cpp @@ -8,6 +8,8 @@ #include "shared/source/os_interface/os_library.h" namespace NEO { +const int *OsLibrary::loadFlagsOverwrite = nullptr; + decltype(&OsLibrary::load) OsLibrary::loadFunc = OsLibrary::load; } // namespace NEO diff --git a/shared/source/os_interface/os_library.h b/shared/source/os_interface/os_library.h index 3a66b243ef..28459a02b3 100644 --- a/shared/source/os_interface/os_library.h +++ b/shared/source/os_interface/os_library.h @@ -31,6 +31,8 @@ class OsLibrary { public: virtual ~OsLibrary() = default; + static const int *loadFlagsOverwrite; + static decltype(&OsLibrary::load) loadFunc; static OsLibrary *loadAndCaptureError(const std::string &name, std::string *errorValue); static const std::string createFullSystemPath(const std::string &name); diff --git a/shared/test/common/mocks/linux/mock_dlopen.cpp b/shared/test/common/mocks/linux/mock_dlopen.cpp index 2ad7d98930..1c5ae3094b 100644 --- a/shared/test/common/mocks/linux/mock_dlopen.cpp +++ b/shared/test/common/mocks/linux/mock_dlopen.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2021-2023 Intel Corporation + * Copyright (C) 2021-2024 Intel Corporation * * SPDX-License-Identifier: MIT * @@ -26,7 +26,8 @@ void *dlopen(const char *filename, int flags) { dlopenError = -1; if (filename == nullptr || (strcmp(filename, "libtest_dynamic_lib.so") == 0) || - (strcmp(filename, "libtest_l0_loader_lib.so") == 0)) { + (strcmp(filename, "libtest_l0_loader_lib.so") == 0) || + (strcmp(filename, "libigsc.so.0") == 0)) { return dlopenFunc(filename, flags); } if (filename[0] == '_') { diff --git a/shared/test/unit_test/os_interface/linux/os_library_linux_tests.cpp b/shared/test/unit_test/os_interface/linux/os_library_linux_tests.cpp index 6a67d610e8..1458e58bd7 100644 --- a/shared/test/unit_test/os_interface/linux/os_library_linux_tests.cpp +++ b/shared/test/unit_test/os_interface/linux/os_library_linux_tests.cpp @@ -73,4 +73,15 @@ TEST(OsLibraryTest, GivenInvalidLibraryWhenOpeningLibraryThenDlopenErrorIsReturn EXPECT_TRUE(NEO::SysCalls::dlOpenCalled); } +TEST(OsLibraryTest, GivenLoadFlagsOverwriteWhenOpeningLibraryThenDlOpenIsCalledWithExpectedFlags) { + VariableBackup dlOpenFlagsBackup{&NEO::SysCalls::dlOpenFlags, 0}; + VariableBackup dlOpenCalledBackup{&NEO::SysCalls::dlOpenCalled, false}; + + auto expectedFlag = RTLD_LAZY | RTLD_GLOBAL; + NEO::OsLibrary::loadFlagsOverwrite = &expectedFlag; + auto lib = std::make_unique("_abc.so", nullptr); + EXPECT_TRUE(NEO::SysCalls::dlOpenCalled); + EXPECT_EQ(NEO::SysCalls::dlOpenFlags, expectedFlag); +} + } // namespace NEO