From 467119931c105ec767ce9726d6a5704191659ca9 Mon Sep 17 00:00:00 2001 From: Matias Cabral Date: Tue, 8 Nov 2022 18:51:55 +0000 Subject: [PATCH] Add SIP version check Make SLM access a single template function Resolves: NEO-7335 Signed-off-by: Matias Cabral --- .../tools/source/debug/debug_session_imp.cpp | 174 +++--------------- .../tools/source/debug/debug_session_imp.h | 115 +++++++++++- .../debug/linux/prelim/debug_session.cpp | 12 +- .../source/debug/windows/debug_session.cpp | 15 +- .../sources/debug/debug_session_tests.cpp | 155 +++++++++++++--- .../linux/debug_session_fixtures_linux.h | 1 + .../debug/linux/test_debug_api_linux.cpp | 2 + .../sources/debug/mock_debug_session.h | 6 +- .../debug/windows/test_debug_api_windows.cpp | 3 + 9 files changed, 278 insertions(+), 205 deletions(-) diff --git a/level_zero/tools/source/debug/debug_session_imp.cpp b/level_zero/tools/source/debug/debug_session_imp.cpp index 9dfef750f5..68b46f7d44 100644 --- a/level_zero/tools/source/debug/debug_session_imp.cpp +++ b/level_zero/tools/source/debug/debug_session_imp.cpp @@ -856,18 +856,41 @@ ze_result_t DebugSessionImp::readEvent(uint64_t timeout, zet_debug_event_t *outp return ZE_RESULT_NOT_READY; } -void DebugSessionImp::validateAndSetStateSaveAreaHeader(const std::vector &data) { +void DebugSessionImp::validateAndSetStateSaveAreaHeader(uint64_t vmHandle, uint64_t gpuVa) { + auto headerSize = sizeof(SIP::StateSaveAreaHeader); + std::vector data(headerSize); + auto retVal = readGpuMemory(vmHandle, data.data(), headerSize, gpuVa); + + if (retVal != ZE_RESULT_SUCCESS) { + PRINT_DEBUGGER_ERROR_LOG("Reading Context State Save Area failed, error = %d\n", retVal); + return; + } + auto pStateSaveArea = reinterpret_cast(data.data()); if (0 == strcmp(pStateSaveArea->versionHeader.magic, "tssarea")) { size_t size = pStateSaveArea->versionHeader.size * 8u; DEBUG_BREAK_IF(size != sizeof(SIP::StateSaveAreaHeader)); stateSaveAreaHeader.assign(data.begin(), data.begin() + size); PRINT_DEBUGGER_INFO_LOG("Context State Save Area : version == %d.%d.%d\n", (int)pStateSaveArea->versionHeader.version.major, (int)pStateSaveArea->versionHeader.version.minor, (int)pStateSaveArea->versionHeader.version.patch); + slmSipVersionCheck(); } else { PRINT_DEBUGGER_ERROR_LOG("Setting Context State Save Area: failed to match magic numbers\n", ""); } } +void DebugSessionImp::slmSipVersionCheck() { + + SIP::version sipVersion = getStateSaveAreaHeader()->versionHeader.version; + if ((sipVersion.major < minSlmSipVersion.major) || + ((sipVersion.major == minSlmSipVersion.major) && (sipVersion.minor < minSlmSipVersion.minor)) || + ((sipVersion.major == minSlmSipVersion.major) && (sipVersion.minor == minSlmSipVersion.minor) && (sipVersion.patch < minSlmSipVersion.patch))) { + + sipSupportsSlm = false; + } else { + sipSupportsSlm = true; + } +} + const SIP::StateSaveAreaHeader *DebugSessionImp::getStateSaveAreaHeader() { if (stateSaveAreaHeader.empty()) { readStateSaveAreaHeader(); @@ -1274,153 +1297,4 @@ ze_result_t DebugSessionImp::waitForCmdReady(EuThread::ThreadId threadId, uint16 return ZE_RESULT_SUCCESS; } -ze_result_t DebugSessionImp::readSLMMemory(EuThread::ThreadId threadId, const zet_debug_memory_space_desc_t *desc, size_t size, void *buffer) { - ze_result_t status; - SIP::sip_command sipCommand = {0}; - - status = waitForCmdReady(threadId, sipRetryCount); - if (status != ZE_RESULT_SUCCESS) { - return status; - } - - uint64_t offset = desc->address & maxNBitValue(slmAddressSpaceTag); - - // SIP accesses SLM in units of slmSendBytesSize at offset allignment of slmSendBytesSize - uint32_t frontPadding = offset % slmSendBytesSize; - uint64_t alignedOffset = offset - frontPadding; - uint32_t remainingSlmSendUnits = static_cast(std::ceil(static_cast(size) / slmSendBytesSize)); - - if ((size + frontPadding) > (remainingSlmSendUnits * slmSendBytesSize)) { - remainingSlmSendUnits++; - } - - uint32_t loops = static_cast(std::ceil(static_cast(remainingSlmSendUnits) / maxUnitsPerLoop)); - - std::unique_ptr tmpBuffer(new char[remainingSlmSendUnits * slmSendBytesSize]); - uint32_t readUnits = 0; - uint32_t bytesAlreadyRead = 0; - - sipCommand.offset = alignedOffset; - - for (uint32_t loop = 0; loop < loops; loop++) { - - if (remainingSlmSendUnits >= maxUnitsPerLoop) { - readUnits = maxUnitsPerLoop; - } else { - readUnits = remainingSlmSendUnits; - } - - sipCommand.command = static_cast(NEO::SipKernel::COMMAND::SLM_READ); - sipCommand.size = static_cast(readUnits); - - status = cmdRegisterAccessHelper(threadId, sipCommand, true); - if (status != ZE_RESULT_SUCCESS) { - return status; - } - - status = resumeImp(std::vector{threadId}, threadId.tileIndex); - if (status != ZE_RESULT_SUCCESS) { - return status; - } - - status = waitForCmdReady(threadId, sipRetryCount); - if (status != ZE_RESULT_SUCCESS) { - return status; - } - - status = cmdRegisterAccessHelper(threadId, sipCommand, false); - if (status != ZE_RESULT_SUCCESS) { - return status; - } - - memcpy_s(tmpBuffer.get() + bytesAlreadyRead, readUnits * slmSendBytesSize, sipCommand.buffer, readUnits * slmSendBytesSize); - - remainingSlmSendUnits -= readUnits; - bytesAlreadyRead += readUnits * slmSendBytesSize; - sipCommand.offset += readUnits * slmSendBytesSize; - } - - memcpy_s(buffer, size, tmpBuffer.get() + frontPadding, size); - - return ZE_RESULT_SUCCESS; -} - -ze_result_t DebugSessionImp::writeSLMMemory(EuThread::ThreadId threadId, const zet_debug_memory_space_desc_t *desc, size_t size, const void *buffer) { - ze_result_t status; - SIP::sip_command sipCommand = {0}; - - uint64_t offset = desc->address & maxNBitValue(slmAddressSpaceTag); - // SIP accesses SLM in units of slmSendBytesSize at offset allignment of slmSendBytesSize - uint32_t frontPadding = offset % slmSendBytesSize; - uint64_t alignedOffset = offset - frontPadding; - uint32_t remainingSlmSendUnits = static_cast(std::ceil(static_cast(size) / slmSendBytesSize)); - size_t tailPadding = (size % slmSendBytesSize) ? slmSendBytesSize - (size % slmSendBytesSize) : 0; - - if ((size + frontPadding) > (remainingSlmSendUnits * slmSendBytesSize)) { - remainingSlmSendUnits++; - } - - std::unique_ptr tmpBuffer(new char[remainingSlmSendUnits * slmSendBytesSize]); - - if ((frontPadding || tailPadding)) { - - zet_debug_memory_space_desc_t alignedDesc = *desc; - alignedDesc.address = desc->address - frontPadding; - size_t alignedSize = remainingSlmSendUnits * slmSendBytesSize; - - status = readSLMMemory(threadId, &alignedDesc, alignedSize, tmpBuffer.get()); - if (status != ZE_RESULT_SUCCESS) { - return status; - } - } - - memcpy_s(tmpBuffer.get() + frontPadding, size, buffer, size); - - status = waitForCmdReady(threadId, sipRetryCount); - if (status != ZE_RESULT_SUCCESS) { - return status; - } - - uint32_t loops = static_cast(std::ceil(static_cast(remainingSlmSendUnits) / maxUnitsPerLoop)); - - uint32_t writeUnits = 0; - uint32_t bytesAlreadyWritten = 0; - - sipCommand.offset = alignedOffset; - - for (uint32_t loop = 0; loop < loops; loop++) { - - if (remainingSlmSendUnits >= maxUnitsPerLoop) { - writeUnits = maxUnitsPerLoop; - } else { - writeUnits = remainingSlmSendUnits; - } - - sipCommand.command = static_cast(NEO::SipKernel::COMMAND::SLM_WRITE); - sipCommand.size = static_cast(writeUnits); - memcpy_s(sipCommand.buffer, writeUnits * slmSendBytesSize, tmpBuffer.get() + bytesAlreadyWritten, writeUnits * slmSendBytesSize); - - status = cmdRegisterAccessHelper(threadId, sipCommand, true); - if (status != ZE_RESULT_SUCCESS) { - return status; - } - - status = resumeImp(std::vector{threadId}, threadId.tileIndex); - if (status != ZE_RESULT_SUCCESS) { - return status; - } - - status = waitForCmdReady(threadId, sipRetryCount); - if (status != ZE_RESULT_SUCCESS) { - return status; - } - - remainingSlmSendUnits -= writeUnits; - bytesAlreadyWritten += writeUnits * slmSendBytesSize; - sipCommand.offset += writeUnits * slmSendBytesSize; - } - - return ZE_RESULT_SUCCESS; -} - } // namespace L0 diff --git a/level_zero/tools/source/debug/debug_session_imp.h b/level_zero/tools/source/debug/debug_session_imp.h index a1525f7235..e3a5600ebc 100644 --- a/level_zero/tools/source/debug/debug_session_imp.h +++ b/level_zero/tools/source/debug/debug_session_imp.h @@ -8,6 +8,7 @@ #pragma once #include "shared/source/built_ins/sip.h" +#include "shared/source/helpers/string.h" #include "level_zero/tools/source/debug/debug_session.h" @@ -80,10 +81,9 @@ struct DebugSessionImp : DebugSession { virtual ze_result_t readGpuMemory(uint64_t memoryHandle, char *output, size_t size, uint64_t gpuVa) = 0; virtual ze_result_t writeGpuMemory(uint64_t memoryHandle, const char *input, size_t size, uint64_t gpuVa) = 0; - ze_result_t readSLMMemory(EuThread::ThreadId threadId, const zet_debug_memory_space_desc_t *desc, - size_t size, void *buffer); - ze_result_t writeSLMMemory(EuThread::ThreadId threadId, const zet_debug_memory_space_desc_t *desc, - size_t size, const void *buffer); + + template + ze_result_t slmMemoryAccess(EuThread::ThreadId threadId, const zet_debug_memory_space_desc_t *desc, size_t size, bufferType buffer); ze_result_t validateThreadAndDescForMemoryAccess(ze_device_thread_t thread, const zet_debug_memory_space_desc_t *desc); @@ -101,13 +101,15 @@ struct DebugSessionImp : DebugSession { MOCKABLE_VIRTUAL void generateEventsForPendingInterrupts(); const SIP::StateSaveAreaHeader *getStateSaveAreaHeader(); - void validateAndSetStateSaveAreaHeader(const std::vector &data); + void validateAndSetStateSaveAreaHeader(uint64_t vmHandle, uint64_t gpuVa); virtual void readStateSaveAreaHeader(){}; virtual uint64_t getContextStateSaveAreaGpuVa(uint64_t memoryHandle) = 0; ze_result_t registersAccessHelper(const EuThread *thread, const SIP::regset_desc *regdesc, uint32_t start, uint32_t count, void *pRegisterValues, bool write); + + void slmSipVersionCheck(); MOCKABLE_VIRTUAL ze_result_t cmdRegisterAccessHelper(const EuThread::ThreadId &threadId, SIP::sip_command &command, bool write); MOCKABLE_VIRTUAL ze_result_t waitForCmdReady(EuThread::ThreadId threadId, uint16_t retryCount); @@ -151,6 +153,8 @@ struct DebugSessionImp : DebugSession { std::vector> pendingInterrupts; std::vector newlyStoppedThreads; std::vector stateSaveAreaHeader; + SIP::version minSlmSipVersion = {2, 0, 0}; + bool sipSupportsSlm = false; std::vector> tileSessions; // DebugSession, attached bool tileAttachEnabled = false; @@ -167,4 +171,105 @@ struct DebugSessionImp : DebugSession { uint32_t maxUnitsPerLoop = EXCHANGE_BUFFER_SIZE / slmSendBytesSize; }; +template +ze_result_t DebugSessionImp::slmMemoryAccess(EuThread::ThreadId threadId, const zet_debug_memory_space_desc_t *desc, size_t size, bufferType buffer) { + ze_result_t status; + + if (!sipSupportsSlm) { + return ZE_RESULT_ERROR_UNSUPPORTED_VERSION; + } + + SIP::sip_command sipCommand = {0}; + + uint64_t offset = desc->address & maxNBitValue(slmAddressSpaceTag); + // SIP accesses SLM in units of slmSendBytesSize at offset allignment of slmSendBytesSize + uint32_t frontPadding = offset % slmSendBytesSize; + uint64_t alignedOffset = offset - frontPadding; + uint32_t remainingSlmSendUnits = static_cast(std::ceil(static_cast(size) / slmSendBytesSize)); + + if ((size + frontPadding) > (remainingSlmSendUnits * slmSendBytesSize)) { + remainingSlmSendUnits++; + } + + std::unique_ptr tmpBuffer(new char[remainingSlmSendUnits * slmSendBytesSize]); + + if constexpr (write) { + size_t tailPadding = (size % slmSendBytesSize) ? slmSendBytesSize - (size % slmSendBytesSize) : 0; + if ((frontPadding || tailPadding)) { + zet_debug_memory_space_desc_t alignedDesc = *desc; + alignedDesc.address = desc->address - frontPadding; + size_t alignedSize = remainingSlmSendUnits * slmSendBytesSize; + + status = slmMemoryAccess(threadId, &alignedDesc, alignedSize, tmpBuffer.get()); + if (status != ZE_RESULT_SUCCESS) { + return status; + } + } + + memcpy_s(tmpBuffer.get() + frontPadding, size, buffer, size); + } + + status = waitForCmdReady(threadId, sipRetryCount); + if (status != ZE_RESULT_SUCCESS) { + return status; + } + + uint32_t loops = static_cast(std::ceil(static_cast(remainingSlmSendUnits) / maxUnitsPerLoop)); + uint32_t accessUnits = 0; + uint32_t countReadyBytes = 0; + sipCommand.offset = alignedOffset; + + for (uint32_t loop = 0; loop < loops; loop++) { + + if (remainingSlmSendUnits >= maxUnitsPerLoop) { + accessUnits = maxUnitsPerLoop; + } else { + accessUnits = remainingSlmSendUnits; + } + + if constexpr (write) { + sipCommand.command = static_cast(NEO::SipKernel::COMMAND::SLM_WRITE); + sipCommand.size = static_cast(accessUnits); + memcpy_s(sipCommand.buffer, accessUnits * slmSendBytesSize, tmpBuffer.get() + countReadyBytes, accessUnits * slmSendBytesSize); + } else { + sipCommand.command = static_cast(NEO::SipKernel::COMMAND::SLM_READ); + sipCommand.size = static_cast(accessUnits); + } + + status = cmdRegisterAccessHelper(threadId, sipCommand, true); + if (status != ZE_RESULT_SUCCESS) { + return status; + } + + status = resumeImp(std::vector{threadId}, threadId.tileIndex); + if (status != ZE_RESULT_SUCCESS) { + return status; + } + + status = waitForCmdReady(threadId, sipRetryCount); + if (status != ZE_RESULT_SUCCESS) { + return status; + } + + if constexpr (!write) { // Read need an extra access to retrieve data + status = cmdRegisterAccessHelper(threadId, sipCommand, false); + if (status != ZE_RESULT_SUCCESS) { + return status; + } + + memcpy_s(tmpBuffer.get() + countReadyBytes, accessUnits * slmSendBytesSize, sipCommand.buffer, accessUnits * slmSendBytesSize); + } + + remainingSlmSendUnits -= accessUnits; + countReadyBytes += accessUnits * slmSendBytesSize; + sipCommand.offset += accessUnits * slmSendBytesSize; + } + + if constexpr (!write) { + memcpy_s(buffer, size, tmpBuffer.get() + frontPadding, size); + } + + return ZE_RESULT_SUCCESS; +} + } // namespace L0 diff --git a/level_zero/tools/source/debug/linux/prelim/debug_session.cpp b/level_zero/tools/source/debug/linux/prelim/debug_session.cpp index 7614a6362d..e550afd6bf 100644 --- a/level_zero/tools/source/debug/linux/prelim/debug_session.cpp +++ b/level_zero/tools/source/debug/linux/prelim/debug_session.cpp @@ -781,14 +781,8 @@ void DebugSessionLinux::readStateSaveAreaHeader() { if (totalSize < headerSize) { PRINT_DEBUGGER_ERROR_LOG("Context State Save Area size incorrect\n", ""); return; - } - std::vector data(headerSize); - auto retVal = readGpuMemory(vm, data.data(), headerSize, gpuVa); - - if (retVal != 0) { - PRINT_DEBUGGER_ERROR_LOG("Reading Context State Save Area failed, error = %d\n", retVal); } else { - validateAndSetStateSaveAreaHeader(data); + validateAndSetStateSaveAreaHeader(vm, gpuVa); } } } @@ -1610,7 +1604,7 @@ ze_result_t DebugSessionLinux::readMemory(ze_device_thread_t thread, const zet_d status = readDefaultMemory(thread, desc, size, buffer); } else { auto threadId = convertToThreadId(thread); - status = readSLMMemory(threadId, desc, size, buffer); + status = slmMemoryAccess(threadId, desc, size, buffer); } return status; @@ -1652,7 +1646,7 @@ ze_result_t DebugSessionLinux::writeMemory(ze_device_thread_t thread, const zet_ status = writeDefaultMemory(thread, desc, size, buffer); } else { auto threadId = convertToThreadId(thread); - status = writeSLMMemory(threadId, desc, size, buffer); + status = slmMemoryAccess(threadId, desc, size, buffer); } return status; diff --git a/level_zero/tools/source/debug/windows/debug_session.cpp b/level_zero/tools/source/debug/windows/debug_session.cpp index 8e964ec79b..1e76ea66d7 100644 --- a/level_zero/tools/source/debug/windows/debug_session.cpp +++ b/level_zero/tools/source/debug/windows/debug_session.cpp @@ -459,7 +459,7 @@ ze_result_t DebugSessionWindows::readMemory(ze_device_thread_t thread, const zet status = readDefaultMemory(thread, desc, size, buffer); } else { auto threadId = convertToThreadId(thread); - status = readSLMMemory(threadId, desc, size, buffer); + status = slmMemoryAccess(threadId, desc, size, buffer); } return status; @@ -504,7 +504,7 @@ ze_result_t DebugSessionWindows::writeMemory(ze_device_thread_t thread, const ze status = writeDefaultMemory(thread, desc, size, buffer); } else { auto threadId = convertToThreadId(thread); - status = writeSLMMemory(threadId, desc, size, buffer); + status = slmMemoryAccess(threadId, desc, size, buffer); } return status; @@ -714,16 +714,7 @@ void DebugSessionWindows::readStateSaveAreaHeader() { memoryHandle = *allContexts.begin(); } - auto headerSize = sizeof(SIP::StateSaveAreaHeader); - std::vector data(headerSize); - auto retVal = readGpuMemory(memoryHandle, data.data(), headerSize, gpuVa); - - if (retVal != ZE_RESULT_SUCCESS) { - PRINT_DEBUGGER_ERROR_LOG("Reading Context State Save Area failed, error = %d\n", retVal); - return; - } - - validateAndSetStateSaveAreaHeader(data); + validateAndSetStateSaveAreaHeader(memoryHandle, gpuVa); } } // namespace L0 diff --git a/level_zero/tools/test/unit_tests/sources/debug/debug_session_tests.cpp b/level_zero/tools/test/unit_tests/sources/debug/debug_session_tests.cpp index 1abd4a7696..093bfb9757 100644 --- a/level_zero/tools/test/unit_tests/sources/debug/debug_session_tests.cpp +++ b/level_zero/tools/test/unit_tests/sources/debug/debug_session_tests.cpp @@ -2040,6 +2040,90 @@ TEST_F(DebugSessionRegistersAccessTest, WhenReadingSbaRegistersThenCorrectAddres EXPECT_EQ(sbaExpected[ZET_DEBUG_SBA_SCRATCH_SPACE_INTEL_GPU], sba[ZET_DEBUG_SBA_SCRATCH_SPACE_INTEL_GPU]); } +TEST_F(DebugSessionRegistersAccessTest, GivenBindlessSipWhenCheckingDifferentSipVersionsThenExpectedResultIsReturned) { + session->debugArea.reserved1 = 1u; + session->stateSaveAreaHeader = MockSipData::createStateSaveAreaHeader(2); + + { + auto pStateSaveAreaHeader = reinterpret_cast(session->stateSaveAreaHeader.data()); + auto size = pStateSaveAreaHeader->versionHeader.size * 8 + + pStateSaveAreaHeader->regHeader.state_area_offset + + pStateSaveAreaHeader->regHeader.state_save_size * 16; + session->stateSaveAreaHeader.resize(size); + } + + ze_device_thread_t thread = {0, 0, 0, 0}; + EuThread::ThreadId threadId(0, thread); + session->allThreads[threadId]->stopThread(1u); + + dumpRegisterState(); + session->minSlmSipVersion = {2, 2, 2}; + // test tssarea version + // Major version cases + reinterpret_cast(session->stateSaveAreaHeader.data())->version.major = 2; + reinterpret_cast(session->stateSaveAreaHeader.data())->version.minor = 2; + reinterpret_cast(session->stateSaveAreaHeader.data())->version.patch = 2; + session->slmSipVersionCheck(); + EXPECT_EQ(session->sipSupportsSlm, true); + + reinterpret_cast(session->stateSaveAreaHeader.data())->version.major = 1; + session->slmSipVersionCheck(); + EXPECT_EQ(session->sipSupportsSlm, false); + + // Minor version cases + reinterpret_cast(session->stateSaveAreaHeader.data())->version.major = 2; + reinterpret_cast(session->stateSaveAreaHeader.data())->version.minor = 1; + session->slmSipVersionCheck(); + EXPECT_EQ(session->sipSupportsSlm, false); + + reinterpret_cast(session->stateSaveAreaHeader.data())->version.major = 3; + reinterpret_cast(session->stateSaveAreaHeader.data())->version.minor = 1; + session->slmSipVersionCheck(); + EXPECT_EQ(session->sipSupportsSlm, true); + + reinterpret_cast(session->stateSaveAreaHeader.data())->version.major = 3; + reinterpret_cast(session->stateSaveAreaHeader.data())->version.minor = 2; + session->slmSipVersionCheck(); + EXPECT_EQ(session->sipSupportsSlm, true); + + // patch version cases + reinterpret_cast(session->stateSaveAreaHeader.data())->version.major = 2; + reinterpret_cast(session->stateSaveAreaHeader.data())->version.minor = 2; + reinterpret_cast(session->stateSaveAreaHeader.data())->version.patch = 1; + session->slmSipVersionCheck(); + EXPECT_EQ(session->sipSupportsSlm, false); + + reinterpret_cast(session->stateSaveAreaHeader.data())->version.major = 2; + reinterpret_cast(session->stateSaveAreaHeader.data())->version.minor = 3; + reinterpret_cast(session->stateSaveAreaHeader.data())->version.patch = 1; + session->slmSipVersionCheck(); + EXPECT_EQ(session->sipSupportsSlm, true); + + reinterpret_cast(session->stateSaveAreaHeader.data())->version.major = 2; + reinterpret_cast(session->stateSaveAreaHeader.data())->version.minor = 3; + reinterpret_cast(session->stateSaveAreaHeader.data())->version.patch = 2; + session->slmSipVersionCheck(); + EXPECT_EQ(session->sipSupportsSlm, true); + + reinterpret_cast(session->stateSaveAreaHeader.data())->version.major = 3; + reinterpret_cast(session->stateSaveAreaHeader.data())->version.minor = 2; + reinterpret_cast(session->stateSaveAreaHeader.data())->version.patch = 1; + session->slmSipVersionCheck(); + EXPECT_EQ(session->sipSupportsSlm, true); + + reinterpret_cast(session->stateSaveAreaHeader.data())->version.major = 3; + reinterpret_cast(session->stateSaveAreaHeader.data())->version.minor = 2; + reinterpret_cast(session->stateSaveAreaHeader.data())->version.patch = 2; + session->slmSipVersionCheck(); + EXPECT_EQ(session->sipSupportsSlm, true); + + reinterpret_cast(session->stateSaveAreaHeader.data())->version.major = 3; + reinterpret_cast(session->stateSaveAreaHeader.data())->version.minor = 3; + reinterpret_cast(session->stateSaveAreaHeader.data())->version.patch = 1; + session->slmSipVersionCheck(); + EXPECT_EQ(session->sipSupportsSlm, true); +} + TEST(DebugSessionTest, GivenStoppedThreadWhenValidAddressesSizesAndOffsetsThenSlmReadIsSuccessful) { zet_debug_config_t config = {}; @@ -2067,29 +2151,30 @@ TEST(DebugSessionTest, GivenStoppedThreadWhenValidAddressesSizesAndOffsetsThenSl memset(output, 0, EXCHANGE_BUFFER_SIZE * 3); sessionMock->slmTesting = true; + sessionMock->sipSupportsSlm = true; int readSize = 7; - auto retVal = sessionMock->readSLMMemory(threadId, &desc, readSize, output); + auto retVal = sessionMock->slmMemoryAccess(threadId, &desc, readSize, output); EXPECT_EQ(ZE_RESULT_SUCCESS, retVal); EXPECT_EQ(memcmp(output, sessionMock->slmMemory, readSize), 0); memset(output, 0, readSize); int offset = 0x05; desc.address = 0x10000000 + offset; - retVal = sessionMock->readSLMMemory(threadId, &desc, readSize, output); + retVal = sessionMock->slmMemoryAccess(threadId, &desc, readSize, output); EXPECT_EQ(ZE_RESULT_SUCCESS, retVal); EXPECT_EQ(memcmp(output, sessionMock->slmMemory + offset, readSize), 0); memset(output, 0, readSize); offset = 0x0f; desc.address = 0x10000000 + offset; - retVal = sessionMock->readSLMMemory(threadId, &desc, readSize, output); + retVal = sessionMock->slmMemoryAccess(threadId, &desc, readSize, output); EXPECT_EQ(ZE_RESULT_SUCCESS, retVal); EXPECT_EQ(memcmp(output, sessionMock->slmMemory + offset, readSize), 0); memset(output, 0, readSize); readSize = 132; - retVal = sessionMock->readSLMMemory(threadId, &desc, readSize, output); + retVal = sessionMock->slmMemoryAccess(threadId, &desc, readSize, output); EXPECT_EQ(ZE_RESULT_SUCCESS, retVal); EXPECT_EQ(memcmp(output, sessionMock->slmMemory + offset, readSize), 0); memset(output, 0, readSize); @@ -2097,7 +2182,7 @@ TEST(DebugSessionTest, GivenStoppedThreadWhenValidAddressesSizesAndOffsetsThenSl readSize = 230; offset = 0x0a; desc.address = 0x10000000 + offset; - retVal = sessionMock->readSLMMemory(threadId, &desc, readSize, output); + retVal = sessionMock->slmMemoryAccess(threadId, &desc, readSize, output); EXPECT_EQ(ZE_RESULT_SUCCESS, retVal); EXPECT_EQ(memcmp(output, sessionMock->slmMemory + offset, readSize), 0); @@ -2118,21 +2203,29 @@ TEST(DebugSessionTest, GivenStoppedThreadWhenUnderInvalidConditionsThenSlmReadFa EuThread::ThreadId threadId(0, 0, 0, 0, 0); sessionMock->allThreads[threadId]->stopThread(1u); - sessionMock->slmTesting = true; + sessionMock->skipWriteResumeCommand = false; zet_debug_memory_space_desc_t desc; desc.address = 0x10000000; desc.type = ZET_DEBUG_MEMORY_SPACE_TYPE_SLM; - sessionMock->skipWriteResumeCommand = false; - memcpy_s(sessionMock->originalSlmMemory, sessionMock->slmSize, sessionMock->slmMemory, sessionMock->slmSize); - constexpr int readSize = EXCHANGE_BUFFER_SIZE * 2; char output[readSize]; ze_result_t retVal; + sessionMock->slmTesting = true; + + memcpy_s(sessionMock->originalSlmMemory, sessionMock->slmSize, sessionMock->slmMemory, sessionMock->slmSize); + + sessionMock->sipSupportsSlm = false; + + retVal = sessionMock->slmMemoryAccess(threadId, &desc, readSize, output); + EXPECT_EQ(ZE_RESULT_ERROR_UNSUPPORTED_VERSION, retVal); + + sessionMock->sipSupportsSlm = true; + sessionMock->resumeImpResult = ZE_RESULT_ERROR_UNKNOWN; - retVal = sessionMock->readSLMMemory(threadId, &desc, readSize, output); + retVal = sessionMock->slmMemoryAccess(threadId, &desc, readSize, output); EXPECT_EQ(ZE_RESULT_ERROR_UNKNOWN, retVal); sessionMock->resumeImpResult = ZE_RESULT_SUCCESS; @@ -2140,24 +2233,24 @@ TEST(DebugSessionTest, GivenStoppedThreadWhenUnderInvalidConditionsThenSlmReadFa sessionMock->slmCmdRegisterCmdvalue = static_cast(NEO::SipKernel::COMMAND::RESUME); sessionMock->forceCmdAccessFail = true; - retVal = sessionMock->readSLMMemory(threadId, &desc, readSize, output); + retVal = sessionMock->slmMemoryAccess(threadId, &desc, readSize, output); EXPECT_EQ(ZE_RESULT_FORCE_UINT32, retVal); sessionMock->forceCmdAccessFail = false; memcpy_s(sessionMock->slmMemory, strlen("FailReadingData"), "FailReadingData", strlen("FailReadingData")); - retVal = sessionMock->readSLMMemory(threadId, &desc, readSize, output); + retVal = sessionMock->slmMemoryAccess(threadId, &desc, readSize, output); EXPECT_EQ(ZE_RESULT_FORCE_UINT32, retVal); memcpy_s(sessionMock->slmMemory, strlen("FailReadingData"), sessionMock->originalSlmMemory, strlen("FailReadingData")); sessionMock->slmCmdRegisterAccessReadyCount = 13; - retVal = sessionMock->readSLMMemory(threadId, &desc, readSize, output); + retVal = sessionMock->slmMemoryAccess(threadId, &desc, readSize, output); EXPECT_EQ(ZE_RESULT_ERROR_NOT_AVAILABLE, retVal); sessionMock->slmCmdRegisterAccessReadyCount = 2; sessionMock->slmCmdRegisterAccessCount = 0; sessionMock->slmCmdRegisterCmdvalue = static_cast(NEO::SipKernel::COMMAND::RESUME); memcpy_s(sessionMock->slmMemory, strlen("FailWaiting"), "FailWaiting", strlen("FailWaiting")); - retVal = sessionMock->readSLMMemory(threadId, &desc, readSize, output); + retVal = sessionMock->slmMemoryAccess(threadId, &desc, readSize, output); EXPECT_EQ(ZE_RESULT_FORCE_UINT32, retVal); memcpy_s(sessionMock->slmMemory, strlen("FailWaiting"), sessionMock->originalSlmMemory, strlen("FailWaiting")); @@ -2179,6 +2272,7 @@ TEST(DebugSessionTest, GivenStoppedThreadWhenValidAddressesSizesAndOffsetsThenSl sessionMock->allThreads[threadId]->stopThread(1u); sessionMock->slmTesting = true; + sessionMock->sipSupportsSlm = true; int i; for (i = 0; i < sessionMock->slmSize; i++) { @@ -2197,7 +2291,7 @@ TEST(DebugSessionTest, GivenStoppedThreadWhenValidAddressesSizesAndOffsetsThenSl int inputSize = 7; memset(input1, 0xff, inputSize); - retVal = sessionMock->writeSLMMemory(threadId, &desc, inputSize, input1); + retVal = sessionMock->slmMemoryAccess(threadId, &desc, inputSize, input1); EXPECT_EQ(ZE_RESULT_SUCCESS, retVal); EXPECT_EQ(memcmp(sessionMock->slmMemory, input1, inputSize), 0); EXPECT_EQ(memcmp(sessionMock->slmMemory + inputSize + 1, sessionMock->originalSlmMemory + inputSize + 1, sessionMock->slmSize - inputSize - 1), 0); @@ -2205,7 +2299,7 @@ TEST(DebugSessionTest, GivenStoppedThreadWhenValidAddressesSizesAndOffsetsThenSl memset(input2, 0xbb, inputSize); int offset = 0x05; desc.address = 0x10000000 + offset; - retVal = sessionMock->writeSLMMemory(threadId, &desc, inputSize, input2); + retVal = sessionMock->slmMemoryAccess(threadId, &desc, inputSize, input2); EXPECT_EQ(ZE_RESULT_SUCCESS, retVal); EXPECT_EQ(memcmp(sessionMock->slmMemory, input1, offset), 0); @@ -2217,7 +2311,7 @@ TEST(DebugSessionTest, GivenStoppedThreadWhenValidAddressesSizesAndOffsetsThenSl desc.address = 0x10000000; memset(input1, 0x0a, inputSize); - retVal = sessionMock->writeSLMMemory(threadId, &desc, inputSize, input1); + retVal = sessionMock->slmMemoryAccess(threadId, &desc, inputSize, input1); EXPECT_EQ(ZE_RESULT_SUCCESS, retVal); EXPECT_EQ(memcmp(sessionMock->slmMemory, input1, inputSize), 0); @@ -2227,7 +2321,7 @@ TEST(DebugSessionTest, GivenStoppedThreadWhenValidAddressesSizesAndOffsetsThenSl offset = 0x07; desc.address = 0x10000000 + offset; - retVal = sessionMock->writeSLMMemory(threadId, &desc, inputSize, input2); + retVal = sessionMock->slmMemoryAccess(threadId, &desc, inputSize, input2); EXPECT_EQ(ZE_RESULT_SUCCESS, retVal); EXPECT_EQ(memcmp(sessionMock->slmMemory, input1, offset), 0); @@ -2242,7 +2336,7 @@ TEST(DebugSessionTest, GivenStoppedThreadWhenValidAddressesSizesAndOffsetsThenSl offset = 0x0f; desc.address = 0x10000000 + offset; - retVal = sessionMock->writeSLMMemory(threadId, &desc, inputSize, input1); + retVal = sessionMock->slmMemoryAccess(threadId, &desc, inputSize, input1); EXPECT_EQ(ZE_RESULT_SUCCESS, retVal); EXPECT_EQ(memcmp(sessionMock->slmMemory, sessionMock->originalSlmMemory, offset), 0); @@ -2255,7 +2349,7 @@ TEST(DebugSessionTest, GivenStoppedThreadWhenValidAddressesSizesAndOffsetsThenSl offset = 0x0a; desc.address = 0x10000000 + offset; - retVal = sessionMock->writeSLMMemory(threadId, &desc, inputSize, input2); + retVal = sessionMock->slmMemoryAccess(threadId, &desc, inputSize, input2); EXPECT_EQ(ZE_RESULT_SUCCESS, retVal); EXPECT_EQ(memcmp(sessionMock->slmMemory, sessionMock->originalSlmMemory, offset), 0); @@ -2291,28 +2385,35 @@ TEST(DebugSessionTest, GivenStoppedThreadWhenUnderInvalidConditionsThenSlmWriteF char input[writeSize]; ze_result_t retVal; + sessionMock->sipSupportsSlm = false; + + retVal = sessionMock->slmMemoryAccess(threadId, &desc, writeSize, input); + EXPECT_EQ(ZE_RESULT_ERROR_UNSUPPORTED_VERSION, retVal); + + sessionMock->sipSupportsSlm = true; + sessionMock->resumeImpResult = ZE_RESULT_ERROR_UNKNOWN; - retVal = sessionMock->writeSLMMemory(threadId, &desc, writeSize, input); + retVal = sessionMock->slmMemoryAccess(threadId, &desc, writeSize, input); EXPECT_EQ(ZE_RESULT_ERROR_UNKNOWN, retVal); sessionMock->resumeImpResult = ZE_RESULT_SUCCESS; sessionMock->forceCmdAccessFail = true; - retVal = sessionMock->writeSLMMemory(threadId, &desc, writeSize, input); + retVal = sessionMock->slmMemoryAccess(threadId, &desc, writeSize, input); EXPECT_EQ(ZE_RESULT_FORCE_UINT32, retVal); sessionMock->forceCmdAccessFail = false; sessionMock->slmCmdRegisterAccessReadyCount = 13; - retVal = sessionMock->writeSLMMemory(threadId, &desc, writeSize, input); + retVal = sessionMock->slmMemoryAccess(threadId, &desc, writeSize, input); EXPECT_EQ(ZE_RESULT_ERROR_NOT_AVAILABLE, retVal); sessionMock->slmCmdRegisterAccessCount = 0; sessionMock->slmCmdRegisterCmdvalue = static_cast(NEO::SipKernel::COMMAND::RESUME); - retVal = sessionMock->writeSLMMemory(threadId, &desc, writeSize, input); + retVal = sessionMock->slmMemoryAccess(threadId, &desc, writeSize, input); EXPECT_EQ(ZE_RESULT_ERROR_NOT_AVAILABLE, retVal); - desc.address = 0x1000000f; // force a read - retVal = sessionMock->writeSLMMemory(threadId, &desc, writeSize, input); + desc.address = 0x1000000f; //force a read + retVal = sessionMock->slmMemoryAccess(threadId, &desc, writeSize, input); EXPECT_EQ(ZE_RESULT_ERROR_NOT_AVAILABLE, retVal); sessionMock->slmCmdRegisterAccessReadyCount = 2; sessionMock->slmCmdRegisterAccessCount = 0; @@ -2320,7 +2421,7 @@ TEST(DebugSessionTest, GivenStoppedThreadWhenUnderInvalidConditionsThenSlmWriteF desc.address = 0x10000000; memcpy_s(sessionMock->slmMemory, strlen("FailWaiting"), "FailWaiting", strlen("FailWaiting")); - retVal = sessionMock->writeSLMMemory(threadId, &desc, writeSize, input); + retVal = sessionMock->slmMemoryAccess(threadId, &desc, writeSize, input); EXPECT_EQ(ZE_RESULT_FORCE_UINT32, retVal); memcpy_s(sessionMock->slmMemory, strlen("FailWaiting"), sessionMock->originalSlmMemory, strlen("FailWaiting")); diff --git a/level_zero/tools/test/unit_tests/sources/debug/linux/debug_session_fixtures_linux.h b/level_zero/tools/test/unit_tests/sources/debug/linux/debug_session_fixtures_linux.h index b3f9045858..99e27c5617 100644 --- a/level_zero/tools/test/unit_tests/sources/debug/linux/debug_session_fixtures_linux.h +++ b/level_zero/tools/test/unit_tests/sources/debug/linux/debug_session_fixtures_linux.h @@ -243,6 +243,7 @@ struct MockDebugSessionLinux : public L0::DebugSessionLinux { using L0::DebugSessionImp::interruptSent; using L0::DebugSessionImp::isValidGpuAddress; using L0::DebugSessionImp::newAttentionRaised; + using L0::DebugSessionImp::sipSupportsSlm; using L0::DebugSessionImp::stateSaveAreaHeader; using L0::DebugSessionImp::tileAttachEnabled; using L0::DebugSessionImp::tileSessions; diff --git a/level_zero/tools/test/unit_tests/sources/debug/linux/test_debug_api_linux.cpp b/level_zero/tools/test/unit_tests/sources/debug/linux/test_debug_api_linux.cpp index 8b85889df4..0b75c04d5f 100644 --- a/level_zero/tools/test/unit_tests/sources/debug/linux/test_debug_api_linux.cpp +++ b/level_zero/tools/test/unit_tests/sources/debug/linux/test_debug_api_linux.cpp @@ -6533,6 +6533,8 @@ TEST_F(DebugApiRegistersAccessTest, GivenSipNotUpdatingSipCmdThenAccessToSlmFail char output[bufferSize]; session->ensureThreadStopped(thread); + session->sipSupportsSlm = true; + auto retVal = session->readMemory(thread, &desc, bufferSize, output); EXPECT_EQ(ZE_RESULT_ERROR_NOT_AVAILABLE, retVal); diff --git a/level_zero/tools/test/unit_tests/sources/debug/mock_debug_session.h b/level_zero/tools/test/unit_tests/sources/debug/mock_debug_session.h index 4fa2eb86b3..935c5fa50f 100644 --- a/level_zero/tools/test/unit_tests/sources/debug/mock_debug_session.h +++ b/level_zero/tools/test/unit_tests/sources/debug/mock_debug_session.h @@ -162,13 +162,15 @@ struct MockDebugSession : public L0::DebugSessionImp { using L0::DebugSessionImp::interruptMutex; using L0::DebugSessionImp::interruptRequests; using L0::DebugSessionImp::isValidGpuAddress; + using L0::DebugSessionImp::minSlmSipVersion; using L0::DebugSessionImp::newlyStoppedThreads; using L0::DebugSessionImp::pendingInterrupts; - using L0::DebugSessionImp::readSLMMemory; using L0::DebugSessionImp::readStateSaveAreaHeader; + using L0::DebugSessionImp::sipSupportsSlm; + using L0::DebugSessionImp::slmMemoryAccess; + using L0::DebugSessionImp::slmSipVersionCheck; using L0::DebugSessionImp::tileAttachEnabled; using L0::DebugSessionImp::tileSessions; - using L0::DebugSessionImp::writeSLMMemory; MockDebugSession(const zet_debug_config_t &config, L0::Device *device) : MockDebugSession(config, device, true) {} diff --git a/level_zero/tools/test/unit_tests/sources/debug/windows/test_debug_api_windows.cpp b/level_zero/tools/test/unit_tests/sources/debug/windows/test_debug_api_windows.cpp index 9c44f255db..c9b039b365 100644 --- a/level_zero/tools/test/unit_tests/sources/debug/windows/test_debug_api_windows.cpp +++ b/level_zero/tools/test/unit_tests/sources/debug/windows/test_debug_api_windows.cpp @@ -64,6 +64,7 @@ struct MockDebugSessionWindows : DebugSessionWindows { using L0::DebugSessionImp::getStateSaveAreaHeader; using L0::DebugSessionImp::interruptSent; using L0::DebugSessionImp::isValidGpuAddress; + using L0::DebugSessionImp::sipSupportsSlm; using L0::DebugSessionImp::stateSaveAreaHeader; using L0::DebugSessionImp::triggerEvents; using L0::DebugSessionWindows::newlyStoppedThreads; @@ -1655,6 +1656,8 @@ TEST_F(DebugApiWindowsTest, GivenSipNotUpdatingSipCmdThenAccessToSlmFailsGracefu ze_device_thread_t thread = {0, 0, 0, 0}; session->allThreads[EuThread::ThreadId(0, thread)]->stopThread(1u); + session->sipSupportsSlm = true; + zet_debug_memory_space_desc_t desc; desc.type = ZET_DEBUG_MEMORY_SPACE_TYPE_SLM; desc.address = 0x10000000;