From 27c089d60d2567677af1717116293d8e7e50236e Mon Sep 17 00:00:00 2001 From: Brandon Yates Date: Thu, 1 Feb 2024 22:03:55 +0000 Subject: [PATCH] feature: Register ELF for xe debugger Related-to: NEO-9674 Signed-off-by: Brandon Yates --- .../source/os_interface/linux/drm_wrappers.h | 4 +- .../os_interface/linux/xe/ioctl_helper_xe.cpp | 7 +++ .../os_interface/linux/xe/ioctl_helper_xe.h | 4 ++ .../linux/xe/ioctl_helper_xe_debugger.cpp | 48 +++++++++++++++++++ .../ioctl_helper_xe_string_value_getter.cpp | 8 +++- .../common/mocks/linux/debug_mock_drm_xe.h | 18 +++++++ .../xe/ioctl_helper_xe_debugger_tests.cpp | 30 ++++++++++++ 7 files changed, 117 insertions(+), 2 deletions(-) diff --git a/shared/source/os_interface/linux/drm_wrappers.h b/shared/source/os_interface/linux/drm_wrappers.h index 7068c108ca..83a3c3378e 100644 --- a/shared/source/os_interface/linux/drm_wrappers.h +++ b/shared/source/os_interface/linux/drm_wrappers.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022-2023 Intel Corporation + * Copyright (C) 2022-2024 Intel Corporation * * SPDX-License-Identifier: MIT * @@ -262,6 +262,8 @@ enum class DrmIoctl { gemCacheReserve, version, vmExport, + metadataCreate, + metadataDestroy, }; enum class DrmParam { diff --git a/shared/source/os_interface/linux/xe/ioctl_helper_xe.cpp b/shared/source/os_interface/linux/xe/ioctl_helper_xe.cpp index 5c11f3828b..ccd9cf110e 100644 --- a/shared/source/os_interface/linux/xe/ioctl_helper_xe.cpp +++ b/shared/source/os_interface/linux/xe/ioctl_helper_xe.cpp @@ -1145,6 +1145,13 @@ int IoctlHelperXe::ioctl(DrmIoctl request, void *arg) { case DrmIoctl::debuggerOpen: { ret = debuggerOpenIoctl(request, arg); } break; + case DrmIoctl::metadataCreate: { + ret = debuggerMetadataCreateIoctl(request, arg); + } break; + case DrmIoctl::metadataDestroy: { + ret = debuggerMetadataDestroyIoctl(request, arg); + } break; + default: xeLog("Not handled 0x%x\n", request); UNRECOVERABLE_IF(true); diff --git a/shared/source/os_interface/linux/xe/ioctl_helper_xe.h b/shared/source/os_interface/linux/xe/ioctl_helper_xe.h index 707e4a1664..9a4a1d09a7 100644 --- a/shared/source/os_interface/linux/xe/ioctl_helper_xe.h +++ b/shared/source/os_interface/linux/xe/ioctl_helper_xe.h @@ -134,6 +134,8 @@ class IoctlHelperXe : public IoctlHelper { uint16_t getCpuCachingMode(); void addDebugMetadata(DrmResourceClass type, uint64_t *offset, uint64_t size); void addDebugMetadataCookie(uint64_t cookie); + uint32_t registerResource(DrmResourceClass classType, const void *data, size_t size) override; + void unregisterResource(uint32_t handle) override; protected: const char *xeGetClassName(int className); @@ -149,6 +151,8 @@ class IoctlHelperXe : public IoctlHelper { void updateBindInfo(uint32_t handle, uint64_t userPtr, uint64_t size); void *allocateDebugMetadata(); int debuggerOpenIoctl(DrmIoctl request, void *arg); + int debuggerMetadataCreateIoctl(DrmIoctl request, void *arg); + int debuggerMetadataDestroyIoctl(DrmIoctl request, void *arg); void *freeDebugMetadata(void *metadata); int getRunaloneExtProperty(); diff --git a/shared/source/os_interface/linux/xe/ioctl_helper_xe_debugger.cpp b/shared/source/os_interface/linux/xe/ioctl_helper_xe_debugger.cpp index fd2e015b30..fdebcfaa84 100644 --- a/shared/source/os_interface/linux/xe/ioctl_helper_xe_debugger.cpp +++ b/shared/source/os_interface/linux/xe/ioctl_helper_xe_debugger.cpp @@ -23,6 +23,10 @@ unsigned int IoctlHelperXe::getIoctlRequestValueDebugger(DrmIoctl ioctlRequest) switch (ioctlRequest) { case DrmIoctl::debuggerOpen: RETURN_ME(DRM_IOCTL_XE_EUDEBUG_CONNECT); + case DrmIoctl::metadataCreate: + RETURN_ME(DRM_IOCTL_XE_DEBUG_METADATA_CREATE); + case DrmIoctl::metadataDestroy: + RETURN_ME(DRM_IOCTL_XE_DEBUG_METADATA_DESTROY); default: UNRECOVERABLE_IF(true); @@ -38,6 +42,22 @@ int IoctlHelperXe::debuggerOpenIoctl(DrmIoctl request, void *arg) { return ret; } +int IoctlHelperXe::debuggerMetadataCreateIoctl(DrmIoctl request, void *arg) { + drm_xe_debug_metadata_create *metadata = static_cast(arg); + auto ret = IoctlHelper::ioctl(request, arg); + xeLog(" -> IoctlHelperXe::ioctl metadataCreate type=%llu user_addr=%uul len=%uul\n id=%uul ret=%d, errno=%d\n", + metadata->type, metadata->user_addr, metadata->len, metadata->id, ret, errno); + return ret; +} + +int IoctlHelperXe::debuggerMetadataDestroyIoctl(DrmIoctl request, void *arg) { + drm_xe_debug_metadata_destroy *metadata = static_cast(arg); + auto ret = IoctlHelper::ioctl(request, arg); + xeLog(" -> IoctlHelperXe::ioctl metadataDestroy id=%llu r=%d\n", + metadata->id, ret); + return ret; +} + void *IoctlHelperXe::allocateDebugMetadata() { drm_xe_ext_vm_set_debug_metadata *prev = nullptr; drm_xe_ext_vm_set_debug_metadata *xeMetadataRoot = nullptr; @@ -134,4 +154,32 @@ int IoctlHelperXe::getEuDebugSysFsEnable() { return enabledEuDebug - '0'; } +uint32_t IoctlHelperXe::registerResource(DrmResourceClass classType, const void *data, size_t size) { + drm_xe_debug_metadata_create metadata = {}; + if (classType == DrmResourceClass::elf) { + metadata.type = DRM_XE_DEBUG_METADATA_ELF_BINARY; + metadata.user_addr = reinterpret_cast(data); + metadata.len = size; + } else if (classType == DrmResourceClass::l0ZebinModule) { + metadata.type = DRM_XE_DEBUG_METADATA_PROGRAM_MODULE; + metadata.user_addr = reinterpret_cast(data); + metadata.len = size; + } else { + UNRECOVERABLE_IF(true); + } + [[maybe_unused]] auto retVal = IoctlHelperXe::ioctl(DrmIoctl::metadataCreate, &metadata); + PRINT_DEBUGGER_INFO_LOG("DRM_XE_DEBUG_METADATA_CREATE: type=%llu user_addr=%llu len=%llu id=%llu\n", + metadata.type, metadata.user_addr, metadata.len, metadata.id); + DEBUG_BREAK_IF(retVal != 0); + return static_cast(metadata.id); +} + +void IoctlHelperXe::unregisterResource(uint32_t handle) { + drm_xe_debug_metadata_destroy metadata = {}; + metadata.id = handle; + [[maybe_unused]] auto retVal = IoctlHelperXe::ioctl(DrmIoctl::metadataDestroy, &metadata); + DEBUG_BREAK_IF(retVal != 0); + PRINT_DEBUGGER_INFO_LOG("DRM_XE_DEBUG_METADATA_DESTROY: id=%llu\n", metadata.id); +} + } // namespace NEO \ No newline at end of file diff --git a/shared/source/os_interface/linux/xe/ioctl_helper_xe_string_value_getter.cpp b/shared/source/os_interface/linux/xe/ioctl_helper_xe_string_value_getter.cpp index 0a0663a5d4..22bce921ff 100644 --- a/shared/source/os_interface/linux/xe/ioctl_helper_xe_string_value_getter.cpp +++ b/shared/source/os_interface/linux/xe/ioctl_helper_xe_string_value_getter.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2023 Intel Corporation + * Copyright (C) 2023-2024 Intel Corporation * * SPDX-License-Identifier: MIT * @@ -43,6 +43,8 @@ unsigned int IoctlHelperXe::getIoctlRequestValue(DrmIoctl ioctlRequest) const { case DrmIoctl::primeHandleToFd: RETURN_ME(DRM_IOCTL_PRIME_HANDLE_TO_FD); case DrmIoctl::debuggerOpen: + case DrmIoctl::metadataCreate: + case DrmIoctl::metadataDestroy: return getIoctlRequestValueDebugger(ioctlRequest); default: UNRECOVERABLE_IF(true); @@ -80,6 +82,10 @@ std::string IoctlHelperXe::getIoctlString(DrmIoctl ioctlRequest) const { STRINGIFY_ME(DRM_IOCTL_PRIME_HANDLE_TO_FD); case DrmIoctl::debuggerOpen: STRINGIFY_ME(DRM_IOCTL_XE_EUDEBUG_CONNECT); + case DrmIoctl::metadataCreate: + STRINGIFY_ME(DRM_IOCTL_XE_DEBUG_METADATA_CREATE); + case DrmIoctl::metadataDestroy: + STRINGIFY_ME(DRM_IOCTL_XE_DEBUG_METADATA_DESTROY); default: return "???"; } diff --git a/shared/test/common/mocks/linux/debug_mock_drm_xe.h b/shared/test/common/mocks/linux/debug_mock_drm_xe.h index d1bf3b1254..a47d38f671 100644 --- a/shared/test/common/mocks/linux/debug_mock_drm_xe.h +++ b/shared/test/common/mocks/linux/debug_mock_drm_xe.h @@ -107,6 +107,19 @@ class DrmMockXeDebug : public DrmMockCustom { } return debuggerOpenRetval; } break; + case DrmIoctl::metadataCreate: { + auto metadata = reinterpret_cast(arg); + metadataAddr = reinterpret_cast(metadata->user_addr); + metadataSize = metadata->len; + metadataType = metadata->type; + metadata->id = metadataID; + return 0; + } break; + case DrmIoctl::metadataDestroy: { + auto metadata = reinterpret_cast(arg); + metadataID = metadata->id; + return 0; + } break; default: break; @@ -162,6 +175,11 @@ class DrmMockXeDebug : public DrmMockCustom { int setIoctlAnswer = 0; int gemVmBindReturn = 0; + uint64_t metadataID = 20; + void *metadataAddr = nullptr; + size_t metadataSize = 0; + uint64_t metadataType = 9999; + alignas(64) std::vector queryTopology; std::vector vmCreateMetadata; diff --git a/shared/test/unit_test/os_interface/linux/xe/ioctl_helper_xe_debugger_tests.cpp b/shared/test/unit_test/os_interface/linux/xe/ioctl_helper_xe_debugger_tests.cpp index 0e7f40bd82..06401abf8c 100644 --- a/shared/test/unit_test/os_interface/linux/xe/ioctl_helper_xe_debugger_tests.cpp +++ b/shared/test/unit_test/os_interface/linux/xe/ioctl_helper_xe_debugger_tests.cpp @@ -306,3 +306,33 @@ TEST(IoctlHelperXeTest, givenXeEnableEuDebugWithInvalidPathThenReturnCorrectValu EXPECT_EQ(0, enableEuDebug); } + +TEST(IoctlHelperXeTest, givenXeRegisterResourceThenCorrectIoctlCalled) { + auto executionEnvironment = std::make_unique(); + DrmMockXeDebug drm{*executionEnvironment->rootDeviceEnvironments[0]}; + auto xeIoctlHelper = std::make_unique(drm); + constexpr size_t bufferSize = 20; + uint8_t buffer[bufferSize]; + auto id = xeIoctlHelper->registerResource(DrmResourceClass::elf, buffer, bufferSize); + EXPECT_EQ(drm.metadataID, id); + EXPECT_EQ(drm.metadataAddr, buffer); + EXPECT_EQ(drm.metadataSize, bufferSize); + EXPECT_EQ(drm.metadataType, static_cast(DRM_XE_DEBUG_METADATA_ELF_BINARY)); + + drm.metadataID = 0; + drm.metadataAddr = nullptr; + drm.metadataSize = 0; + id = xeIoctlHelper->registerResource(DrmResourceClass::l0ZebinModule, buffer, bufferSize); + EXPECT_EQ(drm.metadataID, id); + EXPECT_EQ(drm.metadataAddr, buffer); + EXPECT_EQ(drm.metadataSize, bufferSize); + EXPECT_EQ(drm.metadataType, static_cast(DRM_XE_DEBUG_METADATA_PROGRAM_MODULE)); +} + +TEST(IoctlHelperXeTest, givenXeunregisterResourceThenCorrectIoctlCalled) { + auto executionEnvironment = std::make_unique(); + DrmMockXeDebug drm{*executionEnvironment->rootDeviceEnvironments[0]}; + auto xeIoctlHelper = std::make_unique(drm); + xeIoctlHelper->unregisterResource(0x1234); + EXPECT_EQ(drm.metadataID, 0x1234u); +}