mirror of
https://github.com/intel/compute-runtime.git
synced 2026-01-03 14:55:24 +08:00
L0 Debugger Win - read SBA tracking buffer address
MMIO will store SBA tracking buffer address for current context. This change helps in extracting this address and use to read SBA virtual register. Related-To: NEO-6765 Signed-off-by: Jitendra Sharma <jitendra.sharma@intel.com>
This commit is contained in:
committed by
Compute-Runtime-Automation
parent
4ece30528c
commit
c86c518bc4
@@ -7,6 +7,8 @@
|
||||
|
||||
#include "level_zero/tools/source/debug/windows/debug_session.h"
|
||||
|
||||
#include "shared/source/helpers/register_offsets.h"
|
||||
|
||||
namespace L0 {
|
||||
|
||||
DebugSession *createDebugSessionHelper(const zet_debug_config_t &config, Device *device, int debugFd);
|
||||
@@ -456,8 +458,39 @@ bool DebugSessionWindows::readModuleDebugArea() {
|
||||
return false;
|
||||
}
|
||||
|
||||
ze_result_t DebugSessionWindows::readSbaBuffer(EuThread::ThreadId, NEO::SbaTrackedAddresses &sbaBuffer) {
|
||||
return ZE_RESULT_ERROR_UNSUPPORTED_FEATURE;
|
||||
ze_result_t DebugSessionWindows::readSbaBuffer(EuThread::ThreadId threadId, NEO::SbaTrackedAddresses &sbaBuffer) {
|
||||
uint64_t gpuVa = 0;
|
||||
getSbaBufferGpuVa(gpuVa);
|
||||
if (gpuVa == 0) {
|
||||
return ZE_RESULT_ERROR_UNKNOWN;
|
||||
}
|
||||
|
||||
uint64_t memoryHandle = DebugSessionWindows::invalidHandle;
|
||||
memoryHandle = allThreads[threadId]->getMemoryHandle();
|
||||
if (memoryHandle == EuThread::invalidHandle) {
|
||||
return ZE_RESULT_ERROR_NOT_AVAILABLE;
|
||||
}
|
||||
return readGpuMemory(memoryHandle, reinterpret_cast<char *>(&sbaBuffer), sizeof(sbaBuffer), gpuVa);
|
||||
}
|
||||
|
||||
void DebugSessionWindows::getSbaBufferGpuVa(uint64_t &gpuVa) {
|
||||
KM_ESCAPE_INFO escapeInfo = {0};
|
||||
escapeInfo.KmEuDbgL0EscapeInfo.EscapeActionType = DBGUMD_ACTION_READ_MMIO;
|
||||
escapeInfo.KmEuDbgL0EscapeInfo.MmioReadParams.MmioOffset = CS_GPR_R15;
|
||||
escapeInfo.KmEuDbgL0EscapeInfo.MmioReadParams.RegisterOutBufferPtr = reinterpret_cast<uint64_t>(&gpuVa);
|
||||
|
||||
auto status = runEscape(escapeInfo);
|
||||
if (STATUS_SUCCESS != status) {
|
||||
PRINT_DEBUGGER_ERROR_LOG("DBGUMD_ACTION_READ_MMIO: Escape Failed - Status: %d", status);
|
||||
return;
|
||||
}
|
||||
if (DBGUMD_RETURN_ESCAPE_SUCCESS != escapeInfo.KmEuDbgL0EscapeInfo.EscapeReturnStatus) {
|
||||
PRINT_DEBUGGER_ERROR_LOG("DBGUMD_ACTION_READ_MMIO: Failed - EscapeReturnStatus: %d\n", escapeInfo.KmEuDbgL0EscapeInfo.EscapeReturnStatus);
|
||||
return;
|
||||
}
|
||||
|
||||
PRINT_DEBUGGER_INFO_LOG("DBGUMD_ACTION_READ_MMIO: SUCCESS - gpuVa: 0x%ullx\n", gpuVa);
|
||||
return;
|
||||
}
|
||||
|
||||
} // namespace L0
|
||||
|
||||
@@ -64,8 +64,9 @@ struct DebugSessionWindows : DebugSessionImp {
|
||||
|
||||
ThreadHelper asyncThread;
|
||||
std::mutex asyncThreadMutex;
|
||||
MOCKABLE_VIRTUAL void getSbaBufferGpuVa(uint64_t &gpuVa);
|
||||
|
||||
NTSTATUS runEscape(KM_ESCAPE_INFO &escapeInfo);
|
||||
MOCKABLE_VIRTUAL NTSTATUS runEscape(KM_ESCAPE_INFO &escapeInfo);
|
||||
|
||||
bool moduleDebugAreaCaptured = false;
|
||||
uint32_t processId = 0;
|
||||
|
||||
@@ -22,6 +22,7 @@ struct MockDebugSessionWindows : DebugSessionWindows {
|
||||
using DebugSessionWindows::closeAsyncThread;
|
||||
using DebugSessionWindows::debugHandle;
|
||||
using DebugSessionWindows::ElfRange;
|
||||
using DebugSessionWindows::getSbaBufferGpuVa;
|
||||
using DebugSessionWindows::initialize;
|
||||
using DebugSessionWindows::invalidHandle;
|
||||
using DebugSessionWindows::moduleDebugAreaCaptured;
|
||||
@@ -29,6 +30,8 @@ struct MockDebugSessionWindows : DebugSessionWindows {
|
||||
using DebugSessionWindows::readAllocationDebugData;
|
||||
using DebugSessionWindows::readAndHandleEvent;
|
||||
using DebugSessionWindows::readGpuMemory;
|
||||
using DebugSessionWindows::readSbaBuffer;
|
||||
using DebugSessionWindows::runEscape;
|
||||
using DebugSessionWindows::startAsyncThread;
|
||||
using DebugSessionWindows::wddm;
|
||||
using DebugSessionWindows::writeGpuMemory;
|
||||
@@ -50,6 +53,18 @@ struct MockDebugSessionWindows : DebugSessionWindows {
|
||||
return DebugSessionWindows::readAndHandleEvent(timeoutMs);
|
||||
}
|
||||
|
||||
NTSTATUS runEscape(KM_ESCAPE_INFO &escapeInfo) override {
|
||||
if (shouldEscapeReturnStatusNotSuccess) {
|
||||
escapeInfo.KmEuDbgL0EscapeInfo.EscapeReturnStatus = DBGUMD_RETURN_DEBUGGER_ATTACH_DEVICE_BUSY;
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
if (shouldEscapeCallFail) {
|
||||
return STATUS_WAIT_1;
|
||||
}
|
||||
|
||||
return L0::DebugSessionWindows::runEscape(escapeInfo);
|
||||
}
|
||||
|
||||
void ensureThreadStopped(ze_device_thread_t thread, uint64_t context) {
|
||||
auto threadId = convertToThreadId(thread);
|
||||
if (allThreads.find(threadId) == allThreads.end()) {
|
||||
@@ -61,6 +76,8 @@ struct MockDebugSessionWindows : DebugSessionWindows {
|
||||
ze_result_t resultInitialize = ZE_RESULT_FORCE_UINT32;
|
||||
ze_result_t resultReadAndHandleEvent = ZE_RESULT_FORCE_UINT32;
|
||||
static constexpr uint64_t mockDebugHandle = 1;
|
||||
bool shouldEscapeReturnStatusNotSuccess = false;
|
||||
bool shouldEscapeCallFail = false;
|
||||
};
|
||||
|
||||
struct DebugApiWindowsFixture : public DeviceFixture {
|
||||
@@ -80,6 +97,68 @@ struct DebugApiWindowsFixture : public DeviceFixture {
|
||||
|
||||
using DebugApiWindowsTest = Test<DebugApiWindowsFixture>;
|
||||
|
||||
TEST_F(DebugApiWindowsTest, GivenReadOfGpuVaFailDueToEscapeCallFailureWhenTryingToReadSbaThenErrorIsReported) {
|
||||
zet_debug_config_t config = {};
|
||||
config.pid = 0x1234;
|
||||
|
||||
auto session = std::make_unique<MockDebugSessionWindows>(config, device);
|
||||
session->shouldEscapeCallFail = true;
|
||||
ze_device_thread_t thread{0, 0, 0, 0};
|
||||
SbaTrackedAddresses sbaBuffer;
|
||||
EXPECT_EQ(ZE_RESULT_ERROR_UNKNOWN, session->readSbaBuffer(session->convertToThreadId(thread), sbaBuffer));
|
||||
}
|
||||
|
||||
TEST_F(DebugApiWindowsTest, GivenReadOfGpuVaFailDueToEscapeCallReturnsSuccessButEscapeReturnStatusIsNotSuccessWhenReadSbaBufferThenErrorIsReported) {
|
||||
zet_debug_config_t config = {};
|
||||
config.pid = 0x1234;
|
||||
|
||||
auto session = std::make_unique<MockDebugSessionWindows>(config, device);
|
||||
session->shouldEscapeReturnStatusNotSuccess = true;
|
||||
ze_device_thread_t thread{0, 0, 0, 0};
|
||||
SbaTrackedAddresses sbaBuffer;
|
||||
EXPECT_EQ(ZE_RESULT_ERROR_UNKNOWN, session->readSbaBuffer(session->convertToThreadId(thread), sbaBuffer));
|
||||
}
|
||||
|
||||
TEST_F(DebugApiWindowsTest, GivenSbaBufferGpuVaAvailableWhenReadingSbaBufferThenSuccessIsReturned) {
|
||||
zet_debug_config_t config = {};
|
||||
config.pid = 0x1234;
|
||||
auto session = std::make_unique<MockDebugSessionWindows>(config, device);
|
||||
ze_device_thread_t thread;
|
||||
thread.slice = 1;
|
||||
thread.subslice = 1;
|
||||
thread.eu = 1;
|
||||
thread.thread = 1;
|
||||
session->ensureThreadStopped(thread, 0x12345);
|
||||
SbaTrackedAddresses sbaBuffer;
|
||||
|
||||
session->wddm = mockWddm;
|
||||
session->allContexts.insert(0x12345);
|
||||
EXPECT_EQ(ZE_RESULT_SUCCESS, session->readSbaBuffer(session->convertToThreadId(thread), sbaBuffer));
|
||||
EXPECT_EQ(sbaBuffer.Version, 0xaa);
|
||||
EXPECT_EQ(sbaBuffer.BindlessSamplerStateBaseAddress, 0xaaaaaaaaaaaaaaaa);
|
||||
}
|
||||
|
||||
TEST_F(DebugApiWindowsTest, GivenEscapeCallToReadMMIOReturnsSuccessWhenReadingSbaBufferGpuVaThenValidGpuVaIsObtained) {
|
||||
zet_debug_config_t config = {};
|
||||
config.pid = 0x1234;
|
||||
auto session = std::make_unique<MockDebugSessionWindows>(config, device);
|
||||
session->wddm = mockWddm;
|
||||
uint64_t gpuVa = 0;
|
||||
session->getSbaBufferGpuVa(gpuVa);
|
||||
EXPECT_EQ(mockWddm->mockGpuVa, gpuVa);
|
||||
}
|
||||
|
||||
TEST_F(DebugApiWindowsTest, GivenNoMemoryHandleWhenReadSbaBufferCalledThenErrorIsReturned) {
|
||||
zet_debug_config_t config = {};
|
||||
config.pid = 0x1234;
|
||||
auto session = std::make_unique<MockDebugSessionWindows>(config, device);
|
||||
ze_device_thread_t thread{0, 0, 0, 0};
|
||||
SbaTrackedAddresses sbaBuffer;
|
||||
|
||||
session->wddm = mockWddm;
|
||||
EXPECT_EQ(ZE_RESULT_ERROR_NOT_AVAILABLE, session->readSbaBuffer(session->convertToThreadId(thread), sbaBuffer));
|
||||
}
|
||||
|
||||
TEST_F(DebugApiWindowsTest, givenDebugAttachIsNotAvailableWhenGetDebugPropertiesCalledThenNoFlagIsReturned) {
|
||||
zet_device_debug_properties_t debugProperties = {};
|
||||
debugProperties.flags = ZET_DEVICE_DEBUG_PROPERTY_FLAG_FORCE_UINT32;
|
||||
|
||||
Reference in New Issue
Block a user