feature: Implement metadata create event handling in XE

Related-To: NEO-8407
Signed-off-by: Jitendra Sharma <jitendra.sharma@intel.com>
This commit is contained in:
Jitendra Sharma
2024-03-06 16:23:44 +00:00
committed by Compute-Runtime-Automation
parent 9b98a5ad83
commit e1e1c0d046
7 changed files with 324 additions and 21 deletions

View File

@@ -112,6 +112,18 @@ struct DebugSessionLinux : DebugSessionImp {
std::vector<EventToAck> ackEvents;
};
struct Module {
std::unordered_set<uint64_t> loadAddresses[NEO::EngineLimits::maxHandleCount];
uint64_t moduleHandle;
uint64_t elfHandle;
uint32_t segmentCount;
NEO::DeviceBitfield deviceBitfield;
int segmentVmBindCounter[NEO::EngineLimits::maxHandleCount];
std::vector<EventToAck> ackEvents[NEO::EngineLimits::maxHandleCount];
bool moduleLoadEventAcked[NEO::EngineLimits::maxHandleCount];
};
struct ClientConnection {
virtual ~ClientConnection() = default;
virtual size_t getElfSize(uint64_t elfHandle) = 0;

View File

@@ -447,7 +447,7 @@ void DebugSessionLinuxi915::handleEvent(prelim_drm_i915_debug_event *event) {
auto &newModule = connection->uuidToModule[handle];
newModule.segmentCount = 0;
newModule.moduleUuidHandle = handle;
newModule.moduleHandle = handle;
for (uint32_t i = 0; i < NEO::EngineLimits::maxHandleCount; i++) {
newModule.segmentVmBindCounter[i] = 0;
newModule.loadAddresses[i].clear();
@@ -730,9 +730,9 @@ bool DebugSessionLinuxi915::handleVmBindEvent(prelim_drm_i915_debug_event_vm_bin
if (!perKernelModules) {
auto &module = connection->uuidToModule[vmBind->uuids[moduleUUIDindex]];
DEBUG_BREAK_IF(module.elfUuidHandle != 0 && connection->uuidMap[vmBind->uuids[index]].ptr != connection->uuidMap[module.elfUuidHandle].ptr);
DEBUG_BREAK_IF(module.elfHandle != 0 && connection->uuidMap[vmBind->uuids[index]].ptr != connection->uuidMap[module.elfHandle].ptr);
module.elfUuidHandle = vmBind->uuids[index];
module.elfHandle = vmBind->uuids[index];
module.deviceBitfield = devices;
}
}
@@ -882,8 +882,8 @@ bool DebugSessionLinuxi915::handleVmBindEvent(prelim_drm_i915_debug_event_vm_bin
debugEvent.type = ZET_DEBUG_EVENT_TYPE_MODULE_LOAD;
debugEvent.info.module.format = ZET_MODULE_DEBUG_INFO_FORMAT_ELF_DWARF;
debugEvent.info.module.load = loadAddress;
debugEvent.info.module.moduleBegin = connection->uuidMap[module.elfUuidHandle].ptr;
debugEvent.info.module.moduleEnd = connection->uuidMap[module.elfUuidHandle].ptr + connection->uuidMap[module.elfUuidHandle].dataSize;
debugEvent.info.module.moduleBegin = connection->uuidMap[module.elfHandle].ptr;
debugEvent.info.module.moduleEnd = connection->uuidMap[module.elfHandle].ptr + connection->uuidMap[module.elfHandle].dataSize;
if (!tileSessionsEnabled) {
bool allInstancesEventsReceived = true;
@@ -925,8 +925,8 @@ bool DebugSessionLinuxi915::handleVmBindEvent(prelim_drm_i915_debug_event_vm_bin
debugEvent.type = ZET_DEBUG_EVENT_TYPE_MODULE_LOAD;
debugEvent.info.module.format = ZET_MODULE_DEBUG_INFO_FORMAT_ELF_DWARF;
debugEvent.info.module.load = loadAddress;
debugEvent.info.module.moduleBegin = connection->uuidMap[module.elfUuidHandle].ptr;
debugEvent.info.module.moduleEnd = connection->uuidMap[module.elfUuidHandle].ptr + connection->uuidMap[module.elfUuidHandle].dataSize;
debugEvent.info.module.moduleBegin = connection->uuidMap[module.elfHandle].ptr;
debugEvent.info.module.moduleEnd = connection->uuidMap[module.elfHandle].ptr + connection->uuidMap[module.elfHandle].dataSize;
if (vmBind->base.flags & PRELIM_DRM_I915_DEBUG_EVENT_NEED_ACK) {
debugEvent.flags = ZET_DEBUG_EVENT_FLAG_NEED_ACK;
}
@@ -977,8 +977,8 @@ bool DebugSessionLinuxi915::handleVmBindEvent(prelim_drm_i915_debug_event_vm_bin
debugEvent.type = ZET_DEBUG_EVENT_TYPE_MODULE_UNLOAD;
debugEvent.info.module.format = ZET_MODULE_DEBUG_INFO_FORMAT_ELF_DWARF;
debugEvent.info.module.load = loadAddress;
debugEvent.info.module.moduleBegin = connection->uuidMap[module.elfUuidHandle].ptr;
debugEvent.info.module.moduleEnd = connection->uuidMap[module.elfUuidHandle].ptr + connection->uuidMap[module.elfUuidHandle].dataSize;
debugEvent.info.module.moduleBegin = connection->uuidMap[module.elfHandle].ptr;
debugEvent.info.module.moduleEnd = connection->uuidMap[module.elfHandle].ptr + connection->uuidMap[module.elfHandle].dataSize;
if (tileSessionsEnabled) {

View File

@@ -84,18 +84,6 @@ struct DebugSessionLinuxi915 : DebugSessionLinux {
uint64_t ptr = 0;
};
struct Module {
std::unordered_set<uint64_t> loadAddresses[NEO::EngineLimits::maxHandleCount];
uint64_t moduleUuidHandle;
uint64_t elfUuidHandle;
uint32_t segmentCount;
NEO::DeviceBitfield deviceBitfield;
int segmentVmBindCounter[NEO::EngineLimits::maxHandleCount];
std::vector<EventToAck> ackEvents[NEO::EngineLimits::maxHandleCount];
bool moduleLoadEventAcked[NEO::EngineLimits::maxHandleCount];
};
static bool apiEventCompare(const zet_debug_event_t &event1, const zet_debug_event_t &event2) {
return memcmp(&event1, &event2, sizeof(zet_debug_event_t)) == 0;
};

View File

@@ -292,12 +292,100 @@ void DebugSessionLinuxXe::handleEvent(drm_xe_eudebug_event *event) {
handleAttentionEvent(attention);
} break;
case DRM_XE_EUDEBUG_EVENT_METADATA: {
drm_xe_eudebug_event_metadata *metaData = reinterpret_cast<drm_xe_eudebug_event_metadata *>(event);
PRINT_DEBUGGER_INFO_LOG("DRM_XE_EUDEBUG_IOCTL_READ_EVENT type: DRM_XE_EUDEBUG_EVENT_METADATA flags = %d len = %llu client_handle = %llu metadata_handle = %llu type = %llu len = %llu\n",
(int)event->flags, (uint64_t)event->len, (uint64_t)metaData->client_handle, (uint64_t)metaData->metadata_handle, (uint64_t)metaData->type, (uint64_t)metaData->len);
handleMetadataEvent(metaData);
} break;
default:
PRINT_DEBUGGER_INFO_LOG("DRM_XE_EUDEBUG_IOCTL_READ_EVENT type: UNHANDLED %u flags = %u len = %lu\n", (uint16_t)event->type, (uint16_t)event->flags, (uint32_t)event->len);
break;
}
}
void DebugSessionLinuxXe::handleMetadataEvent(drm_xe_eudebug_event_metadata *metaData) {
bool destroy = metaData->base.flags & DRM_XE_EUDEBUG_EVENT_DESTROY;
bool create = metaData->base.flags & DRM_XE_EUDEBUG_EVENT_CREATE;
UNRECOVERABLE_IF(clientHandleToConnection.find(metaData->client_handle) == clientHandleToConnection.end());
const auto &connection = clientHandleToConnection[metaData->client_handle];
if (destroy && connection->metaDataMap[metaData->metadata_handle].metadata.type == DRM_XE_DEBUG_METADATA_PROGRAM_MODULE) {
DEBUG_BREAK_IF(connection->metaDataToModule[metaData->metadata_handle].segmentVmBindCounter[0] != 0 ||
connection->metaDataToModule[metaData->metadata_handle].loadAddresses[0].size() > 0);
connection->metaDataToModule.erase(metaData->metadata_handle);
}
if (create) {
if (!metaData->len) {
connection->metaDataMap[metaData->metadata_handle].metadata = *metaData;
return;
}
drm_xe_eudebug_read_metadata readMetadata{};
auto ptr = std::make_unique<char[]>(metaData->len);
readMetadata.client_handle = metaData->client_handle;
readMetadata.metadata_handle = static_cast<decltype(readMetadata.metadata_handle)>(metaData->metadata_handle);
readMetadata.ptr = reinterpret_cast<uint64_t>(ptr.get());
readMetadata.size = metaData->len;
auto ret = ioctl(DRM_XE_EUDEBUG_IOCTL_READ_METADATA, &readMetadata);
if (ret != 0) {
PRINT_DEBUGGER_ERROR_LOG("DRM_XE_EUDEBUG_IOCTL_READ_METADATA ret = %d errno = %d\n", ret, errno);
return;
}
connection->metaDataMap[metaData->metadata_handle].metadata = *metaData;
connection->metaDataMap[metaData->metadata_handle].data = std::move(ptr);
if (metaData->type == DRM_XE_DEBUG_METADATA_PROGRAM_MODULE) {
auto handle = metaData->metadata_handle;
auto &newModule = connection->metaDataToModule[handle];
newModule.segmentCount = 0;
newModule.moduleHandle = handle;
for (uint32_t i = 0; i < NEO::EngineLimits::maxHandleCount; i++) {
newModule.segmentVmBindCounter[i] = 0;
newModule.loadAddresses[i].clear();
newModule.moduleLoadEventAcked[i] = false;
}
}
extractMetaData(metaData->client_handle, connection->metaDataMap[metaData->metadata_handle]);
}
}
void DebugSessionLinuxXe::extractMetaData(uint64_t client, const MetaData &metaData) {
if (metaData.metadata.type == WORK_IN_PROGRESS_DRM_XE_DEBUG_METADATA_SBA_AREA ||
metaData.metadata.type == WORK_IN_PROGRESS_DRM_XE_DEBUG_METADATA_MODULE_AREA ||
metaData.metadata.type == WORK_IN_PROGRESS_DRM_XE_DEBUG_METADATA_SIP_AREA) {
UNRECOVERABLE_IF(metaData.metadata.len != 8);
uint64_t *data = (uint64_t *)metaData.data.get();
if (metaData.metadata.type == WORK_IN_PROGRESS_DRM_XE_DEBUG_METADATA_SBA_AREA) {
clientHandleToConnection[client]->stateBaseAreaGpuVa = *data;
PRINT_DEBUGGER_INFO_LOG("SbaTrackingBuffer GPU VA = %p", (void *)clientHandleToConnection[clientHandle]->stateBaseAreaGpuVa);
}
if (metaData.metadata.type == WORK_IN_PROGRESS_DRM_XE_DEBUG_METADATA_MODULE_AREA) {
clientHandleToConnection[client]->moduleDebugAreaGpuVa = *data;
PRINT_DEBUGGER_INFO_LOG("ModuleHeapDebugArea GPU VA = %p", (void *)clientHandleToConnection[clientHandle]->moduleDebugAreaGpuVa);
}
if (metaData.metadata.type == WORK_IN_PROGRESS_DRM_XE_DEBUG_METADATA_SIP_AREA) {
clientHandleToConnection[client]->contextStateSaveAreaGpuVa = *data;
PRINT_DEBUGGER_INFO_LOG("ContextSaveArea GPU VA = %p", (void *)clientHandleToConnection[clientHandle]->contextStateSaveAreaGpuVa);
}
}
if (metaData.metadata.type == DRM_XE_DEBUG_METADATA_PROGRAM_MODULE) {
uint32_t segmentCount = 0;
memcpy_s(&segmentCount, sizeof(uint32_t), metaData.data.get(), metaData.metadata.len);
clientHandleToConnection[client]->metaDataToModule[metaData.metadata.metadata_handle].segmentCount = segmentCount;
PRINT_DEBUGGER_INFO_LOG("Zebin module = %ull, segment count = %ul", metaData.metadata.metadata_handle, segmentCount);
}
}
int DebugSessionLinuxXe::openVmFd(uint64_t vmHandle, [[maybe_unused]] bool readOnly) {
drm_xe_eudebug_vm_open vmOpen = {
.extensions = 0,

View File

@@ -7,6 +7,8 @@
#pragma once
#include "shared/source/os_interface/linux/drm_debug.h"
#include "level_zero/tools/source/debug/debug_session.h"
#include "level_zero/tools/source/debug/debug_session_imp.h"
#include "level_zero/tools/source/debug/linux/debug_session.h"
@@ -84,6 +86,7 @@ struct DebugSessionLinuxXe : DebugSessionLinux {
int threadControlInterruptAll(drm_xe_eudebug_eu_control &euControl);
int threadControlResumeAndStopped(const std::vector<EuThread::ThreadId> &threads, drm_xe_eudebug_eu_control &euControl, std::unique_ptr<uint8_t[]> &bitmaskOut, size_t &bitmaskSizeOut);
void handleAttentionEvent(drm_xe_eudebug_event_eu_attention *attention);
void handleMetadataEvent(drm_xe_eudebug_event_metadata *pMetaData);
void updateContextAndLrcHandlesForThreadsWithAttention(EuThread::ThreadId threadId, AttentionEventFields &attention) override;
void startAsyncThread() override;
@@ -138,6 +141,11 @@ struct DebugSessionLinuxXe : DebugSessionLinux {
UNRECOVERABLE_IF(true);
}
struct MetaData {
drm_xe_eudebug_event_metadata metadata;
std::unique_ptr<char[]> data;
};
struct ClientConnectionXe : public ClientConnection {
drm_xe_eudebug_event_client client = {};
size_t getElfSize(uint64_t elfHandle) override { return 0; };
@@ -145,9 +153,12 @@ struct DebugSessionLinuxXe : DebugSessionLinux {
std::unordered_map<ExecQueueHandle, ExecQueueParams> execQueues;
std::unordered_map<uint64_t, uint64_t> lrcHandleToVmHandle;
std::unordered_map<uint64_t, MetaData> metaDataMap;
std::unordered_map<uint64_t, Module> metaDataToModule;
};
std::unordered_map<uint64_t, std::shared_ptr<ClientConnectionXe>> clientHandleToConnection;
void extractMetaData(uint64_t client, const MetaData &metaData);
std::vector<std::unique_ptr<uint64_t[]>> pendingVmBindEvents;
bool checkAllEventsCollected();
MOCKABLE_VIRTUAL void handleEvent(drm_xe_eudebug_event *event);

View File

@@ -89,6 +89,22 @@ struct MockIoctlHandlerXe : public L0::ult::MockIoctlHandler {
}
}
euControlArgs.push_back(std::move(arg));
} else if ((request == DRM_XE_EUDEBUG_IOCTL_READ_METADATA) && (arg != nullptr)) {
drm_xe_eudebug_read_metadata *readMetadata = reinterpret_cast<drm_xe_eudebug_read_metadata *>(arg);
if (returnMetadata) {
readMetadata->client_handle = returnMetadata->client_handle;
readMetadata->metadata_handle = returnMetadata->metadata_handle;
readMetadata->flags = returnMetadata->flags;
int returnError = 0;
if (readMetadata->size >= returnMetadata->size) {
memcpy(reinterpret_cast<void *>(readMetadata->ptr), reinterpret_cast<void *>(returnMetadata->ptr), returnMetadata->size);
} else {
returnError = -1;
}
returnMetadata = nullptr;
return returnError;
}
return -1;
}
return ioctlRetVal;
@@ -115,6 +131,7 @@ struct MockIoctlHandlerXe : public L0::ult::MockIoctlHandler {
drm_xe_eudebug_event debugEventInput = {};
drm_xe_eudebug_vm_open vmOpen = {};
drm_xe_eudebug_read_metadata *returnMetadata = nullptr;
int ioctlRetVal = 0;
int debugEventRetVal = 0;

View File

@@ -907,6 +907,193 @@ TEST_F(DebugApiLinuxTestXe, whenHandleExecQueueEventThenProcessEnterAndProcessEx
EXPECT_EQ(ZET_DEBUG_EVENT_TYPE_PROCESS_EXIT, event2.type);
}
TEST_F(DebugApiLinuxTestXe, GivenMetadataEventWhenHandlingAndMetadataLengthIsZeroThenMetadataIsInsertedToMap) {
zet_debug_config_t config = {};
config.pid = 0x1234;
auto session = std::make_unique<MockDebugSessionLinuxXe>(config, device, 10);
ASSERT_NE(nullptr, session);
session->clientHandle = MockDebugSessionLinuxXe::mockClientHandle;
drm_xe_eudebug_event_metadata metadata = {};
metadata.base.type = DRM_XE_EUDEBUG_EVENT_METADATA;
metadata.base.flags = DRM_XE_EUDEBUG_EVENT_CREATE;
metadata.base.len = sizeof(drm_xe_eudebug_event_metadata);
metadata.client_handle = MockDebugSessionLinuxXe::mockClientHandle;
metadata.metadata_handle = 2;
metadata.len = 0;
auto handler = new MockIoctlHandlerXe;
handler->eventQueue.push({reinterpret_cast<char *>(&metadata), static_cast<uint64_t>(metadata.base.len)});
handler->pollRetVal = 1;
session->ioctlHandler.reset(handler);
session->handleEvent(&metadata.base);
EXPECT_EQ(1u, session->clientHandleToConnection[metadata.client_handle]->metaDataMap.size());
EXPECT_NE(session->clientHandleToConnection[metadata.client_handle]->metaDataMap.end(), session->clientHandleToConnection[metadata.client_handle]->metaDataMap.find(metadata.metadata_handle));
metadata.base.flags = DRM_XE_EUDEBUG_EVENT_DESTROY;
session->handleEvent(&metadata.base);
EXPECT_NE(session->clientHandleToConnection[metadata.client_handle]->metaDataMap.end(), session->clientHandleToConnection[metadata.client_handle]->metaDataMap.find(metadata.metadata_handle));
}
TEST_F(DebugApiLinuxTestXe, GivenMetadataCreateEventWhenHandlingAndIoctlFailsThenEventHandlingCallImmediatelyReturns) {
zet_debug_config_t config = {};
config.pid = 0x1234;
auto session = std::make_unique<MockDebugSessionLinuxXe>(config, device, 10);
ASSERT_NE(nullptr, session);
session->clientHandle = MockDebugSessionLinuxXe::mockClientHandle;
drm_xe_eudebug_event_metadata metadata = {};
metadata.base.type = DRM_XE_EUDEBUG_EVENT_METADATA;
metadata.base.flags = DRM_XE_EUDEBUG_EVENT_CREATE;
metadata.base.len = sizeof(drm_xe_eudebug_event_metadata);
metadata.client_handle = MockDebugSessionLinuxXe::mockClientHandle;
metadata.metadata_handle = 2;
metadata.len = 5;
auto handler = new MockIoctlHandlerXe;
handler->eventQueue.push({reinterpret_cast<char *>(&metadata), static_cast<uint64_t>(metadata.base.len)});
handler->pollRetVal = 1;
session->ioctlHandler.reset(handler);
session->handleEvent(&metadata.base);
EXPECT_EQ(0u, session->clientHandleToConnection[metadata.client_handle]->metaDataMap.size());
EXPECT_EQ(session->clientHandleToConnection[metadata.client_handle]->metaDataMap.end(), session->clientHandleToConnection[metadata.client_handle]->metaDataMap.find(metadata.metadata_handle));
metadata.base.flags = DRM_XE_EUDEBUG_EVENT_DESTROY;
session->handleEvent(&metadata.base);
EXPECT_NE(session->clientHandleToConnection[metadata.client_handle]->metaDataMap.end(), session->clientHandleToConnection[metadata.client_handle]->metaDataMap.find(metadata.metadata_handle));
}
TEST_F(DebugApiLinuxTestXe, GivenMetadataCreateEventForL0ZebinModuleWhenHandlingEventThenKernelCountFromReadMetadataIsRead) {
zet_debug_config_t config = {};
config.pid = 0x1234;
auto session = std::make_unique<MockDebugSessionLinuxXe>(config, device, 10);
ASSERT_NE(nullptr, session);
session->clientHandle = MockDebugSessionLinuxXe::mockClientHandle;
auto handler = new MockIoctlHandlerXe;
session->ioctlHandler.reset(handler);
uint32_t kernelCount = 5;
drm_xe_eudebug_event_metadata metadata;
metadata.base.type = DRM_XE_EUDEBUG_EVENT_METADATA;
metadata.base.flags = DRM_XE_EUDEBUG_EVENT_CREATE;
metadata.base.len = sizeof(drm_xe_eudebug_event_metadata);
metadata.client_handle = MockDebugSessionLinuxXe::mockClientHandle;
metadata.metadata_handle = 3;
metadata.type = DRM_XE_DEBUG_METADATA_PROGRAM_MODULE;
metadata.len = sizeof(kernelCount);
drm_xe_eudebug_read_metadata readMetadata{};
readMetadata.ptr = reinterpret_cast<uint64_t>(&kernelCount);
readMetadata.size = sizeof(kernelCount);
readMetadata.metadata_handle = 3;
handler->returnMetadata = &readMetadata;
session->handleEvent(&metadata.base);
EXPECT_NE(session->clientHandleToConnection[MockDebugSessionLinuxXe::mockClientHandle]->metaDataToModule.end(),
session->clientHandleToConnection[MockDebugSessionLinuxXe::mockClientHandle]->metaDataToModule.find(metadata.metadata_handle));
EXPECT_EQ(kernelCount, session->clientHandleToConnection[MockDebugSessionLinuxXe::mockClientHandle]->metaDataToModule[metadata.metadata_handle].segmentCount);
EXPECT_EQ(metadata.metadata_handle, session->clientHandleToConnection[MockDebugSessionLinuxXe::mockClientHandle]->metaDataMap[metadata.metadata_handle].metadata.metadata_handle);
EXPECT_NE(nullptr, session->clientHandleToConnection[MockDebugSessionLinuxXe::mockClientHandle]->metaDataMap[metadata.metadata_handle].data);
EXPECT_EQ(sizeof(kernelCount), session->clientHandleToConnection[MockDebugSessionLinuxXe::mockClientHandle]->metaDataMap[metadata.metadata_handle].metadata.len);
EXPECT_EQ(1, handler->ioctlCalled);
// inject module segment
auto &module = session->clientHandleToConnection[MockDebugSessionLinuxXe::mockClientHandle]->metaDataToModule[metadata.metadata_handle];
module.loadAddresses[0].insert(0x12340000);
metadata.base.flags = DRM_XE_EUDEBUG_EVENT_DESTROY;
metadata.len = 0;
session->handleEvent(&metadata.base);
EXPECT_EQ(session->clientHandleToConnection[MockDebugSessionLinuxXe::mockClientHandle]->metaDataToModule.end(),
session->clientHandleToConnection[MockDebugSessionLinuxXe::mockClientHandle]->metaDataToModule.find(metadata.metadata_handle));
}
TEST_F(DebugApiLinuxTestXe, GivenMetadataEventWhenHandlingEventThenGpuAddressIsSavedFromReadMetadata) {
zet_debug_config_t config = {};
config.pid = 0x1234;
auto session = std::make_unique<MockDebugSessionLinuxXe>(config, device, 10);
ASSERT_NE(nullptr, session);
session->clientHandle = DebugSessionLinuxXe::invalidClientHandle;
auto handler = new MockIoctlHandlerXe;
session->ioctlHandler.reset(handler);
uint64_t sbaAddress = 0x1234000;
uint64_t moduleDebugAddress = 0x34567000;
uint64_t contextSaveAddress = 0x56789000;
drm_xe_eudebug_event_metadata metadataSba = {};
metadataSba.base.type = DRM_XE_EUDEBUG_EVENT_METADATA;
metadataSba.base.flags = DRM_XE_EUDEBUG_EVENT_CREATE;
metadataSba.base.len = sizeof(drm_xe_eudebug_event_metadata);
metadataSba.client_handle = MockDebugSessionLinuxXe::mockClientHandle;
metadataSba.metadata_handle = 4;
metadataSba.type = WORK_IN_PROGRESS_DRM_XE_DEBUG_METADATA_SBA_AREA;
metadataSba.len = sizeof(sbaAddress);
drm_xe_eudebug_read_metadata readMetadata = {};
readMetadata.ptr = reinterpret_cast<uint64_t>(&sbaAddress);
readMetadata.size = sizeof(sbaAddress);
readMetadata.metadata_handle = 4;
handler->returnMetadata = &readMetadata;
session->handleEvent(&metadataSba.base);
drm_xe_eudebug_event_metadata metadataModule = {};
metadataModule.base.type = DRM_XE_EUDEBUG_EVENT_METADATA;
metadataModule.base.flags = DRM_XE_EUDEBUG_EVENT_CREATE;
metadataModule.base.len = sizeof(drm_xe_eudebug_event_metadata);
metadataModule.client_handle = MockDebugSessionLinuxXe::mockClientHandle;
metadataModule.metadata_handle = 5;
metadataModule.type = WORK_IN_PROGRESS_DRM_XE_DEBUG_METADATA_MODULE_AREA;
metadataModule.len = sizeof(moduleDebugAddress);
readMetadata = {};
readMetadata.ptr = reinterpret_cast<uint64_t>(&moduleDebugAddress);
readMetadata.size = sizeof(moduleDebugAddress);
readMetadata.metadata_handle = 5;
handler->returnMetadata = &readMetadata;
session->handleEvent(&metadataModule.base);
drm_xe_eudebug_event_metadata metadataContextSave = {};
metadataContextSave.base.type = DRM_XE_EUDEBUG_EVENT_METADATA;
metadataContextSave.base.flags = DRM_XE_EUDEBUG_EVENT_CREATE;
metadataContextSave.base.len = sizeof(drm_xe_eudebug_event_metadata);
metadataContextSave.client_handle = MockDebugSessionLinuxXe::mockClientHandle,
metadataContextSave.metadata_handle = 6,
metadataContextSave.type = WORK_IN_PROGRESS_DRM_XE_DEBUG_METADATA_SIP_AREA;
metadataContextSave.len = sizeof(contextSaveAddress);
readMetadata = {};
readMetadata.ptr = reinterpret_cast<uint64_t>(&contextSaveAddress);
readMetadata.size = sizeof(contextSaveAddress);
readMetadata.metadata_handle = 6;
handler->returnMetadata = &readMetadata;
session->handleEvent(&metadataContextSave.base);
EXPECT_EQ(moduleDebugAddress, session->clientHandleToConnection[MockDebugSessionLinuxXe::mockClientHandle]->moduleDebugAreaGpuVa);
EXPECT_EQ(sbaAddress, session->clientHandleToConnection[MockDebugSessionLinuxXe::mockClientHandle]->stateBaseAreaGpuVa);
EXPECT_EQ(contextSaveAddress, session->clientHandleToConnection[MockDebugSessionLinuxXe::mockClientHandle]->contextStateSaveAreaGpuVa);
}
TEST_F(DebugApiLinuxTestXe, WhenCallingReadAndWriteGpuMemoryThenFsyncIsCalledTwice) {
auto session = std::make_unique<MockDebugSessionLinuxXe>(zet_debug_config_t{0x1234}, device, 10);
ASSERT_NE(nullptr, session);