public inbox for igt-dev@lists.freedesktop.org
 help / color / mirror / Atom feed
* [PATCH i-g-t 00/21] eudebug: uapi changes on connect and metadata
@ 2026-01-12 12:59 Mika Kuoppala
  2026-01-12 12:59 ` [PATCH i-g-t 01/21] lib/xe/xe_eudebug: Dont compare if everything filtered Mika Kuoppala
                   ` (20 more replies)
  0 siblings, 21 replies; 23+ messages in thread
From: Mika Kuoppala @ 2026-01-12 12:59 UTC (permalink / raw)
  To: igt-dev
  Cc: christoph.manszewski, dominik.karol.piatkowski, maciej.patelczyk,
	jan.maslak, zbigniew.kempczynski, Mika Kuoppala

Hi,

Here are the patches that should bring the igt/eudebug in sync
with https://gitlab.freedesktop.org/miku/kernel/-/tree/eudebug-v6

Majority of changes are due to connection opening changes
and metadata rework.

-Mika

Christoph Manszewski (11):
  tests/intel/xe_eudebug_sriov: Align expected return code
  tests/xe_eudebug: Adapt basic-read-event
  lib/xe_eudebug: Adapt to vm_bind debug data
  tests/xe_eudebug: Adapt basic-vm-bind and remove
    basic-vm-bind-extended
  tests/xe_eudebug: Adapt some ufence reliant tests to new vm_bind event
    interface
  tests/xe_eudebug: Adapt vm-bind-clear* subtests to debug data
  lib/xe_eudebug: Remove unused xe_eudebug_client_vm_bind wrappers
  tests/xe_eudebug: Add vm-bind-debug-data-ufence subtest
  lib/intel_batchbuffer: Add dummy OP_DEBUG_DATA operation to
    __xe_alloc_bind_ops
  tests/xe_eudebug_online: Adapt set-breakpoint test to work with new vm
    bind event interface
  tests/xe_eudebug_online: Adapt several subtests to work with new vm
    bind event interface

Mika Kuoppala (10):
  lib/xe/xe_eudebug: Dont compare if everything filtered
  lib/xe/xe_eudebug: Make sure debugger drains events
  lib/xe/xe_eudebug: Avoid matching if event is filtered
  eudebug: Remove metadata tests
  eudebug: Remove EVENT_OPEN and adjust tests
  tests/intel/xe_eudebug: Fix connect-user test
  tests/intel/xe_eudebug: Mold ufence reconnect test to disconnect
  lib/xe/xe_eudebug: Add callback for session work
  tests/intel/xe_eudebug: Add render node testing
  eudebug: Update xe_drm_eudebug.h uapi

 .../drm-uapi-experimental/xe_drm_eudebug.h    |  266 ++--
 include/drm-uapi/xe_drm.h                     |   36 +
 lib/intel_batchbuffer.c                       |   82 +-
 lib/xe/xe_eudebug.c                           | 1038 +++++++-------
 lib/xe/xe_eudebug.h                           |   88 +-
 tests/intel/xe_eudebug.c                      | 1211 ++++++++---------
 tests/intel/xe_eudebug_online.c               |  304 ++---
 tests/intel/xe_eudebug_sriov.c                |    2 +-
 8 files changed, 1495 insertions(+), 1532 deletions(-)

-- 
2.43.0


^ permalink raw reply	[flat|nested] 23+ messages in thread

* [PATCH i-g-t 01/21] lib/xe/xe_eudebug: Dont compare if everything filtered
  2026-01-12 12:59 [PATCH i-g-t 00/21] eudebug: uapi changes on connect and metadata Mika Kuoppala
@ 2026-01-12 12:59 ` Mika Kuoppala
  2026-01-12 12:59 ` [PATCH i-g-t 02/21] lib/xe/xe_eudebug: Make sure debugger drains events Mika Kuoppala
                   ` (19 subsequent siblings)
  20 siblings, 0 replies; 23+ messages in thread
From: Mika Kuoppala @ 2026-01-12 12:59 UTC (permalink / raw)
  To: igt-dev
  Cc: christoph.manszewski, dominik.karol.piatkowski, maciej.patelczyk,
	jan.maslak, zbigniew.kempczynski, Mika Kuoppala

If all events are filtered, we can omit comparing.
Otherwise client might not have had any events
and it will assert of not finding any.

Previously this worked as one event was guaranteed always
which was client open. This event does not exists anymore.

Signed-off-by: Mika Kuoppala <mika.kuoppala@linux.intel.com>
Reviewed-by: Dominik Karol Piątkowski <dominik.karol.piatkowski@intel.com>
---
 lib/xe/xe_eudebug.c | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/lib/xe/xe_eudebug.c b/lib/xe/xe_eudebug.c
index 2abee7ba25..0f09bc8a19 100644
--- a/lib/xe/xe_eudebug.c
+++ b/lib/xe/xe_eudebug.c
@@ -1021,6 +1021,11 @@ void xe_eudebug_event_log_compare(struct xe_eudebug_event_log *log1,
 	igt_assert(log1);
 	igt_assert(log2);
 
+	if (filter == XE_EUDEBUG_FILTER_ALL) {
+		igt_debug("info: filtering everything, skipping compare\n");
+		return;
+	}
+
 	xe_eudebug_for_each_event(ev1, log1) {
 		if (ev1->type == DRM_XE_EUDEBUG_EVENT_OPEN &&
 		    ev1->flags & DRM_XE_EUDEBUG_EVENT_CREATE) {
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [PATCH i-g-t 02/21] lib/xe/xe_eudebug: Make sure debugger drains events
  2026-01-12 12:59 [PATCH i-g-t 00/21] eudebug: uapi changes on connect and metadata Mika Kuoppala
  2026-01-12 12:59 ` [PATCH i-g-t 01/21] lib/xe/xe_eudebug: Dont compare if everything filtered Mika Kuoppala
@ 2026-01-12 12:59 ` Mika Kuoppala
  2026-01-12 12:59 ` [PATCH i-g-t 03/21] lib/xe/xe_eudebug: Avoid matching if event is filtered Mika Kuoppala
                   ` (18 subsequent siblings)
  20 siblings, 0 replies; 23+ messages in thread
From: Mika Kuoppala @ 2026-01-12 12:59 UTC (permalink / raw)
  To: igt-dev
  Cc: christoph.manszewski, dominik.karol.piatkowski, maciej.patelczyk,
	jan.maslak, zbigniew.kempczynski, Mika Kuoppala

Do not exit from debugger worker until poll timeouts
as otherwise session can nuke the worker too early
and some events might get dropped.

Signed-off-by: Mika Kuoppala <mika.kuoppala@linux.intel.com>
Reviewed-by: Christoph Manszewski <christoph.manszewski@intel.com>
---
 lib/xe/xe_eudebug.c             | 66 ++++++++++++++++++++++++---------
 lib/xe/xe_eudebug.h             |  7 ++--
 tests/intel/xe_eudebug_online.c |  4 +-
 3 files changed, 54 insertions(+), 23 deletions(-)

diff --git a/lib/xe/xe_eudebug.c b/lib/xe/xe_eudebug.c
index 0f09bc8a19..7c2c9505d1 100644
--- a/lib/xe/xe_eudebug.c
+++ b/lib/xe/xe_eudebug.c
@@ -1146,8 +1146,12 @@ static void *debugger_worker_loop(void *data)
 	sa.sa_flags |= SA_SIGINFO;
 	igt_assert_eq(sigaction(SIGTERM, &sa, NULL), 0);
 
+	WRITE_ONCE(d->worker_state, DEBUGGER_WORKER_RUNNING);
+
 	do {
 		p.fd = d->fd;
+		p.revents = 0;
+
 		ret = poll(&p, 1, timeout_ms);
 		if (d->received_sigint) {
 			d->handled_sigint = true;
@@ -1163,10 +1167,18 @@ static void *debugger_worker_loop(void *data)
 			}
 
 			igt_info("poll failed with errno %d\n", errno);
-			break;
+			goto out;
+		}
+
+		/* only exit after timeout to not miss events */
+		if (ret == 0 &&
+		    READ_ONCE(d->worker_state) != DEBUGGER_WORKER_RUNNING) {
+			igt_debug("debugger worker quitting with state %d\n",
+				  READ_ONCE(d->worker_state));
+			goto out;
 		}
 
-		if (ret == 1 && (p.revents & POLLIN)) {
+		if (ret == 1 && p.revents & POLLIN) {
 			int err = xe_eudebug_read_event(d->fd, e);
 
 			if (!err) {
@@ -1178,10 +1190,22 @@ static void *debugger_worker_loop(void *data)
 				igt_info("xe_eudebug_read_event returned %d\n", ret);
 			}
 		}
-	} while ((ret && READ_ONCE(d->worker_state) == DEBUGGER_WORKER_QUITTING) ||
-		 READ_ONCE(d->worker_state) == DEBUGGER_WORKER_ACTIVE);
 
-	d->worker_state = DEBUGGER_WORKER_INACTIVE;
+		if (ret == 1 && p.revents & POLLHUP) {
+			igt_info("debugger connection hangup\n");
+			goto out;
+		}
+
+		if (ret == 1 && p.revents & POLLNVAL) {
+			igt_info("debugger fd invalid\n");
+			goto out;
+		}
+	} while (1);
+
+out:
+	WRITE_ONCE(d->worker_state, DEBUGGER_WORKER_FINISHED);
+
+	igt_debug("debugger worker finished\n");
 
 	return NULL;
 }
@@ -1234,6 +1258,8 @@ xe_eudebug_debugger_create(int master_fd, uint64_t flags, void *data)
 	d->handled_sigint = false;
 	d->received_signal = false;
 
+	WRITE_ONCE(d->worker_state, DEBUGGER_WORKER_INIT);
+
 	return d;
 }
 
@@ -1254,7 +1280,7 @@ static void debugger_destroy_triggers(struct xe_eudebug_debugger *d)
  */
 void xe_eudebug_debugger_destroy(struct xe_eudebug_debugger *d)
 {
-	if (d->worker_state != DEBUGGER_WORKER_INACTIVE)
+	if (READ_ONCE(d->worker_state) != DEBUGGER_WORKER_FINISHED)
 		xe_eudebug_debugger_stop_worker(d);
 
 	if (d->target_pid)
@@ -1380,10 +1406,12 @@ void xe_eudebug_debugger_start_worker(struct xe_eudebug_debugger *d)
 {
 	int ret;
 
-	d->worker_state = DEBUGGER_WORKER_ACTIVE;
 	ret = pthread_create(&d->worker_thread, NULL, &debugger_worker_loop, d);
 
 	igt_assert_f(ret == 0, "Debugger worker thread creation failed!");
+
+	while(READ_ONCE(d->worker_state) != DEBUGGER_WORKER_RUNNING)
+		;
 }
 
 /**
@@ -1396,23 +1424,23 @@ void xe_eudebug_debugger_stop_worker(struct xe_eudebug_debugger *d)
 {
 	const int timeout_s = 3;
 	struct timespec t = {};
-	int ret;
-
-	igt_assert_neq(d->worker_state, DEBUGGER_WORKER_INACTIVE);
+	int ret = 0;
 
-	d->worker_state = DEBUGGER_WORKER_QUITTING; /* First time be polite. */
-	igt_assert_eq(clock_gettime(CLOCK_REALTIME, &t), 0);
-	t.tv_sec += timeout_s;
+	if (READ_ONCE(d->worker_state) == DEBUGGER_WORKER_RUNNING) {
+		/* First time be polite. */
+		WRITE_ONCE(d->worker_state, DEBUGGER_WORKER_SHOULD_QUIT);
+		igt_assert_eq(clock_gettime(CLOCK_REALTIME, &t), 0);
+		t.tv_sec += timeout_s;
 
-	ret = pthread_timedjoin_np(d->worker_thread, NULL, &t);
+		ret = pthread_timedjoin_np(d->worker_thread, NULL, &t);
+	}
 
 	if (ret == ETIMEDOUT) {
-		d->worker_state = DEBUGGER_WORKER_INACTIVE;
-		ret = pthread_join(d->worker_thread, NULL);
+		igt_info("DEBUGGER STATE %d FORCING\n", READ_ONCE(d->worker_state));
+		WRITE_ONCE(d->worker_state, DEBUGGER_WORKER_FINISHED);
 	}
 
-	igt_assert_f(ret == 0 || ret != ESRCH,
-		     "pthread join failed with error %d!\n", ret);
+	pthread_join(d->worker_thread, NULL);
 
 	event_log_sort(d->log);
 }
@@ -1720,6 +1748,8 @@ void xe_eudebug_session_run(struct xe_eudebug_session *s)
 
 	xe_eudebug_debugger_stop_worker(debugger);
 
+	xe_eudebug_client_stop(client);
+
 	xe_eudebug_event_log_print(debugger->log, true);
 	xe_eudebug_event_log_print(client->log, true);
 }
diff --git a/lib/xe/xe_eudebug.h b/lib/xe/xe_eudebug.h
index f1a2da4d84..ef9dacf0d2 100644
--- a/lib/xe/xe_eudebug.h
+++ b/lib/xe/xe_eudebug.h
@@ -20,9 +20,10 @@ struct xe_eudebug_event_log {
 };
 
 enum xe_eudebug_debugger_worker_state {
-	DEBUGGER_WORKER_INACTIVE = 0,
-	DEBUGGER_WORKER_ACTIVE,
-	DEBUGGER_WORKER_QUITTING,
+	DEBUGGER_WORKER_INIT = 0,
+	DEBUGGER_WORKER_RUNNING,
+	DEBUGGER_WORKER_SHOULD_QUIT,
+	DEBUGGER_WORKER_FINISHED,
 };
 
 struct xe_eudebug_debugger {
diff --git a/tests/intel/xe_eudebug_online.c b/tests/intel/xe_eudebug_online.c
index ff6c5ff19b..e59b99ee99 100644
--- a/tests/intel/xe_eudebug_online.c
+++ b/tests/intel/xe_eudebug_online.c
@@ -1690,8 +1690,8 @@ static void test_set_breakpoint_online_sigint_debugger(int fd,
 			usleep(1000);
 		close(s->debugger->fd);
 
-		igt_assert_eq(READ_ONCE(s->debugger->worker_state), DEBUGGER_WORKER_ACTIVE);
-		WRITE_ONCE(s->debugger->worker_state, DEBUGGER_WORKER_INACTIVE);
+		igt_assert_eq(READ_ONCE(s->debugger->worker_state), DEBUGGER_WORKER_RUNNING);
+		WRITE_ONCE(s->debugger->worker_state, DEBUGGER_WORKER_SHOULD_QUIT);
 
 		xe_eudebug_client_wait_done(s->client);
 
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [PATCH i-g-t 03/21] lib/xe/xe_eudebug: Avoid matching if event is filtered
  2026-01-12 12:59 [PATCH i-g-t 00/21] eudebug: uapi changes on connect and metadata Mika Kuoppala
  2026-01-12 12:59 ` [PATCH i-g-t 01/21] lib/xe/xe_eudebug: Dont compare if everything filtered Mika Kuoppala
  2026-01-12 12:59 ` [PATCH i-g-t 02/21] lib/xe/xe_eudebug: Make sure debugger drains events Mika Kuoppala
@ 2026-01-12 12:59 ` Mika Kuoppala
  2026-01-12 12:59 ` [PATCH i-g-t 04/21] tests/intel/xe_eudebug_sriov: Align expected return code Mika Kuoppala
                   ` (17 subsequent siblings)
  20 siblings, 0 replies; 23+ messages in thread
From: Mika Kuoppala @ 2026-01-12 12:59 UTC (permalink / raw)
  To: igt-dev
  Cc: christoph.manszewski, dominik.karol.piatkowski, maciej.patelczyk,
	jan.maslak, zbigniew.kempczynski, Mika Kuoppala

Bail out early if event is filtered instead of hitting
assert of not finding it.

Signed-off-by: Mika Kuoppala <mika.kuoppala@linux.intel.com>
Reviewed-by: Dominik Karol Piątkowski <dominik.karol.piatkowski@intel.com>
---
 lib/xe/xe_eudebug.c | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/lib/xe/xe_eudebug.c b/lib/xe/xe_eudebug.c
index 7c2c9505d1..31e4f9c486 100644
--- a/lib/xe/xe_eudebug.c
+++ b/lib/xe/xe_eudebug.c
@@ -1027,9 +1027,17 @@ void xe_eudebug_event_log_compare(struct xe_eudebug_event_log *log1,
 	}
 
 	xe_eudebug_for_each_event(ev1, log1) {
+		if (XE_EUDEBUG_EVENT_IS_FILTERED(ev1->type, filter))
+			continue;
+
 		if (ev1->type == DRM_XE_EUDEBUG_EVENT_OPEN &&
 		    ev1->flags & DRM_XE_EUDEBUG_EVENT_CREATE) {
 			ev2 = event_type_match(log2, ev1, ev2);
+			if (!ev2)
+				igt_debug("match failed to find type %d, seqno %llu\n",
+					  ev1->type, ev1->seqno);
+
+			igt_assert(ev2);
 
 			compare_client(log1, ev1, log2, ev2, filter);
 			compare_client(log2, ev2, log1, ev1, filter);
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [PATCH i-g-t 04/21] tests/intel/xe_eudebug_sriov: Align expected return code
  2026-01-12 12:59 [PATCH i-g-t 00/21] eudebug: uapi changes on connect and metadata Mika Kuoppala
                   ` (2 preceding siblings ...)
  2026-01-12 12:59 ` [PATCH i-g-t 03/21] lib/xe/xe_eudebug: Avoid matching if event is filtered Mika Kuoppala
@ 2026-01-12 12:59 ` Mika Kuoppala
  2026-01-12 13:12   ` Piatkowski, Dominik Karol
  2026-01-12 12:59 ` [PATCH i-g-t 05/21] eudebug: Remove metadata tests Mika Kuoppala
                   ` (16 subsequent siblings)
  20 siblings, 1 reply; 23+ messages in thread
From: Mika Kuoppala @ 2026-01-12 12:59 UTC (permalink / raw)
  To: igt-dev
  Cc: christoph.manszewski, dominik.karol.piatkowski, maciej.patelczyk,
	jan.maslak, zbigniew.kempczynski, Mika Kuoppala

From: Christoph Manszewski <christoph.manszewski@intel.com>

Align with kernel commit 387aba39b7be (drm/xe/pf: Allow to lockdown
the PF using custom guard).

Signed-off-by: Christoph Manszewski <christoph.manszewski@intel.com>
Signed-off-by: Mika Kuoppala <mika.kuoppala@linux.intel.com>
---
 tests/intel/xe_eudebug_sriov.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/tests/intel/xe_eudebug_sriov.c b/tests/intel/xe_eudebug_sriov.c
index 1f150d0efe..8b318d48b0 100644
--- a/tests/intel/xe_eudebug_sriov.c
+++ b/tests/intel/xe_eudebug_sriov.c
@@ -71,7 +71,7 @@ static void test_deny_eudebug(int fd)
 
 	sysfs = igt_sysfs_open(fd);
 	igt_assert_fd(sysfs);
-	igt_assert_eq(igt_sysfs_printf(sysfs, "device/enable_eudebug", "1"), -EPERM);
+	igt_assert_eq(igt_sysfs_printf(sysfs, "device/enable_eudebug", "1"), -EBUSY);
 	close(sysfs);
 }
 
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [PATCH i-g-t 05/21] eudebug: Remove metadata tests
  2026-01-12 12:59 [PATCH i-g-t 00/21] eudebug: uapi changes on connect and metadata Mika Kuoppala
                   ` (3 preceding siblings ...)
  2026-01-12 12:59 ` [PATCH i-g-t 04/21] tests/intel/xe_eudebug_sriov: Align expected return code Mika Kuoppala
@ 2026-01-12 12:59 ` Mika Kuoppala
  2026-01-12 12:59 ` [PATCH i-g-t 06/21] eudebug: Remove EVENT_OPEN and adjust tests Mika Kuoppala
                   ` (15 subsequent siblings)
  20 siblings, 0 replies; 23+ messages in thread
From: Mika Kuoppala @ 2026-01-12 12:59 UTC (permalink / raw)
  To: igt-dev
  Cc: christoph.manszewski, dominik.karol.piatkowski, maciej.patelczyk,
	jan.maslak, zbigniew.kempczynski, Mika Kuoppala

Metadata will be reworked. Remove.

Signed-off-by: Mika Kuoppala <mika.kuoppala@linux.intel.com>
---
 .../drm-uapi-experimental/xe_drm_eudebug.h    |  98 --------
 lib/xe/xe_eudebug.c                           | 184 +--------------
 lib/xe/xe_eudebug.h                           |  10 -
 tests/intel/xe_eudebug.c                      | 209 +-----------------
 tests/intel/xe_eudebug_online.c               |  87 --------
 5 files changed, 9 insertions(+), 579 deletions(-)

diff --git a/include/drm-uapi-experimental/xe_drm_eudebug.h b/include/drm-uapi-experimental/xe_drm_eudebug.h
index 5aeb6a7352..73e4f418f5 100644
--- a/include/drm-uapi-experimental/xe_drm_eudebug.h
+++ b/include/drm-uapi-experimental/xe_drm_eudebug.h
@@ -31,29 +31,6 @@ extern "C" {
 
 /* ... */
 
-struct drm_xe_vm_bind_op_ext_attach_debug {
-	/** @base: base user extension */
-	struct drm_xe_user_extension base;
-
-	/** @id: Debug object id from create metadata */
-	__u64 metadata_id;
-
-	/** @flags: Flags */
-	__u64 flags;
-
-	/** @cookie: Cookie */
-	__u64 cookie;
-
-	/** @reserved: Reserved */
-	__u64 reserved;
-};
-
-/* ... */
-
-#define XE_VM_BIND_OP_EXTENSIONS_ATTACH_DEBUG 0
-
-/* ... */
-
 #define   DRM_XE_EXEC_QUEUE_SET_PROPERTY_EUDEBUG		3
 #define     DRM_XE_EXEC_QUEUE_EUDEBUG_FLAG_ENABLE		(1 << 0)
 
@@ -76,54 +53,6 @@ struct drm_xe_eudebug_connect {
 	__u32 version; /* output: current ABI (ioctl / events) version */
 };
 
-/*
- * struct drm_xe_debug_metadata_create - Create debug metadata
- *
- * Add a region of user memory to be marked as debug metadata.
- * When the debugger attaches, the metadata regions will be delivered
- * for debugger. Debugger can then map these regions to help decode
- * the program state.
- *
- * Returns handle to created metadata entry.
- */
-struct drm_xe_debug_metadata_create {
-	/** @extensions: Pointer to the first extension struct, if any */
-	__u64 extensions;
-
-#define DRM_XE_DEBUG_METADATA_ELF_BINARY     0
-#define DRM_XE_DEBUG_METADATA_PROGRAM_MODULE 1
-#define WORK_IN_PROGRESS_DRM_XE_DEBUG_METADATA_MODULE_AREA 2
-#define WORK_IN_PROGRESS_DRM_XE_DEBUG_METADATA_SBA_AREA 3
-#define WORK_IN_PROGRESS_DRM_XE_DEBUG_METADATA_SIP_AREA 4
-#define WORK_IN_PROGRESS_DRM_XE_DEBUG_METADATA_NUM (1 + \
-	  WORK_IN_PROGRESS_DRM_XE_DEBUG_METADATA_SIP_AREA)
-
-	/** @type: Type of metadata */
-	__u64 type;
-
-	/** @user_addr: pointer to start of the metadata */
-	__u64 user_addr;
-
-	/** @len: length, in bytes of the medata */
-	__u64 len;
-
-	/** @metadata_id: created metadata handle (out) */
-	__u32 metadata_id;
-};
-
-/**
- * struct drm_xe_debug_metadata_destroy - Destroy debug metadata
- *
- * Destroy debug metadata.
- */
-struct drm_xe_debug_metadata_destroy {
-	/** @extensions: Pointer to the first extension struct, if any */
-	__u64 extensions;
-
-	/** @metadata_id: metadata handle to destroy */
-	__u32 metadata_id;
-};
-
 /* XXX: END section moved from xe_drm.h as temporary solution */
 
 /**
@@ -309,33 +238,6 @@ struct drm_xe_eudebug_vm_open {
 	__u64 timeout_ns;
 };
 
-struct drm_xe_eudebug_read_metadata {
-	__u64 client_handle;
-	__u64 metadata_handle;
-	__u32 flags;
-	__u32 reserved;
-	__u64 ptr;
-	__u64 size;
-};
-
-struct drm_xe_eudebug_event_metadata {
-	struct drm_xe_eudebug_event base;
-
-	__u64 client_handle;
-	__u64 metadata_handle;
-	/* XXX: Refer to xe_drm.h for fields */
-	__u64 type;
-	__u64 len;
-};
-
-struct drm_xe_eudebug_event_vm_bind_op_metadata {
-	struct drm_xe_eudebug_event base;
-	__u64 vm_bind_op_ref_seqno; /* *_event_vm_bind_op.base.seqno */
-
-	__u64 metadata_handle;
-	__u64 metadata_cookie;
-};
-
 struct drm_xe_eudebug_event_pagefault {
 	struct drm_xe_eudebug_event base;
 
diff --git a/lib/xe/xe_eudebug.c b/lib/xe/xe_eudebug.c
index 31e4f9c486..0583ce8f31 100644
--- a/lib/xe/xe_eudebug.c
+++ b/lib/xe/xe_eudebug.c
@@ -92,10 +92,6 @@ static const char *type_to_str(unsigned int type)
 		return "vm_bind_op";
 	case DRM_XE_EUDEBUG_EVENT_VM_BIND_UFENCE:
 		return "vm_bind_ufence";
-	case DRM_XE_EUDEBUG_EVENT_METADATA:
-		return "metadata";
-	case DRM_XE_EUDEBUG_EVENT_VM_BIND_OP_METADATA:
-		return "vm_bind_op_metadata";
 	case DRM_XE_EUDEBUG_EVENT_PAGEFAULT:
 		return "pagefault";
 	}
@@ -183,20 +179,6 @@ static const char *event_members_to_str(struct drm_xe_eudebug_event *e, char *bu
 		sprintf(buf, "vm_bind_ref_seqno=%lld", f->vm_bind_ref_seqno);
 		break;
 	}
-	case DRM_XE_EUDEBUG_EVENT_METADATA: {
-		struct drm_xe_eudebug_event_metadata *em = igt_container_of(e, em, base);
-
-		sprintf(buf, "client_handle=%llu, metadata_handle=%llu, type=%llu, len=%llu",
-			em->client_handle, em->metadata_handle, em->type, em->len);
-		break;
-	}
-	case DRM_XE_EUDEBUG_EVENT_VM_BIND_OP_METADATA: {
-		struct drm_xe_eudebug_event_vm_bind_op_metadata *op = igt_container_of(e, op, base);
-
-		sprintf(buf, "vm_bind_op_ref_seqno=%lld, metadata_handle=%llu, metadata_cookie=%llu",
-			op->vm_bind_op_ref_seqno, op->metadata_handle, op->metadata_cookie);
-		break;
-	}
 	case DRM_XE_EUDEBUG_EVENT_PAGEFAULT: {
 		struct drm_xe_eudebug_event_pagefault *pf = igt_container_of(e, pf, base);
 
@@ -505,16 +487,6 @@ static int match_fields(struct drm_xe_eudebug_event *a, void *data)
 			ret = 1;
 		break;
 	}
-	case DRM_XE_EUDEBUG_EVENT_VM_BIND_OP_METADATA: {
-		struct drm_xe_eudebug_event_vm_bind_op_metadata *ea = igt_container_of(a, ea, base);
-		struct drm_xe_eudebug_event_vm_bind_op_metadata *eb = igt_container_of(b, eb, base);
-
-		if (ea->metadata_handle == eb->metadata_handle &&
-		    ea->metadata_cookie == eb->metadata_cookie)
-			ret = 1;
-		break;
-	}
-
 	default:
 		ret = 1;
 		break;
@@ -581,20 +553,6 @@ static int match_client_handle(struct drm_xe_eudebug_event *e, void *data)
 
 		break;
 	}
-	case DRM_XE_EUDEBUG_EVENT_METADATA: {
-		struct drm_xe_eudebug_event_metadata *em = igt_container_of(e, em, base);
-
-		if (em->client_handle == h)
-			return 1;
-		break;
-	}
-	case DRM_XE_EUDEBUG_EVENT_VM_BIND_OP_METADATA: {
-		struct drm_xe_eudebug_event_vm_bind_op_metadata *eo = igt_container_of(e, eo, base);
-
-		if (eo->vm_bind_op_ref_seqno == *bind_op_seqno)
-			return 1;
-		break;
-	}
 	default:
 		break;
 	}
@@ -658,25 +616,6 @@ static int match_opposite_resource(struct drm_xe_eudebug_event *e, void *data)
 			return 1;
 		break;
 	}
-	case DRM_XE_EUDEBUG_EVENT_METADATA: {
-		struct drm_xe_eudebug_event_metadata *em = igt_container_of(e, em, base);
-		struct drm_xe_eudebug_event_metadata *filter = data;
-
-		if (em->metadata_handle == filter->metadata_handle)
-			return 1;
-		break;
-	}
-	case DRM_XE_EUDEBUG_EVENT_VM_BIND_OP_METADATA: {
-		struct drm_xe_eudebug_event_vm_bind_op_metadata *avmb = igt_container_of(e, avmb,
-											 base);
-		struct drm_xe_eudebug_event_vm_bind_op_metadata *filter = data;
-
-		if (avmb->metadata_handle == filter->metadata_handle &&
-		    avmb->metadata_cookie == filter->metadata_cookie)
-			return 1;
-		break;
-	}
-
 	default:
 		break;
 	}
@@ -1071,8 +1010,7 @@ xe_eudebug_event_log_match_opposite(struct xe_eudebug_event_log *l, uint32_t fil
 
 			/* No opposite matching for binds */
 			if ((ev1->type >= DRM_XE_EUDEBUG_EVENT_VM_BIND &&
-			     ev1->type <= DRM_XE_EUDEBUG_EVENT_VM_BIND_UFENCE) ||
-			    ev1->type == DRM_XE_EUDEBUG_EVENT_VM_BIND_OP_METADATA)
+			     ev1->type <= DRM_XE_EUDEBUG_EVENT_VM_BIND_UFENCE))
 				continue;
 
 			ev2 = opposite_event_match(l, ev1, ev1);
@@ -1850,22 +1788,6 @@ static void exec_queue_event(struct xe_eudebug_client *c, uint32_t flags,
 	xe_eudebug_event_log_write(c->log, (void *)&ee);
 }
 
-static void metadata_event(struct xe_eudebug_client *c, uint32_t flags,
-			   int client_fd, uint32_t id, uint64_t type, uint64_t len)
-{
-	struct drm_xe_eudebug_event_metadata em;
-
-	base_event(c, to_base(em), DRM_XE_EUDEBUG_EVENT_METADATA,
-		   flags, sizeof(em));
-
-	em.client_handle = client_fd;
-	em.metadata_handle = id;
-	em.type = type;
-	em.len = len;
-
-	xe_eudebug_event_log_write(c->log, (void *)&em);
-}
-
 /**
  * __xe_eudebug_enable_getset
  * @fd: xe client
@@ -1986,7 +1908,6 @@ void xe_eudebug_client_close_driver(struct xe_eudebug_client *c, int fd)
  * @ext: pointer to the first user extension
  *
  * Calls xe_vm_create() and logs corresponding events
- * (including vm set metadata events) in client's event log.
  *
  * Returns: valid vm handle
  */
@@ -2165,33 +2086,6 @@ void xe_eudebug_client_vm_bind_op_event(struct xe_eudebug_client *c, uint32_t ev
 	xe_eudebug_event_log_write(c->log, (void *)&op);
 }
 
-/**
- * xe_eudebug_client_vm_bind_op_metadata_event:
- * @c: pointer to xe_eudebug_client structure
- * @event_flags: base event flags
- * @op_ref_seqno: base vm bind op reference seqno
- * @metadata_handle: metadata handle
- * @metadata_cookie: metadata cookie
- *
- * Logs vm bind op metadata event in client's event log.
- */
-void xe_eudebug_client_vm_bind_op_metadata_event(struct xe_eudebug_client *c,
-						 uint32_t event_flags, uint64_t op_ref_seqno,
-						 uint64_t metadata_handle, uint64_t metadata_cookie)
-{
-	struct drm_xe_eudebug_event_vm_bind_op_metadata op;
-
-	igt_assert(c);
-
-	base_event(c, to_base(op), DRM_XE_EUDEBUG_EVENT_VM_BIND_OP_METADATA,
-		   event_flags, sizeof(op));
-	op.vm_bind_op_ref_seqno = op_ref_seqno;
-	op.metadata_handle = metadata_handle;
-	op.metadata_cookie = metadata_cookie;
-
-	xe_eudebug_event_log_write(c->log, (void *)&op);
-}
-
 /**
  * xe_eudebug_client_vm_bind_ufence_event:
  * @c: pointer to xe_eudebug_client structure
@@ -2223,12 +2117,6 @@ static bool has_user_fence(const struct drm_xe_sync *sync, uint32_t num_syncs)
 	return false;
 }
 
-#define for_each_metadata(__m, __ext)					\
-	for ((__m) = from_user_pointer(__ext);				\
-	     (__m);							\
-	     (__m) = from_user_pointer((__m)->base.next_extension))	\
-		if ((__m)->base.name == XE_VM_BIND_OP_EXTENSIONS_ATTACH_DEBUG)
-
 static int  __xe_eudebug_client_vm_bind(struct xe_eudebug_client *c,
 					int fd, uint32_t vm, uint32_t exec_queue,
 					uint32_t bo, uint64_t offset,
@@ -2239,24 +2127,19 @@ static int  __xe_eudebug_client_vm_bind(struct xe_eudebug_client *c,
 					uint32_t prefetch_region,
 					uint8_t pat_index, uint64_t op_ext)
 {
-	struct drm_xe_vm_bind_op_ext_attach_debug *metadata;
 	const bool ufence = has_user_fence(sync, num_syncs);
 	const uint32_t bind_flags = ufence ?
 		DRM_XE_EUDEBUG_EVENT_VM_BIND_FLAG_UFENCE : 0;
-	uint64_t seqno = 0, op_seqno = 0, num_metadata = 0;
+	uint64_t seqno = 0, op_seqno = 0;
 	uint32_t bind_base_flags = 0;
 	int ret;
 
-	for_each_metadata(metadata, op_ext)
-		num_metadata++;
-
 	switch (op) {
 	case DRM_XE_VM_BIND_OP_MAP:
 		bind_base_flags = DRM_XE_EUDEBUG_EVENT_CREATE;
 		break;
 	case DRM_XE_VM_BIND_OP_UNMAP:
 		bind_base_flags = DRM_XE_EUDEBUG_EVENT_DESTROY;
-		igt_assert_eq(num_metadata, 0);
 		igt_assert_eq(ufence, false);
 		break;
 	default:
@@ -2278,15 +2161,8 @@ static int  __xe_eudebug_client_vm_bind(struct xe_eudebug_client *c,
 	xe_eudebug_client_vm_bind_event(c, DRM_XE_EUDEBUG_EVENT_STATE_CHANGE,
 					fd, vm, bind_flags, 1, &seqno);
 	xe_eudebug_client_vm_bind_op_event(c, bind_base_flags,
-					   seqno, &op_seqno, addr, size,
-					   num_metadata);
-
-	for_each_metadata(metadata, op_ext)
-		xe_eudebug_client_vm_bind_op_metadata_event(c,
-							    DRM_XE_EUDEBUG_EVENT_CREATE,
-							    op_seqno,
-							    metadata->metadata_id,
-							    metadata->cookie);
+					   seqno, &op_seqno, addr, size, 0);
+
 	if (ufence)
 		xe_eudebug_client_vm_bind_ufence_event(c, DRM_XE_EUDEBUG_EVENT_CREATE |
 						       DRM_XE_EUDEBUG_EVENT_NEED_ACK,
@@ -2413,58 +2289,6 @@ void xe_eudebug_client_vm_unbind(struct xe_eudebug_client *c, int fd, uint32_t v
 					  flags, sync, num_syncs);
 }
 
-/**
- * xe_eudebug_client_metadata_create:
- * @c: pointer to xe_eudebug_client structure
- * @fd: xe client
- * @type: debug metadata type
- * @len: size of @data
- * @data: debug metadata paylad
- *
- * Calls xe metadata create ioctl and logs the corresponding event in
- * client's event log.
- *
- * Return: valid debug metadata id.
- */
-uint32_t xe_eudebug_client_metadata_create(struct xe_eudebug_client *c, int fd,
-					   int type, size_t len, void *data)
-{
-	struct drm_xe_debug_metadata_create create = {
-		.type = type,
-		.user_addr = to_user_pointer(data),
-		.len = len
-	};
-
-	igt_assert(c);
-	igt_assert_eq(igt_ioctl(fd, DRM_IOCTL_XE_DEBUG_METADATA_CREATE, &create), 0);
-
-	metadata_event(c, DRM_XE_EUDEBUG_EVENT_CREATE, fd, create.metadata_id, type, len);
-
-	return create.metadata_id;
-}
-
-/**
- * xe_eudebug_client_metadata_destroy:
- * @c: pointer to xe_eudebug_client structure
- * @fd: xe client
- * @id: xe debug metadata handle
- * @type: debug metadata type
- * @len: size of debug metadata payload
- *
- * Calls xe metadata destroy ioctl and logs the corresponding event in
- * client's event log.
- */
-void xe_eudebug_client_metadata_destroy(struct xe_eudebug_client *c, int fd,
-					uint32_t id, int type, size_t len)
-{
-	struct drm_xe_debug_metadata_destroy destroy = { .metadata_id = id };
-
-	igt_assert(c);
-	igt_assert_eq(igt_ioctl(fd, DRM_IOCTL_XE_DEBUG_METADATA_DESTROY, &destroy), 0);
-
-	metadata_event(c, DRM_XE_EUDEBUG_EVENT_DESTROY, fd, id, type, len);
-}
-
 void xe_eudebug_ack_ufence(int debugfd,
 			   const struct drm_xe_eudebug_event_vm_bind_ufence *f)
 {
diff --git a/lib/xe/xe_eudebug.h b/lib/xe/xe_eudebug.h
index ef9dacf0d2..0706023121 100644
--- a/lib/xe/xe_eudebug.h
+++ b/lib/xe/xe_eudebug.h
@@ -170,8 +170,6 @@ next_event(struct drm_xe_eudebug_event *e, struct xe_eudebug_event_log *l)
 #define XE_EUDEBUG_FILTER_EVENT_VM_BIND			BIT(DRM_XE_EUDEBUG_EVENT_VM_BIND)
 #define XE_EUDEBUG_FILTER_EVENT_VM_BIND_OP		BIT(DRM_XE_EUDEBUG_EVENT_VM_BIND_OP)
 #define XE_EUDEBUG_FILTER_EVENT_VM_BIND_UFENCE		BIT(DRM_XE_EUDEBUG_EVENT_VM_BIND_UFENCE)
-#define XE_EUDEBUG_FILTER_EVENT_METADATA		BIT(DRM_XE_EUDEBUG_EVENT_METADATA)
-#define XE_EUDEBUG_FILTER_EVENT_VM_BIND_OP_METADATA	BIT(DRM_XE_EUDEBUG_EVENT_VM_BIND_OP_METADATA)
 #define XE_EUDEBUG_FILTER_EVENT_PAGEFAULT		BIT(DRM_XE_EUDEBUG_EVENT_PAGEFAULT)
 #define XE_EUDEBUG_FILTER_ALL				GENMASK(DRM_XE_EUDEBUG_EVENT_PAGEFAULT, 0)
 #define XE_EUDEBUG_EVENT_IS_FILTERED(_e, _f)		((1UL << (_e)) & (_f))
@@ -237,9 +235,6 @@ void xe_eudebug_client_vm_bind_op_event(struct xe_eudebug_client *c, uint32_t ev
 					uint64_t ref_seqno, uint64_t *op_ref_seqno,
 					uint64_t addr, uint64_t range,
 					uint64_t num_extensions);
-void xe_eudebug_client_vm_bind_op_metadata_event(struct xe_eudebug_client *c,
-						 uint32_t event_flags, uint64_t op_ref_seqno,
-						 uint64_t metadata_handle, uint64_t metadata_cookie);
 void xe_eudebug_client_vm_bind_ufence_event(struct xe_eudebug_client *c, uint32_t event_flags,
 					    uint64_t ref_seqno);
 void xe_eudebug_ack_ufence(int debugfd,
@@ -260,11 +255,6 @@ void xe_eudebug_client_vm_unbind_flags(struct xe_eudebug_client *c, int fd,
 void xe_eudebug_client_vm_unbind(struct xe_eudebug_client *c, int fd, uint32_t vm,
 				 uint64_t offset, uint64_t addr, uint64_t size);
 
-uint32_t xe_eudebug_client_metadata_create(struct xe_eudebug_client *c, int fd,
-					   int type, size_t len, void *data);
-void xe_eudebug_client_metadata_destroy(struct xe_eudebug_client *c, int fd,
-					uint32_t id, int type, size_t len);
-
 struct xe_eudebug_session *xe_eudebug_session_create(int fd,
 						     xe_eudebug_client_work_fn work,
 						     unsigned int flags,
diff --git a/tests/intel/xe_eudebug.c b/tests/intel/xe_eudebug.c
index 134f317668..55539638f0 100644
--- a/tests/intel/xe_eudebug.c
+++ b/tests/intel/xe_eudebug.c
@@ -60,73 +60,26 @@ static void test_sysfs_toggle(int fd)
 #define VM_BIND				(1 << 2)
 #define VM_BIND_VM_DESTROY		(1 << 3)
 #define VM_BIND_EXTENDED		(1 << 4)
-#define VM_METADATA			(1 << 5)
-#define VM_BIND_METADATA		(1 << 6)
-#define VM_BIND_OP_MAP_USERPTR		(1 << 7)
-#define VM_BIND_DELAY_UFENCE_ACK	(1 << 8)
-#define VM_BIND_UFENCE_RECONNECT	(1 << 9)
-#define VM_BIND_UFENCE_SIGINT_CLIENT	(1 << 10)
+#define VM_BIND_OP_MAP_USERPTR		(1 << 5)
+#define VM_BIND_DELAY_UFENCE_ACK	(1 << 6)
+#define VM_BIND_UFENCE_RECONNECT	(1 << 7)
+#define VM_BIND_UFENCE_SIGINT_CLIENT	(1 << 8)
 #define TEST_FAULTABLE			(1 << 30)
 #define TEST_DISCOVERY			(1 << 31)
 
 #define PAGE_SIZE SZ_4K
-#define MDATA_SIZE (WORK_IN_PROGRESS_DRM_XE_DEBUG_METADATA_NUM * PAGE_SIZE)
 
 #define BO_ADDR 0x1a0000
 
-static struct drm_xe_vm_bind_op_ext_attach_debug *
-basic_vm_bind_metadata_ext_prepare(int fd, struct xe_eudebug_client *c, uint8_t **data)
-{
-	const uint32_t data_size = MDATA_SIZE;
-	struct drm_xe_vm_bind_op_ext_attach_debug *ext;
-	int i;
-
-	*data = calloc(data_size, sizeof(**data));
-	igt_assert(*data);
-
-	for (i = 0; i < data_size; i++)
-		(*data)[i] = (i + i / PAGE_SIZE) % 256;
-
-	ext = calloc(WORK_IN_PROGRESS_DRM_XE_DEBUG_METADATA_NUM, sizeof(*ext));
-	igt_assert(ext);
-
-	for (i = 0; i < WORK_IN_PROGRESS_DRM_XE_DEBUG_METADATA_NUM; i++) {
-		ext[i].base.name = XE_VM_BIND_OP_EXTENSIONS_ATTACH_DEBUG;
-		ext[i].metadata_id = xe_eudebug_client_metadata_create(c, fd, i,
-								       (i + 1) * PAGE_SIZE, *data);
-		ext[i].cookie = i;
-
-		if (i < WORK_IN_PROGRESS_DRM_XE_DEBUG_METADATA_NUM - 1)
-			ext[i].base.next_extension = to_user_pointer(&ext[i + 1]);
-	}
-	return ext;
-}
-
-static void basic_vm_bind_metadata_ext_del(int fd, struct xe_eudebug_client *c,
-					   struct drm_xe_vm_bind_op_ext_attach_debug *ext,
-					   uint8_t *data)
-{
-	for (int i = 0; i < WORK_IN_PROGRESS_DRM_XE_DEBUG_METADATA_NUM; i++)
-		xe_eudebug_client_metadata_destroy(c, fd, ext[i].metadata_id, i,
-						   (i + 1) * PAGE_SIZE);
-	free(ext);
-	free(data);
-}
-
 static void basic_vm_bind_client(int fd, struct xe_eudebug_client *c)
 {
 	struct drm_xe_vm_bind_op_ext_attach_debug *ext = NULL;
 	uint32_t vm = xe_eudebug_client_vm_create(c, fd, DRM_XE_VM_CREATE_FLAG_LR_MODE, 0);
 	size_t bo_size = xe_get_default_alignment(fd);
 	bool test_discovery = c->flags & TEST_DISCOVERY;
-	bool test_metadata = c->flags & VM_BIND_METADATA;
 	uint32_t bo = xe_bo_create(fd, 0, bo_size,
 				   system_memory(fd), 0);
 	uint64_t addr = 0x1a0000;
-	uint8_t *data = NULL;
-
-	if (test_metadata)
-		ext = basic_vm_bind_metadata_ext_prepare(fd, c, &data);
 
 	xe_eudebug_client_vm_bind_flags(c, fd, vm, bo, 0, addr,
 					bo_size, 0, NULL, 0, to_user_pointer(ext));
@@ -138,9 +91,6 @@ static void basic_vm_bind_client(int fd, struct xe_eudebug_client *c)
 
 	xe_eudebug_client_vm_unbind(c, fd, vm, 0, addr, bo_size);
 
-	if (test_metadata)
-		basic_vm_bind_metadata_ext_del(fd, c, ext, data);
-
 	gem_close(fd, bo);
 	xe_eudebug_client_vm_destroy(c, fd, vm);
 }
@@ -477,7 +427,7 @@ static void run_basic_client(struct xe_eudebug_client *c)
 		xe_eudebug_client_vm_destroy(c, fd, vm);
 	}
 
-	if (c->flags & VM_BIND || c->flags & VM_BIND_METADATA)
+	if (c->flags & VM_BIND)
 		basic_vm_bind_client(fd, c);
 
 	if (c->flags & VM_BIND_EXTENDED)
@@ -974,12 +924,6 @@ static void test_basic_sessions(int fd, unsigned int flags, int count, bool matc
  *	Attach the debugger to a process that performs vm-bind before attaching
  *	and check if the discovery process reports it.
  *
- * SUBTEST: basic-vm-bind-metadata-discovery
- * Functionality: VM bind metadata
- * Description:
- *	Attach the debugger to a process that performs vm-bind with metadata attached
- *	before attaching and check if the discovery process reports it.
- *
  * SUBTEST: basic-vm-bind-vm-destroy-discovery
  * Functionality: VM bind event
  * Description:
@@ -1789,140 +1733,6 @@ static void test_vm_access_parameters(int fd, unsigned int flags, int num_client
 					 XE_EUDEBUG_FILTER_EVENT_VM_BIND_UFENCE);
 }
 
-static void metadata_access_client(struct xe_eudebug_client *c)
-{
-	const uint64_t addr = 0x1a0000;
-	struct drm_xe_vm_bind_op_ext_attach_debug *ext;
-	uint8_t *data;
-	size_t bo_size;
-	uint32_t bo, vm;
-	int fd, i;
-
-	fd = xe_eudebug_client_open_driver(c);
-
-	bo_size = xe_get_default_alignment(fd);
-	vm = xe_eudebug_client_vm_create(c, fd, DRM_XE_VM_CREATE_FLAG_LR_MODE, 0);
-	bo = xe_bo_create(fd, vm, bo_size, system_memory(fd), 0);
-
-	ext = basic_vm_bind_metadata_ext_prepare(fd, c, &data);
-
-	xe_eudebug_client_vm_bind_flags(c, fd, vm, bo, 0, addr,
-					bo_size, 0, NULL, 0, to_user_pointer(ext));
-
-	for (i = 0; i < WORK_IN_PROGRESS_DRM_XE_DEBUG_METADATA_NUM; i++)
-		xe_eudebug_client_wait_stage(c, i);
-
-	xe_eudebug_client_vm_unbind(c, fd, vm, 0, addr, bo_size);
-
-	basic_vm_bind_metadata_ext_del(fd, c, ext, data);
-
-	close(bo);
-	xe_eudebug_client_vm_destroy(c, fd, vm);
-
-	xe_eudebug_client_close_driver(c, fd);
-}
-
-static void debugger_test_metadata(struct xe_eudebug_debugger *d,
-				   uint64_t client_handle,
-				   uint64_t metadata_handle,
-				   uint64_t type,
-				   uint64_t len)
-{
-	struct drm_xe_eudebug_read_metadata rm = {
-		.client_handle = client_handle,
-		.metadata_handle = metadata_handle,
-		.size = len,
-	};
-	uint8_t *data;
-	int i;
-
-	data = malloc(len);
-	igt_assert(data);
-
-	rm.ptr = to_user_pointer(data);
-
-	igt_assert_eq(igt_ioctl(d->fd, DRM_XE_EUDEBUG_IOCTL_READ_METADATA, &rm), 0);
-
-	/* syntetic check, test sets different size per metadata type */
-	igt_assert_eq((type + 1) * PAGE_SIZE, rm.size);
-
-	for (i = 0; i < rm.size; i++)
-		igt_assert_eq(data[i], (i + i / PAGE_SIZE) % 256);
-
-	free(data);
-}
-
-static void metadata_read_trigger(struct xe_eudebug_debugger *d,
-				  struct drm_xe_eudebug_event *e)
-{
-	struct drm_xe_eudebug_event_metadata *em = (void *)e;
-
-	/* syntetic check, test sets different size per metadata type */
-	igt_assert_eq((em->type + 1) * PAGE_SIZE, em->len);
-
-	if (e->flags & DRM_XE_EUDEBUG_EVENT_CREATE) {
-		debugger_test_metadata(d, em->client_handle, em->metadata_handle,
-				       em->type, em->len);
-		xe_eudebug_debugger_signal_stage(d, em->type);
-	}
-}
-
-static void metadata_read_on_vm_bind_trigger(struct xe_eudebug_debugger *d,
-					     struct drm_xe_eudebug_event *e)
-{
-	struct drm_xe_eudebug_event_vm_bind_op_metadata *em = (void *)e;
-	struct drm_xe_eudebug_event_vm_bind_op *eo = (void *)e;
-	struct drm_xe_eudebug_event_vm_bind *eb;
-
-	/* For testing purpose client sets metadata_cookie = type */
-
-	/*
-	 * Metadata event has a reference to vm-bind-op event which has a reference
-	 * to vm-bind event which contains proper client-handle.
-	 */
-	eo = (struct drm_xe_eudebug_event_vm_bind_op *)
-		xe_eudebug_event_log_find_seqno(d->log, em->vm_bind_op_ref_seqno);
-	igt_assert(eo);
-	eb = (struct drm_xe_eudebug_event_vm_bind *)
-		xe_eudebug_event_log_find_seqno(d->log, eo->vm_bind_ref_seqno);
-	igt_assert(eb);
-
-	debugger_test_metadata(d,
-			       eb->client_handle,
-			       em->metadata_handle,
-			       em->metadata_cookie,
-			       MDATA_SIZE); /* max size */
-
-	xe_eudebug_debugger_signal_stage(d, em->metadata_cookie);
-}
-
-/**
- * SUBTEST: read-metadata
- * Functionality: metadata
- * Description:
- *      Exercise DRM_XE_EUDEBUG_IOCTL_READ_METADATA and debug metadata create|destroy events.
- */
-static void test_metadata_read(int fd, unsigned int flags, int num_clients)
-{
-	test_client_with_trigger(fd, flags, num_clients, metadata_access_client,
-				 DRM_XE_EUDEBUG_EVENT_METADATA, metadata_read_trigger,
-				 NULL, true, 0);
-}
-
-/**
- * SUBTEST: attach-debug-metadata
- * Functionality: metadata
- * Description:
- *      Read debug metadata when vm_bind has it attached.
- */
-static void test_metadata_attach(int fd, unsigned int flags, int num_clients)
-{
-	test_client_with_trigger(fd, flags, num_clients, metadata_access_client,
-				 DRM_XE_EUDEBUG_EVENT_VM_BIND_OP_METADATA,
-				 metadata_read_on_vm_bind_trigger,
-				 NULL, true, 0);
-}
-
 #define STAGE_CLIENT_WAIT_ON_UFENCE_DONE 1337
 
 #define UFENCE_EVENT_COUNT_EXPECTED 4
@@ -2885,9 +2695,6 @@ int igt_main()
 	igt_subtest("basic-vm-bind-discovery")
 		test_basic_discovery(fd, VM_BIND, true);
 
-	igt_subtest("basic-vm-bind-metadata-discovery")
-		test_basic_discovery(fd, VM_BIND_METADATA, true);
-
 	igt_subtest("basic-vm-bind-vm-destroy")
 		test_basic_sessions(fd, VM_BIND_VM_DESTROY, 1, false);
 
@@ -2900,12 +2707,6 @@ int igt_main()
 	igt_subtest("basic-vm-bind-extended-discovery")
 		test_basic_discovery(fd, VM_BIND_EXTENDED, true);
 
-	igt_subtest("read-metadata")
-		test_metadata_read(fd, 0, 1);
-
-	igt_subtest("attach-debug-metadata")
-		test_metadata_attach(fd, 0, 1);
-
 	igt_subtest("discovery-race")
 		test_race_discovery(fd, 0, 4);
 
diff --git a/tests/intel/xe_eudebug_online.c b/tests/intel/xe_eudebug_online.c
index e59b99ee99..9b1e010d2a 100644
--- a/tests/intel/xe_eudebug_online.c
+++ b/tests/intel/xe_eudebug_online.c
@@ -891,52 +891,6 @@ static void vm_open_trigger(struct xe_eudebug_debugger *d,
 	pthread_mutex_unlock(&data->mutex);
 }
 
-static void read_metadata(struct xe_eudebug_debugger *d,
-			  uint64_t client_handle,
-			  uint64_t metadata_handle,
-			  uint64_t type,
-			  uint64_t len)
-{
-	struct drm_xe_eudebug_read_metadata rm = {
-		.client_handle = client_handle,
-		.metadata_handle = metadata_handle,
-		.size = len,
-	};
-	struct online_debug_data *data = d->ptr;
-	uint64_t *metadata;
-
-	metadata = malloc(len);
-	igt_assert(metadata);
-
-	rm.ptr = to_user_pointer(metadata);
-	igt_assert_eq(igt_ioctl(d->fd, DRM_XE_EUDEBUG_IOCTL_READ_METADATA, &rm), 0);
-
-	pthread_mutex_lock(&data->mutex);
-	switch (type) {
-	case DRM_XE_DEBUG_METADATA_ELF_BINARY:
-		data->bb_offset = metadata[0];
-		data->bb_size = metadata[1];
-		break;
-	case DRM_XE_DEBUG_METADATA_PROGRAM_MODULE:
-		data->target_offset = metadata[0];
-		data->target_size = metadata[1];
-		break;
-	default:
-		break;
-	}
-	pthread_mutex_unlock(&data->mutex);
-
-	free(metadata);
-}
-
-static void create_metadata_trigger(struct xe_eudebug_debugger *d, struct drm_xe_eudebug_event *e)
-{
-	struct drm_xe_eudebug_event_metadata *em = (void *)e;
-
-	if (e->flags & DRM_XE_EUDEBUG_EVENT_CREATE)
-		read_metadata(d, em->client_handle, em->metadata_handle, em->type, em->len);
-}
-
 static void overwrite_immediate_value_in_common_target_write(int vm_fd, uint64_t offset,
 							     uint32_t old_val, uint32_t new_val)
 {
@@ -1114,18 +1068,11 @@ static void run_online_client(struct xe_eudebug_client *c)
 	struct dim_t s_dim;
 	struct timespec ts = { };
 	struct gpgpu_shader *sip, *shader;
-	uint32_t metadata_id[2];
-	uint64_t *metadata[2];
 	struct intel_bb *ibb;
 	struct intel_buf *buf;
 	uint32_t *ptr;
 	int fd, vm_flags;
 
-	metadata[0] = calloc(2, sizeof(**metadata));
-	metadata[1] = calloc(2, sizeof(**metadata));
-	igt_assert(metadata[0]);
-	igt_assert(metadata[1]);
-
 	fd = xe_eudebug_client_open_driver(c);
 
 	threads = data->thread_count;
@@ -1146,16 +1093,6 @@ static void run_online_client(struct xe_eudebug_client *c)
 
 	buf->addr.offset = target_offset;
 
-	metadata[0][0] = bb_offset;
-	metadata[0][1] = bb_size;
-	metadata[1][0] = target_offset;
-	metadata[1][1] = buf->size;
-	metadata_id[0] = xe_eudebug_client_metadata_create(c, fd, DRM_XE_DEBUG_METADATA_ELF_BINARY,
-							   2 * sizeof(**metadata), metadata[0]);
-	metadata_id[1] = xe_eudebug_client_metadata_create(c, fd,
-							   DRM_XE_DEBUG_METADATA_PROGRAM_MODULE,
-							   2 * sizeof(**metadata), metadata[1]);
-
 	vm_flags = DRM_XE_VM_CREATE_FLAG_LR_MODE;
 	vm_flags |= c->flags & (SHADER_PAGEFAULT | FAULTABLE_VM) ?
 			DRM_XE_VM_CREATE_FLAG_FAULT_MODE : 0;
@@ -1209,12 +1146,6 @@ static void run_online_client(struct xe_eudebug_client *c)
 	xe_eudebug_client_exec_queue_destroy(c, fd, &create);
 	xe_eudebug_client_vm_destroy(c, fd, create.vm_id);
 
-	xe_eudebug_client_metadata_destroy(c, fd, metadata_id[0], DRM_XE_DEBUG_METADATA_ELF_BINARY,
-					   2 * sizeof(**metadata));
-	xe_eudebug_client_metadata_destroy(c, fd, metadata_id[1],
-					   DRM_XE_DEBUG_METADATA_PROGRAM_MODULE,
-					   2 * sizeof(**metadata));
-
 	intel_buf_destroy(buf);
 
 	xe_eudebug_client_close_driver(c, fd);
@@ -1587,8 +1518,6 @@ static void test_set_breakpoint_online(int fd, struct drm_xe_engine_class_instan
 	xe_eudebug_debugger_add_trigger(s->debugger, DRM_XE_EUDEBUG_EVENT_EXEC_QUEUE,
 					exec_queue_trigger);
 	xe_eudebug_debugger_add_trigger(s->debugger, DRM_XE_EUDEBUG_EVENT_VM, vm_open_trigger);
-	xe_eudebug_debugger_add_trigger(s->debugger, DRM_XE_EUDEBUG_EVENT_METADATA,
-					create_metadata_trigger);
 	xe_eudebug_debugger_add_trigger(s->debugger, DRM_XE_EUDEBUG_EVENT_VM_BIND_UFENCE,
 					ufence_ack_set_bp_trigger);
 	xe_eudebug_debugger_add_trigger(s->debugger, DRM_XE_EUDEBUG_EVENT_EU_ATTENTION,
@@ -1652,8 +1581,6 @@ static void test_set_breakpoint_online_sigint_debugger(int fd,
 						exec_queue_trigger);
 		xe_eudebug_debugger_add_trigger(s->debugger, DRM_XE_EUDEBUG_EVENT_VM,
 						vm_open_trigger);
-		xe_eudebug_debugger_add_trigger(s->debugger, DRM_XE_EUDEBUG_EVENT_METADATA,
-						create_metadata_trigger);
 		xe_eudebug_debugger_add_trigger(s->debugger, DRM_XE_EUDEBUG_EVENT_VM_BIND_UFENCE,
 						ufence_ack_set_bp_trigger);
 		xe_eudebug_debugger_add_trigger(s->debugger, DRM_XE_EUDEBUG_EVENT_EU_ATTENTION,
@@ -1780,8 +1707,6 @@ static void test_pagefault_online(int fd, struct drm_xe_engine_class_instance *h
 	xe_eudebug_debugger_add_trigger(s->debugger, DRM_XE_EUDEBUG_EVENT_EU_ATTENTION,
 					eu_attention_resume_trigger);
 	xe_eudebug_debugger_add_trigger(s->debugger, DRM_XE_EUDEBUG_EVENT_VM, vm_open_trigger);
-	xe_eudebug_debugger_add_trigger(s->debugger, DRM_XE_EUDEBUG_EVENT_METADATA,
-					create_metadata_trigger);
 	xe_eudebug_debugger_add_trigger(s->debugger, DRM_XE_EUDEBUG_EVENT_VM_BIND_UFENCE,
 					ufence_ack_trigger);
 	xe_eudebug_debugger_add_trigger(s->debugger, DRM_XE_EUDEBUG_EVENT_PAGEFAULT,
@@ -1919,8 +1844,6 @@ static void test_interrupt_all(int fd, struct drm_xe_engine_class_instance *hwe,
 	xe_eudebug_debugger_add_trigger(s->debugger, DRM_XE_EUDEBUG_EVENT_EU_ATTENTION,
 					eu_attention_resume_trigger);
 	xe_eudebug_debugger_add_trigger(s->debugger, DRM_XE_EUDEBUG_EVENT_VM, vm_open_trigger);
-	xe_eudebug_debugger_add_trigger(s->debugger, DRM_XE_EUDEBUG_EVENT_METADATA,
-					create_metadata_trigger);
 	xe_eudebug_debugger_add_trigger(s->debugger, DRM_XE_EUDEBUG_EVENT_VM_BIND_UFENCE,
 					ufence_ack_trigger);
 
@@ -2005,8 +1928,6 @@ static void test_interrupt_other(int fd, struct drm_xe_engine_class_instance *hw
 	xe_eudebug_debugger_add_trigger(s->debugger, DRM_XE_EUDEBUG_EVENT_EXEC_QUEUE,
 					exec_queue_trigger);
 	xe_eudebug_debugger_add_trigger(s->debugger, DRM_XE_EUDEBUG_EVENT_VM, vm_open_trigger);
-	xe_eudebug_debugger_add_trigger(s->debugger, DRM_XE_EUDEBUG_EVENT_METADATA,
-					create_metadata_trigger);
 	xe_eudebug_debugger_add_trigger(s->debugger, DRM_XE_EUDEBUG_EVENT_VM_BIND_UFENCE,
 					ufence_ack_trigger);
 
@@ -2101,8 +2022,6 @@ static void test_tdctl_parameters(int fd, struct drm_xe_engine_class_instance *h
 	xe_eudebug_debugger_add_trigger(s->debugger, DRM_XE_EUDEBUG_EVENT_EU_ATTENTION,
 					eu_attention_resume_trigger);
 	xe_eudebug_debugger_add_trigger(s->debugger, DRM_XE_EUDEBUG_EVENT_VM, vm_open_trigger);
-	xe_eudebug_debugger_add_trigger(s->debugger, DRM_XE_EUDEBUG_EVENT_METADATA,
-					create_metadata_trigger);
 	xe_eudebug_debugger_add_trigger(s->debugger, DRM_XE_EUDEBUG_EVENT_VM_BIND_UFENCE,
 					ufence_ack_trigger);
 
@@ -2251,8 +2170,6 @@ static void test_interrupt_reconnect(int fd, struct drm_xe_engine_class_instance
 	xe_eudebug_debugger_add_trigger(s->debugger, DRM_XE_EUDEBUG_EVENT_EU_ATTENTION,
 					eu_attention_debugger_detach_trigger);
 	xe_eudebug_debugger_add_trigger(s->debugger, DRM_XE_EUDEBUG_EVENT_VM, vm_open_trigger);
-	xe_eudebug_debugger_add_trigger(s->debugger, DRM_XE_EUDEBUG_EVENT_METADATA,
-					create_metadata_trigger);
 	xe_eudebug_debugger_add_trigger(s->debugger, DRM_XE_EUDEBUG_EVENT_VM_BIND_UFENCE,
 					ufence_ack_trigger);
 
@@ -2328,8 +2245,6 @@ static void test_single_step(int fd, struct drm_xe_engine_class_instance *hwe, i
 	xe_eudebug_debugger_add_trigger(s->debugger, DRM_XE_EUDEBUG_EVENT_EU_ATTENTION,
 					eu_attention_resume_single_step_trigger);
 	xe_eudebug_debugger_add_trigger(s->debugger, DRM_XE_EUDEBUG_EVENT_VM, vm_open_trigger);
-	xe_eudebug_debugger_add_trigger(s->debugger, DRM_XE_EUDEBUG_EVENT_METADATA,
-					create_metadata_trigger);
 	xe_eudebug_debugger_add_trigger(s->debugger, DRM_XE_EUDEBUG_EVENT_VM_BIND_UFENCE,
 					ufence_ack_trigger);
 
@@ -2429,8 +2344,6 @@ static void test_caching(int fd, struct drm_xe_engine_class_instance *hwe, int f
 	xe_eudebug_debugger_add_trigger(s->debugger, DRM_XE_EUDEBUG_EVENT_EU_ATTENTION,
 					eu_attention_resume_caching_trigger);
 	xe_eudebug_debugger_add_trigger(s->debugger, DRM_XE_EUDEBUG_EVENT_VM, vm_open_trigger);
-	xe_eudebug_debugger_add_trigger(s->debugger, DRM_XE_EUDEBUG_EVENT_METADATA,
-					create_metadata_trigger);
 	xe_eudebug_debugger_add_trigger(s->debugger, DRM_XE_EUDEBUG_EVENT_VM_BIND_UFENCE,
 					ufence_ack_trigger);
 
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [PATCH i-g-t 06/21] eudebug: Remove EVENT_OPEN and adjust tests
  2026-01-12 12:59 [PATCH i-g-t 00/21] eudebug: uapi changes on connect and metadata Mika Kuoppala
                   ` (4 preceding siblings ...)
  2026-01-12 12:59 ` [PATCH i-g-t 05/21] eudebug: Remove metadata tests Mika Kuoppala
@ 2026-01-12 12:59 ` Mika Kuoppala
  2026-01-12 12:59 ` [PATCH i-g-t 07/21] tests/xe_eudebug: Adapt basic-read-event Mika Kuoppala
                   ` (14 subsequent siblings)
  20 siblings, 0 replies; 23+ messages in thread
From: Mika Kuoppala @ 2026-01-12 12:59 UTC (permalink / raw)
  To: igt-dev
  Cc: christoph.manszewski, dominik.karol.piatkowski, maciej.patelczyk,
	jan.maslak, zbigniew.kempczynski, Mika Kuoppala

eudebug connections are against drm client filedescriptor
instead of the whole process (pid). This simplifies
access control as in order to gain access to the drm clients
file descriptor, the debugger either has delivered fd through
pipe or gone through proc/<pid>/fs to find it.

Start with removing client_handles from all events.
Put client->fd into the xe_eudebug_client structure as it is
singleton and immutable through client lifetime now.

The discovery tests have strong assumption how connection works,
disable them now until lib/xe_eudebug.c can accommodate.

With this in place basic-connect/basic-close/basic-client works.

v2: __xe_eudebug_connect helper (Christoph)

Signed-off-by: Mika Kuoppala <mika.kuoppala@linux.intel.com>
Signed-off-by: Christoph Manszewski <christoph.manszewski@intel.com>
---
 .../drm-uapi-experimental/xe_drm_eudebug.h    |  46 +-
 lib/xe/xe_eudebug.c                           | 462 ++++++++++--------
 lib/xe/xe_eudebug.h                           |  26 +-
 tests/intel/xe_eudebug.c                      | 390 +++++++--------
 tests/intel/xe_eudebug_online.c               | 151 ++----
 5 files changed, 496 insertions(+), 579 deletions(-)

diff --git a/include/drm-uapi-experimental/xe_drm_eudebug.h b/include/drm-uapi-experimental/xe_drm_eudebug.h
index 73e4f418f5..a9aa87f564 100644
--- a/include/drm-uapi-experimental/xe_drm_eudebug.h
+++ b/include/drm-uapi-experimental/xe_drm_eudebug.h
@@ -19,19 +19,13 @@ extern "C" {
  */
 
 /* XXX: BEGIN section moved from xe_drm.h as temporary solution */
-#define DRM_XE_EUDEBUG_CONNECT		0x0e
-#define DRM_XE_DEBUG_METADATA_CREATE	0x0f
-#define DRM_XE_DEBUG_METADATA_DESTROY	0x10
-
-/* ... */
 
+#define DRM_XE_EUDEBUG_CONNECT		0x0f
 #define DRM_IOCTL_XE_EUDEBUG_CONNECT		DRM_IOWR(DRM_COMMAND_BASE + DRM_XE_EUDEBUG_CONNECT, struct drm_xe_eudebug_connect)
-#define DRM_IOCTL_XE_DEBUG_METADATA_CREATE	 DRM_IOWR(DRM_COMMAND_BASE + DRM_XE_DEBUG_METADATA_CREATE, struct drm_xe_debug_metadata_create)
-#define DRM_IOCTL_XE_DEBUG_METADATA_DESTROY	 DRM_IOW(DRM_COMMAND_BASE + DRM_XE_DEBUG_METADATA_DESTROY, struct drm_xe_debug_metadata_destroy)
 
 /* ... */
 
-#define   DRM_XE_EXEC_QUEUE_SET_PROPERTY_EUDEBUG		3
+#define   DRM_XE_EXEC_QUEUE_SET_PROPERTY_EUDEBUG		6
 #define     DRM_XE_EXEC_QUEUE_EUDEBUG_FLAG_ENABLE		(1 << 0)
 
 /* ... */
@@ -47,7 +41,7 @@ struct drm_xe_eudebug_connect {
 	/** @extensions: Pointer to the first extension struct, if any */
 	__u64 extensions;
 
-	__u64 pid; /* input: Target process ID */
+	__u64 fd; /* Target drm client fd */
 	__u32 flags; /* MBZ */
 
 	__u32 version; /* output: current ABI (ioctl / events) version */
@@ -73,16 +67,15 @@ struct drm_xe_eudebug_event {
 	__u16 type;
 #define DRM_XE_EUDEBUG_EVENT_NONE		0
 #define DRM_XE_EUDEBUG_EVENT_READ		1
-#define DRM_XE_EUDEBUG_EVENT_OPEN		2
-#define DRM_XE_EUDEBUG_EVENT_VM			3
-#define DRM_XE_EUDEBUG_EVENT_EXEC_QUEUE		4
-#define DRM_XE_EUDEBUG_EVENT_EU_ATTENTION	5
-#define DRM_XE_EUDEBUG_EVENT_VM_BIND		6
-#define DRM_XE_EUDEBUG_EVENT_VM_BIND_OP		7
-#define DRM_XE_EUDEBUG_EVENT_VM_BIND_UFENCE	8
-#define DRM_XE_EUDEBUG_EVENT_METADATA		9
-#define DRM_XE_EUDEBUG_EVENT_VM_BIND_OP_METADATA 10
-#define DRM_XE_EUDEBUG_EVENT_PAGEFAULT		11
+#define DRM_XE_EUDEBUG_EVENT_VM			2
+#define DRM_XE_EUDEBUG_EVENT_EXEC_QUEUE		3
+#define DRM_XE_EUDEBUG_EVENT_EU_ATTENTION	4
+#define DRM_XE_EUDEBUG_EVENT_VM_BIND		5
+#define DRM_XE_EUDEBUG_EVENT_VM_BIND_OP		6
+#define DRM_XE_EUDEBUG_EVENT_VM_BIND_UFENCE	7
+#define DRM_XE_EUDEBUG_EVENT_METADATA		8
+#define DRM_XE_EUDEBUG_EVENT_VM_BIND_OP_METADATA 9
+#define DRM_XE_EUDEBUG_EVENT_PAGEFAULT		10
 
 	__u16 flags;
 #define DRM_XE_EUDEBUG_EVENT_CREATE		(1 << 0)
@@ -94,23 +87,15 @@ struct drm_xe_eudebug_event {
 	__u64 reserved;
 };
 
-struct drm_xe_eudebug_event_client {
-	struct drm_xe_eudebug_event base;
-
-	__u64 client_handle; /* This is unique per debug connection */
-};
-
 struct drm_xe_eudebug_event_vm {
 	struct drm_xe_eudebug_event base;
 
-	__u64 client_handle;
 	__u64 vm_handle;
 };
 
 struct drm_xe_eudebug_event_exec_queue {
 	struct drm_xe_eudebug_event base;
 
-	__u64 client_handle;
 	__u64 vm_handle;
 	__u64 exec_queue_handle;
 	__u32 engine_class;
@@ -121,7 +106,6 @@ struct drm_xe_eudebug_event_exec_queue {
 struct drm_xe_eudebug_event_eu_attention {
 	struct drm_xe_eudebug_event base;
 
-	__u64 client_handle;
 	__u64 exec_queue_handle;
 	__u64 lrc_handle;
 	__u32 flags;
@@ -130,7 +114,6 @@ struct drm_xe_eudebug_event_eu_attention {
 };
 
 struct drm_xe_eudebug_eu_control {
-	__u64 client_handle;
 
 #define DRM_XE_EUDEBUG_EU_CONTROL_CMD_INTERRUPT_ALL	0
 #define DRM_XE_EUDEBUG_EU_CONTROL_CMD_STOPPED		1
@@ -191,7 +174,6 @@ struct drm_xe_eudebug_eu_control {
 struct drm_xe_eudebug_event_vm_bind {
 	struct drm_xe_eudebug_event base;
 
-	__u64 client_handle;
 	__u64 vm_handle;
 
 	__u32 flags;
@@ -224,9 +206,6 @@ struct drm_xe_eudebug_vm_open {
 	/** @extensions: Pointer to the first extension struct, if any */
 	__u64 extensions;
 
-	/** @client_handle: id of client */
-	__u64 client_handle;
-
 	/** @vm_handle: id of vm */
 	__u64 vm_handle;
 
@@ -241,7 +220,6 @@ struct drm_xe_eudebug_vm_open {
 struct drm_xe_eudebug_event_pagefault {
 	struct drm_xe_eudebug_event base;
 
-	__u64 client_handle;
 	__u64 exec_queue_handle;
 	__u64 lrc_handle;
 	__u32 flags;
diff --git a/lib/xe/xe_eudebug.c b/lib/xe/xe_eudebug.c
index 0583ce8f31..2f2e82a65c 100644
--- a/lib/xe/xe_eudebug.c
+++ b/lib/xe/xe_eudebug.c
@@ -4,6 +4,7 @@
  */
 
 #include <fcntl.h>
+#include <dirent.h>
 #include <poll.h>
 #include <signal.h>
 #include <sys/select.h>
@@ -32,7 +33,6 @@ struct seqno_list_entry {
 struct match_dto {
 	struct drm_xe_eudebug_event *target;
 	struct igt_list_head *seqno_list;
-	uint64_t client_handle;
 	uint32_t filter;
 
 	/* store latest 'EVENT_VM_BIND' seqno */
@@ -43,17 +43,19 @@ struct match_dto {
 
 #define TOKEN_NONE  0
 #define CLIENT_PID  1
-#define CLIENT_RUN  2
-#define CLIENT_FINI 3
-#define CLIENT_STOP 4
-#define CLIENT_STAGE 5
-#define DEBUGGER_STAGE 6
+#define CLIENT_FD   2
+#define CLIENT_RUN  3
+#define CLIENT_FINI 4
+#define CLIENT_STOP 5
+#define CLIENT_STAGE 6
+#define DEBUGGER_STAGE 7
 
 static const char *token_to_str(uint64_t token)
 {
 	static const char * const s[] = {
 		"none",
 		"client pid",
+		"client fd",
 		"client run",
 		"client fini",
 		"client stop",
@@ -78,20 +80,18 @@ static const char *type_to_str(unsigned int type)
 		return "none";
 	case DRM_XE_EUDEBUG_EVENT_READ:
 		return "read";
-	case DRM_XE_EUDEBUG_EVENT_OPEN:
-		return "client";
 	case DRM_XE_EUDEBUG_EVENT_VM:
 		return "vm";
 	case DRM_XE_EUDEBUG_EVENT_EXEC_QUEUE:
 		return "exec_queue";
-	case DRM_XE_EUDEBUG_EVENT_EU_ATTENTION:
-		return "attention";
 	case DRM_XE_EUDEBUG_EVENT_VM_BIND:
 		return "vm_bind";
 	case DRM_XE_EUDEBUG_EVENT_VM_BIND_OP:
 		return "vm_bind_op";
 	case DRM_XE_EUDEBUG_EVENT_VM_BIND_UFENCE:
 		return "vm_bind_ufence";
+	case DRM_XE_EUDEBUG_EVENT_EU_ATTENTION:
+		return "attention";
 	case DRM_XE_EUDEBUG_EVENT_PAGEFAULT:
 		return "pagefault";
 	}
@@ -128,42 +128,26 @@ static const char *flags_to_str(unsigned int flags)
 static const char *event_members_to_str(struct drm_xe_eudebug_event *e, char *buf)
 {
 	switch (e->type) {
-	case DRM_XE_EUDEBUG_EVENT_OPEN: {
-		struct drm_xe_eudebug_event_client *ec = igt_container_of(e, ec, base);
-
-		sprintf(buf, "handle=%llu", ec->client_handle);
-		break;
-	}
 	case DRM_XE_EUDEBUG_EVENT_VM: {
 		struct drm_xe_eudebug_event_vm *evm = igt_container_of(e, evm, base);
 
-		sprintf(buf, "client_handle=%llu, handle=%llu",
-			evm->client_handle, evm->vm_handle);
+		sprintf(buf, "vm_handle=%llu", evm->vm_handle);
 		break;
 	}
 	case DRM_XE_EUDEBUG_EVENT_EXEC_QUEUE: {
 		struct drm_xe_eudebug_event_exec_queue *ee = igt_container_of(e, ee, base);
 
-		sprintf(buf, "client_handle=%llu, vm_handle=%llu, "
+		sprintf(buf, "vm_handle=%llu, "
 			"exec_queue_handle=%llu, engine_class=%d, exec_queue_width=%d",
-			ee->client_handle, ee->vm_handle,
+			ee->vm_handle,
 			ee->exec_queue_handle, ee->engine_class, ee->width);
 		break;
 	}
-	case DRM_XE_EUDEBUG_EVENT_EU_ATTENTION: {
-		struct drm_xe_eudebug_event_eu_attention *ea = igt_container_of(e, ea, base);
-
-		sprintf(buf, "client_handle=%llu, exec_queue_handle=%llu, "
-			"lrc_handle=%llu, bitmask_size=%d",
-			ea->client_handle, ea->exec_queue_handle,
-			ea->lrc_handle, ea->bitmask_size);
-		break;
-	}
 	case DRM_XE_EUDEBUG_EVENT_VM_BIND: {
 		struct drm_xe_eudebug_event_vm_bind *evmb = igt_container_of(e, evmb, base);
 
-		sprintf(buf, "client_handle=%llu, vm_handle=%llu, flags=0x%x, num_binds=%u",
-			evmb->client_handle, evmb->vm_handle, evmb->flags, evmb->num_binds);
+		sprintf(buf, "vm_handle=%llu, flags=0x%x, num_binds=%u",
+			evmb->vm_handle, evmb->flags, evmb->num_binds);
 		break;
 	}
 	case DRM_XE_EUDEBUG_EVENT_VM_BIND_OP: {
@@ -179,12 +163,21 @@ static const char *event_members_to_str(struct drm_xe_eudebug_event *e, char *bu
 		sprintf(buf, "vm_bind_ref_seqno=%lld", f->vm_bind_ref_seqno);
 		break;
 	}
+	case DRM_XE_EUDEBUG_EVENT_EU_ATTENTION: {
+		struct drm_xe_eudebug_event_eu_attention *ea = igt_container_of(e, ea, base);
+
+		sprintf(buf, "exec_queue_handle=%llu, "
+			"lrc_handle=%llu, bitmask_size=%d",
+			ea->exec_queue_handle,
+			ea->lrc_handle, ea->bitmask_size);
+		break;
+	}
 	case DRM_XE_EUDEBUG_EVENT_PAGEFAULT: {
 		struct drm_xe_eudebug_event_pagefault *pf = igt_container_of(e, pf, base);
 
-		sprintf(buf, "client_handle=%llu, exec_queue_handle=%llu, "
+		sprintf(buf, "exec_queue_handle=%llu, "
 			"lrc_handle=%llu, bitmask_size=%d, pagefault_address=0x%llx",
-			pf->client_handle, pf->exec_queue_handle, pf->lrc_handle,
+			pf->exec_queue_handle, pf->lrc_handle,
 			pf->bitmask_size, pf->pagefault_address);
 		break;
 	}
@@ -372,15 +365,143 @@ static void client_signal(struct xe_eudebug_client *c,
 	token_signal(c->p_out, token, value);
 }
 
-static int __xe_eudebug_connect(int fd, pid_t pid, uint32_t flags, uint64_t events)
+static int open_pidfd(int tgid)
+{
+	int pidfd;
+
+	pidfd = syscall(SYS_pidfd_open, tgid, 0);
+	if (pidfd < 0) {
+		igt_warn("Failed to open pidfd for tgid=%d: %s\n", tgid, strerror(errno));
+		return -1;
+	}
+
+	return pidfd;
+}
+
+/* Helper function to acquire a file descriptor from a target process using pidfd_getfd */
+static int pidfd_getfd(int pidfd, int target_fd)
+{
+	int my_fd;
+
+	my_fd = syscall(SYS_pidfd_getfd, pidfd, target_fd, 0);
+	if (my_fd < 0) {
+		igt_warn("failed to get fd=%d for pidfd=%d: %s\n", target_fd, pidfd,
+			 strerror(errno));
+		return -1;
+	}
+
+	return my_fd;
+}
+
+static int is_drm_fd(const char *path, const char *fname)
+{
+	char line[256];
+	char fullname[4096];
+	FILE *file;
+	int is_xe = 0;
+
+	snprintf(fullname, sizeof(fullname), "%s/%s", path, fname);
+
+	file = fopen(fullname, "r");
+	if (!file) {
+		igt_debug("cannot open %s: %s\n", fullname, strerror(errno));
+		return 0;
+	}
+
+	while (fgets(line, sizeof(line), file)) {
+		if (strstr(line, "drm-driver:\txe")) {
+			is_xe = 1;
+			break;
+		}
+	}
+
+	fclose(file);
+
+	return is_xe;
+}
+
+static int scan_fdinfo_for_xe_client(pid_t pid)
+{
+	char fdinfo_dir[64];
+	DIR *dir;
+	struct dirent *entry;
+	int fd = -1;
+	int drm_fd = -1;
+
+	snprintf(fdinfo_dir, sizeof(fdinfo_dir), "/proc/%d/fdinfo", pid);
+
+	dir = opendir(fdinfo_dir);
+	if (!dir) {
+		igt_debug("failed to open %s: %s\n", fdinfo_dir, strerror(errno));
+		return -1;
+	}
+
+	/* XXX we want last fd as it is most recent */
+	while ((entry = readdir(dir))) {
+		char *endptr;
+
+		if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0)
+			continue;
+
+		fd = strtol(entry->d_name, &endptr, 10);
+		if (*endptr != '\0' || fd < 0) {
+			continue;
+		}
+
+		if (is_drm_fd(fdinfo_dir, entry->d_name)) {
+			igt_debug("%s is drm fd\n", entry->d_name);
+			drm_fd = fd;
+		}
+	}
+
+	closedir(dir);
+
+	return drm_fd;
+}
+
+/* Get fd for this process for pid:target_fd */
+static int get_fd_for_target(pid_t pid, int targetfd)
+{
+	int pidfd;
+	int myfd;
+
+	pidfd = open_pidfd(pid);
+	if (pidfd < 0)
+		return pidfd;
+
+	myfd = pidfd_getfd(pidfd, targetfd);
+	if (myfd < 0) {
+		close(pidfd);
+		return myfd;
+	}
+
+	igt_debug("my pid %d:%d now mapped to remote %d:%d\n",
+		  getpid(), myfd,
+		  pid, targetfd);
+
+	return myfd;
+}
+
+int xe_eudebug_fd_for_pid(pid_t pid)
+{
+	int client_fd;
+
+	client_fd = scan_fdinfo_for_xe_client(pid);
+	if (client_fd < 0)
+		return client_fd;
+
+	return get_fd_for_target(pid, client_fd);
+}
+
+static int __xe_eudebug_connect_fd(int my_fd, int target_fd, uint32_t flags)
 {
 	struct drm_xe_eudebug_connect param = {
-		.pid = pid,
 		.flags = flags,
+		.fd = target_fd,
 	};
 	int debugfd;
 
-	debugfd = igt_ioctl(fd, DRM_IOCTL_XE_EUDEBUG_CONNECT, &param);
+	debugfd = igt_ioctl(my_fd, DRM_IOCTL_XE_EUDEBUG_CONNECT, &param);
 
 	if (debugfd < 0)
 		return -errno;
@@ -500,40 +621,20 @@ static int match_client_handle(struct drm_xe_eudebug_event *e, void *data)
 	struct match_dto *md = data;
 	uint64_t *bind_seqno = md->bind_seqno;
 	uint64_t *bind_op_seqno = md->bind_op_seqno;
-	uint64_t h = md->client_handle;
 
 	if (XE_EUDEBUG_EVENT_IS_FILTERED(e->type, md->filter))
 		return 0;
 
 	switch (e->type) {
-	case DRM_XE_EUDEBUG_EVENT_OPEN: {
-		struct drm_xe_eudebug_event_client *client = igt_container_of(e, client, base);
-
-		if (client->client_handle == h)
-			return 1;
-		break;
-	}
-	case DRM_XE_EUDEBUG_EVENT_VM: {
-		struct drm_xe_eudebug_event_vm *vm = igt_container_of(e, vm, base);
-
-		if (vm->client_handle == h)
-			return 1;
-		break;
-	}
-	case DRM_XE_EUDEBUG_EVENT_EXEC_QUEUE: {
-	struct drm_xe_eudebug_event_exec_queue *ee = igt_container_of(e, ee, base);
+	case DRM_XE_EUDEBUG_EVENT_VM:
+	case DRM_XE_EUDEBUG_EVENT_EXEC_QUEUE:
+		return 1;
 
-		if (ee->client_handle == h)
-			return 1;
-		break;
-	}
 	case DRM_XE_EUDEBUG_EVENT_VM_BIND: {
 		struct drm_xe_eudebug_event_vm_bind *evmb = igt_container_of(e, evmb, base);
 
-		if (evmb->client_handle == h) {
-			*bind_seqno = evmb->base.seqno;
-			return 1;
-		}
+		*bind_seqno = evmb->base.seqno;
+		return 1;
 		break;
 	}
 	case DRM_XE_EUDEBUG_EVENT_VM_BIND_OP: {
@@ -574,14 +675,6 @@ static int match_opposite_resource(struct drm_xe_eudebug_event *e, void *data)
 		return 0;
 
 	switch (e->type) {
-	case DRM_XE_EUDEBUG_EVENT_OPEN: {
-		struct drm_xe_eudebug_event_client *client = igt_container_of(e, client, base);
-		struct drm_xe_eudebug_event_client *filter = data;
-
-		if (client->client_handle == filter->client_handle)
-			return 1;
-		break;
-	}
 	case DRM_XE_EUDEBUG_EVENT_VM: {
 		struct drm_xe_eudebug_event_vm *vm = igt_container_of(e, vm, base);
 		struct drm_xe_eudebug_event_vm *filter = data;
@@ -625,7 +718,6 @@ static int match_opposite_resource(struct drm_xe_eudebug_event *e, void *data)
 static int match_full(struct drm_xe_eudebug_event *e, void *data)
 {
 	struct seqno_list_entry *sl;
-
 	struct match_dto *md = (void *)data;
 	int ret = 0;
 
@@ -655,14 +747,12 @@ event_type_match(struct xe_eudebug_event_log *l,
 
 static struct drm_xe_eudebug_event *
 client_match(struct xe_eudebug_event_log *l,
-	     uint64_t client_handle,
 	     struct drm_xe_eudebug_event *current,
 	     uint32_t filter,
 	     uint64_t *bind_seqno,
 	     uint64_t *bind_op_seqno)
 {
 	struct match_dto md = {
-		.client_handle = client_handle,
 		.filter = filter,
 		.bind_seqno = bind_seqno,
 		.bind_op_seqno = bind_op_seqno,
@@ -682,14 +772,12 @@ opposite_event_match(struct xe_eudebug_event_log *l,
 static struct drm_xe_eudebug_event *
 event_match(struct xe_eudebug_event_log *l,
 	    struct drm_xe_eudebug_event *target,
-	    uint64_t client_handle,
 	    struct igt_list_head *seqno_list,
 	    uint64_t *bind_seqno,
 	    uint64_t *bind_op_seqno)
 {
 	struct match_dto md = {
 		.target = target,
-		.client_handle = client_handle,
 		.seqno_list = seqno_list,
 		.bind_seqno = bind_seqno,
 		.bind_op_seqno = bind_op_seqno,
@@ -698,40 +786,32 @@ event_match(struct xe_eudebug_event_log *l,
 	return event_cmp(l, NULL, match_full, &md);
 }
 
-static void compare_client(struct xe_eudebug_event_log *log1, struct drm_xe_eudebug_event *ev1,
-			   struct xe_eudebug_event_log *log2, struct drm_xe_eudebug_event *ev2,
+static void compare_client(struct xe_eudebug_event_log *log1,
+			   struct xe_eudebug_event_log *log2,
 			   uint32_t filter)
 {
-	struct drm_xe_eudebug_event_client *ev1_client = igt_container_of(ev1, ev1_client, base);
-	struct drm_xe_eudebug_event_client *ev2_client = igt_container_of(ev2, ev2_client, base);
 	uint64_t cbs = 0, dbs = 0, cbso = 0, dbso = 0;
 
 	struct igt_list_head matched_seqno_list;
 	struct drm_xe_eudebug_event *evptr1, *evptr2;
 	struct seqno_list_entry *entry, *tmp;
 
-	igt_assert(ev1_client);
-	igt_assert(ev2_client);
-
-	igt_debug("client: %llu -> %llu\n", ev1_client->client_handle, ev2_client->client_handle);
-
 	evptr1 = NULL;
 	evptr2 = NULL;
 	IGT_INIT_LIST_HEAD(&matched_seqno_list);
 
 	do {
-		evptr1 = client_match(log1, ev1_client->client_handle, evptr1, filter, &cbs, &cbso);
+		evptr1 = client_match(log1, evptr1, filter, &cbs, &cbso);
 		if (!evptr1)
 			break;
 
-		evptr2 = event_match(log2, evptr1, ev2_client->client_handle, &matched_seqno_list,
+		evptr2 = event_match(log2, evptr1, &matched_seqno_list,
 				     &dbs, &dbso);
 
-		igt_assert_f(evptr2, "%s (%llu): no matching event type %u found for client %llu\n",
+		igt_assert_f(evptr2, "%s (%llu): no matching event type %u found for client\n",
 			     log1->name,
 			     evptr1->seqno,
-			     evptr1->type,
-			     ev1_client->client_handle);
+			     evptr1->type);
 
 		igt_debug("comparing %s %llu vs %s %llu\n",
 			  log1->name, evptr1->seqno, log2->name, evptr2->seqno);
@@ -828,26 +908,6 @@ static void event_log_sort(struct xe_eudebug_event_log *l)
 	xe_eudebug_event_log_destroy(tmp);
 }
 
-/**
- * xe_eudebug_connect:
- * @fd: Xe file descriptor
- * @pid: client PID
- * @flags: connection flags
- *
- * Opens the xe eu debugger connection to the process described by @pid
- *
- * Returns: 0 if the debugger was successfully attached, -errno otherwise.
- */
-int xe_eudebug_connect(int fd, pid_t pid, uint32_t flags)
-{
-	int ret;
-	uint64_t events = 0; /* events filtering not supported yet! */
-
-	ret = __xe_eudebug_connect(fd, pid, flags, events);
-
-	return ret;
-}
-
 /**
  * xe_eudebug_event_log_create:
  * @name: event log identifier
@@ -944,8 +1004,7 @@ xe_eudebug_event_log_print(struct xe_eudebug_event_log *l, bool debug)
  * @a: event log pointer
  * @b: event log pointer
  * @filter: mask that represents events to be skipped during comparison, useful
- * for events like 'VM_BIND' since they can be asymmetric. Note that
- * 'DRM_XE_EUDEBUG_EVENT_OPEN' will always be matched.
+ * for events like 'VM_BIND' since they can be asymmetric.
  *
  * Compares and asserts event logs @a, @b if the event
  * sequence matches.
@@ -955,7 +1014,6 @@ void xe_eudebug_event_log_compare(struct xe_eudebug_event_log *log1,
 				  uint32_t filter)
 {
 	struct drm_xe_eudebug_event *ev1 = NULL;
-	struct drm_xe_eudebug_event *ev2 = NULL;
 
 	igt_assert(log1);
 	igt_assert(log2);
@@ -966,21 +1024,20 @@ void xe_eudebug_event_log_compare(struct xe_eudebug_event_log *log1,
 	}
 
 	xe_eudebug_for_each_event(ev1, log1) {
+		struct drm_xe_eudebug_event *ev2 = NULL;
+
 		if (XE_EUDEBUG_EVENT_IS_FILTERED(ev1->type, filter))
 			continue;
 
-		if (ev1->type == DRM_XE_EUDEBUG_EVENT_OPEN &&
-		    ev1->flags & DRM_XE_EUDEBUG_EVENT_CREATE) {
-			ev2 = event_type_match(log2, ev1, ev2);
-			if (!ev2)
-				igt_debug("match failed to find type %d, seqno %llu\n",
-					  ev1->type, ev1->seqno);
+		ev2 = event_type_match(log2, ev1, ev2);
+		if (!ev2)
+			igt_debug("match failed to find type %d, seqno %llu\n",
+				  ev1->type, ev1->seqno);
 
-			igt_assert(ev2);
+		igt_assert(ev2);
 
-			compare_client(log1, ev1, log2, ev2, filter);
-			compare_client(log2, ev2, log1, ev1, filter);
-		}
+		compare_client(log1, log2, filter);
+		compare_client(log2, log1, filter);
 	}
 }
 
@@ -1164,9 +1221,10 @@ out:
  */
 bool xe_eudebug_debugger_available(int fd)
 {
-	struct drm_xe_eudebug_connect param = { .pid = getpid() };
+	struct drm_xe_eudebug_connect param = { 0, };
 	int debugfd;
 
+	param.fd = fd;
 	debugfd = igt_ioctl(fd, DRM_IOCTL_XE_EUDEBUG_CONNECT, &param);
 	if (debugfd >= 0)
 		close(debugfd);
@@ -1237,12 +1295,35 @@ void xe_eudebug_debugger_destroy(struct xe_eudebug_debugger *d)
 	free(d);
 }
 
+/**
+ * xe_eudebug_connect:
+ * @master_fd: Xe client used to open the debugger connection
+ * @target_fd: fd of the Xe client to connect to
+ * @target_pid: pid of the owner of target_fd
+ * @flags: optional connection flags
+ *
+ * Opens a Xe EU debugger connection to the Xe client described by target_pid and target_fd.
+ *
+ * Returns: a valid debugger fd if the debugger was successfully attached, -errno otherwise.
+ */
+int __xe_eudebug_connect(int master_fd, int target_fd, pid_t target_pid, int flags)
+{
+	int myfd;
+
+	myfd = get_fd_for_target(target_pid, target_fd);
+	igt_assert(myfd > 0);
+
+	return __xe_eudebug_connect_fd(master_fd, myfd, flags);
+}
+
 /**
  * xe_eudebug_debugger_attach:
  * @d: pointer to the debugger
  * @c: pointer to the client
  *
- * Opens the xe eu debugger connection to the process described by @c (c->pid)
+ * Opens a Xe EU debugger connection to the Xe client described by @c. Asserts that the debugger
+ * pointed by @d has no active session and that @c is valid. Logically associates the debugger
+ * instance pointed by @d with the client pointed by @c.
  *
  * Returns: 0 if the debugger was successfully attached, -errno otherwise.
  */
@@ -1253,13 +1334,14 @@ int xe_eudebug_debugger_attach(struct xe_eudebug_debugger *d,
 
 	igt_assert_eq(d->fd, -1);
 	igt_assert_neq(c->pid, 0);
-	ret = xe_eudebug_connect(d->master_fd, c->pid, 0);
+	igt_assert(c->fd > 0);
 
-	if (ret < 0)
-		return ret;
+	ret = __xe_eudebug_connect(d->master_fd, c->fd, c->pid, 0);
+	igt_assert(ret > 0);
 
 	d->fd = ret;
 	d->target_pid = c->pid;
+	d->target_fd = c->fd;
 	d->p_client[0] = c->p_in[0];
 	d->p_client[1] = c->p_in[1];
 
@@ -1280,6 +1362,7 @@ void xe_eudebug_debugger_detach(struct xe_eudebug_debugger *d)
 	igt_assert(d->target_pid);
 	close(d->fd);
 	d->target_pid = 0;
+	d->target_fd = -1;
 	d->fd = -1;
 }
 
@@ -1487,8 +1570,15 @@ struct xe_eudebug_client *xe_eudebug_client_create(int master_fd, xe_eudebug_cli
 		close(c->p_in[1]);
 		c->p_in[1] = -1;
 
+		/* XXX drm_open_driver dont allow skips from fork */
+		c->fd = drm_open_driver(DRIVER_XE);
+		igt_assert(c->fd > 0);
+
+		xe_device_get(c->fd);
+
 		mypid = getpid();
 		client_signal(c, CLIENT_PID, mypid);
+		client_signal(c, CLIENT_FD, c->fd);
 
 		c->pid = client_wait_token(c, CLIENT_RUN);
 		igt_assert_eq(c->pid, mypid);
@@ -1498,6 +1588,7 @@ struct xe_eudebug_client *xe_eudebug_client_create(int master_fd, xe_eudebug_cli
 		work(c);
 		igt_debug("client: work end\n");
 
+		xe_device_put(c->fd);
 		client_signal(c, CLIENT_FINI, c->seqno);
 
 		event_log_write_to_fd(c->log, c->p_out[1]);
@@ -1512,8 +1603,9 @@ struct xe_eudebug_client *xe_eudebug_client_create(int master_fd, xe_eudebug_cli
 	c->p_in[0] = -1;
 
 	c->pid = wait_from_client(c, CLIENT_PID);
+	c->fd = wait_from_client(c, CLIENT_FD);
 
-	igt_info("client running with pid %d\n", c->pid);
+	igt_info("client %d with running with pid %d\n", c->fd, c->pid);
 
 	return c;
 }
@@ -1746,31 +1838,19 @@ static void base_event(struct xe_eudebug_client *c,
 	e->len = size;
 }
 
-static void client_event(struct xe_eudebug_client *c, uint32_t flags, int client_fd)
-{
-	struct drm_xe_eudebug_event_client ec;
-
-	base_event(c, to_base(ec), DRM_XE_EUDEBUG_EVENT_OPEN, flags, sizeof(ec));
-
-	ec.client_handle = client_fd;
-
-	xe_eudebug_event_log_write(c->log, (void *)&ec);
-}
-
-static void vm_event(struct xe_eudebug_client *c, uint32_t flags, int client_fd, uint32_t vm_id)
+static void vm_event(struct xe_eudebug_client *c, uint32_t flags, uint32_t vm_id)
 {
 	struct drm_xe_eudebug_event_vm evm;
 
 	base_event(c, to_base(evm), DRM_XE_EUDEBUG_EVENT_VM, flags, sizeof(evm));
 
-	evm.client_handle = client_fd;
 	evm.vm_handle = vm_id;
 
 	xe_eudebug_event_log_write(c->log, (void *)&evm);
 }
 
 static void exec_queue_event(struct xe_eudebug_client *c, uint32_t flags,
-			     int client_fd, uint32_t vm_id,
+			     uint32_t vm_id,
 			     uint32_t exec_queue_handle, uint16_t class,
 			     uint16_t width)
 {
@@ -1779,7 +1859,6 @@ static void exec_queue_event(struct xe_eudebug_client *c, uint32_t flags,
 	base_event(c, to_base(ee), DRM_XE_EUDEBUG_EVENT_EXEC_QUEUE,
 		   flags, sizeof(ee));
 
-	ee.client_handle = client_fd;
 	ee.vm_handle = vm_id;
 	ee.exec_queue_handle = exec_queue_handle;
 	ee.engine_class = class;
@@ -1863,47 +1942,9 @@ bool xe_eudebug_enable(int fd, bool enable)
 	return old;
 }
 
-/* Eu debugger wrappers around resource creating xe ioctls. */
-
-/**
- * xe_eudebug_client_open_driver:
- * @c: pointer to xe_eudebug_client structure
- *
- * Calls drm_open_client(DRIVER_XE) and logs the corresponding
- * event in client's event log.
- *
- * Returns: valid DRM file descriptor
- */
-int xe_eudebug_client_open_driver(struct xe_eudebug_client *c)
-{
-	int fd;
-
-	igt_assert(c);
-	fd = drm_reopen_driver(c->master_fd);
-	client_event(c, DRM_XE_EUDEBUG_EVENT_CREATE, fd);
-
-	return fd;
-}
-
-/**
- * xe_eudebug_client_close_driver:
- * @c: pointer to xe_eudebug_client structure
- * @fd: xe client
- *
- * Calls close driver and logs the corresponding event in
- * client's event log.
- */
-void xe_eudebug_client_close_driver(struct xe_eudebug_client *c, int fd)
-{
-	igt_assert(c);
-	client_event(c, DRM_XE_EUDEBUG_EVENT_DESTROY, fd);
-	drm_close_driver(fd);
-}
-
 /**
  * xe_eudebug_client_vm_create:
  * @c: pointer to xe_eudebug_client structure
- * @fd: xe client
  * @flags: vm bind flags
  * @ext: pointer to the first user extension
  *
@@ -1911,14 +1952,14 @@ void xe_eudebug_client_close_driver(struct xe_eudebug_client *c, int fd)
  *
  * Returns: valid vm handle
  */
-uint32_t xe_eudebug_client_vm_create(struct xe_eudebug_client *c, int fd,
+uint32_t xe_eudebug_client_vm_create(struct xe_eudebug_client *c,
 				     uint32_t flags, uint64_t ext)
 {
 	uint32_t vm;
 
 	igt_assert(c);
-	vm = xe_vm_create(fd, flags, ext);
-	vm_event(c, DRM_XE_EUDEBUG_EVENT_CREATE, fd, vm);
+	vm = xe_vm_create(c->fd, flags, ext);
+	vm_event(c, DRM_XE_EUDEBUG_EVENT_CREATE, vm);
 
 	return vm;
 }
@@ -1926,23 +1967,21 @@ uint32_t xe_eudebug_client_vm_create(struct xe_eudebug_client *c, int fd,
 /**
  * xe_eudebug_client_vm_destroy:
  * @c: pointer to xe_eudebug_client structure
- * fd: xe client
  * vm: vm handle
  *
  * Calls xe_vm_destroy() and logs the corresponding event in
  * client's event log.
  */
-void xe_eudebug_client_vm_destroy(struct xe_eudebug_client *c, int fd, uint32_t vm)
+void xe_eudebug_client_vm_destroy(struct xe_eudebug_client *c, uint32_t vm)
 {
 	igt_assert(c);
-	xe_vm_destroy(fd, vm);
-	vm_event(c, DRM_XE_EUDEBUG_EVENT_DESTROY, fd, vm);
+	xe_vm_destroy(c->fd, vm);
+	vm_event(c, DRM_XE_EUDEBUG_EVENT_DESTROY, vm);
 }
 
 /**
  * xe_eudebug_client_exec_queue_create:
  * @c: pointer to xe_eudebug_client structure
- * @fd: xe client
  * @create: exec_queue create drm struct
  *
  * Calls xe exec queue create ioctl and logs the corresponding event in
@@ -1950,7 +1989,7 @@ void xe_eudebug_client_vm_destroy(struct xe_eudebug_client *c, int fd, uint32_t
  *
  * Returns: valid exec queue handle
  */
-uint32_t xe_eudebug_client_exec_queue_create(struct xe_eudebug_client *c, int fd,
+uint32_t xe_eudebug_client_exec_queue_create(struct xe_eudebug_client *c,
 					     struct drm_xe_exec_queue_create *create)
 {
 	struct drm_xe_engine_class_instance *instances;
@@ -1964,7 +2003,7 @@ uint32_t xe_eudebug_client_exec_queue_create(struct xe_eudebug_client *c, int fd
 	instances = from_user_pointer(create->instances);
 	class = instances[0].engine_class;
 
-	igt_assert_eq(igt_ioctl(fd, DRM_IOCTL_XE_EXEC_QUEUE_CREATE, create), 0);
+	igt_assert_eq(igt_ioctl(c->fd, DRM_IOCTL_XE_EXEC_QUEUE_CREATE, create), 0);
 
 	for (ext = from_user_pointer(create->extensions); ext;
 	     ext = from_user_pointer(ext->base.next_extension))
@@ -1974,7 +2013,7 @@ uint32_t xe_eudebug_client_exec_queue_create(struct xe_eudebug_client *c, int fd
 			send = true;
 
 	if (send)
-		exec_queue_event(c, DRM_XE_EUDEBUG_EVENT_CREATE, fd, create->vm_id,
+		exec_queue_event(c, DRM_XE_EUDEBUG_EVENT_CREATE, create->vm_id,
 				 create->exec_queue_id, class, create->width);
 
 	return create->exec_queue_id;
@@ -1983,13 +2022,12 @@ uint32_t xe_eudebug_client_exec_queue_create(struct xe_eudebug_client *c, int fd
 /**
  * xe_eudebug_client_exec_queue_destroy:
  * @c: pointer to xe_eudebug_client structure
- * @fd: xe client
  * @create: exec_queue create drm struct which was used for creation
  *
  * Calls xe exec_queue destroy ioctl and logs the corresponding event in
  * client's event log.
  */
-void xe_eudebug_client_exec_queue_destroy(struct xe_eudebug_client *c, int fd,
+void xe_eudebug_client_exec_queue_destroy(struct xe_eudebug_client *c,
 					  struct drm_xe_exec_queue_create *create)
 {
 	struct drm_xe_engine_class_instance *instances;
@@ -2013,17 +2051,16 @@ void xe_eudebug_client_exec_queue_destroy(struct xe_eudebug_client *c, int fd,
 			send = true;
 
 	if (send)
-		exec_queue_event(c, DRM_XE_EUDEBUG_EVENT_DESTROY, fd, create->vm_id,
+		exec_queue_event(c, DRM_XE_EUDEBUG_EVENT_DESTROY, create->vm_id,
 				 create->exec_queue_id, class, create->width);
 
-	igt_assert_eq(igt_ioctl(fd, DRM_IOCTL_XE_EXEC_QUEUE_DESTROY, &destroy), 0);
+	igt_assert_eq(igt_ioctl(c->fd, DRM_IOCTL_XE_EXEC_QUEUE_DESTROY, &destroy), 0);
 }
 
 /**
  * xe_eudebug_client_vm_bind_event:
  * @c: pointer to xe_eudebug_client structure
  * @event_flags: base event flags
- * @fd: xe client
  * @vm: vm handle
  * @bind_flags: bind flags of vm_bind_event
  * @num_binds: number of bind (operations) for event
@@ -2031,7 +2068,7 @@ void xe_eudebug_client_exec_queue_destroy(struct xe_eudebug_client *c, int fd,
  * Logs vm bind event in client's event log.
  */
 void xe_eudebug_client_vm_bind_event(struct xe_eudebug_client *c,
-				     uint32_t event_flags, int fd,
+				     uint32_t event_flags,
 				     uint32_t vm, uint32_t bind_flags,
 				     uint32_t num_binds, u64 *ref_seqno)
 {
@@ -2042,7 +2079,6 @@ void xe_eudebug_client_vm_bind_event(struct xe_eudebug_client *c,
 
 	base_event(c, to_base(evmb), DRM_XE_EUDEBUG_EVENT_VM_BIND,
 		   event_flags, sizeof(evmb));
-	evmb.client_handle = fd;
 	evmb.vm_handle = vm;
 	evmb.flags = bind_flags;
 	evmb.num_binds = num_binds;
@@ -2118,7 +2154,7 @@ static bool has_user_fence(const struct drm_xe_sync *sync, uint32_t num_syncs)
 }
 
 static int  __xe_eudebug_client_vm_bind(struct xe_eudebug_client *c,
-					int fd, uint32_t vm, uint32_t exec_queue,
+					uint32_t vm, uint32_t exec_queue,
 					uint32_t bo, uint64_t offset,
 					uint64_t addr, uint64_t size,
 					uint32_t op, uint32_t flags,
@@ -2148,7 +2184,7 @@ static int  __xe_eudebug_client_vm_bind(struct xe_eudebug_client *c,
 		break;
 	}
 
-	ret = ___xe_vm_bind(fd, vm, exec_queue, bo, offset, addr, size,
+	ret = ___xe_vm_bind(c->fd, vm, exec_queue, bo, offset, addr, size,
 			    op, flags, sync, num_syncs, prefetch_region,
 			    pat_index, 0, op_ext);
 
@@ -2159,7 +2195,7 @@ static int  __xe_eudebug_client_vm_bind(struct xe_eudebug_client *c,
 		return -EINVAL;
 
 	xe_eudebug_client_vm_bind_event(c, DRM_XE_EUDEBUG_EVENT_STATE_CHANGE,
-					fd, vm, bind_flags, 1, &seqno);
+					vm, bind_flags, 1, &seqno);
 	xe_eudebug_client_vm_bind_op_event(c, bind_base_flags,
 					   seqno, &op_seqno, addr, size, 0);
 
@@ -2170,7 +2206,7 @@ static int  __xe_eudebug_client_vm_bind(struct xe_eudebug_client *c,
 	return ret;
 }
 
-static void _xe_eudebug_client_vm_bind(struct xe_eudebug_client *c, int fd,
+static void _xe_eudebug_client_vm_bind(struct xe_eudebug_client *c,
 				       uint32_t vm, uint32_t bo,
 				       uint64_t offset, uint64_t addr, uint64_t size,
 				       uint32_t op,
@@ -2182,7 +2218,7 @@ static void _xe_eudebug_client_vm_bind(struct xe_eudebug_client *c, int fd,
 	const uint32_t exec_queue_id = 0;
 	const uint32_t prefetch_region = 0;
 
-	igt_assert_eq(__xe_eudebug_client_vm_bind(c, fd, vm, exec_queue_id, bo, offset,
+	igt_assert_eq(__xe_eudebug_client_vm_bind(c, vm, exec_queue_id, bo, offset,
 						  addr, size, op, flags,
 						  sync, num_syncs, prefetch_region,
 						  DEFAULT_PAT_INDEX, op_ext),
@@ -2192,7 +2228,6 @@ static void _xe_eudebug_client_vm_bind(struct xe_eudebug_client *c, int fd,
 /**
  * xe_eudebug_client_vm_bind_flags
  * @c: pointer to xe_eudebug_client structure
- * @fd: xe client
  * @vm: vm handle
  * @bo: buffer object handle
  * @offset: offset within buffer object
@@ -2205,14 +2240,14 @@ static void _xe_eudebug_client_vm_bind(struct xe_eudebug_client *c, int fd,
  *
  * Calls xe vm_bind ioctl and logs the corresponding event in client's event log.
  */
-void xe_eudebug_client_vm_bind_flags(struct xe_eudebug_client *c, int fd, uint32_t vm,
+void xe_eudebug_client_vm_bind_flags(struct xe_eudebug_client *c, uint32_t vm,
 				     uint32_t bo, uint64_t offset,
 				     uint64_t addr, uint64_t size, uint32_t flags,
 				     struct drm_xe_sync *sync, uint32_t num_syncs,
 				     uint64_t op_ext)
 {
 	igt_assert(c);
-	_xe_eudebug_client_vm_bind(c, fd, vm, bo, offset, addr, size,
+	_xe_eudebug_client_vm_bind(c, vm, bo, offset, addr, size,
 				   DRM_XE_VM_BIND_OP_MAP, flags,
 				   sync, num_syncs, op_ext);
 }
@@ -2220,7 +2255,6 @@ void xe_eudebug_client_vm_bind_flags(struct xe_eudebug_client *c, int fd, uint32
 /**
  * xe_eudebug_client_vm_bind
  * @c: pointer to xe_eudebug_client structure
- * @fd: xe client
  * @vm: vm handle
  * @bo: buffer object handle
  * @offset: offset within buffer object
@@ -2229,7 +2263,7 @@ void xe_eudebug_client_vm_bind_flags(struct xe_eudebug_client *c, int fd, uint32
  *
  * Calls xe vm_bind ioctl and logs the corresponding event in client's event log.
  */
-void xe_eudebug_client_vm_bind(struct xe_eudebug_client *c, int fd, uint32_t vm,
+void xe_eudebug_client_vm_bind(struct xe_eudebug_client *c, uint32_t vm,
 			       uint32_t bo, uint64_t offset,
 			       uint64_t addr, uint64_t size)
 {
@@ -2238,14 +2272,13 @@ void xe_eudebug_client_vm_bind(struct xe_eudebug_client *c, int fd, uint32_t vm,
 	const uint32_t num_syncs = 0;
 	const uint64_t op_ext = 0;
 
-	xe_eudebug_client_vm_bind_flags(c, fd, vm, bo, offset, addr, size, flags, sync, num_syncs,
+	xe_eudebug_client_vm_bind_flags(c, vm, bo, offset, addr, size, flags, sync, num_syncs,
 					op_ext);
 }
 
 /**
  * xe_eudebug_client_vm_unbind_flags
  * @c: pointer to xe_eudebug_client structure
- * @fd: xe client
  * @vm: vm handle
  * @offset: offset
  * @addr: ppgtt address
@@ -2256,13 +2289,13 @@ void xe_eudebug_client_vm_bind(struct xe_eudebug_client *c, int fd, uint32_t vm,
  *
  * Calls xe vm_unbind ioctl and logs the corresponding event in client's event log.
  */
-void xe_eudebug_client_vm_unbind_flags(struct xe_eudebug_client *c, int fd,
+void xe_eudebug_client_vm_unbind_flags(struct xe_eudebug_client *c,
 				       uint32_t vm, uint64_t offset,
 				       uint64_t addr, uint64_t size, uint32_t flags,
 				       struct drm_xe_sync *sync, uint32_t num_syncs)
 {
 	igt_assert(c);
-	_xe_eudebug_client_vm_bind(c, fd, vm, 0, offset, addr, size,
+	_xe_eudebug_client_vm_bind(c, vm, 0, offset, addr, size,
 				   DRM_XE_VM_BIND_OP_UNMAP, flags,
 				   sync, num_syncs, 0);
 }
@@ -2270,7 +2303,6 @@ void xe_eudebug_client_vm_unbind_flags(struct xe_eudebug_client *c, int fd,
 /**
  * xe_eudebug_client_vm_unbind
  * @c: pointer to xe_eudebug_client structure
- * @fd: xe client
  * @vm: vm handle
  * @offset: offset
  * @addr: ppgtt address
@@ -2278,14 +2310,14 @@ void xe_eudebug_client_vm_unbind_flags(struct xe_eudebug_client *c, int fd,
  *
  * Calls xe vm_unbind ioctl and logs the corresponding event in client's event log.
  */
-void xe_eudebug_client_vm_unbind(struct xe_eudebug_client *c, int fd, uint32_t vm,
+void xe_eudebug_client_vm_unbind(struct xe_eudebug_client *c, uint32_t vm,
 				 uint64_t offset, uint64_t addr, uint64_t size)
 {
 	const uint32_t flags = 0;
 	struct drm_xe_sync *sync = NULL;
 	const uint32_t num_syncs = 0;
 
-	xe_eudebug_client_vm_unbind_flags(c, fd, vm, offset, addr, size,
+	xe_eudebug_client_vm_unbind_flags(c, vm, offset, addr, size,
 					  flags, sync, num_syncs);
 }
 
diff --git a/lib/xe/xe_eudebug.h b/lib/xe/xe_eudebug.h
index 0706023121..ea7b320a27 100644
--- a/lib/xe/xe_eudebug.h
+++ b/lib/xe/xe_eudebug.h
@@ -38,6 +38,7 @@ struct xe_eudebug_debugger {
 	uint64_t event_count;
 
 	uint64_t target_pid;
+	int target_fd;
 
 	struct igt_list_head triggers;
 
@@ -54,6 +55,7 @@ struct xe_eudebug_debugger {
 };
 
 struct xe_eudebug_client {
+	int fd;
 	int pid;
 	uint64_t seqno;
 	uint64_t flags;
@@ -162,7 +164,6 @@ next_event(struct drm_xe_eudebug_event *e, struct xe_eudebug_event_log *l)
 
 #define XE_EUDEBUG_FILTER_EVENT_NONE			BIT(DRM_XE_EUDEBUG_EVENT_NONE)
 #define XE_EUDEBUG_FILTER_EVENT_READ			BIT(DRM_XE_EUDEBUG_EVENT_READ)
-#define XE_EUDEBUG_FILTER_EVENT_OPEN			BIT(DRM_XE_EUDEBUG_EVENT_OPEN)
 #define XE_EUDEBUG_FILTER_EVENT_VM			BIT(DRM_XE_EUDEBUG_EVENT_VM)
 #define XE_EUDEBUG_FILTER_EVENT_EXEC_QUEUE		BIT(DRM_XE_EUDEBUG_EVENT_EXEC_QUEUE)
 #define XE_EUDEBUG_FILTER_EVENT_EXEC_QUEUE_PLACEMENTS	BIT(DRM_XE_EUDEBUG_EVENT_EXEC_QUEUE_PLACEMENTS)
@@ -174,7 +175,7 @@ next_event(struct drm_xe_eudebug_event *e, struct xe_eudebug_event_log *l)
 #define XE_EUDEBUG_FILTER_ALL				GENMASK(DRM_XE_EUDEBUG_EVENT_PAGEFAULT, 0)
 #define XE_EUDEBUG_EVENT_IS_FILTERED(_e, _f)		((1UL << (_e)) & (_f))
 
-int xe_eudebug_connect(int fd, pid_t pid, uint32_t flags);
+int xe_eudebug_fd_for_pid(pid_t pid);
 const char *xe_eudebug_event_to_str(struct drm_xe_eudebug_event *e, char *buf, size_t len);
 struct drm_xe_eudebug_event *
 xe_eudebug_event_log_find_seqno(struct xe_eudebug_event_log *l, uint64_t seqno);
@@ -191,6 +192,7 @@ bool xe_eudebug_debugger_available(int fd);
 struct xe_eudebug_debugger *
 xe_eudebug_debugger_create(int xe, uint64_t flags, void *data);
 void xe_eudebug_debugger_destroy(struct xe_eudebug_debugger *d);
+int __xe_eudebug_connect(int master_fd, int target_fd, pid_t target_pid, int flags);
 int xe_eudebug_debugger_attach(struct xe_eudebug_debugger *d, struct xe_eudebug_client *c);
 void xe_eudebug_debugger_start_worker(struct xe_eudebug_debugger *d);
 void xe_eudebug_debugger_stop_worker(struct xe_eudebug_debugger *d);
@@ -219,16 +221,14 @@ void xe_eudebug_client_set_data(struct xe_eudebug_client *c, void *ptr);
 int __xe_eudebug_enable_getset(int fd, bool *old, bool *new);
 bool xe_eudebug_enable(int fd, bool enable);
 
-int xe_eudebug_client_open_driver(struct xe_eudebug_client *c);
-void xe_eudebug_client_close_driver(struct xe_eudebug_client *c, int fd);
-uint32_t xe_eudebug_client_vm_create(struct xe_eudebug_client *c, int fd,
+uint32_t xe_eudebug_client_vm_create(struct xe_eudebug_client *c,
 				     uint32_t flags, uint64_t ext);
-void xe_eudebug_client_vm_destroy(struct xe_eudebug_client *c, int fd, uint32_t vm);
-uint32_t xe_eudebug_client_exec_queue_create(struct xe_eudebug_client *c, int fd,
+void xe_eudebug_client_vm_destroy(struct xe_eudebug_client *c, uint32_t vm);
+uint32_t xe_eudebug_client_exec_queue_create(struct xe_eudebug_client *c,
 					     struct drm_xe_exec_queue_create *create);
-void xe_eudebug_client_exec_queue_destroy(struct xe_eudebug_client *c, int fd,
+void xe_eudebug_client_exec_queue_destroy(struct xe_eudebug_client *c,
 					  struct drm_xe_exec_queue_create *create);
-void xe_eudebug_client_vm_bind_event(struct xe_eudebug_client *c, uint32_t event_flags, int fd,
+void xe_eudebug_client_vm_bind_event(struct xe_eudebug_client *c, uint32_t event_flags,
 				     uint32_t vm, uint32_t bind_flags,
 				     uint32_t num_ops, uint64_t *ref_seqno);
 void xe_eudebug_client_vm_bind_op_event(struct xe_eudebug_client *c, uint32_t event_flags,
@@ -240,19 +240,19 @@ void xe_eudebug_client_vm_bind_ufence_event(struct xe_eudebug_client *c, uint32_
 void xe_eudebug_ack_ufence(int debugfd,
 			   const struct drm_xe_eudebug_event_vm_bind_ufence *f);
 
-void xe_eudebug_client_vm_bind_flags(struct xe_eudebug_client *c, int fd, uint32_t vm,
+void xe_eudebug_client_vm_bind_flags(struct xe_eudebug_client *c, uint32_t vm,
 				     uint32_t bo, uint64_t offset,
 				     uint64_t addr, uint64_t size, uint32_t flags,
 				     struct drm_xe_sync *sync, uint32_t num_syncs,
 				     uint64_t op_ext);
-void xe_eudebug_client_vm_bind(struct xe_eudebug_client *c, int fd, uint32_t vm,
+void xe_eudebug_client_vm_bind(struct xe_eudebug_client *c, uint32_t vm,
 			       uint32_t bo, uint64_t offset,
 			       uint64_t addr, uint64_t size);
-void xe_eudebug_client_vm_unbind_flags(struct xe_eudebug_client *c, int fd,
+void xe_eudebug_client_vm_unbind_flags(struct xe_eudebug_client *c,
 				       uint32_t vm, uint64_t offset,
 				       uint64_t addr, uint64_t size, uint32_t flags,
 				       struct drm_xe_sync *sync, uint32_t num_syncs);
-void xe_eudebug_client_vm_unbind(struct xe_eudebug_client *c, int fd, uint32_t vm,
+void xe_eudebug_client_vm_unbind(struct xe_eudebug_client *c, uint32_t vm,
 				 uint64_t offset, uint64_t addr, uint64_t size);
 
 struct xe_eudebug_session *xe_eudebug_session_create(int fd,
diff --git a/tests/intel/xe_eudebug.c b/tests/intel/xe_eudebug.c
index 55539638f0..8d673b68bb 100644
--- a/tests/intel/xe_eudebug.c
+++ b/tests/intel/xe_eudebug.c
@@ -71,17 +71,17 @@ static void test_sysfs_toggle(int fd)
 
 #define BO_ADDR 0x1a0000
 
-static void basic_vm_bind_client(int fd, struct xe_eudebug_client *c)
+static void basic_vm_bind_client(struct xe_eudebug_client *c)
 {
 	struct drm_xe_vm_bind_op_ext_attach_debug *ext = NULL;
-	uint32_t vm = xe_eudebug_client_vm_create(c, fd, DRM_XE_VM_CREATE_FLAG_LR_MODE, 0);
-	size_t bo_size = xe_get_default_alignment(fd);
+	uint32_t vm = xe_eudebug_client_vm_create(c, DRM_XE_VM_CREATE_FLAG_LR_MODE, 0);
+	size_t bo_size = xe_get_default_alignment(c->fd);
 	bool test_discovery = c->flags & TEST_DISCOVERY;
-	uint32_t bo = xe_bo_create(fd, 0, bo_size,
-				   system_memory(fd), 0);
+	uint32_t bo = xe_bo_create(c->fd, 0, bo_size,
+				   system_memory(c->fd), 0);
 	uint64_t addr = 0x1a0000;
 
-	xe_eudebug_client_vm_bind_flags(c, fd, vm, bo, 0, addr,
+	xe_eudebug_client_vm_bind_flags(c, vm, bo, 0, addr,
 					bo_size, 0, NULL, 0, to_user_pointer(ext));
 
 	if (test_discovery) {
@@ -89,37 +89,37 @@ static void basic_vm_bind_client(int fd, struct xe_eudebug_client *c)
 		xe_eudebug_client_wait_stage(c, STAGE_DISCOVERY_DONE);
 	}
 
-	xe_eudebug_client_vm_unbind(c, fd, vm, 0, addr, bo_size);
+	xe_eudebug_client_vm_unbind(c, vm, 0, addr, bo_size);
 
-	gem_close(fd, bo);
-	xe_eudebug_client_vm_destroy(c, fd, vm);
+	gem_close(c->fd, bo);
+	xe_eudebug_client_vm_destroy(c, vm);
 }
 
-static void basic_vm_bind_vm_destroy_client(int fd, struct xe_eudebug_client *c)
+static void basic_vm_bind_vm_destroy_client(struct xe_eudebug_client *c)
 {
-	uint32_t vm = xe_eudebug_client_vm_create(c, fd, DRM_XE_VM_CREATE_FLAG_LR_MODE, 0);
-	size_t bo_size = xe_get_default_alignment(fd);
+	uint32_t vm = xe_eudebug_client_vm_create(c, DRM_XE_VM_CREATE_FLAG_LR_MODE, 0);
+	size_t bo_size = xe_get_default_alignment(c->fd);
 	bool test_discovery = c->flags & TEST_DISCOVERY;
-	uint32_t bo = xe_bo_create(fd, 0, bo_size,
-				   system_memory(fd), 0);
+	uint32_t bo = xe_bo_create(c->fd, 0, bo_size,
+				   system_memory(c->fd), 0);
 	uint64_t addr = 0x1a0000;
 
 	if (test_discovery) {
-		vm = xe_vm_create(fd, DRM_XE_VM_CREATE_FLAG_LR_MODE, 0);
+		vm = xe_vm_create(c->fd, DRM_XE_VM_CREATE_FLAG_LR_MODE, 0);
 
-		xe_vm_bind_async(fd, vm, 0, bo, 0, addr, bo_size, NULL, 0);
+		xe_vm_bind_async(c->fd, vm, 0, bo, 0, addr, bo_size, NULL, 0);
 
-		xe_vm_destroy(fd, vm);
+		xe_vm_destroy(c->fd, vm);
 
 		xe_eudebug_client_signal_stage(c, STAGE_PRE_DEBUG_RESOURCES_DONE);
 		xe_eudebug_client_wait_stage(c, STAGE_DISCOVERY_DONE);
 	} else {
-		vm = xe_eudebug_client_vm_create(c, fd, DRM_XE_VM_CREATE_FLAG_LR_MODE, 0);
-		xe_eudebug_client_vm_bind(c, fd, vm, bo, 0, addr, bo_size);
-		xe_eudebug_client_vm_destroy(c, fd, vm);
+		vm = xe_eudebug_client_vm_create(c, DRM_XE_VM_CREATE_FLAG_LR_MODE, 0);
+		xe_eudebug_client_vm_bind(c, vm, bo, 0, addr, bo_size);
+		xe_eudebug_client_vm_destroy(c, vm);
 	}
 
-	gem_close(fd, bo);
+	gem_close(c->fd, bo);
 }
 
 #define BO_ITEMS 4096
@@ -131,7 +131,6 @@ union buf_id {
 };
 
 struct bind_list {
-	int fd;
 	uint32_t vm;
 	union buf_id *bo;
 	struct drm_xe_vm_bind_op *bind_ops;
@@ -217,7 +216,6 @@ static struct bind_list *create_bind_list(int fd, uint32_t bo_placement,
 	struct bind_list *bl;
 
 	bl = malloc(sizeof(*bl));
-	bl->fd = fd;
 	bl->vm = vm;
 	bl->bo = vm_create_objects(fd, bo_placement, vm, bo_size, n);
 	bl->n = n;
@@ -263,16 +261,16 @@ static void do_bind_list(struct xe_eudebug_client *c,
 	int i;
 
 	if (sync) {
-		fence_data = aligned_alloc(xe_get_default_alignment(bl->fd),
+		fence_data = aligned_alloc(xe_get_default_alignment(c->fd),
 					   sizeof(*fence_data));
 		igt_assert(fence_data);
 		uf_sync.addr = to_user_pointer(fence_data);
 		memset(fence_data, 0, sizeof(*fence_data));
 	}
 
-	xe_vm_bind_array(bl->fd, bl->vm, 0, bl->bind_ops, bl->n, &uf_sync, sync ? 1 : 0);
+	xe_vm_bind_array(c->fd, bl->vm, 0, bl->bind_ops, bl->n, &uf_sync, sync ? 1 : 0);
 	xe_eudebug_client_vm_bind_event(c, DRM_XE_EUDEBUG_EVENT_STATE_CHANGE,
-					bl->fd, bl->vm, 0, bl->n, &ref_seqno);
+					bl->vm, 0, bl->n, &ref_seqno);
 	for (i = 0; i < bl->n; i++)
 		xe_eudebug_client_vm_bind_op_event(c, DRM_XE_EUDEBUG_EVENT_CREATE,
 						   ref_seqno,
@@ -282,7 +280,7 @@ static void do_bind_list(struct xe_eudebug_client *c,
 						   0);
 
 	if (sync) {
-		xe_wait_ufence(bl->fd, fence_data, uf_sync.timeline_value, 0,
+		xe_wait_ufence(c->fd, fence_data, uf_sync.timeline_value, 0,
 			       XE_EUDEBUG_DEFAULT_TIMEOUT_SEC * NSEC_PER_SEC);
 		free(fence_data);
 	}
@@ -295,10 +293,10 @@ static void free_bind_list(struct xe_eudebug_client *c, struct bind_list *bl)
 	for (i = 0; i < bl->n; i++) {
 		igt_debug("%d: checking 0x%llx (%lld)\n",
 			  i, bl->bind_ops[i].addr, bl->bind_ops[i].addr);
-		bo_check(bl->fd, &bl->bind_ops[i]);
+		bo_check(c->fd, &bl->bind_ops[i]);
 		if (bl->bind_ops[i].op == DRM_XE_VM_BIND_OP_MAP_USERPTR)
 			free(bl->bo[i].userptr);
-		xe_eudebug_client_vm_unbind(c, bl->fd, bl->vm, 0,
+		xe_eudebug_client_vm_unbind(c, bl->vm, 0,
 					    bl->bind_ops[i].addr,
 					    bl->bind_ops[i].range);
 	}
@@ -308,38 +306,38 @@ static void free_bind_list(struct xe_eudebug_client *c, struct bind_list *bl)
 	free(bl);
 }
 
-static void vm_bind_client(int fd, struct xe_eudebug_client *c)
+static void vm_bind_client(struct xe_eudebug_client *c)
 {
 	uint64_t op_ref_seqno, ref_seqno;
 	struct bind_list *bl;
 	bool test_discovery = c->flags & TEST_DISCOVERY;
-	size_t bo_size = 3 * xe_get_default_alignment(fd);
+	size_t bo_size = 3 * xe_get_default_alignment(c->fd);
 	uint32_t bo[2] = {
-		xe_bo_create(fd, 0, bo_size, system_memory(fd), 0),
-		xe_bo_create(fd, 0, bo_size, system_memory(fd), 0),
+		xe_bo_create(c->fd, 0, bo_size, system_memory(c->fd), 0),
+		xe_bo_create(c->fd, 0, bo_size, system_memory(c->fd), 0),
 	};
-	uint32_t vm = xe_eudebug_client_vm_create(c, fd, DRM_XE_VM_CREATE_FLAG_LR_MODE, 0);
+	uint32_t vm = xe_eudebug_client_vm_create(c, DRM_XE_VM_CREATE_FLAG_LR_MODE, 0);
 	uint64_t addr[] = {0x2a0000, 0x3a0000};
 	uint64_t rebind_bo_offset = 2 * bo_size / 3;
 	uint64_t size = bo_size / 3;
 	int i = 0;
 
 	if (test_discovery) {
-		xe_vm_bind_async(fd, vm, 0, bo[0], 0, addr[0], bo_size, NULL, 0);
+		xe_vm_bind_async(c->fd, vm, 0, bo[0], 0, addr[0], bo_size, NULL, 0);
 
-		xe_vm_unbind_async(fd, vm, 0, 0, addr[0] + size, size, NULL, 0);
+		xe_vm_unbind_async(c->fd, vm, 0, 0, addr[0] + size, size, NULL, 0);
 
-		xe_vm_bind_async(fd, vm, 0, bo[1], 0, addr[1], bo_size, NULL, 0);
+		xe_vm_bind_async(c->fd, vm, 0, bo[1], 0, addr[1], bo_size, NULL, 0);
 
-		xe_vm_bind_async(fd, vm, 0, bo[1], rebind_bo_offset, addr[1], size, NULL, 0);
+		xe_vm_bind_async(c->fd, vm, 0, bo[1], rebind_bo_offset, addr[1], size, NULL, 0);
 
-		bl = create_bind_list(fd, system_memory(fd), vm, 4, 0);
-		xe_vm_bind_array(bl->fd, bl->vm, 0, bl->bind_ops, bl->n, NULL, 0);
+		bl = create_bind_list(c->fd, system_memory(c->fd), vm, 4, 0);
+		xe_vm_bind_array(c->fd, bl->vm, 0, bl->bind_ops, bl->n, NULL, 0);
 
-		xe_vm_unbind_all_async(fd, vm, 0, bo[0], NULL, 0);
+		xe_vm_unbind_all_async(c->fd, vm, 0, bo[0], NULL, 0);
 
 		xe_eudebug_client_vm_bind_event(c, DRM_XE_EUDEBUG_EVENT_STATE_CHANGE,
-						bl->fd, bl->vm, 0, bl->n + 2, &ref_seqno);
+						bl->vm, 0, bl->n + 2, &ref_seqno);
 
 		xe_eudebug_client_vm_bind_op_event(c, DRM_XE_EUDEBUG_EVENT_CREATE, ref_seqno,
 						   &op_ref_seqno, addr[1], size, 0);
@@ -355,33 +353,31 @@ static void vm_bind_client(int fd, struct xe_eudebug_client *c)
 		xe_eudebug_client_signal_stage(c, STAGE_PRE_DEBUG_RESOURCES_DONE);
 		xe_eudebug_client_wait_stage(c, STAGE_DISCOVERY_DONE);
 	} else {
-		xe_eudebug_client_vm_bind(c, fd, vm, bo[0], 0, addr[0], bo_size);
-		xe_eudebug_client_vm_unbind(c, fd, vm, 0, addr[0] + size, size);
+		xe_eudebug_client_vm_bind(c, vm, bo[0], 0, addr[0], bo_size);
+		xe_eudebug_client_vm_unbind(c, vm, 0, addr[0] + size, size);
 
-		xe_eudebug_client_vm_bind(c, fd, vm, bo[1], 0, addr[1], bo_size);
-		xe_eudebug_client_vm_bind(c, fd, vm, bo[1], rebind_bo_offset, addr[1], size);
+		xe_eudebug_client_vm_bind(c, vm, bo[1], 0, addr[1], bo_size);
+		xe_eudebug_client_vm_bind(c, vm, bo[1], rebind_bo_offset, addr[1], size);
 
-		bl = create_bind_list(fd, system_memory(fd), vm, 4, 0);
+		bl = create_bind_list(c->fd, system_memory(c->fd), vm, 4, 0);
 		do_bind_list(c, bl, false);
 	}
 
-	xe_vm_unbind_all_async(fd, vm, 0, bo[1], NULL, 0);
+	xe_vm_unbind_all_async(c->fd, vm, 0, bo[1], NULL, 0);
 
-	xe_eudebug_client_vm_bind_event(c, DRM_XE_EUDEBUG_EVENT_STATE_CHANGE, fd, vm, 0,
+	xe_eudebug_client_vm_bind_event(c, DRM_XE_EUDEBUG_EVENT_STATE_CHANGE, vm, 0,
 					1, &ref_seqno);
 	xe_eudebug_client_vm_bind_op_event(c, DRM_XE_EUDEBUG_EVENT_DESTROY, ref_seqno,
 					   &op_ref_seqno, 0, 0, 0);
 
-	gem_close(fd, bo[0]);
-	gem_close(fd, bo[1]);
-	xe_eudebug_client_vm_destroy(c, fd, vm);
+	gem_close(c->fd, bo[0]);
+	gem_close(c->fd, bo[1]);
+	xe_eudebug_client_vm_destroy(c, vm);
 }
 
 static void run_basic_client(struct xe_eudebug_client *c)
 {
-	int fd, i;
-
-	fd = xe_eudebug_client_open_driver(c);
+	int i;
 
 	if (c->flags & CREATE_VMS) {
 		const uint32_t flags[] = {
@@ -391,10 +387,10 @@ static void run_basic_client(struct xe_eudebug_client *c)
 		uint32_t vms[ARRAY_SIZE(flags)];
 
 		for (i = 0; i < ARRAY_SIZE(flags); i++)
-			vms[i] = xe_eudebug_client_vm_create(c, fd, flags[i], 0);
+			vms[i] = xe_eudebug_client_vm_create(c, flags[i], 0);
 
 		for (i--; i >= 0; i--)
-			xe_eudebug_client_vm_destroy(c, fd, vms[i]);
+			xe_eudebug_client_vm_destroy(c, vms[i]);
 	}
 
 	if (c->flags & CREATE_EXEC_QUEUES) {
@@ -407,36 +403,34 @@ static void run_basic_client(struct xe_eudebug_client *c)
 		};
 		uint32_t vm;
 
-		create = calloc(xe_number_engines(fd), sizeof(*create));
+		create = calloc(xe_number_engines(c->fd), sizeof(*create));
 
-		vm = xe_eudebug_client_vm_create(c, fd, DRM_XE_VM_CREATE_FLAG_LR_MODE, 0);
+		vm = xe_eudebug_client_vm_create(c, DRM_XE_VM_CREATE_FLAG_LR_MODE, 0);
 
 		i = 0;
-		xe_eudebug_for_each_engine(fd, hwe) {
+		xe_eudebug_for_each_engine(c->fd, hwe) {
 			create[i].instances = to_user_pointer(hwe);
 			create[i].vm_id = vm;
 			create[i].width = 1;
 			create[i].num_placements = 1;
 			create[i].extensions = to_user_pointer(&eq_ext);
-			xe_eudebug_client_exec_queue_create(c, fd, &create[i++]);
+			xe_eudebug_client_exec_queue_create(c, &create[i++]);
 		}
 
 		while (--i >= 0)
-			xe_eudebug_client_exec_queue_destroy(c, fd, &create[i]);
+			xe_eudebug_client_exec_queue_destroy(c, &create[i]);
 
-		xe_eudebug_client_vm_destroy(c, fd, vm);
+		xe_eudebug_client_vm_destroy(c, vm);
 	}
 
 	if (c->flags & VM_BIND)
-		basic_vm_bind_client(fd, c);
+		basic_vm_bind_client(c);
 
 	if (c->flags & VM_BIND_EXTENDED)
-		vm_bind_client(fd, c);
+		vm_bind_client(c);
 
 	if (c->flags & VM_BIND_VM_DESTROY)
-		basic_vm_bind_vm_destroy_client(fd, c);
-
-	xe_eudebug_client_close_driver(c, fd);
+		basic_vm_bind_vm_destroy_client(c);
 }
 
 static int read_event(int debugfd, struct drm_xe_eudebug_event *event)
@@ -514,19 +508,19 @@ static void test_connect(int fd)
 		*pid = getpid();
 
 	igt_waitchildren();
-	param.pid = *pid;
+	param.fd = xe_eudebug_fd_for_pid(*pid);
 	munmap(pid, sizeof(pid_t));
 
 	ret = __debug_connect(fd, &debugfd, &param);
 	igt_assert(debugfd == -1);
-	igt_assert_eq(ret, param.pid ? -ENOENT : -EINVAL);
+	igt_assert_eq(ret, -EBADFD);
 
-	param.pid = 0;
+	param.fd = 0;
 	ret = __debug_connect(fd, &debugfd, &param);
 	igt_assert(debugfd == -1);
 	igt_assert_eq(ret, -EINVAL);
 
-	param.pid = getpid();
+	param.fd = xe_eudebug_fd_for_pid(getpid());
 	param.version = -1;
 	ret = __debug_connect(fd, &debugfd, &param);
 	igt_assert(debugfd == -1);
@@ -687,7 +681,7 @@ static void test_connect_user(int fd)
 					switch_user(test[i].u[P_GDB], test[i].g[P_GDB]);
 
 				igt_assert(read(p1[0], &pid, sizeof(pid)) == sizeof(pid));
-				param.pid = pid;
+				param.fd = xe_eudebug_fd_for_pid(pid);
 
 				newfd = drm_open_driver(DRIVER_XE);
 				ret = __debug_connect(newfd, &debugfd, &param);
@@ -722,9 +716,30 @@ static void test_close(int fd)
 	struct drm_xe_eudebug_connect param = { 0,  };
 	int debug_fd1, debug_fd2;
 	int fd2;
+	pid_t *pid;
+
+	pid = mmap(NULL, sizeof(pid_t), PROT_WRITE,
+		   MAP_SHARED | MAP_ANON, -1, 0);
+
+	*pid = 0;
+
+	/* get fresh unrelated pid */
+	igt_fork(child, 1) {
+		close(fd);
+
+		fd = drm_open_driver(DRIVER_XE);
+		*pid = getpid();
+	}
 
-	param.pid = getpid();
+	igt_until_timeout(3) {
+		if (!*pid)
+			continue;
+
+		param.fd = xe_eudebug_fd_for_pid(*pid);
+		break;
+	}
 
+	igt_assert(param.fd);
 	igt_assert_eq(__debug_connect(fd, &debug_fd1, &param), 0);
 	igt_assert(debug_fd1 >= 0);
 	igt_assert_eq(__debug_connect(fd, &debug_fd2, &param), -EBUSY);
@@ -733,11 +748,15 @@ static void test_close(int fd)
 	close(debug_fd1);
 	fd2 = drm_open_driver(DRIVER_XE);
 
+	/* XXX FIXME the debugger is still on client so we get EBUSY */
+	/* Try to close all refs for earlier disconnect */
 	igt_assert_eq(__debug_connect(fd2, &debug_fd2, &param), 0);
 	igt_assert(debug_fd2 >= 0);
 	close(fd2);
 	close(debug_fd2);
 	close(debug_fd1);
+
+	igt_waitchildren();
 }
 
 /**
@@ -773,7 +792,6 @@ static void test_read_event(int fd)
 	igt_assert_eq(poll_event(d->fd, 500), 1);
 	event->type = DRM_XE_EUDEBUG_EVENT_READ;
 	igt_assert_eq(read_event(d->fd, event), 0);
-	igt_assert_eq(event->type, DRM_XE_EUDEBUG_EVENT_OPEN);
 	igt_assert_eq(event->flags, DRM_XE_EUDEBUG_EVENT_CREATE);
 
 	igt_assert_eq(poll_event(d->fd, 500), 1);
@@ -810,7 +828,6 @@ static void test_read_event(int fd)
 
 	/* Positive read event - client destroy */
 	igt_assert_eq(read_event(d->fd, event), 0);
-	igt_assert_eq(event->type, DRM_XE_EUDEBUG_EVENT_OPEN);
 	igt_assert_eq(event->flags, DRM_XE_EUDEBUG_EVENT_DESTROY);
 
 	fcntl(d->fd, F_SETFL, fcntl(d->fd, F_GETFL) | O_NONBLOCK);
@@ -987,10 +1004,8 @@ static void run_discovery_client(struct xe_eudebug_client *c)
 	for (i = 0; i < RESOURCE_COUNT; i++) {
 		struct drm_xe_engine_class_instance *hwe = NULL;
 
-		fd[i] = xe_eudebug_client_open_driver(c);
-
 		/* Get first */
-		xe_eudebug_for_each_engine(fd[i], hwe)
+		xe_eudebug_for_each_engine(c->fd, hwe)
 			break;
 
 		igt_assert(hwe);
@@ -1003,7 +1018,7 @@ static void run_discovery_client(struct xe_eudebug_client *c)
 			sleep(1);
 
 		for (int j = 0; j < RESOURCE_COUNT; j++) {
-			uint32_t vm = xe_eudebug_client_vm_create(c, fd[i],
+			uint32_t vm = xe_eudebug_client_vm_create(c,
 								  DRM_XE_VM_CREATE_FLAG_LR_MODE, 0);
 			struct drm_xe_ext_set_property eq_ext = {
 				.base.name = DRM_XE_EXEC_QUEUE_EXTENSION_SET_PROPERTY,
@@ -1018,26 +1033,26 @@ static void run_discovery_client(struct xe_eudebug_client *c)
 				.extensions = to_user_pointer(&eq_ext),
 			};
 			const unsigned int bo_size = max_t(bo_size,
-							   xe_get_default_alignment(fd[i]),
+							   xe_get_default_alignment(c->fd),
 							   MIN_BO_SIZE);
-			uint32_t bo = xe_bo_create(fd[i], 0, bo_size, system_memory(fd[i]), 0);
+			uint32_t bo = xe_bo_create(fd[i], 0, bo_size, system_memory(c->fd), 0);
 
-			xe_eudebug_client_exec_queue_create(c, fd[i], &create);
+			xe_eudebug_client_exec_queue_create(c, &create);
 
 			if (c->flags & DISCOVERY_VM_BIND) {
-				xe_eudebug_client_vm_bind(c, fd[i], vm, bo, 0, addr, bo_size);
+				xe_eudebug_client_vm_bind(c, vm, bo, 0, addr, bo_size);
 				addr += bo_size;
 			}
 
 			if (c->flags & DISCOVERY_DESTROY_RESOURCES) {
-				xe_eudebug_client_exec_queue_destroy(c, fd[i], &create);
-				xe_eudebug_client_vm_destroy(c, fd[i], create.vm_id);
-				gem_close(fd[i], bo);
+				xe_eudebug_client_exec_queue_destroy(c, &create);
+				xe_eudebug_client_vm_destroy(c, create.vm_id);
+				gem_close(c->fd, bo);
 			}
 		}
 
 		if (c->flags & DISCOVERY_CLOSE_CLIENT)
-			xe_eudebug_client_close_driver(c, fd[i]);
+			close(c->fd);
 	}
 }
 
@@ -1106,28 +1121,6 @@ static void *discovery_race_thread(void *data)
 			igt_debug("Resources discovered: %" PRIu64 "\n", s->debugger->event_count);
 			if (!s->client->done) {
 				xe_eudebug_for_each_event(e, s->debugger->log) {
-					if (e->type == DRM_XE_EUDEBUG_EVENT_OPEN) {
-						struct drm_xe_eudebug_event_client *eo = (void *)e;
-
-						if (i >= 0) {
-							igt_assert_eq(clients[i].vm_count,
-								      RESOURCE_COUNT);
-
-							igt_assert_eq(clients[i].exec_queue_count,
-								      RESOURCE_COUNT);
-
-							if (s->client->flags & DISCOVERY_VM_BIND)
-								igt_assert_eq(clients[i].vm_bind_op_count,
-									      RESOURCE_COUNT);
-						}
-
-						igt_assert(++i < RESOURCE_COUNT);
-						clients[i].client_handle = eo->client_handle;
-						clients[i].vm_count = 0;
-						clients[i].exec_queue_count = 0;
-						clients[i].vm_bind_op_count = 0;
-					}
-
 					if (e->type == DRM_XE_EUDEBUG_EVENT_VM)
 						clients[i].vm_count++;
 
@@ -1140,14 +1133,6 @@ static void *discovery_race_thread(void *data)
 
 				igt_assert_lte(0, i);
 			}
-			for (int j = 0; j < i; j++)
-				for (int k = 0; k < i; k++) {
-					if (k == j)
-						continue;
-
-					igt_assert_neq(clients[j].client_handle,
-						       clients[k].client_handle);
-				}
 
 			if (s->debugger->event_count >= expected)
 				done = true;
@@ -1345,7 +1330,6 @@ static void test_client_with_trigger(int fd, unsigned int flags, int count,
 
 struct thread_fn_args {
 	struct xe_eudebug_client *client;
-	int fd;
 };
 
 static void *basic_client_th(void *data)
@@ -1353,10 +1337,9 @@ static void *basic_client_th(void *data)
 	struct thread_fn_args *f = data;
 	struct xe_eudebug_client *c = f->client;
 	uint32_t *vms;
-	int fd, i, num_vms;
+	int i, num_vms;
 
-	fd = f->fd;
-	igt_assert(fd);
+	igt_assert(c->fd);
 
 	num_vms = 2 + rand() % 16;
 	vms = calloc(num_vms, sizeof(*vms));
@@ -1364,10 +1347,10 @@ static void *basic_client_th(void *data)
 	igt_debug("Create %d client vms\n", num_vms);
 
 	for (i = 0; i < num_vms; i++)
-		vms[i] = xe_eudebug_client_vm_create(c, fd, DRM_XE_VM_CREATE_FLAG_LR_MODE, 0);
+		vms[i] = xe_eudebug_client_vm_create(c, DRM_XE_VM_CREATE_FLAG_LR_MODE, 0);
 
 	for (i = 0; i < num_vms; i++)
-		xe_eudebug_client_vm_destroy(c, fd, vms[i]);
+		xe_eudebug_client_vm_destroy(c, vms[i]);
 
 	free(vms);
 
@@ -1377,7 +1360,7 @@ static void *basic_client_th(void *data)
 static void run_basic_client_th(struct xe_eudebug_client *c)
 {
 	struct thread_fn_args *args;
-	int i, num_threads, fd;
+	int i, num_threads;
 	pthread_t *threads;
 
 	args = calloc(1, sizeof(*args));
@@ -1388,9 +1371,7 @@ static void run_basic_client_th(struct xe_eudebug_client *c)
 	threads = calloc(num_threads, sizeof(*threads));
 	igt_assert(threads);
 
-	fd = xe_eudebug_client_open_driver(c);
 	args->client = c;
-	args->fd = fd;
 
 	for (i = 0; i < num_threads; i++)
 		pthread_create(&threads[i], NULL, basic_client_th, args);
@@ -1398,7 +1379,6 @@ static void run_basic_client_th(struct xe_eudebug_client *c)
 	for (i = 0; i < num_threads; i++)
 		pthread_join(threads[i], NULL);
 
-	xe_eudebug_client_close_driver(c, fd);
 	free(args);
 	free(threads);
 }
@@ -1416,24 +1396,22 @@ static void vm_access_client(struct xe_eudebug_client *c)
 	uint32_t bo_placement;
 	struct bind_list *bl;
 	uint32_t vm;
-	int fd, i, j;
+	int i, j;
 
 	igt_debug("Using %s\n", xe_engine_class_string(hwe->engine_class));
 
-	fd = xe_eudebug_client_open_driver(c);
-
 	vm_flags |= (c->flags & TEST_FAULTABLE) ? DRM_XE_VM_CREATE_FLAG_FAULT_MODE : 0;
-	vm = xe_eudebug_client_vm_create(c, fd, vm_flags, 0);
+	vm = xe_eudebug_client_vm_create(c, vm_flags, 0);
 
 	if (c->flags & VM_BIND_OP_MAP_USERPTR)
 		bo_placement = 0;
 	else
-		bo_placement = vram_if_possible(fd, hwe->gt_id);
+		bo_placement = vram_if_possible(c->fd, hwe->gt_id);
 
 	for (j = 0; j < 5; j++) {
 		unsigned int target_size = MIN_BO_SIZE * (1 << j);
 
-		bl = create_bind_list(fd, bo_placement, vm, 4, target_size);
+		bl = create_bind_list(c->fd, bo_placement, vm, 4, target_size);
 		do_bind_list(c, bl, true);
 
 		for (i = 0; i < bl->n; i++)
@@ -1441,13 +1419,10 @@ static void vm_access_client(struct xe_eudebug_client *c)
 
 		free_bind_list(c, bl);
 	}
-	xe_eudebug_client_vm_destroy(c, fd, vm);
-
-	xe_eudebug_client_close_driver(c, fd);
+	xe_eudebug_client_vm_destroy(c, vm);
 }
 
 static void debugger_test_vma(struct xe_eudebug_debugger *d,
-			      uint64_t client_handle,
 			      uint64_t vm_handle,
 			      uint64_t va_start,
 			      uint64_t va_length)
@@ -1464,7 +1439,6 @@ static void debugger_test_vma(struct xe_eudebug_debugger *d,
 	v2 = malloc(va_length);
 	igt_assert(v2);
 
-	vo.client_handle = client_handle;
 	vo.vm_handle = vm_handle;
 
 	fd = igt_ioctl(d->fd, DRM_XE_EUDEBUG_IOCTL_VM_OPEN, &vo);
@@ -1523,7 +1497,7 @@ static void vm_trigger(struct xe_eudebug_debugger *d,
 			xe_eudebug_event_log_find_seqno(d->log, eo->vm_bind_ref_seqno);
 		igt_assert(eb);
 
-		debugger_test_vma(d, eb->client_handle, eb->vm_handle,
+		debugger_test_vma(d, eb->vm_handle,
 				  eo->addr, eo->range);
 		xe_eudebug_debugger_signal_stage(d, eo->addr);
 	}
@@ -1572,7 +1546,6 @@ static void test_vm_access(int fd, unsigned int flags, int num_clients)
 }
 
 static void debugger_test_vma_parameters(struct xe_eudebug_debugger *d,
-					 uint64_t client_handle,
 					 uint64_t vm_handle,
 					 uint64_t va_start,
 					 uint64_t va_length)
@@ -1586,20 +1559,12 @@ static void debugger_test_vma_parameters(struct xe_eudebug_debugger *d,
 	v = malloc(va_length);
 	igt_assert(v);
 
-	/* Negative VM open - bad client handle */
-	vo.client_handle = client_handle + 123;
-	vo.vm_handle = vm_handle;
-	fd = igt_ioctl(d->fd, DRM_XE_EUDEBUG_IOCTL_VM_OPEN, &vo);
-	igt_assert_lt(fd, 0);
-
 	/* Negative VM open - bad vm handle */
-	vo.client_handle = client_handle;
 	vo.vm_handle = vm_handle + 123;
 	fd = igt_ioctl(d->fd, DRM_XE_EUDEBUG_IOCTL_VM_OPEN, &vo);
 	igt_assert_lt(fd, 0);
 
 	/* Positive VM open */
-	vo.client_handle = client_handle;
 	vo.vm_handle = vm_handle;
 	fd = igt_ioctl(d->fd, DRM_XE_EUDEBUG_IOCTL_VM_OPEN, &vo);
 	igt_assert_lte(0, fd);
@@ -1688,7 +1653,7 @@ static void vm_trigger_access_parameters(struct xe_eudebug_debugger *d,
 			xe_eudebug_event_log_find_seqno(d->log, eo->vm_bind_ref_seqno);
 		igt_assert(eb);
 
-		debugger_test_vma_parameters(d, eb->client_handle, eb->vm_handle, eo->addr,
+		debugger_test_vma_parameters(d, eb->vm_handle, eo->addr,
 					     eo->range);
 		xe_eudebug_debugger_signal_stage(d, eo->addr);
 	}
@@ -1749,7 +1714,7 @@ struct ufence_bind {
 };
 
 static void client_wait_ufences(struct xe_eudebug_client *c,
-				int fd, struct ufence_bind *binds, int count)
+				struct ufence_bind *binds, int count)
 {
 	const int64_t default_fence_timeout_ns = 500 * NSEC_PER_MSEC;
 	int64_t timeout_ns;
@@ -1760,7 +1725,8 @@ static void client_wait_ufences(struct xe_eudebug_client *c,
 		struct ufence_bind *b = &binds[i];
 
 		timeout_ns = default_fence_timeout_ns;
-		err = __xe_wait_ufence(fd, &b->fence_data->vm_sync, b->f.timeline_value,
+		err = __xe_wait_ufence(c->fd,
+				       &b->fence_data->vm_sync, b->f.timeline_value,
 				       0, &timeout_ns);
 		igt_assert_eq(err, -ETIME);
 		igt_assert_neq(b->fence_data->vm_sync, b->f.timeline_value);
@@ -1775,7 +1741,8 @@ static void client_wait_ufences(struct xe_eudebug_client *c,
 		struct ufence_bind *b = &binds[i];
 
 		timeout_ns = XE_EUDEBUG_DEFAULT_TIMEOUT_SEC * NSEC_PER_SEC;
-		err = __xe_wait_ufence(fd, &b->fence_data->vm_sync, b->f.timeline_value,
+		err = __xe_wait_ufence(c->fd, &b->fence_data->vm_sync,
+				       b->f.timeline_value,
 				       0, &timeout_ns);
 		igt_assert_eq(err, 0);
 		igt_assert_eq(b->fence_data->vm_sync, b->f.timeline_value);
@@ -1820,32 +1787,30 @@ static void destroy_binds_with_ufence(struct ufence_bind *binds, int count)
 static void basic_ufence_client(struct xe_eudebug_client *c)
 {
 	const unsigned int n = UFENCE_EVENT_COUNT_EXPECTED;
-	int fd = xe_eudebug_client_open_driver(c);
-	uint32_t vm = xe_eudebug_client_vm_create(c, fd, DRM_XE_VM_CREATE_FLAG_LR_MODE, 0);
-	size_t bo_size = n * xe_get_default_alignment(fd);
-	uint32_t bo = xe_bo_create(fd, 0, bo_size,
-				   system_memory(fd), 0);
-	struct ufence_bind *binds = create_binds_with_ufence(fd, n);
+	uint32_t vm = xe_eudebug_client_vm_create(c, DRM_XE_VM_CREATE_FLAG_LR_MODE, 0);
+	size_t bo_size = n * xe_get_default_alignment(c->fd);
+	uint32_t bo = xe_bo_create(c->fd, 0, bo_size,
+				   system_memory(c->fd), 0);
+	struct ufence_bind *binds = create_binds_with_ufence(c->fd, n);
 
 	for (int i = 0; i < n; i++) {
 		struct ufence_bind *b = &binds[i];
 
-		xe_eudebug_client_vm_bind_flags(c, fd, vm, bo, 0, b->addr, b->range, 0,
+		xe_eudebug_client_vm_bind_flags(c, vm, bo, 0, b->addr, b->range, 0,
 						&b->f, 1, 0);
 	}
 
-	client_wait_ufences(c, fd, binds, n);
+	client_wait_ufences(c, binds, n);
 
 	for (int i = 0; i < n; i++) {
 		struct ufence_bind *b = &binds[i];
 
-		xe_eudebug_client_vm_unbind(c, fd, vm, 0, b->addr, b->range);
+		xe_eudebug_client_vm_unbind(c, vm, 0, b->addr, b->range);
 	}
 
 	destroy_binds_with_ufence(binds, n);
-	gem_close(fd, bo);
-	xe_eudebug_client_vm_destroy(c, fd, vm);
-	xe_eudebug_client_close_driver(c, fd);
+	gem_close(c->fd, bo);
+	xe_eudebug_client_vm_destroy(c, vm);
 }
 
 struct ufence_priv {
@@ -1992,8 +1957,7 @@ static void test_basic_ufence(int fd, unsigned int flags)
 		c->pid = 0;
 		c->done = 1;
 	} else if (flags & VM_BIND_UFENCE_RECONNECT) {
-		filter = XE_EUDEBUG_FILTER_EVENT_VM_BIND | XE_EUDEBUG_FILTER_EVENT_VM |
-				XE_EUDEBUG_FILTER_EVENT_OPEN;
+		filter = XE_EUDEBUG_FILTER_EVENT_VM_BIND | XE_EUDEBUG_FILTER_EVENT_VM;
 		xe_eudebug_debugger_detach(d);
 		xe_eudebug_client_wait_done(c);
 		igt_assert_eq(xe_eudebug_debugger_attach(d, c), 0);
@@ -2052,19 +2016,19 @@ static void *vm_bind_clear_thread(void *data)
 		.type = DRM_XE_SYNC_TYPE_USER_FENCE, .flags = DRM_XE_SYNC_FLAG_SIGNAL,
 	};
 	struct vm_bind_clear_thread_priv *priv = data;
-	int fd = xe_eudebug_client_open_driver(priv->c);
-	uint32_t gtt_size = 1ull << min_t(uint32_t, xe_va_bits(fd), 48);
+	struct xe_eudebug_client *c = priv->c;
+	uint32_t gtt_size = 1ull << min_t(uint32_t, xe_va_bits(c->fd), 48);
 	uint32_t vm_flags = DRM_XE_VM_CREATE_FLAG_LR_MODE;
-	size_t bo_size = xe_bb_size(fd, batch_size);
+	size_t bo_size = xe_bb_size(c->fd, batch_size);
 	unsigned long count = 0;
 	uint64_t *fence_data;
 	uint32_t vm;
 
 	vm_flags |= (priv->c->flags & TEST_FAULTABLE) ? DRM_XE_VM_CREATE_FLAG_FAULT_MODE : 0;
-	vm = xe_eudebug_client_vm_create(priv->c, fd, vm_flags, 0);
+	vm = xe_eudebug_client_vm_create(c, vm_flags, 0);
 
 	/* init uf_sync */
-	fence_data = aligned_alloc(xe_get_default_alignment(fd), sizeof(*fence_data));
+	fence_data = aligned_alloc(xe_get_default_alignment(c->fd), sizeof(*fence_data));
 	igt_assert(fence_data);
 	uf_sync.timeline_value = 1337;
 
@@ -2104,24 +2068,24 @@ static void *vm_bind_clear_thread(void *data)
 
 		uf_sync.addr = to_user_pointer(fence_data);
 		/* prepare clean bo */
-		clean_bo = xe_bo_create(fd, vm, bo_size, priv->region,
+		clean_bo = xe_bo_create(c->fd, vm, bo_size, priv->region,
 					DRM_XE_GEM_CREATE_FLAG_NEEDS_VISIBLE_VRAM);
 		memset(fence_data, 0, sizeof(*fence_data));
-		xe_eudebug_client_vm_bind_flags(priv->c, fd, vm, clean_bo, 0, clean_offset, bo_size,
+		xe_eudebug_client_vm_bind_flags(c, vm, clean_bo, 0, clean_offset, bo_size,
 						0, &uf_sync, 1, 0);
-		xe_wait_ufence(fd, fence_data, uf_sync.timeline_value, 0,
+		xe_wait_ufence(c->fd, fence_data, uf_sync.timeline_value, 0,
 			       XE_EUDEBUG_DEFAULT_TIMEOUT_SEC * NSEC_PER_SEC);
 
 		/* prepare batch bo */
-		batch_bo = xe_bo_create(fd, vm, bo_size, priv->region,
+		batch_bo = xe_bo_create(c->fd, vm, bo_size, priv->region,
 					DRM_XE_GEM_CREATE_FLAG_NEEDS_VISIBLE_VRAM);
 		memset(fence_data, 0, sizeof(*fence_data));
-		xe_eudebug_client_vm_bind_flags(priv->c, fd, vm, batch_bo, 0, batch_offset, bo_size,
+		xe_eudebug_client_vm_bind_flags(c, vm, batch_bo, 0, batch_offset, bo_size,
 						0, &uf_sync, 1, 0);
-		xe_wait_ufence(fd, fence_data, uf_sync.timeline_value, 0,
+		xe_wait_ufence(c->fd, fence_data, uf_sync.timeline_value, 0,
 			       XE_EUDEBUG_DEFAULT_TIMEOUT_SEC * NSEC_PER_SEC);
 
-		map = xe_bo_map(fd, batch_bo, bo_size);
+		map = xe_bo_map(c->fd, batch_bo, bo_size);
 
 		cs = map;
 		*cs++ = MI_NOOP | 0xc5a3;
@@ -2141,24 +2105,24 @@ static void *vm_bind_clear_thread(void *data)
 		eq_create.vm_id = vm;
 		eq_create.instances = to_user_pointer(priv->hwe);
 		eq_create.extensions = to_user_pointer(&eq_ext);
-		exec_queue = xe_eudebug_client_exec_queue_create(priv->c, fd, &eq_create);
+		exec_queue = xe_eudebug_client_exec_queue_create(c, &eq_create);
 
 		uf_sync.addr = (cs - map) * 4 + batch_offset;
-		xe_exec_sync(fd, exec_queue, batch_offset, &uf_sync, 1);
-		xe_wait_ufence(fd, (uint64_t *)cs, uf_sync.timeline_value, exec_queue,
+		xe_exec_sync(c->fd, exec_queue, batch_offset, &uf_sync, 1);
+		xe_wait_ufence(c->fd, (uint64_t *)cs, uf_sync.timeline_value, exec_queue,
 			       XE_EUDEBUG_DEFAULT_TIMEOUT_SEC * NSEC_PER_SEC);
 
 		igt_assert_eq(*map, 0);
 
 		/* cleanup */
-		xe_eudebug_client_exec_queue_destroy(priv->c, fd, &eq_create);
+		xe_eudebug_client_exec_queue_destroy(c, &eq_create);
 		munmap(map, bo_size);
 
-		xe_eudebug_client_vm_unbind(priv->c, fd, vm, 0, batch_offset, bo_size);
-		gem_close(fd, batch_bo);
+		xe_eudebug_client_vm_unbind(c, vm, 0, batch_offset, bo_size);
+		gem_close(c->fd, batch_bo);
 
-		xe_eudebug_client_vm_unbind(priv->c, fd, vm, 0, clean_offset, bo_size);
-		gem_close(fd, clean_bo);
+		xe_eudebug_client_vm_unbind(c, vm, 0, clean_offset, bo_size);
+		gem_close(c->fd, clean_bo);
 
 		count++;
 	}
@@ -2166,16 +2130,15 @@ static void *vm_bind_clear_thread(void *data)
 	priv->sum = count;
 
 	free(fence_data);
-	xe_eudebug_client_close_driver(priv->c, fd);
+
 	return NULL;
 }
 
 static void vm_bind_clear_client(struct xe_eudebug_client *c)
 {
-	int fd = xe_eudebug_client_open_driver(c);
-	struct xe_device *xe_dev = xe_device_get(fd);
-	int count = xe_number_engines(fd) * xe_dev->mem_regions->num_mem_regions;
-	uint64_t memreg = all_memory_regions(fd);
+	struct xe_device *xe_dev = xe_device_get(c->fd);
+	int count = xe_number_engines(c->fd) * xe_dev->mem_regions->num_mem_regions;
+	uint64_t memreg = all_memory_regions(c->fd);
 	struct vm_bind_clear_priv *priv = c->ptr;
 	int current = 0;
 	struct drm_xe_engine_class_instance *engine;
@@ -2187,7 +2150,7 @@ static void vm_bind_clear_client(struct xe_eudebug_client *c)
 	priv->sum = 0;
 
 	xe_for_each_mem_region(fd, memreg, region) {
-		xe_eudebug_for_each_engine(fd, engine) {
+		xe_eudebug_for_each_engine(c->fd, engine) {
 			threads[current].c = c;
 			threads[current].hwe = engine;
 			threads[current].region = region;
@@ -2213,8 +2176,7 @@ static void vm_bind_clear_client(struct xe_eudebug_client *c)
 	}
 
 	free(threads);
-	xe_device_put(fd);
-	xe_eudebug_client_close_driver(c, fd);
+	xe_device_put(c->fd);
 }
 
 static void vm_bind_clear_test_trigger(struct xe_eudebug_debugger *d,
@@ -2238,7 +2200,6 @@ static void vm_bind_clear_test_trigger(struct xe_eudebug_debugger *d,
 				xe_eudebug_event_log_find_seqno(d->log, eo->vm_bind_ref_seqno);
 			igt_assert(eb);
 
-			vo.client_handle = eb->client_handle;
 			vo.vm_handle = eb->vm_handle;
 
 			fd = igt_ioctl(d->fd, DRM_XE_EUDEBUG_IOCTL_VM_OPEN, &vo);
@@ -2312,22 +2273,21 @@ static void test_vm_bind_clear(int fd, uint32_t flags)
 static void vma_ufence_client(struct xe_eudebug_client *c)
 {
 	const unsigned int n = UFENCE_EVENT_COUNT_EXPECTED;
-	int fd = xe_eudebug_client_open_driver(c);
-	struct ufence_bind *binds = create_binds_with_ufence(fd, n);
+	struct ufence_bind *binds = create_binds_with_ufence(c->fd, n);
 	uint32_t vm_flags = DRM_XE_VM_CREATE_FLAG_LR_MODE;
-	size_t bo_size = xe_get_default_alignment(fd);
+	size_t bo_size = xe_get_default_alignment(c->fd);
 	uint64_t items = bo_size / sizeof(uint32_t);
 	uint32_t bo[UFENCE_EVENT_COUNT_EXPECTED];
 	uint32_t *ptr[UFENCE_EVENT_COUNT_EXPECTED];
 	uint32_t vm;
 
 	vm_flags |= (c->flags & TEST_FAULTABLE) ? DRM_XE_VM_CREATE_FLAG_FAULT_MODE : 0;
-	vm = xe_eudebug_client_vm_create(c, fd, vm_flags, 0);
+	vm = xe_eudebug_client_vm_create(c, vm_flags, 0);
 
 	for (int i = 0; i < n; i++) {
-		bo[i] = xe_bo_create(fd, 0, bo_size,
-				     system_memory(fd), 0);
-		ptr[i] = xe_bo_map(fd, bo[i], bo_size);
+		bo[i] = xe_bo_create(c->fd, 0, bo_size,
+				     system_memory(c->fd), 0);
+		ptr[i] = xe_bo_map(c->fd, bo[i], bo_size);
 		igt_assert(ptr[i]);
 		memset(ptr[i], UFENCE_CLIENT_VM_TEST_VAL_START, bo_size);
 	}
@@ -2335,7 +2295,7 @@ static void vma_ufence_client(struct xe_eudebug_client *c)
 	for (int i = 0; i < n; i++) {
 		struct ufence_bind *b = &binds[i];
 
-		xe_eudebug_client_vm_bind_flags(c, fd, vm, bo[i], 0, b->addr, b->range, 0,
+		xe_eudebug_client_vm_bind_flags(c, vm, bo[i], 0, b->addr, b->range, 0,
 						&b->f, 1, 0);
 	}
 
@@ -2346,7 +2306,8 @@ static void vma_ufence_client(struct xe_eudebug_client *c)
 		struct ufence_bind *b = &binds[i];
 
 		timeout_ns = XE_EUDEBUG_DEFAULT_TIMEOUT_SEC * NSEC_PER_SEC;
-		err = __xe_wait_ufence(fd, &b->fence_data->vm_sync, b->f.timeline_value,
+		err = __xe_wait_ufence(c->fd,
+				       &b->fence_data->vm_sync, b->f.timeline_value,
 				       0, &timeout_ns);
 		igt_assert_eq(err, 0);
 		igt_assert_eq(b->fence_data->vm_sync, b->f.timeline_value);
@@ -2359,22 +2320,20 @@ static void vma_ufence_client(struct xe_eudebug_client *c)
 	for (int i = 0; i < n; i++) {
 		struct ufence_bind *b = &binds[i];
 
-		xe_eudebug_client_vm_unbind(c, fd, vm, 0, b->addr, b->range);
+		xe_eudebug_client_vm_unbind(c, vm, 0, b->addr, b->range);
 	}
 
 	destroy_binds_with_ufence(binds, n);
 
 	for (int i = 0; i < n; i++) {
 		munmap(ptr[i], bo_size);
-		gem_close(fd, bo[i]);
+		gem_close(c->fd, bo[i]);
 	}
 
-	xe_eudebug_client_vm_destroy(c, fd, vm);
-	xe_eudebug_client_close_driver(c, fd);
+	xe_eudebug_client_vm_destroy(c, vm);
 }
 
 static void debugger_test_vma_ufence(struct xe_eudebug_debugger *d,
-				     uint64_t client_handle,
 				     uint64_t vm_handle,
 				     uint64_t va_start,
 				     uint64_t va_length)
@@ -2390,7 +2349,6 @@ static void debugger_test_vma_ufence(struct xe_eudebug_debugger *d,
 	v2 = malloc(va_length);
 	igt_assert(v2);
 
-	vo.client_handle = client_handle;
 	vo.vm_handle = vm_handle;
 
 	fd = igt_ioctl(d->fd, DRM_XE_EUDEBUG_IOCTL_VM_OPEN, &vo);
@@ -2486,7 +2444,7 @@ static void vma_ufence_trigger(struct xe_eudebug_debugger *d,
 			  ef->vm_bind_ref_seqno,
 			  addr,
 			  range);
-		debugger_test_vma_ufence(d, eb->client_handle, eb->vm_handle,
+		debugger_test_vma_ufence(d, eb->vm_handle,
 					 addr, range);
 
 		xe_eudebug_ack_ufence(d->fd, ef);
@@ -2634,11 +2592,10 @@ int igt_main()
 		test_read_event(fd);
 
 	igt_subtest("basic-client")
-		test_basic_sessions(fd, 0, 1, true);
+		test_basic_sessions(fd, CREATE_VMS, 1, true);
 
 	igt_subtest("basic-client-th")
-		test_basic_sessions_th(fd, 0, 1, true);
-
+		test_basic_sessions_th(fd, CREATE_VMS, 1, true);
 
 	igt_subtest_group() {
 		uint32_t flags[] = {0, TEST_FAULTABLE};
@@ -2668,9 +2625,6 @@ int igt_main()
 	igt_subtest("multiple-sessions")
 		test_basic_sessions(fd, CREATE_VMS | CREATE_EXEC_QUEUES, 4, true);
 
-	igt_subtest("basic-vms")
-		test_basic_sessions(fd, CREATE_VMS, 1, true);
-
 	igt_subtest("basic-exec-queues-enable")
 		test_basic_exec_queues_enable(fd);
 
diff --git a/tests/intel/xe_eudebug_online.c b/tests/intel/xe_eudebug_online.c
index 9b1e010d2a..c4e9ff2fce 100644
--- a/tests/intel/xe_eudebug_online.c
+++ b/tests/intel/xe_eudebug_online.c
@@ -151,7 +151,6 @@ struct online_debug_data {
 	/* client out */
 	int thread_hit_count;
 	/* debugger internals */
-	uint64_t client_handle;
 	uint64_t exec_queue_handle;
 	uint64_t lrc_handle;
 	uint64_t target_offset;
@@ -353,13 +352,12 @@ static const char *td_ctl_cmd_to_str(uint32_t cmd)
 	}
 }
 
-static int __eu_ctl(int debugfd, uint64_t client,
+static int __eu_ctl(int debugfd,
 		    uint64_t exec_queue, uint64_t lrc,
 		    uint8_t *bitmask, uint32_t *bitmask_size,
 		    uint32_t cmd, uint64_t *seqno)
 {
 	struct drm_xe_eudebug_eu_control control = {
-		.client_handle = lower_32_bits(client),
 		.exec_queue_handle = exec_queue,
 		.lrc_handle = lrc,
 		.cmd = cmd,
@@ -386,13 +384,13 @@ static int __eu_ctl(int debugfd, uint64_t client,
 	return 0;
 }
 
-static uint64_t eu_ctl(int debugfd, uint64_t client,
+static uint64_t eu_ctl(int debugfd,
 		       uint64_t exec_queue, uint64_t lrc,
 		       uint8_t *bitmask, uint32_t *bitmask_size, uint32_t cmd)
 {
 	uint64_t seqno;
 
-	igt_assert_eq(__eu_ctl(debugfd, client, exec_queue, lrc, bitmask,
+	igt_assert_eq(__eu_ctl(debugfd, exec_queue, lrc, bitmask,
 			       bitmask_size, cmd, &seqno), 0);
 
 	return seqno;
@@ -405,7 +403,7 @@ static bool intel_gen_needs_resume_wa(int fd)
 	return intel_gen(id) == 12 && intel_graphics_ver(id) < IP_VER(12, 55);
 }
 
-static uint64_t eu_ctl_resume(int fd, int debugfd, uint64_t client,
+static uint64_t eu_ctl_resume(int fd, int debugfd,
 			      uint64_t exec_queue, uint64_t lrc,
 			      uint8_t *bitmask, uint32_t bitmask_size)
 {
@@ -421,22 +419,22 @@ static uint64_t eu_ctl_resume(int fd, int debugfd, uint64_t client,
 		}
 	}
 
-	return eu_ctl(debugfd, client, exec_queue, lrc, bitmask, &bitmask_size,
+	return eu_ctl(debugfd, exec_queue, lrc, bitmask, &bitmask_size,
 		      DRM_XE_EUDEBUG_EU_CONTROL_CMD_RESUME);
 }
 
-static inline uint64_t eu_ctl_stopped(int debugfd, uint64_t client,
+static inline uint64_t eu_ctl_stopped(int debugfd,
 				      uint64_t exec_queue, uint64_t lrc,
 				      uint8_t *bitmask, uint32_t *bitmask_size)
 {
-	return eu_ctl(debugfd, client, exec_queue, lrc, bitmask, bitmask_size,
+	return eu_ctl(debugfd, exec_queue, lrc, bitmask, bitmask_size,
 		      DRM_XE_EUDEBUG_EU_CONTROL_CMD_STOPPED);
 }
 
-static inline uint64_t eu_ctl_interrupt_all(int debugfd, uint64_t client,
+static inline uint64_t eu_ctl_interrupt_all(int debugfd,
 					    uint64_t exec_queue, uint64_t lrc)
 {
-	return eu_ctl(debugfd, client, exec_queue, lrc, NULL, 0,
+	return eu_ctl(debugfd, exec_queue, lrc, NULL, 0,
 		      DRM_XE_EUDEBUG_EU_CONTROL_CMD_INTERRUPT_ALL);
 }
 
@@ -454,7 +452,6 @@ online_debug_data_create(int drm_fd, struct drm_xe_engine_class_instance *hwe, u
 	data->flags = flags;
 	data->thread_count = get_number_of_threads(data);
 	pthread_mutex_init(&data->mutex, NULL);
-	data->client_handle = -1ULL;
 	data->exec_queue_handle = -1ULL;
 	data->lrc_handle = -1ULL;
 	data->vm_fd = -1;
@@ -477,10 +474,11 @@ static void eu_attention_debug_trigger(struct xe_eudebug_debugger *d,
 	uint32_t *ptr = (uint32_t *)att->bitmask;
 
 	igt_debug("EVENT[%llu] eu-attenttion; threads=%d "
-		 "client[%llu], exec_queue[%llu], lrc[%llu], bitmask_size[%d]\n",
-		 att->base.seqno, igt_bitmap_hweight(att->bitmask, att->bitmask_size * 8),
-				att->client_handle, att->exec_queue_handle,
-				att->lrc_handle, att->bitmask_size);
+		  "exec_queue[%llu], lrc[%llu], bitmask_size[%d]\n",
+		  att->base.seqno,
+		  igt_bitmap_hweight(att->bitmask, att->bitmask_size * 8),
+		  att->exec_queue_handle,
+		  att->lrc_handle, att->bitmask_size);
 
 	for (uint32_t i = 0; i < att->bitmask_size / 4; i += 2)
 		igt_debug("bitmask[%d] = 0x%08x%08x\n", i / 2, ptr[i], ptr[i + 1]);
@@ -494,10 +492,11 @@ static void eu_attention_reset_trigger(struct xe_eudebug_debugger *d,
 	struct online_debug_data *data = d->ptr;
 
 	igt_debug("EVENT[%llu] eu-attention with reset; threads=%d "
-		 "client[%llu], exec_queue[%llu], lrc[%llu], bitmask_size[%d]\n",
-		 att->base.seqno, igt_bitmap_hweight(att->bitmask, att->bitmask_size * 8),
-				att->client_handle, att->exec_queue_handle,
-				att->lrc_handle, att->bitmask_size);
+		  "exec_queue[%llu], lrc[%llu], bitmask_size[%d]\n",
+		  att->base.seqno,
+		  igt_bitmap_hweight(att->bitmask, att->bitmask_size * 8),
+		  att->exec_queue_handle,
+		  att->lrc_handle, att->bitmask_size);
 
 	for (uint32_t i = 0; i < att->bitmask_size / 4; i += 2)
 		igt_debug("bitmask[%d] = 0x%08x%08x\n", i / 2, ptr[i], ptr[i + 1]);
@@ -676,7 +675,7 @@ static void eu_attention_resume_trigger(struct xe_eudebug_debugger *d,
 	bitmask = calloc(1, att->bitmask_size);
 	igt_assert(bitmask);
 
-	eu_ctl_stopped(d->fd, att->client_handle, att->exec_queue_handle,
+	eu_ctl_stopped(d->fd, att->exec_queue_handle,
 		       att->lrc_handle, bitmask, &bitmask_size);
 	igt_assert(bitmask_size == att->bitmask_size);
 
@@ -732,7 +731,7 @@ static void eu_attention_resume_trigger(struct xe_eudebug_debugger *d,
 	}
 	pthread_mutex_unlock(&data->mutex);
 
-	data->last_eu_control_seqno = eu_ctl_resume(d->master_fd, d->fd, att->client_handle,
+	data->last_eu_control_seqno = eu_ctl_resume(d->master_fd, d->fd,
 						    att->exec_queue_handle, att->lrc_handle,
 						    bitmask, att->bitmask_size);
 
@@ -825,7 +824,7 @@ static void eu_attention_resume_single_step_trigger(struct xe_eudebug_debugger *
 			     data->target_offset + steering_offset(threads)), sz);
 	fsync(data->vm_fd);
 
-	data->last_eu_control_seqno = eu_ctl_resume(d->master_fd, d->fd, att->client_handle,
+	data->last_eu_control_seqno = eu_ctl_resume(d->master_fd, d->fd,
 						    att->exec_queue_handle, att->lrc_handle,
 						    att->bitmask, att->bitmask_size);
 
@@ -834,20 +833,6 @@ static void eu_attention_resume_single_step_trigger(struct xe_eudebug_debugger *
 			data->single_step_bitmask[i] &= ~att->bitmask[i];
 }
 
-static void open_trigger(struct xe_eudebug_debugger *d,
-			 struct drm_xe_eudebug_event *e)
-{
-	struct drm_xe_eudebug_event_client *client = (void *)e;
-	struct online_debug_data *data = d->ptr;
-
-	if (e->flags & DRM_XE_EUDEBUG_EVENT_DESTROY)
-		return;
-
-	pthread_mutex_lock(&data->mutex);
-	data->client_handle = client->client_handle;
-	pthread_mutex_unlock(&data->mutex);
-}
-
 static void exec_queue_trigger(struct xe_eudebug_debugger *d,
 			       struct drm_xe_eudebug_event *e)
 {
@@ -869,7 +854,6 @@ static void vm_open_trigger(struct xe_eudebug_debugger *d,
 	struct drm_xe_eudebug_event_vm *vm = (void *)e;
 	struct online_debug_data *data = d->ptr;
 	struct drm_xe_eudebug_vm_open vo = {
-		.client_handle = vm->client_handle,
 		.vm_handle = vm->vm_handle,
 	};
 	int fd;
@@ -995,7 +979,7 @@ static void eu_attention_resume_caching_trigger(struct xe_eudebug_debugger *d,
 				     "Poison value found at %04d!\n", i);
 		}
 
-	ret = __eu_ctl(d->fd, att->client_handle, att->exec_queue_handle, att->lrc_handle,
+	ret = __eu_ctl(d->fd, att->exec_queue_handle, att->lrc_handle,
 		       att->bitmask, &att->bitmask_size, DRM_XE_EUDEBUG_EU_CONTROL_CMD_RESUME,
 		       &seqno);
 
@@ -1071,25 +1055,23 @@ static void run_online_client(struct xe_eudebug_client *c)
 	struct intel_bb *ibb;
 	struct intel_buf *buf;
 	uint32_t *ptr;
-	int fd, vm_flags;
-
-	fd = xe_eudebug_client_open_driver(c);
+	int vm_flags;
 
 	threads = data->thread_count;
 	w_dim = walker_dimensions(threads);
 	s_dim = surface_dimensions(threads);
 
 	shader = get_shader(data);
-	bb_size = get_bb_size(fd, shader);
+	bb_size = get_bb_size(c->fd, shader);
 
 	/* Additional memory for steering control */
 	if (c->flags & SHADER_LOOP || c->flags & SHADER_SINGLE_STEP || c->flags & SHADER_PAGEFAULT)
 		s_dim.y++;
 	/* Additional memory for caching check */
 	if ((c->flags & SHADER_CACHING_SRAM) || (c->flags & SHADER_CACHING_VRAM))
-		s_dim.y += caching_get_instruction_count(fd, s_dim.x, c->flags);
-	buf = create_uc_buf(fd, s_dim.x, s_dim.y,
-			    get_memory_region(fd, c->flags, TARGET_REGION_BITMASK));
+		s_dim.y += caching_get_instruction_count(c->fd, s_dim.x, c->flags);
+	buf = create_uc_buf(c->fd, s_dim.x, s_dim.y,
+			    get_memory_region(c->fd, c->flags, TARGET_REGION_BITMASK));
 
 	buf->addr.offset = target_offset;
 
@@ -1097,12 +1079,13 @@ static void run_online_client(struct xe_eudebug_client *c)
 	vm_flags |= c->flags & (SHADER_PAGEFAULT | FAULTABLE_VM) ?
 			DRM_XE_VM_CREATE_FLAG_FAULT_MODE : 0;
 
-	create.vm_id = xe_eudebug_client_vm_create(c, fd, vm_flags, 0);
+	create.vm_id = xe_eudebug_client_vm_create(c, vm_flags, 0);
 
-	xe_eudebug_client_exec_queue_create(c, fd, &create);
+	xe_eudebug_client_exec_queue_create(c, &create);
 
-	ibb = xe_bb_create_on_offset(fd, create.exec_queue_id, create.vm_id, bb_offset, bb_size,
-				     get_memory_region(fd, c->flags, BB_REGION_BITMASK));
+	ibb = xe_bb_create_on_offset(c->fd,
+				     create.exec_queue_id, create.vm_id, bb_offset, bb_size,
+				     get_memory_region(c->fd, c->flags, BB_REGION_BITMASK));
 	intel_bb_set_lr_mode(ibb, true);
 
 	sip = get_sip(data);
@@ -1122,10 +1105,9 @@ static void run_online_client(struct xe_eudebug_client *c)
 		igt_assert(igt_nsec_elapsed(&ts) < XE_EUDEBUG_DEFAULT_TIMEOUT_SEC * NSEC_PER_SEC);
 
 	if (!(c->flags & DO_NOT_EXPECT_CANARIES)) {
-		ptr = xe_bo_mmap_ext(fd, buf->handle, buf->size, PROT_READ);
+		ptr = xe_bo_mmap_ext(c->fd, buf->handle, buf->size, PROT_READ);
 		data->thread_hit_count = count_canaries_neq(ptr, w_dim, 0);
 		igt_assert_f(data->thread_hit_count, "No canaries found, nothing executed?\n");
-
 		if ((c->flags & SHADER_BREAKPOINT || c->flags & TRIGGER_RESUME_SET_BP ||
 		     c->flags & SHADER_N_NOOP_BREAKPOINT) && !(c->flags & DISABLE_DEBUG_MODE)) {
 			uint32_t aip = ptr[0];
@@ -1143,12 +1125,10 @@ static void run_online_client(struct xe_eudebug_client *c)
 
 	intel_bb_destroy(ibb);
 
-	xe_eudebug_client_exec_queue_destroy(c, fd, &create);
-	xe_eudebug_client_vm_destroy(c, fd, create.vm_id);
+	xe_eudebug_client_exec_queue_destroy(c, &create);
+	xe_eudebug_client_vm_destroy(c, create.vm_id);
 
 	intel_buf_destroy(buf);
-
-	xe_eudebug_client_close_driver(c, fd);
 }
 
 static bool intel_gen_has_lockstep_eus(int fd)
@@ -1221,9 +1201,6 @@ match_attention_with_exec_queue(struct xe_eudebug_event_log *log,
 			if (ee->exec_queue_handle != ea->exec_queue_handle)
 				continue;
 
-			if (ee->client_handle != ea->client_handle)
-				continue;
-
 			for (lrc_idx = 0; lrc_idx < ee->width; lrc_idx++) {
 				if (ee->lrc_handle[lrc_idx] == ea->lrc_handle)
 					break;
@@ -1388,10 +1365,10 @@ static void pagefault_trigger(struct xe_eudebug_debugger *d,
 
 	igt_debug("EVENT[%llu] pagefault; threads[before=%d, after=%d, "
 		  "resolved=%d, pagefault=%d] "
-		  "client[%llu], exec_queue[%llu], lrc[%llu], bitmask_size[%d], "
+		  "exec_queue[%llu], lrc[%llu], bitmask_size[%d], "
 		  "pagefault_address[0x%llx]\n",
 		  pf->base.seqno, threads[0], threads[1], threads[2],
-		  pagefault_threads, pf->client_handle, pf->exec_queue_handle,
+		  pagefault_threads, pf->exec_queue_handle,
 		  pf->lrc_handle, pf->bitmask_size,
 		  pf->pagefault_address);
 
@@ -1513,8 +1490,6 @@ static void test_set_breakpoint_online(int fd, struct drm_xe_engine_class_instan
 
 	data = online_debug_data_create(fd, hwe, flags);
 	s = xe_eudebug_session_create(fd, run_online_client, flags, data);
-	xe_eudebug_debugger_add_trigger(s->debugger, DRM_XE_EUDEBUG_EVENT_OPEN,
-					open_trigger);
 	xe_eudebug_debugger_add_trigger(s->debugger, DRM_XE_EUDEBUG_EVENT_EXEC_QUEUE,
 					exec_queue_trigger);
 	xe_eudebug_debugger_add_trigger(s->debugger, DRM_XE_EUDEBUG_EVENT_VM, vm_open_trigger);
@@ -1575,8 +1550,7 @@ static void test_set_breakpoint_online_sigint_debugger(int fd,
 		data = online_debug_data_create(fd, hwe, flags);
 		s = xe_eudebug_session_create(fd, run_online_client, flags, data);
 		s->client->allow_dead_client = true;
-		xe_eudebug_debugger_add_trigger(s->debugger, DRM_XE_EUDEBUG_EVENT_OPEN,
-						open_trigger);
+
 		xe_eudebug_debugger_add_trigger(s->debugger, DRM_XE_EUDEBUG_EVENT_EXEC_QUEUE,
 						exec_queue_trigger);
 		xe_eudebug_debugger_add_trigger(s->debugger, DRM_XE_EUDEBUG_EVENT_VM,
@@ -1698,8 +1672,6 @@ static void test_pagefault_online(int fd, struct drm_xe_engine_class_instance *h
 	}
 	s = xe_eudebug_session_create(fd, run_online_client, data->flags, data);
 
-	xe_eudebug_debugger_add_trigger(s->debugger, DRM_XE_EUDEBUG_EVENT_OPEN,
-					open_trigger);
 	xe_eudebug_debugger_add_trigger(s->debugger, DRM_XE_EUDEBUG_EVENT_EXEC_QUEUE,
 					exec_queue_trigger);
 	xe_eudebug_debugger_add_trigger(s->debugger, DRM_XE_EUDEBUG_EVENT_EU_ATTENTION,
@@ -1835,8 +1807,6 @@ static void test_interrupt_all(int fd, struct drm_xe_engine_class_instance *hwe,
 	data = online_debug_data_create(fd, hwe, flags);
 	s = xe_eudebug_session_create(fd, run_online_client, flags, data);
 
-	xe_eudebug_debugger_add_trigger(s->debugger, DRM_XE_EUDEBUG_EVENT_OPEN,
-					open_trigger);
 	xe_eudebug_debugger_add_trigger(s->debugger, DRM_XE_EUDEBUG_EVENT_EXEC_QUEUE,
 					exec_queue_trigger);
 	xe_eudebug_debugger_add_trigger(s->debugger, DRM_XE_EUDEBUG_EVENT_EU_ATTENTION,
@@ -1863,9 +1833,8 @@ static void test_interrupt_all(int fd, struct drm_xe_engine_class_instance *hwe,
 	}
 
 	pthread_mutex_lock(&data->mutex);
-	igt_assert(data->client_handle != -1);
 	igt_assert(data->exec_queue_handle != -1);
-	eu_ctl_interrupt_all(s->debugger->fd, data->client_handle,
+	eu_ctl_interrupt_all(s->debugger->fd,
 			     data->exec_queue_handle, data->lrc_handle);
 	pthread_mutex_unlock(&data->mutex);
 
@@ -1924,7 +1893,6 @@ static void test_interrupt_other(int fd, struct drm_xe_engine_class_instance *hw
 	data = online_debug_data_create(fd, hwe, flags);
 	s = xe_eudebug_session_create(fd, run_online_client, flags, data);
 
-	xe_eudebug_debugger_add_trigger(s->debugger, DRM_XE_EUDEBUG_EVENT_OPEN, open_trigger);
 	xe_eudebug_debugger_add_trigger(s->debugger, DRM_XE_EUDEBUG_EVENT_EXEC_QUEUE,
 					exec_queue_trigger);
 	xe_eudebug_debugger_add_trigger(s->debugger, DRM_XE_EUDEBUG_EVENT_VM, vm_open_trigger);
@@ -1961,14 +1929,13 @@ static void test_interrupt_other(int fd, struct drm_xe_engine_class_instance *hw
 	}
 
 	pthread_mutex_lock(&debugee_data->mutex);
-	igt_assert(debugee_data->client_handle != -1);
 	igt_assert(debugee_data->exec_queue_handle != -1);
 
 	/*
 	 * Interrupting the other client should return invalid state
 	 * as it is running in runalone mode
 	 */
-	igt_assert_eq(__eu_ctl(s->debugger->fd, debugee_data->client_handle,
+	igt_assert_eq(__eu_ctl(s->debugger->fd,
 		      debugee_data->exec_queue_handle, debugee_data->lrc_handle, NULL, 0,
 		      DRM_XE_EUDEBUG_EU_CONTROL_CMD_INTERRUPT_ALL, NULL), -EINVAL);
 	pthread_mutex_unlock(&debugee_data->mutex);
@@ -2013,8 +1980,6 @@ static void test_tdctl_parameters(int fd, struct drm_xe_engine_class_instance *h
 	data = online_debug_data_create(fd, hwe, flags);
 	s = xe_eudebug_session_create(fd, run_online_client, flags, data);
 
-	xe_eudebug_debugger_add_trigger(s->debugger, DRM_XE_EUDEBUG_EVENT_OPEN,
-					open_trigger);
 	xe_eudebug_debugger_add_trigger(s->debugger, DRM_XE_EUDEBUG_EVENT_EXEC_QUEUE,
 					exec_queue_trigger);
 	xe_eudebug_debugger_add_trigger(s->debugger, DRM_XE_EUDEBUG_EVENT_EU_ATTENTION,
@@ -2041,34 +2006,27 @@ static void test_tdctl_parameters(int fd, struct drm_xe_engine_class_instance *h
 	}
 
 	pthread_mutex_lock(&data->mutex);
-	igt_assert(data->client_handle != -1);
 	igt_assert(data->exec_queue_handle != -1);
 	igt_assert(data->lrc_handle != -1);
 
 	/* fail on invalid lrc_handle */
-	igt_assert(__eu_ctl(s->debugger->fd, data->client_handle,
+	igt_assert(__eu_ctl(s->debugger->fd,
 			    data->exec_queue_handle, data->lrc_handle + 1,
 			    attention_bitmask, &bitmask_size,
 			    DRM_XE_EUDEBUG_EU_CONTROL_CMD_INTERRUPT_ALL, NULL) == -EINVAL);
 
 	/* fail on invalid exec_queue_handle */
-	igt_assert(__eu_ctl(s->debugger->fd, data->client_handle,
+	igt_assert(__eu_ctl(s->debugger->fd,
 			    data->exec_queue_handle + 1, data->lrc_handle,
 			    attention_bitmask, &bitmask_size,
 			    DRM_XE_EUDEBUG_EU_CONTROL_CMD_INTERRUPT_ALL, NULL) == -EINVAL);
 
-	/* fail on invalid client */
-	igt_assert(__eu_ctl(s->debugger->fd, data->client_handle + 1,
-			    data->exec_queue_handle, data->lrc_handle,
-			    attention_bitmask, &bitmask_size,
-			    DRM_XE_EUDEBUG_EU_CONTROL_CMD_INTERRUPT_ALL, NULL) == -EINVAL);
-
 	/*
 	 * bitmask size must be aligned to sizeof(u32) for all commands
 	 * and be zero for interrupt all
 	 */
 	bitmask_size = sizeof(uint32_t) - 1;
-	igt_assert(__eu_ctl(s->debugger->fd, data->client_handle,
+	igt_assert(__eu_ctl(s->debugger->fd,
 			    data->exec_queue_handle, data->lrc_handle,
 			    attention_bitmask, &bitmask_size,
 			    DRM_XE_EUDEBUG_EU_CONTROL_CMD_STOPPED, NULL) == -EINVAL);
@@ -2076,13 +2034,13 @@ static void test_tdctl_parameters(int fd, struct drm_xe_engine_class_instance *h
 
 	/* fail on invalid command */
 	random_command = random() | (DRM_XE_EUDEBUG_EU_CONTROL_CMD_RESUME + 1);
-	igt_assert(__eu_ctl(s->debugger->fd, data->client_handle,
+	igt_assert(__eu_ctl(s->debugger->fd,
 			    data->exec_queue_handle, data->lrc_handle,
 			    attention_bitmask, &bitmask_size, random_command, NULL) == -EINVAL);
 
 	free(attention_bitmask);
 
-	eu_ctl_interrupt_all(s->debugger->fd, data->client_handle,
+	eu_ctl_interrupt_all(s->debugger->fd,
 			     data->exec_queue_handle, data->lrc_handle);
 	pthread_mutex_unlock(&data->mutex);
 
@@ -2104,9 +2062,10 @@ static void eu_attention_debugger_detach_trigger(struct xe_eudebug_debugger *d,
 {
 	struct online_debug_data *data = d->ptr;
 	uint64_t c_pid;
-	int ret;
+	int ret, c_fd;
 
 	c_pid = d->target_pid;
+	c_fd = d->target_fd;
 
 	/* Reset VM data so the re-triggered VM open handler works properly */
 	data->vm_fd = -1;
@@ -2124,10 +2083,11 @@ static void eu_attention_debugger_detach_trigger(struct xe_eudebug_debugger *d,
 	 */
 	reset_debugger_log(d);
 
-	ret = xe_eudebug_connect(d->master_fd, c_pid, 0);
+	ret = __xe_eudebug_connect(d->master_fd, c_fd, c_pid, 0);
 	igt_assert(ret >= 0);
 	d->fd = ret;
 	d->target_pid = c_pid;
+	d->target_fd = c_fd;
 
 	/* Discovery worker will replay events that have occurred, which leads to
 	 * a vm event being sent and vm_open_trigger being re-run, which would lead
@@ -2161,8 +2121,6 @@ static void test_interrupt_reconnect(int fd, struct drm_xe_engine_class_instance
 	data = online_debug_data_create(fd, hwe, flags);
 	s = xe_eudebug_session_create(fd, run_online_client, flags, data);
 
-	xe_eudebug_debugger_add_trigger(s->debugger, DRM_XE_EUDEBUG_EVENT_OPEN,
-					open_trigger);
 	xe_eudebug_debugger_add_trigger(s->debugger, DRM_XE_EUDEBUG_EVENT_EXEC_QUEUE,
 					exec_queue_trigger);
 	xe_eudebug_debugger_add_trigger(s->debugger, DRM_XE_EUDEBUG_EVENT_EU_ATTENTION,
@@ -2189,9 +2147,8 @@ static void test_interrupt_reconnect(int fd, struct drm_xe_engine_class_instance
 	}
 
 	pthread_mutex_lock(&data->mutex);
-	igt_assert(data->client_handle != -1);
 	igt_assert(data->exec_queue_handle != -1);
-	eu_ctl_interrupt_all(s->debugger->fd, data->client_handle,
+	eu_ctl_interrupt_all(s->debugger->fd,
 			     data->exec_queue_handle, data->lrc_handle);
 	pthread_mutex_unlock(&data->mutex);
 
@@ -2238,8 +2195,6 @@ static void test_single_step(int fd, struct drm_xe_engine_class_instance *hwe, i
 	data = online_debug_data_create(fd, hwe, flags);
 	s = xe_eudebug_session_create(fd, run_online_client, flags, data);
 
-	xe_eudebug_debugger_add_trigger(s->debugger, DRM_XE_EUDEBUG_EVENT_OPEN,
-					open_trigger);
 	xe_eudebug_debugger_add_trigger(s->debugger, DRM_XE_EUDEBUG_EVENT_EU_ATTENTION,
 					eu_attention_debug_trigger);
 	xe_eudebug_debugger_add_trigger(s->debugger, DRM_XE_EUDEBUG_EVENT_EU_ATTENTION,
@@ -2337,8 +2292,6 @@ static void test_caching(int fd, struct drm_xe_engine_class_instance *hwe, int f
 	data = online_debug_data_create(fd, hwe, flags);
 	s = xe_eudebug_session_create(fd, run_online_client, flags, data);
 
-	xe_eudebug_debugger_add_trigger(s->debugger, DRM_XE_EUDEBUG_EVENT_OPEN,
-					open_trigger);
 	xe_eudebug_debugger_add_trigger(s->debugger, DRM_XE_EUDEBUG_EVENT_EU_ATTENTION,
 					eu_attention_debug_trigger);
 	xe_eudebug_debugger_add_trigger(s->debugger, DRM_XE_EUDEBUG_EVENT_EU_ATTENTION,
@@ -2496,7 +2449,7 @@ static void test_many_sessions_on_tiles(int fd, bool multi_tile)
 				usleep(WORKLOAD_DELAY_US);
 				eus = (struct drm_xe_eudebug_event_eu_attention *)data[i]->exception_event;
 				eu_ctl_resume(s[i]->debugger->master_fd, s[i]->debugger->fd,
-					      eus->client_handle, eus->exec_queue_handle,
+					      eus->exec_queue_handle,
 					      eus->lrc_handle, eus->bitmask, eus->bitmask_size);
 				free(eus);
 
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [PATCH i-g-t 07/21] tests/xe_eudebug: Adapt basic-read-event
  2026-01-12 12:59 [PATCH i-g-t 00/21] eudebug: uapi changes on connect and metadata Mika Kuoppala
                   ` (5 preceding siblings ...)
  2026-01-12 12:59 ` [PATCH i-g-t 06/21] eudebug: Remove EVENT_OPEN and adjust tests Mika Kuoppala
@ 2026-01-12 12:59 ` Mika Kuoppala
  2026-01-12 12:59 ` [PATCH i-g-t 08/21] tests/intel/xe_eudebug: Fix connect-user test Mika Kuoppala
                   ` (13 subsequent siblings)
  20 siblings, 0 replies; 23+ messages in thread
From: Mika Kuoppala @ 2026-01-12 12:59 UTC (permalink / raw)
  To: igt-dev
  Cc: christoph.manszewski, dominik.karol.piatkowski, maciej.patelczyk,
	jan.maslak, zbigniew.kempczynski, Mika Kuoppala

From: Christoph Manszewski <christoph.manszewski@intel.com>

Adapt basic-read-event test to rely on vm create/destroy events for
positive test path since client create/destroy events are no longer
present.

Also update the assert for blocking event_read ioctl with no events
to expect -ETIMEDOUT

Signed-off-by: Christoph Manszewski <christoph.manszewski@intel.com>
Signed-off-by: Mika Kuoppala <mika.kuoppala@linux.intel.com>
---
 tests/intel/xe_eudebug.c | 34 +++++++++++++++++++++-------------
 1 file changed, 21 insertions(+), 13 deletions(-)

diff --git a/tests/intel/xe_eudebug.c b/tests/intel/xe_eudebug.c
index 8d673b68bb..3c7a13f6fe 100644
--- a/tests/intel/xe_eudebug.c
+++ b/tests/intel/xe_eudebug.c
@@ -55,15 +55,16 @@ static void test_sysfs_toggle(int fd)
 #define STAGE_PRE_DEBUG_RESOURCES_DONE	1
 #define STAGE_DISCOVERY_DONE		2
 
-#define CREATE_VMS			(1 << 0)
-#define CREATE_EXEC_QUEUES		(1 << 1)
-#define VM_BIND				(1 << 2)
-#define VM_BIND_VM_DESTROY		(1 << 3)
-#define VM_BIND_EXTENDED		(1 << 4)
-#define VM_BIND_OP_MAP_USERPTR		(1 << 5)
-#define VM_BIND_DELAY_UFENCE_ACK	(1 << 6)
-#define VM_BIND_UFENCE_RECONNECT	(1 << 7)
-#define VM_BIND_UFENCE_SIGINT_CLIENT	(1 << 8)
+#define CREATE_VM			(1 << 0)
+#define CREATE_VMS			(1 << 1)
+#define CREATE_EXEC_QUEUES		(1 << 2)
+#define VM_BIND				(1 << 3)
+#define VM_BIND_VM_DESTROY		(1 << 4)
+#define VM_BIND_EXTENDED		(1 << 5)
+#define VM_BIND_OP_MAP_USERPTR		(1 << 6)
+#define VM_BIND_DELAY_UFENCE_ACK	(1 << 7)
+#define VM_BIND_UFENCE_RECONNECT	(1 << 8)
+#define VM_BIND_UFENCE_SIGINT_CLIENT	(1 << 9)
 #define TEST_FAULTABLE			(1 << 30)
 #define TEST_DISCOVERY			(1 << 31)
 
@@ -379,6 +380,11 @@ static void run_basic_client(struct xe_eudebug_client *c)
 {
 	int i;
 
+	if (c->flags & CREATE_VM) {
+		int vm = xe_eudebug_client_vm_create(c, DRM_XE_VM_CREATE_FLAG_LR_MODE, 0);
+		xe_eudebug_client_vm_destroy(c, vm);
+	}
+
 	if (c->flags & CREATE_VMS) {
 		const uint32_t flags[] = {
 			DRM_XE_VM_CREATE_FLAG_SCRATCH_PAGE | DRM_XE_VM_CREATE_FLAG_LR_MODE,
@@ -775,7 +781,7 @@ static void test_read_event(int fd)
 	event = calloc(1, MAX_EVENT_SIZE);
 	igt_assert(event);
 
-	c = xe_eudebug_client_create(fd, run_basic_client, 0, NULL);
+	c = xe_eudebug_client_create(fd, run_basic_client, CREATE_VM, NULL);
 	d = xe_eudebug_debugger_create(fd, 0, NULL);
 
 	igt_assert_eq(xe_eudebug_debugger_attach(d, c), 0);
@@ -784,14 +790,15 @@ static void test_read_event(int fd)
 	/* Negative read event - no events to read */
 	event->len = MAX_EVENT_SIZE;
 	event->type = DRM_XE_EUDEBUG_EVENT_READ;
-	igt_assert_eq(read_event(d->fd, event), -ENOENT);
+	igt_assert_eq(read_event(d->fd, event), -ETIMEDOUT);
 
 	xe_eudebug_client_start(c);
 
-	/* Positive read event - client create */
+	/* Positive read event - vm create */
 	igt_assert_eq(poll_event(d->fd, 500), 1);
 	event->type = DRM_XE_EUDEBUG_EVENT_READ;
 	igt_assert_eq(read_event(d->fd, event), 0);
+	igt_assert_eq(event->type, DRM_XE_EUDEBUG_EVENT_VM);
 	igt_assert_eq(event->flags, DRM_XE_EUDEBUG_EVENT_CREATE);
 
 	igt_assert_eq(poll_event(d->fd, 500), 1);
@@ -826,8 +833,9 @@ static void test_read_event(int fd)
 	/* event->len should now contain exact len */
 	igt_assert_lt(sizeof(*event), event->len);
 
-	/* Positive read event - client destroy */
+	/* Positive read event - vm destroy */
 	igt_assert_eq(read_event(d->fd, event), 0);
+	igt_assert_eq(event->type, DRM_XE_EUDEBUG_EVENT_VM);
 	igt_assert_eq(event->flags, DRM_XE_EUDEBUG_EVENT_DESTROY);
 
 	fcntl(d->fd, F_SETFL, fcntl(d->fd, F_GETFL) | O_NONBLOCK);
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [PATCH i-g-t 08/21] tests/intel/xe_eudebug: Fix connect-user test
  2026-01-12 12:59 [PATCH i-g-t 00/21] eudebug: uapi changes on connect and metadata Mika Kuoppala
                   ` (6 preceding siblings ...)
  2026-01-12 12:59 ` [PATCH i-g-t 07/21] tests/xe_eudebug: Adapt basic-read-event Mika Kuoppala
@ 2026-01-12 12:59 ` Mika Kuoppala
  2026-01-12 12:59 ` [PATCH i-g-t 09/21] tests/intel/xe_eudebug: Mold ufence reconnect test to disconnect Mika Kuoppala
                   ` (12 subsequent siblings)
  20 siblings, 0 replies; 23+ messages in thread
From: Mika Kuoppala @ 2026-01-12 12:59 UTC (permalink / raw)
  To: igt-dev
  Cc: christoph.manszewski, dominik.karol.piatkowski, maciej.patelczyk,
	jan.maslak, zbigniew.kempczynski, Mika Kuoppala

We changed from connecting to pid into connecting into
a filedescriptor of a drm client. As the access checks
are now in a filedescriptor level we get EBADFD
instead of EACCESS. Adjust to new error returns.

Signed-off-by: Mika Kuoppala <mika.kuoppala@linux.intel.com>
---
 tests/intel/xe_eudebug.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/tests/intel/xe_eudebug.c b/tests/intel/xe_eudebug.c
index 3c7a13f6fe..1bb30a1cad 100644
--- a/tests/intel/xe_eudebug.c
+++ b/tests/intel/xe_eudebug.c
@@ -637,7 +637,7 @@ static void test_connect_user(int fd)
 	test[0].skip = !pwd;
 	test[0].u[P_GDB] = u1;
 	test[0].g[P_GDB] = g1;
-	test[0].ret = -EACCES;
+	test[0].ret = -EBADFD;
 	test[0].desc = "User GDB to Root App";
 
 	test[1].skip = !pwd;
@@ -659,7 +659,7 @@ static void test_connect_user(int fd)
 	test[3].g[P_APP] = g1;
 	test[3].u[P_GDB] = u2;
 	test[3].g[P_GDB] = g2;
-	test[3].ret = -EACCES;
+	test[3].ret = -EBADFD;
 	test[3].desc = "User GDB to Other User App";
 
 	if (!pwd2)
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [PATCH i-g-t 09/21] tests/intel/xe_eudebug: Mold ufence reconnect test to disconnect
  2026-01-12 12:59 [PATCH i-g-t 00/21] eudebug: uapi changes on connect and metadata Mika Kuoppala
                   ` (7 preceding siblings ...)
  2026-01-12 12:59 ` [PATCH i-g-t 08/21] tests/intel/xe_eudebug: Fix connect-user test Mika Kuoppala
@ 2026-01-12 12:59 ` Mika Kuoppala
  2026-01-12 12:59 ` [PATCH i-g-t 10/21] lib/xe_eudebug: Adapt to vm_bind debug data Mika Kuoppala
                   ` (11 subsequent siblings)
  20 siblings, 0 replies; 23+ messages in thread
From: Mika Kuoppala @ 2026-01-12 12:59 UTC (permalink / raw)
  To: igt-dev
  Cc: christoph.manszewski, dominik.karol.piatkowski, maciej.patelczyk,
	jan.maslak, zbigniew.kempczynski, Mika Kuoppala

If debugger disconnects, the driver will automatically ack all
ufences as we have 1:1 mapping between debuggers and drm clients.

In old way of connecting, reconnecting test made sense but it
does not anymore.

Convert the test to just disconnect the debugger.

Signed-off-by: Mika Kuoppala <mika.kuoppala@linux.intel.com>
---
 tests/intel/xe_eudebug.c | 16 +++++++---------
 1 file changed, 7 insertions(+), 9 deletions(-)

diff --git a/tests/intel/xe_eudebug.c b/tests/intel/xe_eudebug.c
index 1bb30a1cad..353828f673 100644
--- a/tests/intel/xe_eudebug.c
+++ b/tests/intel/xe_eudebug.c
@@ -63,7 +63,7 @@ static void test_sysfs_toggle(int fd)
 #define VM_BIND_EXTENDED		(1 << 5)
 #define VM_BIND_OP_MAP_USERPTR		(1 << 6)
 #define VM_BIND_DELAY_UFENCE_ACK	(1 << 7)
-#define VM_BIND_UFENCE_RECONNECT	(1 << 8)
+#define VM_BIND_UFENCE_DISCONNECT	(1 << 8)
 #define VM_BIND_UFENCE_SIGINT_CLIENT	(1 << 9)
 #define TEST_FAULTABLE			(1 << 30)
 #define TEST_DISCOVERY			(1 << 31)
@@ -1920,7 +1920,7 @@ static int wait_for_ufence_events(struct ufence_priv *priv, int timeout_ms)
  * Description:
  *	Give user fence in application and check if delayed ufence ack works
  *
- * SUBTEST: basic-vm-bind-ufence-reconnect
+ * SUBTEST: basic-vm-bind-ufence-disconnect
  * Functionality: VM bind event
  * Description:
  *	Give user fence in application, hold it, drop the debugger connection and check if anything
@@ -1964,11 +1964,9 @@ static void test_basic_ufence(int fd, unsigned int flags)
 		kill(c->pid, SIGINT);
 		c->pid = 0;
 		c->done = 1;
-	} else if (flags & VM_BIND_UFENCE_RECONNECT) {
-		filter = XE_EUDEBUG_FILTER_EVENT_VM_BIND | XE_EUDEBUG_FILTER_EVENT_VM;
-		xe_eudebug_debugger_detach(d);
-		xe_eudebug_client_wait_done(c);
-		igt_assert_eq(xe_eudebug_debugger_attach(d, c), 0);
+	} else if (flags & VM_BIND_UFENCE_DISCONNECT) {
+		filter = XE_EUDEBUG_FILTER_ALL;
+		close(s->debugger->fd);
 	} else {
 		ack_fences(d);
 	}
@@ -2648,8 +2646,8 @@ int igt_main()
 	igt_subtest("basic-vm-bind-ufence-delay-ack")
 		test_basic_ufence(fd, VM_BIND_DELAY_UFENCE_ACK);
 
-	igt_subtest("basic-vm-bind-ufence-reconnect")
-		test_basic_ufence(fd, VM_BIND_UFENCE_RECONNECT);
+	igt_subtest("basic-vm-bind-ufence-disconnect")
+		test_basic_ufence(fd, VM_BIND_UFENCE_DISCONNECT);
 
 	igt_subtest("basic-vm-bind-ufence-sigint-client")
 		test_basic_ufence(fd, VM_BIND_UFENCE_SIGINT_CLIENT);
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [PATCH i-g-t 10/21] lib/xe_eudebug: Adapt to vm_bind debug data
  2026-01-12 12:59 [PATCH i-g-t 00/21] eudebug: uapi changes on connect and metadata Mika Kuoppala
                   ` (8 preceding siblings ...)
  2026-01-12 12:59 ` [PATCH i-g-t 09/21] tests/intel/xe_eudebug: Mold ufence reconnect test to disconnect Mika Kuoppala
@ 2026-01-12 12:59 ` Mika Kuoppala
  2026-01-12 12:59 ` [PATCH i-g-t 11/21] tests/xe_eudebug: Adapt basic-vm-bind and remove basic-vm-bind-extended Mika Kuoppala
                   ` (10 subsequent siblings)
  20 siblings, 0 replies; 23+ messages in thread
From: Mika Kuoppala @ 2026-01-12 12:59 UTC (permalink / raw)
  To: igt-dev
  Cc: christoph.manszewski, dominik.karol.piatkowski, maciej.patelczyk,
	jan.maslak, zbigniew.kempczynski, Mika Kuoppala

From: Christoph Manszewski <christoph.manszewski@intel.com>

EU debug no longer relays events for VM_BIND_OP_[MAP|UNMAP] operations.
Instead it reports newly added 'VM_BIND_OP_DEBUG_DATA_[ADD|REMOVE]'
operations through the event interface. Add a wrapper for the newly
added vm bind operations and don't store OP_[MAP|UNMAP] events in the
client log.

Signed-off-by: Christoph Manszewski <christoph.manszewski@intel.com>
Signed-off-by: Mika Kuoppala <mika.kuoppala@linux.intel.com>
---
 include/drm-uapi/xe_drm.h |  36 +++++
 lib/xe/xe_eudebug.c       | 287 ++++++++++++++++++++++++++++++++++++--
 lib/xe/xe_eudebug.h       |  20 +++
 3 files changed, 335 insertions(+), 8 deletions(-)

diff --git a/include/drm-uapi/xe_drm.h b/include/drm-uapi/xe_drm.h
index 077e66a682..13add4fb8d 100644
--- a/include/drm-uapi/xe_drm.h
+++ b/include/drm-uapi/xe_drm.h
@@ -6,6 +6,8 @@
 #ifndef _UAPI_XE_DRM_H_
 #define _UAPI_XE_DRM_H_
 
+#include <linux/limits.h>
+
 #include "drm.h"
 
 #if defined(__cplusplus)
@@ -1007,6 +1009,35 @@ struct drm_xe_vm_destroy {
 	__u64 reserved[2];
 };
 
+struct drm_xe_vm_bind_op_ext_debug_data {
+	/** @base: base user extension */
+	struct drm_xe_user_extension base;
+
+	/** @addr: Address of the metadata mapping */
+	__u64 addr;
+
+	/** @range: Range of the metadata mapping */
+	__u64 range;
+
+#define DRM_XE_VM_BIND_DEBUG_DATA_FLAG_PSEUDO (1 << 0)
+	/** @flags: Debug metadata flags */
+	__u64 flags;
+
+	/** @offset: Offset into the debug data file, MBZ for DEBUG_PSEUDO */
+	__u32 offset;
+
+	/** @reserved: Reserved */
+	__u32 reserved;
+
+	union {
+#define DRM_XE_VM_BIND_DEBUG_DATA_PSEUDO_MODULE_AREA	0x1
+#define DRM_XE_VM_BIND_DEBUG_DATA_PSEUDO_SBA_AREA	0x2
+#define DRM_XE_VM_BIND_DEBUG_DATA_PSEUDO_SIP_AREA	0x3
+		__u64 pseudopath;
+		char pathname[PATH_MAX];
+	};
+};
+
 /**
  * struct drm_xe_vm_bind_op - run bind operations
  *
@@ -1016,6 +1047,8 @@ struct drm_xe_vm_destroy {
  *  - %DRM_XE_VM_BIND_OP_MAP_USERPTR
  *  - %DRM_XE_VM_BIND_OP_UNMAP_ALL
  *  - %DRM_XE_VM_BIND_OP_PREFETCH
+ *  - %DRM_XE_VM_BIND_OP_ADD_DEBUG_DATA
+ *  - %DRM_XE_VM_BIND_OP_REMOVE_DEBUG_DATA
  *
  * and the @flags can be:
  *  - %DRM_XE_VM_BIND_FLAG_READONLY - Setup the page tables as read-only
@@ -1059,6 +1092,7 @@ struct drm_xe_vm_destroy {
  *    the memory region advised by madvise.
  */
 struct drm_xe_vm_bind_op {
+#define	XE_VM_BIND_OP_EXTENSIONS_DEBUG_DATA 0
 	/** @extensions: Pointer to the first extension struct, if any */
 	__u64 extensions;
 
@@ -1150,6 +1184,8 @@ struct drm_xe_vm_bind_op {
 #define DRM_XE_VM_BIND_OP_MAP_USERPTR	0x2
 #define DRM_XE_VM_BIND_OP_UNMAP_ALL	0x3
 #define DRM_XE_VM_BIND_OP_PREFETCH	0x4
+#define DRM_XE_VM_BIND_OP_ADD_DEBUG_DATA	0x5
+#define DRM_XE_VM_BIND_OP_REMOVE_DEBUG_DATA	0x6
 	/** @op: Bind operation to perform */
 	__u32 op;
 
diff --git a/lib/xe/xe_eudebug.c b/lib/xe/xe_eudebug.c
index 2f2e82a65c..7c4ef80e4c 100644
--- a/lib/xe/xe_eudebug.c
+++ b/lib/xe/xe_eudebug.c
@@ -2164,23 +2164,22 @@ static int  __xe_eudebug_client_vm_bind(struct xe_eudebug_client *c,
 					uint8_t pat_index, uint64_t op_ext)
 {
 	const bool ufence = has_user_fence(sync, num_syncs);
-	const uint32_t bind_flags = ufence ?
-		DRM_XE_EUDEBUG_EVENT_VM_BIND_FLAG_UFENCE : 0;
+	const uint32_t bind_flags = ufence ? DRM_XE_EUDEBUG_EVENT_VM_BIND_FLAG_UFENCE : 0;
 	uint64_t seqno = 0, op_seqno = 0;
 	uint32_t bind_base_flags = 0;
+	struct drm_xe_vm_bind_op_ext_debug_data *ext;
 	int ret;
 
 	switch (op) {
-	case DRM_XE_VM_BIND_OP_MAP:
+	case DRM_XE_VM_BIND_OP_ADD_DEBUG_DATA:
 		bind_base_flags = DRM_XE_EUDEBUG_EVENT_CREATE;
 		break;
-	case DRM_XE_VM_BIND_OP_UNMAP:
+	case DRM_XE_VM_BIND_OP_REMOVE_DEBUG_DATA:
 		bind_base_flags = DRM_XE_EUDEBUG_EVENT_DESTROY;
 		igt_assert_eq(ufence, false);
 		break;
 	default:
-		/* XXX unmap all? */
-		igt_assert(op);
+		/* Wrapper used for VM_BIND_OP that we are not tracking */
 		break;
 	}
 
@@ -2192,12 +2191,15 @@ static int  __xe_eudebug_client_vm_bind(struct xe_eudebug_client *c,
 		return ret;
 
 	if (!bind_base_flags)
-		return -EINVAL;
+		return 0; /* No events to log */
 
+	igt_assert(op_ext);
+
+	ext = from_user_pointer(op_ext);
 	xe_eudebug_client_vm_bind_event(c, DRM_XE_EUDEBUG_EVENT_STATE_CHANGE,
 					vm, bind_flags, 1, &seqno);
 	xe_eudebug_client_vm_bind_op_event(c, bind_base_flags,
-					   seqno, &op_seqno, addr, size, 0);
+					   seqno, &op_seqno, ext->addr, ext->range, 0);
 
 	if (ufence)
 		xe_eudebug_client_vm_bind_ufence_event(c, DRM_XE_EUDEBUG_EVENT_CREATE |
@@ -2321,6 +2323,275 @@ void xe_eudebug_client_vm_unbind(struct xe_eudebug_client *c, uint32_t vm,
 					  flags, sync, num_syncs);
 }
 
+/**
+ * xe_eudebug_client_vm_bind_debug_data_add
+ * @c: pointer to xe_eudebug_client structure
+ * @vm: vm handle
+ * @offset: offset into the debug data file
+ * @addr: ppgtt address
+ * @range: size of the binding
+ * @pseudopath: pseudopath of the metadata
+ * @path: path of the metadata file
+ * @sync: sync objects
+ * @num_syncs: number of sync objects
+ *
+ * Calls xe vm_bind ioctl and logs the corresponding event in client's event log.
+ */
+void xe_eudebug_client_vm_bind_debug_data_add(struct xe_eudebug_client *c, uint32_t vm,
+					      uint32_t offset, uint64_t addr, uint64_t range,
+					      uint64_t pseudopath, char *path,
+					      struct drm_xe_sync *sync, uint32_t num_syncs)
+{
+	struct drm_xe_vm_bind_op_ext_debug_data op_ext = { 0, };
+
+	igt_assert(!pseudopath || !path);
+
+	op_ext.base.name = XE_VM_BIND_OP_EXTENSIONS_DEBUG_DATA;
+	op_ext.base.next_extension = 0;
+	op_ext.base.pad = 0;
+
+	if (path) {
+		strncpy(op_ext.pathname, path, PATH_MAX - 1);
+		op_ext.flags = 0;
+	} else {
+		op_ext.pseudopath = pseudopath;
+		op_ext.flags = DRM_XE_VM_BIND_DEBUG_DATA_FLAG_PSEUDO;
+	}
+
+	op_ext.addr = addr;
+	op_ext.range = range;
+	op_ext.offset = offset;
+
+	_xe_eudebug_client_vm_bind(c, vm, 0, 0, 0, 0,
+				   DRM_XE_VM_BIND_OP_ADD_DEBUG_DATA, 0,
+				   sync, num_syncs, to_user_pointer(&op_ext));
+}
+
+/**
+ * xe_eudebug_client_vm_bind_debug_data_remove
+ * @c: pointer to xe_eudebug_client structure
+ * @vm: vm handle
+ * @addr: ppgtt address
+ * @range: size of the binding
+ *
+ * Calls xe vm_bind ioctl and logs the corresponding event in client's event log.
+ */
+void xe_eudebug_client_vm_bind_debug_data_remove(struct xe_eudebug_client *c, uint32_t vm,
+						 uint64_t addr, uint64_t range)
+{
+	struct drm_xe_vm_bind_op_ext_debug_data op_ext = { 0, };
+
+	op_ext.base.name = XE_VM_BIND_OP_EXTENSIONS_DEBUG_DATA;
+	op_ext.base.next_extension = 0;
+	op_ext.base.pad = 0;
+
+	op_ext.addr = addr;
+	op_ext.range = range;
+
+	_xe_eudebug_client_vm_bind(c, vm, 0, 0, 0, 0,
+				   DRM_XE_VM_BIND_OP_REMOVE_DEBUG_DATA, 0,
+				   NULL, 0, to_user_pointer(&op_ext));
+}
+
+/**
+ * xe_eudebug_client_vm_bind_array
+ * @c: pointer to xe_eudebug_client structure
+ * @vm: vm handle
+ * @exec_queue: exec queue handle
+ * @bind_ops: array of vm bind operations
+ * @num_binds: number of bind operations
+ * @sync: sync objects
+ * @num_syncs: number of sync objects
+ *
+ * Wrapper for xe vm_bind_array ioctl. Logs the relevant events (EVENT_VM_BIND,
+ * EVENT_VM_BIND_OP_DEBUG_DATA if debug data ops are present and EVENT_VM_BIND_UFENCE if debug data
+ * ops are present and ufence is provided) in client's event log.
+ */
+void xe_eudebug_client_vm_bind_array(struct xe_eudebug_client *c,
+				     uint32_t vm, uint32_t exec_queue,
+				     struct drm_xe_vm_bind_op *bind_ops,
+				     uint32_t num_binds, struct drm_xe_sync *sync,
+				     uint32_t num_syncs)
+{
+	uint64_t bind_seqno = 0, bind_op_seqno = 0;
+	bool ufence = has_user_fence(sync, num_syncs);
+	uint32_t event_flags = 0;
+	int dd_binds = 0;
+
+	xe_vm_bind_array(c->fd, vm, 0, bind_ops, num_binds, sync, num_syncs);
+
+	for (int i = 0; i < num_binds; i++)
+		if (bind_ops[i].op == DRM_XE_VM_BIND_OP_ADD_DEBUG_DATA ||
+		    bind_ops[i].op == DRM_XE_VM_BIND_OP_REMOVE_DEBUG_DATA)
+			dd_binds++;
+
+	if (!dd_binds)
+		return; /* No debug data ops, no events to log */
+
+	xe_eudebug_client_vm_bind_event(c, DRM_XE_EUDEBUG_EVENT_STATE_CHANGE,
+					vm, ufence ? DRM_XE_EUDEBUG_EVENT_VM_BIND_FLAG_UFENCE : 0,
+					dd_binds, &bind_seqno);
+
+	for (int i = 0; i < num_binds; i++) {
+		struct drm_xe_vm_bind_op_ext_debug_data *ext_dd = NULL;
+		struct drm_xe_user_extension *ext = NULL;
+		int ext_count = 0;
+
+		if (bind_ops[i].op != DRM_XE_VM_BIND_OP_ADD_DEBUG_DATA &&
+		    bind_ops[i].op != DRM_XE_VM_BIND_OP_REMOVE_DEBUG_DATA)
+		    continue;
+
+		ext = from_user_pointer(bind_ops[i].extensions);
+		while (ext) {
+			if (ext->name == XE_VM_BIND_OP_EXTENSIONS_DEBUG_DATA)
+				ext_dd = igt_container_of(ext, ext_dd, base);
+			ext_count++;
+			ext = from_user_pointer(ext->next_extension);
+		}
+
+		igt_assert(ext_dd);
+		event_flags = (bind_ops[i].op == DRM_XE_VM_BIND_OP_ADD_DEBUG_DATA) ?
+			      DRM_XE_EUDEBUG_EVENT_CREATE : DRM_XE_EUDEBUG_EVENT_DESTROY;
+		xe_eudebug_client_vm_bind_op_event(c, event_flags,
+						   bind_seqno,
+						   &bind_op_seqno,
+						   ext_dd->addr,
+						   ext_dd->range,
+						   0); // XXX: KMD always sets num_extensions to 0?
+	}
+
+	if (ufence)
+		xe_eudebug_client_vm_bind_ufence_event(c, DRM_XE_EUDEBUG_EVENT_CREATE |
+						       DRM_XE_EUDEBUG_EVENT_NEED_ACK,
+						       bind_seqno);
+}
+
+/**
+ * xe_eudebug_client_vm_bind_map_with_debug_data
+ * @c: pointer to xe_eudebug_client structure
+ * @vm: vm handle
+ * @addr: ppgtt address to map to
+ * @range: size of the binding
+ * @bo: buffer object handle
+ * @bo_offset: offset within the buffer object
+ * @path: path of the metadata file
+ * @pseudopath: pseudopath of the metadata
+ * @offset: offset into the debug data file
+ * @sync: sync objects
+ * @num_syncs: number of sync objects
+ *
+ * Calls xe vm_bind_array ioctl with two ops: OP_MAP and OP_ADD_DEBUG_DATA. Logs the corresponding
+ * events (EVENT_VM_BIND, EVENT_VM_BIND_OP_DEBUG_DATA and if ufence provided, EVENT_VM_BIND_UFENCE)
+ * in client's event log.
+ */
+void xe_eudebug_client_vm_bind_map_with_debug_data(struct xe_eudebug_client *c, uint32_t vm,
+						   uint64_t addr, uint64_t range,
+						   uint32_t bo, uint64_t bo_offset,
+						   char *path, uint64_t pseudopath, uint32_t offset,
+						   struct drm_xe_sync *sync, uint32_t num_syncs)
+{
+	struct drm_xe_vm_bind_op_ext_debug_data op_ext = { 0, };
+	struct drm_xe_vm_bind_op *bind_ops, *op;
+	const int bind_cnt = 2;
+
+	igt_assert(!path || !pseudopath);
+
+	bind_ops = calloc(bind_cnt, sizeof(*bind_ops));
+
+	/* prepare map op */
+	op = &bind_ops[0];
+	op->extensions = 0;
+	op->obj = bo;
+	op->obj_offset = bo_offset;
+	op->range = range;
+	op->addr = addr;
+	op->op = DRM_XE_VM_BIND_OP_MAP;
+	op->flags = 0;
+	op->prefetch_mem_region_instance = 0;
+	op->pat_index = intel_get_pat_idx_wb(c->fd);
+
+	/* prepare debug data op */
+	op_ext.base.name = XE_VM_BIND_OP_EXTENSIONS_DEBUG_DATA;
+	op_ext.base.next_extension = 0;
+	op_ext.base.pad = 0;
+
+	if (path) {
+		strncpy(op_ext.pathname, path, PATH_MAX - 1);
+		op_ext.flags = 0;
+	} else {
+		op_ext.pseudopath = pseudopath;
+		op_ext.flags = DRM_XE_VM_BIND_DEBUG_DATA_FLAG_PSEUDO;
+	}
+
+	op_ext.addr = addr;
+	op_ext.range = range;
+	op_ext.offset = offset;
+
+	op = &bind_ops[1];
+	op->extensions = to_user_pointer(&op_ext);
+	op->obj = 0;
+	op->obj_offset = 0;
+	op->range = 0;
+	op->addr = 0;
+	op->op = DRM_XE_VM_BIND_OP_ADD_DEBUG_DATA;
+	op->flags = 0;
+	op->prefetch_mem_region_instance = 0;
+	op->pat_index = intel_get_pat_idx_wb(c->fd);
+
+	xe_eudebug_client_vm_bind_array(c, vm, 0, bind_ops, 2, sync, num_syncs);
+}
+
+/**
+ * xe_eudebug_client_vm_bind_unmap_with_debug_data
+ * @c: pointer to xe_eudebug_client structure
+ * @vm: vm handle
+ * @addr: ppgtt address to unmap
+ * @range: size of the binding
+ *
+ * Calls xe vm_bind_array ioctl with two ops: OP_UNMAP and OP_REMOVE_DEBUG_DATA. Logs
+ * the corresponding events (EVENT_VM_BIND and EVENT_VM_BIND_OP_DEBUG_DATA) in client's event log.
+ */
+void xe_eudebug_client_vm_bind_unmap_with_debug_data(struct xe_eudebug_client *c, uint32_t vm,
+						     uint64_t addr, uint64_t range)
+{
+	struct drm_xe_vm_bind_op_ext_debug_data op_ext = { 0, };
+	struct drm_xe_vm_bind_op *bind_ops, *op;
+	const int bind_cnt = 2;
+
+	bind_ops = calloc(bind_cnt, sizeof(*bind_ops));
+
+	/* prepare unmap op */
+	op = &bind_ops[0];
+	op->extensions = 0;
+	op->range = range;
+	op->addr = addr;
+	op->op = DRM_XE_VM_BIND_OP_UNMAP;
+	op->flags = 0;
+	op->prefetch_mem_region_instance = 0;
+	op->pat_index = intel_get_pat_idx_wb(c->fd);
+
+	/* prepare debug data op */
+	op_ext.base.name = XE_VM_BIND_OP_EXTENSIONS_DEBUG_DATA;
+	op_ext.base.next_extension = 0;
+	op_ext.base.pad = 0;
+
+	op_ext.addr = addr;
+	op_ext.range = range;
+
+	op = &bind_ops[1];
+	op->extensions = to_user_pointer(&op_ext),
+		op->obj = 0,
+		op->obj_offset = 0,
+		op->range = 0,
+		op->addr = 0,
+		op->op = DRM_XE_VM_BIND_OP_REMOVE_DEBUG_DATA,
+		op->flags = 0,
+		op->prefetch_mem_region_instance = 0,
+		op->pat_index = intel_get_pat_idx_wb(c->fd);
+
+	xe_eudebug_client_vm_bind_array(c, vm, 0, bind_ops, 2, NULL, 0);
+}
+
 void xe_eudebug_ack_ufence(int debugfd,
 			   const struct drm_xe_eudebug_event_vm_bind_ufence *f)
 {
diff --git a/lib/xe/xe_eudebug.h b/lib/xe/xe_eudebug.h
index ea7b320a27..a53bd99dc0 100644
--- a/lib/xe/xe_eudebug.h
+++ b/lib/xe/xe_eudebug.h
@@ -255,6 +255,26 @@ void xe_eudebug_client_vm_unbind_flags(struct xe_eudebug_client *c,
 void xe_eudebug_client_vm_unbind(struct xe_eudebug_client *c, uint32_t vm,
 				 uint64_t offset, uint64_t addr, uint64_t size);
 
+void xe_eudebug_client_vm_bind_debug_data_add(struct xe_eudebug_client *c, uint32_t vm,
+					      uint32_t offset, uint64_t addr, uint64_t range,
+					      uint64_t pseudopath, char *path,
+					      struct drm_xe_sync *sync, uint32_t num_syncs);
+void xe_eudebug_client_vm_bind_debug_data_remove(struct xe_eudebug_client *c, uint32_t vm,
+						 uint64_t addr, uint64_t range);
+
+void xe_eudebug_client_vm_bind_array(struct xe_eudebug_client *c,
+				     uint32_t vm, uint32_t exec_queue,
+				     struct drm_xe_vm_bind_op *bind_ops,
+				     uint32_t num_binds, struct drm_xe_sync *sync,
+				     uint32_t num_syncs);
+void xe_eudebug_client_vm_bind_map_with_debug_data(struct xe_eudebug_client *c, uint32_t vm,
+						   uint64_t addr, uint64_t range,
+						   uint32_t bo, uint64_t bo_offset,
+						   char *path, uint64_t pseudopath, uint32_t offset,
+						   struct drm_xe_sync *sync, uint32_t num_syncs);
+void xe_eudebug_client_vm_bind_unmap_with_debug_data(struct xe_eudebug_client *c, uint32_t vm,
+						     uint64_t addr, uint64_t range);
+
 struct xe_eudebug_session *xe_eudebug_session_create(int fd,
 						     xe_eudebug_client_work_fn work,
 						     unsigned int flags,
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [PATCH i-g-t 11/21] tests/xe_eudebug: Adapt basic-vm-bind and remove basic-vm-bind-extended
  2026-01-12 12:59 [PATCH i-g-t 00/21] eudebug: uapi changes on connect and metadata Mika Kuoppala
                   ` (9 preceding siblings ...)
  2026-01-12 12:59 ` [PATCH i-g-t 10/21] lib/xe_eudebug: Adapt to vm_bind debug data Mika Kuoppala
@ 2026-01-12 12:59 ` Mika Kuoppala
  2026-01-12 12:59 ` [PATCH i-g-t 12/21] tests/xe_eudebug: Adapt some ufence reliant tests to new vm_bind event interface Mika Kuoppala
                   ` (9 subsequent siblings)
  20 siblings, 0 replies; 23+ messages in thread
From: Mika Kuoppala @ 2026-01-12 12:59 UTC (permalink / raw)
  To: igt-dev
  Cc: christoph.manszewski, dominik.karol.piatkowski, maciej.patelczyk,
	jan.maslak, zbigniew.kempczynski, Mika Kuoppala

From: Christoph Manszewski <christoph.manszewski@intel.com>

EU debug no longer relays events for VM_BIND_OP_[MAP|UNMAP] operations.
Instead it reports newly added 'VM_BIND_OP_DEBUG_DATA_[ADD|REMOVE]'
operations through the event interface. Convert the basic-vm-bind
subtest to use these newly introduced ops. Because debug data can't be
rebound and partially unbound, remove the basic-vm-bind-extended
subtest.

Signed-off-by: Christoph Manszewski <christoph.manszewski@intel.com>
Signed-off-by: Mika Kuoppala <mika.kuoppala@linux.intel.com>
---
 tests/intel/xe_eudebug.c | 154 ++++++++++-----------------------------
 1 file changed, 39 insertions(+), 115 deletions(-)

diff --git a/tests/intel/xe_eudebug.c b/tests/intel/xe_eudebug.c
index 353828f673..e9efb47da8 100644
--- a/tests/intel/xe_eudebug.c
+++ b/tests/intel/xe_eudebug.c
@@ -60,11 +60,10 @@ static void test_sysfs_toggle(int fd)
 #define CREATE_EXEC_QUEUES		(1 << 2)
 #define VM_BIND				(1 << 3)
 #define VM_BIND_VM_DESTROY		(1 << 4)
-#define VM_BIND_EXTENDED		(1 << 5)
-#define VM_BIND_OP_MAP_USERPTR		(1 << 6)
-#define VM_BIND_DELAY_UFENCE_ACK	(1 << 7)
-#define VM_BIND_UFENCE_DISCONNECT	(1 << 8)
-#define VM_BIND_UFENCE_SIGINT_CLIENT	(1 << 9)
+#define VM_BIND_OP_MAP_USERPTR		(1 << 5)
+#define VM_BIND_DELAY_UFENCE_ACK	(1 << 6)
+#define VM_BIND_UFENCE_DISCONNECT	(1 << 7)
+#define VM_BIND_UFENCE_SIGINT_CLIENT	(1 << 8)
 #define TEST_FAULTABLE			(1 << 30)
 #define TEST_DISCOVERY			(1 << 31)
 
@@ -74,41 +73,58 @@ static void test_sysfs_toggle(int fd)
 
 static void basic_vm_bind_client(struct xe_eudebug_client *c)
 {
-	struct drm_xe_vm_bind_op_ext_attach_debug *ext = NULL;
 	uint32_t vm = xe_eudebug_client_vm_create(c, DRM_XE_VM_CREATE_FLAG_LR_MODE, 0);
-	size_t bo_size = xe_get_default_alignment(c->fd);
 	bool test_discovery = c->flags & TEST_DISCOVERY;
-	uint32_t bo = xe_bo_create(c->fd, 0, bo_size,
-				   system_memory(c->fd), 0);
 	uint64_t addr = 0x1a0000;
+	size_t range = 0x1000;
 
-	xe_eudebug_client_vm_bind_flags(c, vm, bo, 0, addr,
-					bo_size, 0, NULL, 0, to_user_pointer(ext));
+	xe_eudebug_client_vm_bind_debug_data_add(c, vm, 0, addr, range,
+						 DRM_XE_VM_BIND_DEBUG_DATA_PSEUDO_MODULE_AREA,
+						 NULL, NULL, 0);
 
 	if (test_discovery) {
 		xe_eudebug_client_signal_stage(c, STAGE_PRE_DEBUG_RESOURCES_DONE);
 		xe_eudebug_client_wait_stage(c, STAGE_DISCOVERY_DONE);
 	}
 
-	xe_eudebug_client_vm_unbind(c, vm, 0, addr, bo_size);
+	xe_eudebug_client_vm_bind_debug_data_remove(c, vm, addr, range);
 
-	gem_close(c->fd, bo);
 	xe_eudebug_client_vm_destroy(c, vm);
 }
 
+static void vm_bind_add_debug_data(struct xe_eudebug_client *c, uint32_t vm,
+				   uint64_t addr, uint64_t range)
+{
+	struct drm_xe_vm_bind_op_ext_debug_data op_ext = { 0, };
+
+	op_ext.base.name = XE_VM_BIND_OP_EXTENSIONS_DEBUG_DATA;
+	op_ext.base.next_extension = 0;
+	op_ext.base.pad = 0;
+
+	op_ext.pseudopath = DRM_XE_VM_BIND_DEBUG_DATA_PSEUDO_MODULE_AREA;
+	op_ext.flags = DRM_XE_VM_BIND_DEBUG_DATA_FLAG_PSEUDO;
+
+	op_ext.addr = addr;
+	op_ext.range = range;
+	op_ext.offset = 0;
+	op_ext.reserved = 0;
+
+	___xe_vm_bind(c->fd, vm, 0, 0, 0, 0, 0,
+		      DRM_XE_VM_BIND_OP_ADD_DEBUG_DATA, 0, NULL, 0, 0,
+		      0, 0, to_user_pointer(&op_ext));
+}
+
 static void basic_vm_bind_vm_destroy_client(struct xe_eudebug_client *c)
 {
 	uint32_t vm = xe_eudebug_client_vm_create(c, DRM_XE_VM_CREATE_FLAG_LR_MODE, 0);
-	size_t bo_size = xe_get_default_alignment(c->fd);
 	bool test_discovery = c->flags & TEST_DISCOVERY;
-	uint32_t bo = xe_bo_create(c->fd, 0, bo_size,
-				   system_memory(c->fd), 0);
 	uint64_t addr = 0x1a0000;
+	uint64_t range = 0x1000;
 
 	if (test_discovery) {
 		vm = xe_vm_create(c->fd, DRM_XE_VM_CREATE_FLAG_LR_MODE, 0);
 
-		xe_vm_bind_async(c->fd, vm, 0, bo, 0, addr, bo_size, NULL, 0);
+		vm_bind_add_debug_data(c, vm, addr, range);
 
 		xe_vm_destroy(c->fd, vm);
 
@@ -116,11 +132,11 @@ static void basic_vm_bind_vm_destroy_client(struct xe_eudebug_client *c)
 		xe_eudebug_client_wait_stage(c, STAGE_DISCOVERY_DONE);
 	} else {
 		vm = xe_eudebug_client_vm_create(c, DRM_XE_VM_CREATE_FLAG_LR_MODE, 0);
-		xe_eudebug_client_vm_bind(c, vm, bo, 0, addr, bo_size);
+		xe_eudebug_client_vm_bind_debug_data_add(c, vm, 0, addr, range,
+							 DRM_XE_VM_BIND_DEBUG_DATA_PSEUDO_MODULE_AREA,
+							 NULL, NULL, 0);
 		xe_eudebug_client_vm_destroy(c, vm);
 	}
-
-	gem_close(c->fd, bo);
 }
 
 #define BO_ITEMS 4096
@@ -307,75 +323,6 @@ static void free_bind_list(struct xe_eudebug_client *c, struct bind_list *bl)
 	free(bl);
 }
 
-static void vm_bind_client(struct xe_eudebug_client *c)
-{
-	uint64_t op_ref_seqno, ref_seqno;
-	struct bind_list *bl;
-	bool test_discovery = c->flags & TEST_DISCOVERY;
-	size_t bo_size = 3 * xe_get_default_alignment(c->fd);
-	uint32_t bo[2] = {
-		xe_bo_create(c->fd, 0, bo_size, system_memory(c->fd), 0),
-		xe_bo_create(c->fd, 0, bo_size, system_memory(c->fd), 0),
-	};
-	uint32_t vm = xe_eudebug_client_vm_create(c, DRM_XE_VM_CREATE_FLAG_LR_MODE, 0);
-	uint64_t addr[] = {0x2a0000, 0x3a0000};
-	uint64_t rebind_bo_offset = 2 * bo_size / 3;
-	uint64_t size = bo_size / 3;
-	int i = 0;
-
-	if (test_discovery) {
-		xe_vm_bind_async(c->fd, vm, 0, bo[0], 0, addr[0], bo_size, NULL, 0);
-
-		xe_vm_unbind_async(c->fd, vm, 0, 0, addr[0] + size, size, NULL, 0);
-
-		xe_vm_bind_async(c->fd, vm, 0, bo[1], 0, addr[1], bo_size, NULL, 0);
-
-		xe_vm_bind_async(c->fd, vm, 0, bo[1], rebind_bo_offset, addr[1], size, NULL, 0);
-
-		bl = create_bind_list(c->fd, system_memory(c->fd), vm, 4, 0);
-		xe_vm_bind_array(c->fd, bl->vm, 0, bl->bind_ops, bl->n, NULL, 0);
-
-		xe_vm_unbind_all_async(c->fd, vm, 0, bo[0], NULL, 0);
-
-		xe_eudebug_client_vm_bind_event(c, DRM_XE_EUDEBUG_EVENT_STATE_CHANGE,
-						bl->vm, 0, bl->n + 2, &ref_seqno);
-
-		xe_eudebug_client_vm_bind_op_event(c, DRM_XE_EUDEBUG_EVENT_CREATE, ref_seqno,
-						   &op_ref_seqno, addr[1], size, 0);
-		xe_eudebug_client_vm_bind_op_event(c, DRM_XE_EUDEBUG_EVENT_CREATE, ref_seqno,
-						   &op_ref_seqno, addr[1] + size, size * 2, 0);
-
-		for (i = 0; i < bl->n; i++)
-			xe_eudebug_client_vm_bind_op_event(c, DRM_XE_EUDEBUG_EVENT_CREATE,
-							   ref_seqno, &op_ref_seqno,
-							   bl->bind_ops[i].addr,
-							   bl->bind_ops[i].range, 0);
-
-		xe_eudebug_client_signal_stage(c, STAGE_PRE_DEBUG_RESOURCES_DONE);
-		xe_eudebug_client_wait_stage(c, STAGE_DISCOVERY_DONE);
-	} else {
-		xe_eudebug_client_vm_bind(c, vm, bo[0], 0, addr[0], bo_size);
-		xe_eudebug_client_vm_unbind(c, vm, 0, addr[0] + size, size);
-
-		xe_eudebug_client_vm_bind(c, vm, bo[1], 0, addr[1], bo_size);
-		xe_eudebug_client_vm_bind(c, vm, bo[1], rebind_bo_offset, addr[1], size);
-
-		bl = create_bind_list(c->fd, system_memory(c->fd), vm, 4, 0);
-		do_bind_list(c, bl, false);
-	}
-
-	xe_vm_unbind_all_async(c->fd, vm, 0, bo[1], NULL, 0);
-
-	xe_eudebug_client_vm_bind_event(c, DRM_XE_EUDEBUG_EVENT_STATE_CHANGE, vm, 0,
-					1, &ref_seqno);
-	xe_eudebug_client_vm_bind_op_event(c, DRM_XE_EUDEBUG_EVENT_DESTROY, ref_seqno,
-					   &op_ref_seqno, 0, 0, 0);
-
-	gem_close(c->fd, bo[0]);
-	gem_close(c->fd, bo[1]);
-	xe_eudebug_client_vm_destroy(c, vm);
-}
-
 static void run_basic_client(struct xe_eudebug_client *c)
 {
 	int i;
@@ -432,9 +379,6 @@ static void run_basic_client(struct xe_eudebug_client *c)
 	if (c->flags & VM_BIND)
 		basic_vm_bind_client(c);
 
-	if (c->flags & VM_BIND_EXTENDED)
-		vm_bind_client(c);
-
 	if (c->flags & VM_BIND_VM_DESTROY)
 		basic_vm_bind_vm_destroy_client(c);
 }
@@ -891,20 +835,13 @@ static void test_read_event(int fd)
  * SUBTEST: basic-vm-bind
  * Functionality: VM bind event
  * Description:
- *	Attach the debugger to a process that performs synchronous vm bind
- *	and vm unbind.
+ *	Attach the debugger to a process that adds and removes vm debug data.
  *
  * SUBTEST: basic-vm-bind-vm-destroy
  * Functionality: VM bind event
  * Description:
- *	Attach the debugger to a process that performs vm bind, and destroys
- *	the vm without unbinding. Make sure that we don't get unbind events.
- *
- * SUBTEST: basic-vm-bind-extended
- * Functionality: VM bind event
- * Description:
- *	Attach the debugger to a process that performs bind, bind array, rebind,
- *	partial unbind, unbind and unbind all operations.
+ *	Attach the debugger to a process that adds vm debug data, and destroys the vm without
+ *	removing debug data. Make sure that we don't get debug data remove events.
  *
  * SUBTEST: multigpu-basic-client
  * Mega feature: MultiGPU
@@ -955,13 +892,6 @@ static void test_basic_sessions(int fd, unsigned int flags, int count, bool matc
  *	Attach the debugger to a process that performs vm bind, and destroys
  *	the vm without unbinding before attaching. Make sure that we don't get
  *	any bind/unbind and vm create/destroy events.
- *
- * SUBTEST: basic-vm-bind-extended-discovery
- * Functionality: VM bind event
- * Description:
- *	Attach the debugger to a process that performs bind, bind array, rebind,
- *	partial unbind, and unbind all operations before attaching. Ensure that
- *	we get a only a singe 'VM_BIND' event from the discovery worker.
  */
 static void test_basic_discovery(int fd, unsigned int flags, bool match_opposite)
 {
@@ -2661,12 +2591,6 @@ int igt_main()
 	igt_subtest("basic-vm-bind-vm-destroy-discovery")
 		test_basic_discovery(fd, VM_BIND_VM_DESTROY, false);
 
-	igt_subtest("basic-vm-bind-extended")
-		test_basic_sessions(fd, VM_BIND_EXTENDED, 1, true);
-
-	igt_subtest("basic-vm-bind-extended-discovery")
-		test_basic_discovery(fd, VM_BIND_EXTENDED, true);
-
 	igt_subtest("discovery-race")
 		test_race_discovery(fd, 0, 4);
 
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [PATCH i-g-t 12/21] tests/xe_eudebug: Adapt some ufence reliant tests to new vm_bind event interface
  2026-01-12 12:59 [PATCH i-g-t 00/21] eudebug: uapi changes on connect and metadata Mika Kuoppala
                   ` (10 preceding siblings ...)
  2026-01-12 12:59 ` [PATCH i-g-t 11/21] tests/xe_eudebug: Adapt basic-vm-bind and remove basic-vm-bind-extended Mika Kuoppala
@ 2026-01-12 12:59 ` Mika Kuoppala
  2026-01-12 12:59 ` [PATCH i-g-t 13/21] tests/xe_eudebug: Adapt vm-bind-clear* subtests to debug data Mika Kuoppala
                   ` (8 subsequent siblings)
  20 siblings, 0 replies; 23+ messages in thread
From: Mika Kuoppala @ 2026-01-12 12:59 UTC (permalink / raw)
  To: igt-dev
  Cc: christoph.manszewski, dominik.karol.piatkowski, maciej.patelczyk,
	jan.maslak, zbigniew.kempczynski, Mika Kuoppala

From: Christoph Manszewski <christoph.manszewski@intel.com>

EU debug no longer relays events for VM_BIND_OP_[MAP|UNMAP] operations,
this includes ufence events for binds that perorm only these operations.
Instead it reports newly added 'VM_BIND_OP_DEBUG_DATA_[ADD|REMOVE]'
operations through the event interface and ufence events if a ufence for
these operations was provided.

Perform neccessary debug data operations to enable the following subtests:
- basic-vm-bind-ufence*
- vma-ufence*
- basic-vm-acccess*

Signed-off-by: Christoph Manszewski <christoph.manszewski@intel.com>
Signed-off-by: Mika Kuoppala <mika.kuoppala@linux.intel.com>
---
 tests/intel/xe_eudebug.c | 96 +++++++++++++++++++++++++---------------
 1 file changed, 60 insertions(+), 36 deletions(-)

diff --git a/tests/intel/xe_eudebug.c b/tests/intel/xe_eudebug.c
index e9efb47da8..fed9a47405 100644
--- a/tests/intel/xe_eudebug.c
+++ b/tests/intel/xe_eudebug.c
@@ -236,27 +236,40 @@ static struct bind_list *create_bind_list(int fd, uint32_t bo_placement,
 	bl->vm = vm;
 	bl->bo = vm_create_objects(fd, bo_placement, vm, bo_size, n);
 	bl->n = n;
-	bl->bind_ops = calloc(n, sizeof(*bl->bind_ops));
+	bl->bind_ops = calloc(n * 2, sizeof(*bl->bind_ops));
 	igt_assert(bl->bind_ops);
 
 	for (i = 0; i < n; i++) {
-		struct drm_xe_vm_bind_op *o = &bl->bind_ops[i];
+		struct drm_xe_vm_bind_op *om = &bl->bind_ops[i * 2], *od = &bl->bind_ops[i * 2 + 1];
+		struct drm_xe_vm_bind_op_ext_debug_data *op_ext;
 
 		if (is_userptr) {
-			o->userptr = (uintptr_t)bl->bo[i].userptr;
-			o->op = DRM_XE_VM_BIND_OP_MAP_USERPTR;
+			om->userptr = (uintptr_t)bl->bo[i].userptr;
+			om->op = DRM_XE_VM_BIND_OP_MAP_USERPTR;
 		} else {
-			o->obj = bl->bo[i].fd;
-			o->op = DRM_XE_VM_BIND_OP_MAP;
+			om->obj = bl->bo[i].fd;
+			om->op = DRM_XE_VM_BIND_OP_MAP;
 		}
 
-		o->range = bo_size;
-		o->addr = BO_ADDR + 2 * i * bo_size;
-		o->pat_index = intel_get_pat_idx_wb(fd);
+		om->range = bo_size;
+		om->addr = BO_ADDR + 2 * i * bo_size;
+		om->pat_index = intel_get_pat_idx_wb(fd);
+
+		/* debug data */
+		op_ext = calloc(1, sizeof(*op_ext));
+		op_ext->base.name = XE_VM_BIND_OP_EXTENSIONS_DEBUG_DATA;
+		op_ext->flags = DRM_XE_VM_BIND_DEBUG_DATA_FLAG_PSEUDO;
+		op_ext->pseudopath = DRM_XE_VM_BIND_DEBUG_DATA_PSEUDO_MODULE_AREA;
+		op_ext->addr = om->addr;
+		op_ext->range = om->range;
+
+		od->extensions = to_user_pointer(op_ext);
+		od->op = DRM_XE_VM_BIND_OP_ADD_DEBUG_DATA;
+		od->pat_index = intel_get_pat_idx_wb(fd);
 	}
 
 	for (i = 0; i < bl->n; i++) {
-		struct drm_xe_vm_bind_op *o = &bl->bind_ops[i];
+		struct drm_xe_vm_bind_op *o = &bl->bind_ops[i * 2];
 
 		igt_debug("bo %d: addr 0x%llx, range 0x%llx\n", i, o->addr, o->range);
 		bo_prime(fd, o);
@@ -273,9 +286,7 @@ static void do_bind_list(struct xe_eudebug_client *c,
 		.flags = DRM_XE_SYNC_FLAG_SIGNAL,
 		.timeline_value = 1337,
 	};
-	uint64_t ref_seqno = 0, op_ref_seqno = 0;
 	uint64_t *fence_data;
-	int i;
 
 	if (sync) {
 		fence_data = aligned_alloc(xe_get_default_alignment(c->fd),
@@ -285,16 +296,8 @@ static void do_bind_list(struct xe_eudebug_client *c,
 		memset(fence_data, 0, sizeof(*fence_data));
 	}
 
-	xe_vm_bind_array(c->fd, bl->vm, 0, bl->bind_ops, bl->n, &uf_sync, sync ? 1 : 0);
-	xe_eudebug_client_vm_bind_event(c, DRM_XE_EUDEBUG_EVENT_STATE_CHANGE,
-					bl->vm, 0, bl->n, &ref_seqno);
-	for (i = 0; i < bl->n; i++)
-		xe_eudebug_client_vm_bind_op_event(c, DRM_XE_EUDEBUG_EVENT_CREATE,
-						   ref_seqno,
-						   &op_ref_seqno,
-						   bl->bind_ops[i].addr,
-						   bl->bind_ops[i].range,
-						   0);
+	xe_eudebug_client_vm_bind_array(c, bl->vm, 0, bl->bind_ops, bl->n * 2, &uf_sync,
+					sync ? 1 : 0);
 
 	if (sync) {
 		xe_wait_ufence(c->fd, fence_data, uf_sync.timeline_value, 0,
@@ -308,14 +311,33 @@ static void free_bind_list(struct xe_eudebug_client *c, struct bind_list *bl)
 	unsigned int i;
 
 	for (i = 0; i < bl->n; i++) {
-		igt_debug("%d: checking 0x%llx (%lld)\n",
-			  i, bl->bind_ops[i].addr, bl->bind_ops[i].addr);
-		bo_check(c->fd, &bl->bind_ops[i]);
-		if (bl->bind_ops[i].op == DRM_XE_VM_BIND_OP_MAP_USERPTR)
+		struct drm_xe_vm_bind_op *om = &bl->bind_ops[i * 2], *od = &bl->bind_ops[i * 2 + 1];
+		struct drm_xe_vm_bind_op_ext_debug_data *op_ext;
+		igt_debug("%d: checking 0x%llx (%lld)\n", i, om->addr, om->addr);
+
+		bo_check(c->fd, om);
+
+		om->op = DRM_XE_VM_BIND_OP_UNMAP;
+		om->obj = 0;
+		od->op = DRM_XE_VM_BIND_OP_REMOVE_DEBUG_DATA;
+
+		op_ext = from_user_pointer(od->extensions);
+		op_ext->offset = 0;
+		op_ext->flags = 0;
+		memset(op_ext->pathname, 0, sizeof(op_ext->pathname));
+	}
+
+	xe_eudebug_client_vm_bind_array(c, bl->vm, 0, bl->bind_ops, bl->n * 2, NULL, 0);
+
+	for (i = 0; i < bl->n; i++) {
+		struct drm_xe_vm_bind_op *om = &bl->bind_ops[i * 2], *od = &bl->bind_ops[i * 2 + 1];
+		struct drm_xe_vm_bind_op_ext_debug_data *op_ext;
+
+		if (om->op == DRM_XE_VM_BIND_OP_MAP_USERPTR)
 			free(bl->bo[i].userptr);
-		xe_eudebug_client_vm_unbind(c, bl->vm, 0,
-					    bl->bind_ops[i].addr,
-					    bl->bind_ops[i].range);
+
+		op_ext = from_user_pointer(od->extensions);
+		free(op_ext);
 	}
 
 	free(bl->bind_ops);
@@ -1353,7 +1375,7 @@ static void vm_access_client(struct xe_eudebug_client *c)
 		do_bind_list(c, bl, true);
 
 		for (i = 0; i < bl->n; i++)
-			xe_eudebug_client_wait_stage(c, bl->bind_ops[i].addr);
+			xe_eudebug_client_wait_stage(c, bl->bind_ops[i * 2].addr);
 
 		free_bind_list(c, bl);
 	}
@@ -1734,8 +1756,9 @@ static void basic_ufence_client(struct xe_eudebug_client *c)
 	for (int i = 0; i < n; i++) {
 		struct ufence_bind *b = &binds[i];
 
-		xe_eudebug_client_vm_bind_flags(c, vm, bo, 0, b->addr, b->range, 0,
-						&b->f, 1, 0);
+		xe_eudebug_client_vm_bind_map_with_debug_data(c, vm, b->addr, b->range, bo, 0, NULL,
+							      DRM_XE_VM_BIND_DEBUG_DATA_PSEUDO_MODULE_AREA,
+							      0, &b->f, 1);
 	}
 
 	client_wait_ufences(c, binds, n);
@@ -1743,7 +1766,7 @@ static void basic_ufence_client(struct xe_eudebug_client *c)
 	for (int i = 0; i < n; i++) {
 		struct ufence_bind *b = &binds[i];
 
-		xe_eudebug_client_vm_unbind(c, vm, 0, b->addr, b->range);
+		xe_eudebug_client_vm_bind_unmap_with_debug_data(c, vm, b->addr, b->range);
 	}
 
 	destroy_binds_with_ufence(binds, n);
@@ -2231,8 +2254,9 @@ static void vma_ufence_client(struct xe_eudebug_client *c)
 	for (int i = 0; i < n; i++) {
 		struct ufence_bind *b = &binds[i];
 
-		xe_eudebug_client_vm_bind_flags(c, vm, bo[i], 0, b->addr, b->range, 0,
-						&b->f, 1, 0);
+		xe_eudebug_client_vm_bind_map_with_debug_data(c, vm, b->addr, b->range, bo[i], 0, NULL,
+							      DRM_XE_VM_BIND_DEBUG_DATA_PSEUDO_MODULE_AREA,
+							      0, &b->f, 1);
 	}
 
 	/* Wait for acks on ufences */
@@ -2256,7 +2280,7 @@ static void vma_ufence_client(struct xe_eudebug_client *c)
 	for (int i = 0; i < n; i++) {
 		struct ufence_bind *b = &binds[i];
 
-		xe_eudebug_client_vm_unbind(c, vm, 0, b->addr, b->range);
+		xe_eudebug_client_vm_bind_unmap_with_debug_data(c, vm, b->addr, b->range);
 	}
 
 	destroy_binds_with_ufence(binds, n);
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [PATCH i-g-t 13/21] tests/xe_eudebug: Adapt vm-bind-clear* subtests to debug data
  2026-01-12 12:59 [PATCH i-g-t 00/21] eudebug: uapi changes on connect and metadata Mika Kuoppala
                   ` (11 preceding siblings ...)
  2026-01-12 12:59 ` [PATCH i-g-t 12/21] tests/xe_eudebug: Adapt some ufence reliant tests to new vm_bind event interface Mika Kuoppala
@ 2026-01-12 12:59 ` Mika Kuoppala
  2026-01-12 13:00 ` [PATCH i-g-t 14/21] lib/xe_eudebug: Remove unused xe_eudebug_client_vm_bind wrappers Mika Kuoppala
                   ` (7 subsequent siblings)
  20 siblings, 0 replies; 23+ messages in thread
From: Mika Kuoppala @ 2026-01-12 12:59 UTC (permalink / raw)
  To: igt-dev
  Cc: christoph.manszewski, dominik.karol.piatkowski, maciej.patelczyk,
	jan.maslak, zbigniew.kempczynski, Mika Kuoppala

From: Christoph Manszewski <christoph.manszewski@intel.com>

EU debug no longer relays events for VM_BIND_OP_[MAP|UNMAP] operations.
Instead it reports newly added 'VM_BIND_OP_DEBUG_DATA_[ADD|REMOVE]'
operations through the event interface. Convert the vm-bind-clear*
subtests by appending the newly added ops to each regular map/unmap
operation.

Signed-off-by: Christoph Manszewski <christoph.manszewski@intel.com>
Signed-off-by: Mika Kuoppala <mika.kuoppala@linux.intel.com>
---
 tests/intel/xe_eudebug.c | 16 ++++++++++------
 1 file changed, 10 insertions(+), 6 deletions(-)

diff --git a/tests/intel/xe_eudebug.c b/tests/intel/xe_eudebug.c
index fed9a47405..3cd1f61f7b 100644
--- a/tests/intel/xe_eudebug.c
+++ b/tests/intel/xe_eudebug.c
@@ -2030,8 +2030,10 @@ static void *vm_bind_clear_thread(void *data)
 		clean_bo = xe_bo_create(c->fd, vm, bo_size, priv->region,
 					DRM_XE_GEM_CREATE_FLAG_NEEDS_VISIBLE_VRAM);
 		memset(fence_data, 0, sizeof(*fence_data));
-		xe_eudebug_client_vm_bind_flags(c, vm, clean_bo, 0, clean_offset, bo_size,
-						0, &uf_sync, 1, 0);
+		xe_eudebug_client_vm_bind_map_with_debug_data(c, vm, clean_offset, bo_size,
+							      clean_bo, 0, NULL,
+							      DRM_XE_VM_BIND_DEBUG_DATA_PSEUDO_MODULE_AREA,
+							      0, &uf_sync, 1);
 		xe_wait_ufence(c->fd, fence_data, uf_sync.timeline_value, 0,
 			       XE_EUDEBUG_DEFAULT_TIMEOUT_SEC * NSEC_PER_SEC);
 
@@ -2039,8 +2041,10 @@ static void *vm_bind_clear_thread(void *data)
 		batch_bo = xe_bo_create(c->fd, vm, bo_size, priv->region,
 					DRM_XE_GEM_CREATE_FLAG_NEEDS_VISIBLE_VRAM);
 		memset(fence_data, 0, sizeof(*fence_data));
-		xe_eudebug_client_vm_bind_flags(c, vm, batch_bo, 0, batch_offset, bo_size,
-						0, &uf_sync, 1, 0);
+		xe_eudebug_client_vm_bind_map_with_debug_data(c, vm, batch_offset, bo_size,
+							      batch_bo, 0, NULL,
+							      DRM_XE_VM_BIND_DEBUG_DATA_PSEUDO_MODULE_AREA,
+							      0, &uf_sync, 1);
 		xe_wait_ufence(c->fd, fence_data, uf_sync.timeline_value, 0,
 			       XE_EUDEBUG_DEFAULT_TIMEOUT_SEC * NSEC_PER_SEC);
 
@@ -2077,10 +2081,10 @@ static void *vm_bind_clear_thread(void *data)
 		xe_eudebug_client_exec_queue_destroy(c, &eq_create);
 		munmap(map, bo_size);
 
-		xe_eudebug_client_vm_unbind(c, vm, 0, batch_offset, bo_size);
+		xe_eudebug_client_vm_bind_unmap_with_debug_data(c, vm, batch_offset, bo_size);
 		gem_close(c->fd, batch_bo);
 
-		xe_eudebug_client_vm_unbind(c, vm, 0, clean_offset, bo_size);
+		xe_eudebug_client_vm_bind_unmap_with_debug_data(c, vm, clean_offset, bo_size);
 		gem_close(c->fd, clean_bo);
 
 		count++;
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [PATCH i-g-t 14/21] lib/xe_eudebug: Remove unused xe_eudebug_client_vm_bind wrappers
  2026-01-12 12:59 [PATCH i-g-t 00/21] eudebug: uapi changes on connect and metadata Mika Kuoppala
                   ` (12 preceding siblings ...)
  2026-01-12 12:59 ` [PATCH i-g-t 13/21] tests/xe_eudebug: Adapt vm-bind-clear* subtests to debug data Mika Kuoppala
@ 2026-01-12 13:00 ` Mika Kuoppala
  2026-01-12 13:00 ` [PATCH i-g-t 15/21] tests/xe_eudebug: Add vm-bind-debug-data-ufence subtest Mika Kuoppala
                   ` (6 subsequent siblings)
  20 siblings, 0 replies; 23+ messages in thread
From: Mika Kuoppala @ 2026-01-12 13:00 UTC (permalink / raw)
  To: igt-dev
  Cc: christoph.manszewski, dominik.karol.piatkowski, maciej.patelczyk,
	jan.maslak, zbigniew.kempczynski, Mika Kuoppala

From: Christoph Manszewski <christoph.manszewski@intel.com>

EU debug no longer relays events for VM_BIND_OP_[MAP|UNMAP] operations.
Remove the old xe_eudebug_client_vm_bind wrappers that were supposed to
track these events in the client (test) side log.

v2: discovery vm bind makes no sense in current form (Mika)

Signed-off-by: Christoph Manszewski <christoph.manszewski@intel.com>
Signed-off-by: Mika Kuoppala <mika.kuoppala@linux.intel.com>
---
 lib/xe/xe_eudebug.c      | 96 ----------------------------------------
 lib/xe/xe_eudebug.h      | 15 -------
 tests/intel/xe_eudebug.c | 10 -----
 3 files changed, 121 deletions(-)

diff --git a/lib/xe/xe_eudebug.c b/lib/xe/xe_eudebug.c
index 7c4ef80e4c..1774e01f6f 100644
--- a/lib/xe/xe_eudebug.c
+++ b/lib/xe/xe_eudebug.c
@@ -2227,102 +2227,6 @@ static void _xe_eudebug_client_vm_bind(struct xe_eudebug_client *c,
 		      0);
 }
 
-/**
- * xe_eudebug_client_vm_bind_flags
- * @c: pointer to xe_eudebug_client structure
- * @vm: vm handle
- * @bo: buffer object handle
- * @offset: offset within buffer object
- * @addr: ppgtt address
- * @size: size of the binding
- * @flags: vm_bind flags
- * @sync: sync objects
- * @num_syncs: number of sync objects
- * @op_ext: BIND_OP extensions
- *
- * Calls xe vm_bind ioctl and logs the corresponding event in client's event log.
- */
-void xe_eudebug_client_vm_bind_flags(struct xe_eudebug_client *c, uint32_t vm,
-				     uint32_t bo, uint64_t offset,
-				     uint64_t addr, uint64_t size, uint32_t flags,
-				     struct drm_xe_sync *sync, uint32_t num_syncs,
-				     uint64_t op_ext)
-{
-	igt_assert(c);
-	_xe_eudebug_client_vm_bind(c, vm, bo, offset, addr, size,
-				   DRM_XE_VM_BIND_OP_MAP, flags,
-				   sync, num_syncs, op_ext);
-}
-
-/**
- * xe_eudebug_client_vm_bind
- * @c: pointer to xe_eudebug_client structure
- * @vm: vm handle
- * @bo: buffer object handle
- * @offset: offset within buffer object
- * @addr: ppgtt address
- * @size: size of the binding
- *
- * Calls xe vm_bind ioctl and logs the corresponding event in client's event log.
- */
-void xe_eudebug_client_vm_bind(struct xe_eudebug_client *c, uint32_t vm,
-			       uint32_t bo, uint64_t offset,
-			       uint64_t addr, uint64_t size)
-{
-	const uint32_t flags = 0;
-	struct drm_xe_sync *sync = NULL;
-	const uint32_t num_syncs = 0;
-	const uint64_t op_ext = 0;
-
-	xe_eudebug_client_vm_bind_flags(c, vm, bo, offset, addr, size, flags, sync, num_syncs,
-					op_ext);
-}
-
-/**
- * xe_eudebug_client_vm_unbind_flags
- * @c: pointer to xe_eudebug_client structure
- * @vm: vm handle
- * @offset: offset
- * @addr: ppgtt address
- * @size: size of the binding
- * @flags: vm_bind flags
- * @sync: sync objects
- * @num_syncs: number of sync objects
- *
- * Calls xe vm_unbind ioctl and logs the corresponding event in client's event log.
- */
-void xe_eudebug_client_vm_unbind_flags(struct xe_eudebug_client *c,
-				       uint32_t vm, uint64_t offset,
-				       uint64_t addr, uint64_t size, uint32_t flags,
-				       struct drm_xe_sync *sync, uint32_t num_syncs)
-{
-	igt_assert(c);
-	_xe_eudebug_client_vm_bind(c, vm, 0, offset, addr, size,
-				   DRM_XE_VM_BIND_OP_UNMAP, flags,
-				   sync, num_syncs, 0);
-}
-
-/**
- * xe_eudebug_client_vm_unbind
- * @c: pointer to xe_eudebug_client structure
- * @vm: vm handle
- * @offset: offset
- * @addr: ppgtt address
- * @size: size of the binding
- *
- * Calls xe vm_unbind ioctl and logs the corresponding event in client's event log.
- */
-void xe_eudebug_client_vm_unbind(struct xe_eudebug_client *c, uint32_t vm,
-				 uint64_t offset, uint64_t addr, uint64_t size)
-{
-	const uint32_t flags = 0;
-	struct drm_xe_sync *sync = NULL;
-	const uint32_t num_syncs = 0;
-
-	xe_eudebug_client_vm_unbind_flags(c, vm, offset, addr, size,
-					  flags, sync, num_syncs);
-}
-
 /**
  * xe_eudebug_client_vm_bind_debug_data_add
  * @c: pointer to xe_eudebug_client structure
diff --git a/lib/xe/xe_eudebug.h b/lib/xe/xe_eudebug.h
index a53bd99dc0..d191f8be8d 100644
--- a/lib/xe/xe_eudebug.h
+++ b/lib/xe/xe_eudebug.h
@@ -240,21 +240,6 @@ void xe_eudebug_client_vm_bind_ufence_event(struct xe_eudebug_client *c, uint32_
 void xe_eudebug_ack_ufence(int debugfd,
 			   const struct drm_xe_eudebug_event_vm_bind_ufence *f);
 
-void xe_eudebug_client_vm_bind_flags(struct xe_eudebug_client *c, uint32_t vm,
-				     uint32_t bo, uint64_t offset,
-				     uint64_t addr, uint64_t size, uint32_t flags,
-				     struct drm_xe_sync *sync, uint32_t num_syncs,
-				     uint64_t op_ext);
-void xe_eudebug_client_vm_bind(struct xe_eudebug_client *c, uint32_t vm,
-			       uint32_t bo, uint64_t offset,
-			       uint64_t addr, uint64_t size);
-void xe_eudebug_client_vm_unbind_flags(struct xe_eudebug_client *c,
-				       uint32_t vm, uint64_t offset,
-				       uint64_t addr, uint64_t size, uint32_t flags,
-				       struct drm_xe_sync *sync, uint32_t num_syncs);
-void xe_eudebug_client_vm_unbind(struct xe_eudebug_client *c, uint32_t vm,
-				 uint64_t offset, uint64_t addr, uint64_t size);
-
 void xe_eudebug_client_vm_bind_debug_data_add(struct xe_eudebug_client *c, uint32_t vm,
 					      uint32_t offset, uint64_t addr, uint64_t range,
 					      uint64_t pseudopath, char *path,
diff --git a/tests/intel/xe_eudebug.c b/tests/intel/xe_eudebug.c
index 3cd1f61f7b..bdd1996f38 100644
--- a/tests/intel/xe_eudebug.c
+++ b/tests/intel/xe_eudebug.c
@@ -951,13 +951,11 @@ static void test_basic_discovery(int fd, unsigned int flags, bool match_opposite
 #define PRIMARY_THREAD			(1 << 0)
 #define DISCOVERY_CLOSE_CLIENT		(1 << 1)
 #define DISCOVERY_DESTROY_RESOURCES	(1 << 2)
-#define DISCOVERY_VM_BIND		(1 << 3)
 #define DISCOVERY_SIGINT		(1 << 4)
 static void run_discovery_client(struct xe_eudebug_client *c)
 {
 	int fd[RESOURCE_COUNT], i;
 	bool skip_sleep = c->flags & (DISCOVERY_DESTROY_RESOURCES | DISCOVERY_CLOSE_CLIENT);
-	uint64_t addr = 0x1a0000;
 
 	srand(getpid());
 
@@ -999,11 +997,6 @@ static void run_discovery_client(struct xe_eudebug_client *c)
 
 			xe_eudebug_client_exec_queue_create(c, &create);
 
-			if (c->flags & DISCOVERY_VM_BIND) {
-				xe_eudebug_client_vm_bind(c, vm, bo, 0, addr, bo_size);
-				addr += bo_size;
-			}
-
 			if (c->flags & DISCOVERY_DESTROY_RESOURCES) {
 				xe_eudebug_client_exec_queue_destroy(c, &create);
 				xe_eudebug_client_vm_destroy(c, create.vm_id);
@@ -2622,9 +2615,6 @@ int igt_main()
 	igt_subtest("discovery-race")
 		test_race_discovery(fd, 0, 4);
 
-	igt_subtest("discovery-race-vmbind")
-		test_race_discovery(fd, DISCOVERY_VM_BIND, 4);
-
 	igt_subtest("discovery-race-sigint")
 		test_race_discovery(fd, DISCOVERY_SIGINT, 1);
 
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [PATCH i-g-t 15/21] tests/xe_eudebug: Add vm-bind-debug-data-ufence subtest
  2026-01-12 12:59 [PATCH i-g-t 00/21] eudebug: uapi changes on connect and metadata Mika Kuoppala
                   ` (13 preceding siblings ...)
  2026-01-12 13:00 ` [PATCH i-g-t 14/21] lib/xe_eudebug: Remove unused xe_eudebug_client_vm_bind wrappers Mika Kuoppala
@ 2026-01-12 13:00 ` Mika Kuoppala
  2026-01-12 13:00 ` [PATCH i-g-t 16/21] lib/intel_batchbuffer: Add dummy OP_DEBUG_DATA operation to __xe_alloc_bind_ops Mika Kuoppala
                   ` (5 subsequent siblings)
  20 siblings, 0 replies; 23+ messages in thread
From: Mika Kuoppala @ 2026-01-12 13:00 UTC (permalink / raw)
  To: igt-dev
  Cc: christoph.manszewski, dominik.karol.piatkowski, maciej.patelczyk,
	jan.maslak, zbigniew.kempczynski, Mika Kuoppala

From: Christoph Manszewski <christoph.manszewski@intel.com>

Add a subtest for the newly introduced debug data passing interface.
Debug data (formery metadata) used to be attached as an extension to
VM_BIND_OP_MAP operations. As dedicated VM_BIND_OP_DEBUG_DATA_[ADD|REMOVE]
operations got introduced for debug data passing, this subtest
provides basic coverage for this new interface.

v2: squash in uapi changes (Mika)

Signed-off-by: Christoph Manszewski <christoph.manszewski@intel.com>
Signed-off-by: Mika Kuoppala <mika.kuoppala@linux.intel.com>
---
 .../drm-uapi-experimental/xe_drm_eudebug.h    |  33 +-
 lib/xe/xe_eudebug.c                           |  32 +-
 lib/xe/xe_eudebug.h                           |   5 +-
 tests/intel/xe_eudebug.c                      | 314 ++++++++++++++++--
 tests/intel/xe_eudebug_online.c               |   6 +-
 5 files changed, 325 insertions(+), 65 deletions(-)

diff --git a/include/drm-uapi-experimental/xe_drm_eudebug.h b/include/drm-uapi-experimental/xe_drm_eudebug.h
index a9aa87f564..43b8d12b47 100644
--- a/include/drm-uapi-experimental/xe_drm_eudebug.h
+++ b/include/drm-uapi-experimental/xe_drm_eudebug.h
@@ -69,13 +69,11 @@ struct drm_xe_eudebug_event {
 #define DRM_XE_EUDEBUG_EVENT_READ		1
 #define DRM_XE_EUDEBUG_EVENT_VM			2
 #define DRM_XE_EUDEBUG_EVENT_EXEC_QUEUE		3
-#define DRM_XE_EUDEBUG_EVENT_EU_ATTENTION	4
-#define DRM_XE_EUDEBUG_EVENT_VM_BIND		5
-#define DRM_XE_EUDEBUG_EVENT_VM_BIND_OP		6
-#define DRM_XE_EUDEBUG_EVENT_VM_BIND_UFENCE	7
-#define DRM_XE_EUDEBUG_EVENT_METADATA		8
-#define DRM_XE_EUDEBUG_EVENT_VM_BIND_OP_METADATA 9
-#define DRM_XE_EUDEBUG_EVENT_PAGEFAULT		10
+#define DRM_XE_EUDEBUG_EVENT_VM_BIND		4
+#define DRM_XE_EUDEBUG_EVENT_VM_BIND_OP_DEBUG_DATA 5
+#define DRM_XE_EUDEBUG_EVENT_VM_BIND_UFENCE	6
+#define DRM_XE_EUDEBUG_EVENT_EU_ATTENTION	7
+#define DRM_XE_EUDEBUG_EVENT_PAGEFAULT		8
 
 	__u16 flags;
 #define DRM_XE_EUDEBUG_EVENT_CREATE		(1 << 0)
@@ -182,13 +180,20 @@ struct drm_xe_eudebug_event_vm_bind {
 	__u32 num_binds;
 };
 
-struct drm_xe_eudebug_event_vm_bind_op {
-	struct drm_xe_eudebug_event base;
-	__u64 vm_bind_ref_seqno; /* *_event_vm_bind.base.seqno */
-	__u64 num_extensions;
-
-	__u64 addr; /* XXX: Zero for unmap all? */
-	__u64 range; /* XXX: Zero for unmap all? */
+struct drm_xe_eudebug_event_vm_bind_op_debug_data {
+        struct drm_xe_eudebug_event base;
+        __u64 vm_bind_ref_seqno; /* *_event_vm_bind.base.seqno */
+        __u64 num_extensions;
+
+        __u64 addr;
+        __u64 range;
+        __u64 flags;
+        __u32 offset;
+        __u32 reserved;
+        union {
+                __u64 pseudopath;
+                char pathname[PATH_MAX];
+        };
 };
 
 struct drm_xe_eudebug_event_vm_bind_ufence {
diff --git a/lib/xe/xe_eudebug.c b/lib/xe/xe_eudebug.c
index 1774e01f6f..f441a3c824 100644
--- a/lib/xe/xe_eudebug.c
+++ b/lib/xe/xe_eudebug.c
@@ -86,8 +86,8 @@ static const char *type_to_str(unsigned int type)
 		return "exec_queue";
 	case DRM_XE_EUDEBUG_EVENT_VM_BIND:
 		return "vm_bind";
-	case DRM_XE_EUDEBUG_EVENT_VM_BIND_OP:
-		return "vm_bind_op";
+	case DRM_XE_EUDEBUG_EVENT_VM_BIND_OP_DEBUG_DATA:
+		return "vm_bind_op_debug_data";
 	case DRM_XE_EUDEBUG_EVENT_VM_BIND_UFENCE:
 		return "vm_bind_ufence";
 	case DRM_XE_EUDEBUG_EVENT_EU_ATTENTION:
@@ -150,8 +150,9 @@ static const char *event_members_to_str(struct drm_xe_eudebug_event *e, char *bu
 			evmb->vm_handle, evmb->flags, evmb->num_binds);
 		break;
 	}
-	case DRM_XE_EUDEBUG_EVENT_VM_BIND_OP: {
-		struct drm_xe_eudebug_event_vm_bind_op *op = igt_container_of(e, op, base);
+	case DRM_XE_EUDEBUG_EVENT_VM_BIND_OP_DEBUG_DATA: {
+		struct drm_xe_eudebug_event_vm_bind_op_debug_data *op =
+			igt_container_of(e, op, base);
 
 		sprintf(buf, "vm_bind_ref_seqno=%lld, addr=%016llx, range=%llu num_extensions=%llu",
 			op->vm_bind_ref_seqno, op->addr, op->range, op->num_extensions);
@@ -599,9 +600,11 @@ static int match_fields(struct drm_xe_eudebug_event *a, void *data)
 			ret = 1;
 		break;
 	}
-	case DRM_XE_EUDEBUG_EVENT_VM_BIND_OP: {
-		struct drm_xe_eudebug_event_vm_bind_op *ea = igt_container_of(a, ea, base);
-		struct drm_xe_eudebug_event_vm_bind_op *eb = igt_container_of(b, eb, base);
+	case DRM_XE_EUDEBUG_EVENT_VM_BIND_OP_DEBUG_DATA: {
+		struct drm_xe_eudebug_event_vm_bind_op_debug_data *ea =
+			igt_container_of(a, ea, base);
+		struct drm_xe_eudebug_event_vm_bind_op_debug_data *eb =
+			igt_container_of(b, eb, base);
 
 		if (ea->addr == eb->addr && ea->range == eb->range &&
 		    ea->num_extensions == eb->num_extensions)
@@ -637,8 +640,8 @@ static int match_client_handle(struct drm_xe_eudebug_event *e, void *data)
 		return 1;
 		break;
 	}
-	case DRM_XE_EUDEBUG_EVENT_VM_BIND_OP: {
-		struct drm_xe_eudebug_event_vm_bind_op *eo = igt_container_of(e, eo, base);
+	case DRM_XE_EUDEBUG_EVENT_VM_BIND_OP_DEBUG_DATA: {
+		struct drm_xe_eudebug_event_vm_bind_op_debug_data *eo = igt_container_of(e, eo, base);
 
 		if (eo->vm_bind_ref_seqno == *bind_seqno) {
 			*bind_op_seqno = eo->base.seqno;
@@ -700,9 +703,10 @@ static int match_opposite_resource(struct drm_xe_eudebug_event *e, void *data)
 			return 1;
 		break;
 	}
-	case DRM_XE_EUDEBUG_EVENT_VM_BIND_OP: {
-		struct drm_xe_eudebug_event_vm_bind_op *avmb = igt_container_of(e, avmb, base);
-		struct drm_xe_eudebug_event_vm_bind_op *filter = data;
+	case DRM_XE_EUDEBUG_EVENT_VM_BIND_OP_DEBUG_DATA: {
+		struct drm_xe_eudebug_event_vm_bind_op_debug_data *avmb =
+			igt_container_of(e, avmb, base);
+		struct drm_xe_eudebug_event_vm_bind_op_debug_data *filter = data;
 
 		if (avmb->addr == filter->addr &&
 		    avmb->range == filter->range)
@@ -2105,12 +2109,12 @@ void xe_eudebug_client_vm_bind_op_event(struct xe_eudebug_client *c, uint32_t ev
 					uint64_t addr, uint64_t range,
 					uint64_t num_extensions)
 {
-	struct drm_xe_eudebug_event_vm_bind_op op;
+	struct drm_xe_eudebug_event_vm_bind_op_debug_data op = { 0 };
 
 	igt_assert(c);
 	igt_assert(op_ref_seqno);
 
-	base_event(c, to_base(op), DRM_XE_EUDEBUG_EVENT_VM_BIND_OP,
+	base_event(c, to_base(op), DRM_XE_EUDEBUG_EVENT_VM_BIND_OP_DEBUG_DATA,
 		   event_flags, sizeof(op));
 	op.vm_bind_ref_seqno = bind_ref_seqno;
 	op.addr = addr;
diff --git a/lib/xe/xe_eudebug.h b/lib/xe/xe_eudebug.h
index d191f8be8d..acf5bf601d 100644
--- a/lib/xe/xe_eudebug.h
+++ b/lib/xe/xe_eudebug.h
@@ -166,11 +166,10 @@ next_event(struct drm_xe_eudebug_event *e, struct xe_eudebug_event_log *l)
 #define XE_EUDEBUG_FILTER_EVENT_READ			BIT(DRM_XE_EUDEBUG_EVENT_READ)
 #define XE_EUDEBUG_FILTER_EVENT_VM			BIT(DRM_XE_EUDEBUG_EVENT_VM)
 #define XE_EUDEBUG_FILTER_EVENT_EXEC_QUEUE		BIT(DRM_XE_EUDEBUG_EVENT_EXEC_QUEUE)
-#define XE_EUDEBUG_FILTER_EVENT_EXEC_QUEUE_PLACEMENTS	BIT(DRM_XE_EUDEBUG_EVENT_EXEC_QUEUE_PLACEMENTS)
-#define XE_EUDEBUG_FILTER_EVENT_EU_ATTENTION		BIT(DRM_XE_EUDEBUG_EVENT_EU_ATTENTION)
 #define XE_EUDEBUG_FILTER_EVENT_VM_BIND			BIT(DRM_XE_EUDEBUG_EVENT_VM_BIND)
-#define XE_EUDEBUG_FILTER_EVENT_VM_BIND_OP		BIT(DRM_XE_EUDEBUG_EVENT_VM_BIND_OP)
+#define XE_EUDEBUG_FILTER_EVENT_VM_BIND_OP_DEBUG_DATA		BIT(DRM_XE_EUDEBUG_EVENT_VM_BIND_OP_DEBUG_DATA)
 #define XE_EUDEBUG_FILTER_EVENT_VM_BIND_UFENCE		BIT(DRM_XE_EUDEBUG_EVENT_VM_BIND_UFENCE)
+#define XE_EUDEBUG_FILTER_EVENT_EU_ATTENTION		BIT(DRM_XE_EUDEBUG_EVENT_EU_ATTENTION)
 #define XE_EUDEBUG_FILTER_EVENT_PAGEFAULT		BIT(DRM_XE_EUDEBUG_EVENT_PAGEFAULT)
 #define XE_EUDEBUG_FILTER_ALL				GENMASK(DRM_XE_EUDEBUG_EVENT_PAGEFAULT, 0)
 #define XE_EUDEBUG_EVENT_IS_FILTERED(_e, _f)		((1UL << (_e)) & (_f))
diff --git a/tests/intel/xe_eudebug.c b/tests/intel/xe_eudebug.c
index bdd1996f38..9e40f61fcf 100644
--- a/tests/intel/xe_eudebug.c
+++ b/tests/intel/xe_eudebug.c
@@ -64,6 +64,7 @@ static void test_sysfs_toggle(int fd)
 #define VM_BIND_DELAY_UFENCE_ACK	(1 << 6)
 #define VM_BIND_UFENCE_DISCONNECT	(1 << 7)
 #define VM_BIND_UFENCE_SIGINT_CLIENT	(1 << 8)
+#define VM_BIND_UFENCE_DEBUG_DATA	(1 << 9)
 #define TEST_FAULTABLE			(1 << 30)
 #define TEST_DISCOVERY			(1 << 31)
 
@@ -1080,7 +1081,7 @@ static void *discovery_race_thread(void *data)
 					if (e->type == DRM_XE_EUDEBUG_EVENT_EXEC_QUEUE)
 						clients[i].exec_queue_count++;
 
-					if (e->type == DRM_XE_EUDEBUG_EVENT_VM_BIND_OP)
+					if (e->type == DRM_XE_EUDEBUG_EVENT_VM_BIND_OP_DEBUG_DATA)
 						clients[i].vm_bind_op_count++;
 				};
 
@@ -1436,7 +1437,7 @@ static void debugger_test_vma(struct xe_eudebug_debugger *d,
 static void vm_trigger(struct xe_eudebug_debugger *d,
 		       struct drm_xe_eudebug_event *e)
 {
-	struct drm_xe_eudebug_event_vm_bind_op *eo = (void *)e;
+	struct drm_xe_eudebug_event_vm_bind_op_debug_data *eo = (void *)e;
 
 	if (e->flags & DRM_XE_EUDEBUG_EVENT_CREATE) {
 		struct drm_xe_eudebug_event_vm_bind *eb;
@@ -1491,10 +1492,10 @@ static void test_vm_access(int fd, unsigned int flags, int num_clients)
 	xe_eudebug_for_each_engine(fd, hwe)
 		test_client_with_trigger(fd, flags, num_clients,
 					 vm_access_client,
-					 DRM_XE_EUDEBUG_EVENT_VM_BIND_OP,
+					 DRM_XE_EUDEBUG_EVENT_VM_BIND_OP_DEBUG_DATA,
 					 vm_trigger, hwe,
 					 false,
-					 XE_EUDEBUG_FILTER_EVENT_VM_BIND_OP |
+					 XE_EUDEBUG_FILTER_EVENT_VM_BIND_OP_DEBUG_DATA |
 					 XE_EUDEBUG_FILTER_EVENT_VM_BIND_UFENCE);
 }
 
@@ -1592,7 +1593,7 @@ static void debugger_test_vma_parameters(struct xe_eudebug_debugger *d,
 static void vm_trigger_access_parameters(struct xe_eudebug_debugger *d,
 					 struct drm_xe_eudebug_event *e)
 {
-	struct drm_xe_eudebug_event_vm_bind_op *eo = (void *)e;
+	struct drm_xe_eudebug_event_vm_bind_op_debug_data *eo = (void *)e;
 
 	if (e->flags & DRM_XE_EUDEBUG_EVENT_CREATE) {
 		struct drm_xe_eudebug_event_vm_bind *eb;
@@ -1644,10 +1645,10 @@ static void test_vm_access_parameters(int fd, unsigned int flags, int num_client
 	xe_eudebug_for_each_engine(fd, hwe)
 		test_client_with_trigger(fd, flags, num_clients,
 					 vm_access_client,
-					 DRM_XE_EUDEBUG_EVENT_VM_BIND_OP,
+					 DRM_XE_EUDEBUG_EVENT_VM_BIND_OP_DEBUG_DATA,
 					 vm_trigger_access_parameters, hwe,
 					 false,
-					 XE_EUDEBUG_FILTER_EVENT_VM_BIND_OP |
+					 XE_EUDEBUG_FILTER_EVENT_VM_BIND_OP_DEBUG_DATA |
 					 XE_EUDEBUG_FILTER_EVENT_VM_BIND_UFENCE);
 }
 
@@ -1661,13 +1662,16 @@ struct ufence_bind {
 	uint64_t addr;
 	uint64_t range;
 	uint64_t value;
+
+	uint64_t pseudopath;
+	char pathname[PATH_MAX];
 	struct {
 		uint64_t vm_sync;
 	} *fence_data;
 };
 
-static void client_wait_ufences(struct xe_eudebug_client *c,
-				struct ufence_bind *binds, int count)
+static void client_wait_ufences_timeout(struct xe_eudebug_client *c,
+					struct ufence_bind *binds, int count)
 {
 	const int64_t default_fence_timeout_ns = 500 * NSEC_PER_MSEC;
 	int64_t timeout_ns;
@@ -1703,6 +1707,8 @@ static void client_wait_ufences(struct xe_eudebug_client *c,
 	}
 }
 
+#define BINDS_WITH_UFENCE_RANGE 0x1000
+#define BINDS_WITH_UFENCE_BASE_ADDR 0x100000
 static struct ufence_bind *create_binds_with_ufence(int fd, int count)
 {
 	struct ufence_bind *binds;
@@ -1713,8 +1719,8 @@ static struct ufence_bind *create_binds_with_ufence(int fd, int count)
 	for (int i = 0; i < count; i++) {
 		struct ufence_bind *b = &binds[i];
 
-		b->range = 0x1000;
-		b->addr = 0x100000 + b->range * i;
+		b->range = BINDS_WITH_UFENCE_RANGE;
+		b->addr = BINDS_WITH_UFENCE_BASE_ADDR + b->range * i;
 		b->fence_data = aligned_alloc(xe_get_default_alignment(fd),
 					      sizeof(*b->fence_data));
 		igt_assert(b->fence_data);
@@ -1744,6 +1750,7 @@ static void basic_ufence_client(struct xe_eudebug_client *c)
 	size_t bo_size = n * xe_get_default_alignment(c->fd);
 	uint32_t bo = xe_bo_create(c->fd, 0, bo_size,
 				   system_memory(c->fd), 0);
+
 	struct ufence_bind *binds = create_binds_with_ufence(c->fd, n);
 
 	for (int i = 0; i < n; i++) {
@@ -1754,7 +1761,7 @@ static void basic_ufence_client(struct xe_eudebug_client *c)
 							      0, &b->f, 1);
 	}
 
-	client_wait_ufences(c, binds, n);
+	client_wait_ufences_timeout(c, binds, n);
 
 	for (int i = 0; i < n; i++) {
 		struct ufence_bind *b = &binds[i];
@@ -1767,8 +1774,10 @@ static void basic_ufence_client(struct xe_eudebug_client *c)
 	xe_eudebug_client_vm_destroy(c, vm);
 }
 
+#define DEBUG_DATA_COUNT 4
 struct ufence_priv {
 	struct drm_xe_eudebug_event_vm_bind_ufence ufence_events[UFENCE_EVENT_COUNT_MAX];
+	struct drm_xe_eudebug_event_vm_bind_op_debug_data debug_data_events[DEBUG_DATA_COUNT];
 	uint64_t ufence_event_seqno[UFENCE_EVENT_COUNT_MAX];
 	uint64_t ufence_event_vm_addr_start[UFENCE_EVENT_COUNT_MAX];
 	uint64_t ufence_event_vm_addr_range[UFENCE_EVENT_COUNT_MAX];
@@ -2138,7 +2147,7 @@ static void vm_bind_clear_client(struct xe_eudebug_client *c)
 static void vm_bind_clear_test_trigger(struct xe_eudebug_debugger *d,
 				       struct drm_xe_eudebug_event *e)
 {
-	struct drm_xe_eudebug_event_vm_bind_op *eo = (void *)e;
+	struct drm_xe_eudebug_event_vm_bind_op_debug_data *eo = (void *)e;
 	struct vm_bind_clear_priv *priv = d->ptr;
 
 	if (e->flags & DRM_XE_EUDEBUG_EVENT_CREATE) {
@@ -2204,7 +2213,8 @@ static void test_vm_bind_clear(int fd, uint32_t flags)
 	priv = vm_bind_clear_priv_create();
 	s = xe_eudebug_session_create(fd, vm_bind_clear_client, flags, priv);
 
-	xe_eudebug_debugger_add_trigger(s->debugger, DRM_XE_EUDEBUG_EVENT_VM_BIND_OP,
+	xe_eudebug_debugger_add_trigger(s->debugger,
+					DRM_XE_EUDEBUG_EVENT_VM_BIND_OP_DEBUG_DATA,
 					vm_bind_clear_test_trigger);
 	xe_eudebug_debugger_add_trigger(s->debugger, DRM_XE_EUDEBUG_EVENT_VM_BIND_UFENCE,
 					vm_bind_clear_ack_trigger);
@@ -2226,6 +2236,24 @@ static void test_vm_bind_clear(int fd, uint32_t flags)
 #define UFENCE_CLIENT_VM_TEST_VAL_START 0xaaaaaaaa
 #define UFENCE_CLIENT_VM_TEST_VAL_END 0xbbbbbbbb
 
+static void client_wait_ufences(struct xe_eudebug_client *c, int num_ufences,
+				struct ufence_bind *binds)
+{
+	for (int i = 0; i < num_ufences; i++) {
+		int err;
+		int64_t timeout_ns;
+		struct ufence_bind *b = &binds[i];
+
+		timeout_ns = XE_EUDEBUG_DEFAULT_TIMEOUT_SEC * NSEC_PER_SEC;
+		err = __xe_wait_ufence(c->fd,
+				       &b->fence_data->vm_sync, b->f.timeline_value,
+				       0, &timeout_ns);
+		igt_assert_eq(err, 0);
+		igt_assert_eq(b->fence_data->vm_sync, b->f.timeline_value);
+		igt_debug("wait #%d completed\n", i);
+	}
+}
+
 static void vma_ufence_client(struct xe_eudebug_client *c)
 {
 	const unsigned int n = UFENCE_EVENT_COUNT_EXPECTED;
@@ -2256,26 +2284,13 @@ static void vma_ufence_client(struct xe_eudebug_client *c)
 							      0, &b->f, 1);
 	}
 
-	/* Wait for acks on ufences */
+	client_wait_ufences(c, n, binds);
+
 	for (int i = 0; i < n; i++) {
-		int err;
-		int64_t timeout_ns;
 		struct ufence_bind *b = &binds[i];
 
-		timeout_ns = XE_EUDEBUG_DEFAULT_TIMEOUT_SEC * NSEC_PER_SEC;
-		err = __xe_wait_ufence(c->fd,
-				       &b->fence_data->vm_sync, b->f.timeline_value,
-				       0, &timeout_ns);
-		igt_assert_eq(err, 0);
-		igt_assert_eq(b->fence_data->vm_sync, b->f.timeline_value);
-		igt_debug("wait #%d completed\n", i);
-
 		for (int j = 0; j < items; j++)
 			igt_assert_eq(ptr[i][j], UFENCE_CLIENT_VM_TEST_VAL_END);
-	}
-
-	for (int i = 0; i < n; i++) {
-		struct ufence_bind *b = &binds[i];
 
 		xe_eudebug_client_vm_bind_unmap_with_debug_data(c, vm, b->addr, b->range);
 	}
@@ -2339,7 +2354,7 @@ static void debugger_test_vma_ufence(struct xe_eudebug_debugger *d,
 static void vma_ufence_op_trigger(struct xe_eudebug_debugger *d,
 				  struct drm_xe_eudebug_event *e)
 {
-	struct drm_xe_eudebug_event_vm_bind_op *eo = (void *)e;
+	struct drm_xe_eudebug_event_vm_bind_op_debug_data *eo = (void *)e;
 	struct ufence_priv *priv = d->ptr;
 
 	if (e->flags & DRM_XE_EUDEBUG_EVENT_CREATE) {
@@ -2431,7 +2446,7 @@ static void test_vma_ufence(int fd, unsigned int flags)
 	s = xe_eudebug_session_create(fd, vma_ufence_client, flags, priv);
 
 	xe_eudebug_debugger_add_trigger(s->debugger,
-					DRM_XE_EUDEBUG_EVENT_VM_BIND_OP,
+					DRM_XE_EUDEBUG_EVENT_VM_BIND_OP_DEBUG_DATA,
 					vma_ufence_op_trigger);
 	xe_eudebug_debugger_add_trigger(s->debugger,
 					DRM_XE_EUDEBUG_EVENT_VM_BIND_UFENCE,
@@ -2453,6 +2468,239 @@ static void test_vma_ufence(int fd, unsigned int flags)
 	ufence_priv_destroy(priv);
 }
 
+#define DEBUG_DATA_FPATH_TEMPLATE "/tmp/xe_eudebug_debug_data-%d"
+#define DEBUG_DATA_SIZE 16 * PATH_MAX
+
+static void debug_data_init(struct ufence_bind *b, int idx)
+{
+	const uint32_t debug_data_size = DEBUG_DATA_SIZE;
+	uint8_t *debug_data_content;
+	size_t written;
+	FILE *file;
+
+	b->pseudopath = idx;
+
+	if (idx)
+		return;
+
+	snprintf(b->pathname, PATH_MAX, DEBUG_DATA_FPATH_TEMPLATE, rand());
+	igt_debug("Debug data file path: %s\n", b->pathname);
+
+	debug_data_content = calloc(debug_data_size, sizeof(*debug_data_content));
+	igt_assert(debug_data_content);
+
+	for (int i = 0; i < debug_data_size; i++)
+		debug_data_content[i] = i % 256;
+
+	file = fopen(b->pathname, "wb");
+	igt_assert(file);
+
+	written = fwrite(debug_data_content, 1, debug_data_size, file);
+	igt_assert(written == debug_data_size);
+
+	fsync(fileno(file));
+	fclose(file);
+
+	free(debug_data_content);
+}
+
+static void debug_data_fini(struct ufence_bind *b, int idx)
+{
+	if (idx)
+		return;
+
+	igt_assert(b->pathname);
+	remove(b->pathname);
+}
+
+static void debug_data_ufence_client(struct xe_eudebug_client *c)
+{
+	const unsigned int n = DEBUG_DATA_COUNT;
+	struct ufence_bind *binds = create_binds_with_ufence(c->fd, n);
+	uint32_t vm;
+
+	size_t bo_size = xe_get_default_alignment(c->fd);
+	uint32_t bo[n];
+	uint32_t *ptr[n];
+
+	vm = xe_eudebug_client_vm_create(c, DRM_XE_VM_CREATE_FLAG_LR_MODE, 0);
+
+	for (int i = 0; i < n; i++)
+		debug_data_init(&binds[i], i);
+
+	for (int i = 0; i < n; i++) {
+		bo[i] = xe_bo_create(c->fd, 0, bo_size,
+				     system_memory(c->fd), 0);
+		ptr[i] = xe_bo_map(c->fd, bo[i], bo_size);
+		igt_assert(ptr[i]);
+		memset(ptr[i], UFENCE_CLIENT_VM_TEST_VAL_START, bo_size);
+	}
+
+	for (int i = 0; i < n; i++) {
+		struct ufence_bind *b = &binds[i];
+
+		xe_eudebug_client_vm_bind_debug_data_add(c, vm, 0, b->addr, b->range, b->pseudopath,
+							 b->pseudopath ? NULL : b->pathname,
+							 &b->f, 1);
+	}
+
+	client_wait_ufences(c, n, binds);
+
+	for (int i = 0; i < n; i++) {
+		struct ufence_bind *b = &binds[i];
+
+		xe_eudebug_client_vm_bind_debug_data_remove(c, vm, b->addr, b->range);
+		debug_data_fini(b, i);
+	}
+
+	destroy_binds_with_ufence(binds, n);
+	xe_eudebug_client_vm_destroy(c, vm);
+}
+
+static int debug_data_event_idx(struct drm_xe_eudebug_event_vm_bind_op_debug_data *event)
+{
+	if (!(event->flags & DRM_XE_VM_BIND_DEBUG_DATA_FLAG_PSEUDO))
+		return 0;
+	else if (event->pseudopath == DRM_XE_VM_BIND_DEBUG_DATA_PSEUDO_MODULE_AREA)
+		return 1;
+	else if (event->pseudopath == DRM_XE_VM_BIND_DEBUG_DATA_PSEUDO_SBA_AREA)
+		return 2;
+	else
+		return 3;
+}
+
+static void debug_data_op_trigger(struct xe_eudebug_debugger *d,
+				  struct drm_xe_eudebug_event *e)
+{
+	struct drm_xe_eudebug_event_vm_bind_op_debug_data *eo = (void *)e;
+	struct ufence_priv *priv = d->ptr;
+
+	if (e->flags & DRM_XE_EUDEBUG_EVENT_CREATE) {
+		char event_str[XE_EUDEBUG_EVENT_STRING_MAX_LEN];
+		struct drm_xe_eudebug_event_vm_bind *eb;
+		unsigned int op_count = priv->vm_bind_op_count++;
+		int idx = debug_data_event_idx(eo);
+
+		xe_eudebug_event_to_str(e, event_str, XE_EUDEBUG_EVENT_STRING_MAX_LEN);
+		igt_debug("vm bind op event: ref %lld, addr 0x%llx, range 0x%llx, op_count %u\n",
+			  eo->vm_bind_ref_seqno,
+			  eo->addr,
+			  eo->range,
+			  op_count);
+		igt_debug("vm bind op event received: %s\n", event_str);
+		xe_eudebug_assert(d, eo->vm_bind_ref_seqno);
+		eb = (struct drm_xe_eudebug_event_vm_bind *)
+			xe_eudebug_event_log_find_seqno(d->log, eo->vm_bind_ref_seqno);
+
+		xe_eudebug_assert_f(d, eb, "vm bind event with seqno (%lld) not found\n",
+				    eo->vm_bind_ref_seqno);
+		xe_eudebug_assert_f(d, eb->flags & DRM_XE_EUDEBUG_EVENT_VM_BIND_FLAG_UFENCE,
+				    "vm bind event does not have ufence: %s\n", event_str);
+
+		memcpy(&priv->debug_data_events[idx], eo, sizeof(*eo));
+	}
+}
+
+static void check_debug_data(struct xe_eudebug_debugger *d,
+			     struct drm_xe_eudebug_event_vm_bind_op_debug_data *eo)
+{
+	uint8_t *debug_data_content;
+	uint8_t *debug_data_path;
+	size_t read;
+	FILE *file;
+	int i;
+
+	igt_assert_eq(eo->range, BINDS_WITH_UFENCE_RANGE);
+	igt_assert_eq(eo->addr, BINDS_WITH_UFENCE_BASE_ADDR + debug_data_event_idx(eo) * eo->range);
+	igt_assert_eq(eo->reserved, 0);
+
+	if (eo->flags & DRM_XE_VM_BIND_DEBUG_DATA_FLAG_PSEUDO) {
+		igt_assert_eq(eo->offset, 0);
+		return;
+	}
+
+	file = fopen(eo->pathname, "rb");
+	igt_assert(file);
+
+	debug_data_content = malloc(DEBUG_DATA_SIZE);
+	read = fread(debug_data_content, 1, DEBUG_DATA_SIZE, file);
+	igt_assert_eq(read, DEBUG_DATA_SIZE);
+
+	for (i = 0; i < read; i++)
+		igt_assert_eq(debug_data_content[i], i % 256);
+
+	free(debug_data_content);
+	fclose(file);
+	free(debug_data_path);
+}
+
+static void debug_data_ufence_trigger(struct xe_eudebug_debugger *d,
+				      struct drm_xe_eudebug_event *e)
+{
+	struct drm_xe_eudebug_event_vm_bind_ufence *ef = (void *)e;
+	struct drm_xe_eudebug_event_vm_bind_op_debug_data *eo;
+	struct ufence_priv *priv = d->ptr;
+
+	if (e->flags & DRM_XE_EUDEBUG_EVENT_CREATE) {
+		char event_str[XE_EUDEBUG_EVENT_STRING_MAX_LEN];
+		bool found = false;
+
+		xe_eudebug_event_to_str(e, event_str, XE_EUDEBUG_EVENT_STRING_MAX_LEN);
+		igt_debug("ufence event received: %s\n", event_str);
+
+		xe_eudebug_assert_f(d, priv->ufence_event_count < DEBUG_DATA_COUNT,
+				    "surplus ufence event received: %s\n", event_str);
+		xe_eudebug_assert(d, ef->vm_bind_ref_seqno);
+
+		for (int i = 0; i < DEBUG_DATA_COUNT; ++i) {
+			if (priv->debug_data_events[i].vm_bind_ref_seqno == ef->vm_bind_ref_seqno) {
+				eo = &priv->debug_data_events[i];
+				found = true;
+				break;
+			}
+		}
+
+		xe_eudebug_assert_f(d, found,
+				    "vm bind op event with ref seqno (%lld) not found\n",
+				    ef->vm_bind_ref_seqno);
+
+		check_debug_data(d, eo);
+
+		xe_eudebug_ack_ufence(d->fd, ef);
+	}
+}
+
+/**
+ * SUBTEST: vm-bind-debug-data-ufence
+ * Functionality: VM bind debug data
+ * Description:
+ *	Intercept vm bind after receiving ufence event, then access debug data and ensure it matches
+ *	what the address and ranges provided by the client. For file based debug data, also ensure
+ *	the content matches what was written to the file by the client.
+ */
+static void test_debug_data(int fd)
+{
+	struct xe_eudebug_session *s;
+	struct ufence_priv *priv;
+
+	priv = ufence_priv_create();
+
+	s = xe_eudebug_session_create(fd, debug_data_ufence_client, 0, priv);
+
+	xe_eudebug_debugger_add_trigger(s->debugger,
+					DRM_XE_EUDEBUG_EVENT_VM_BIND_OP_DEBUG_DATA,
+					debug_data_op_trigger);
+	xe_eudebug_debugger_add_trigger(s->debugger,
+					DRM_XE_EUDEBUG_EVENT_VM_BIND_UFENCE,
+					debug_data_ufence_trigger);
+
+	xe_eudebug_session_run(s);
+	xe_eudebug_session_check(s, true, 0);
+	xe_eudebug_session_destroy(s);
+
+	ufence_priv_destroy(priv);
+}
+
 /**
  * SUBTEST: basic-exec-queues-enable
  * Functionality: exec queues events
@@ -2528,6 +2776,7 @@ int igt_main()
 	igt_fixture() {
 		fd = drm_open_driver(DRIVER_XE);
 		was_enabled = xe_eudebug_enable(fd, true);
+		igt_srandom();
 
 		igt_install_exit_handler(igt_drm_debug_mask_reset_exit_handler);
 		update_debug_mask_if_ci(DRM_UT_KMS);
@@ -2603,6 +2852,9 @@ int igt_main()
 	igt_subtest("basic-vm-bind-ufence-sigint-client")
 		test_basic_ufence(fd, VM_BIND_UFENCE_SIGINT_CLIENT);
 
+	igt_subtest("vm-bind-debug-data-ufence")
+		test_debug_data(fd);
+
 	igt_subtest("basic-vm-bind-discovery")
 		test_basic_discovery(fd, VM_BIND, true);
 
diff --git a/tests/intel/xe_eudebug_online.c b/tests/intel/xe_eudebug_online.c
index c4e9ff2fce..34a8ff26e9 100644
--- a/tests/intel/xe_eudebug_online.c
+++ b/tests/intel/xe_eudebug_online.c
@@ -1254,7 +1254,7 @@ static void online_session_check(struct xe_eudebug_session *s, int flags)
 	int pagefault_threads = 0;
 
 	xe_eudebug_session_check(s, true, XE_EUDEBUG_FILTER_EVENT_VM_BIND |
-					  XE_EUDEBUG_FILTER_EVENT_VM_BIND_OP |
+					  XE_EUDEBUG_FILTER_EVENT_VM_BIND_OP_DEBUG_DATA |
 					  XE_EUDEBUG_FILTER_EVENT_VM_BIND_UFENCE);
 
 	bitmask_size = query_attention_bitmask_size(s->debugger->master_fd, data->hwe.gt_id);
@@ -1949,7 +1949,7 @@ static void test_interrupt_other(int fd, struct drm_xe_engine_class_instance *hw
 	xe_eudebug_event_log_print(debugee->log, true);
 
 	xe_eudebug_session_check(s, true, XE_EUDEBUG_FILTER_EVENT_VM_BIND |
-				 XE_EUDEBUG_FILTER_EVENT_VM_BIND_OP |
+				 XE_EUDEBUG_FILTER_EVENT_VM_BIND_OP_DEBUG_DATA |
 				 XE_EUDEBUG_FILTER_EVENT_VM_BIND_UFENCE);
 
 	xe_eudebug_client_destroy(debugee);
@@ -2160,7 +2160,7 @@ static void test_interrupt_reconnect(int fd, struct drm_xe_engine_class_instance
 	xe_eudebug_event_log_print(s->client->log, true);
 
 	xe_eudebug_session_check(s, true, XE_EUDEBUG_FILTER_EVENT_VM_BIND |
-					  XE_EUDEBUG_FILTER_EVENT_VM_BIND_OP |
+					  XE_EUDEBUG_FILTER_EVENT_VM_BIND_OP_DEBUG_DATA |
 					  XE_EUDEBUG_FILTER_EVENT_VM_BIND_UFENCE);
 
 	/* We expect workload reset, so no attention should be raised */
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [PATCH i-g-t 16/21] lib/intel_batchbuffer: Add dummy OP_DEBUG_DATA operation to __xe_alloc_bind_ops
  2026-01-12 12:59 [PATCH i-g-t 00/21] eudebug: uapi changes on connect and metadata Mika Kuoppala
                   ` (14 preceding siblings ...)
  2026-01-12 13:00 ` [PATCH i-g-t 15/21] tests/xe_eudebug: Add vm-bind-debug-data-ufence subtest Mika Kuoppala
@ 2026-01-12 13:00 ` Mika Kuoppala
  2026-01-12 13:00 ` [PATCH i-g-t 17/21] tests/xe_eudebug_online: Adapt set-breakpoint test to work with new vm bind event interface Mika Kuoppala
                   ` (4 subsequent siblings)
  20 siblings, 0 replies; 23+ messages in thread
From: Mika Kuoppala @ 2026-01-12 13:00 UTC (permalink / raw)
  To: igt-dev
  Cc: christoph.manszewski, dominik.karol.piatkowski, maciej.patelczyk,
	jan.maslak, zbigniew.kempczynski, Mika Kuoppala

From: Christoph Manszewski <christoph.manszewski@intel.com>

xe_eudebug_online tests rely on ufence blocking/acking by the debugger
to set the breakpoint bit on a client shader instruction before
the workload is executed. Ufence events and debugger blocking/acking
is no longer present for binds that only contain 'OP_MAP' operations -
at least a single 'OP_ADD_DEBUG_DATA' has to be present to trigger this
functionality. Make it possible to inject a dummy debug data vm bind
operation to the list of bind operations during bb execution.

Signed-off-by: Christoph Manszewski <christoph.manszewski@intel.com>
Signed-off-by: Mika Kuoppala <mika.kuoppala@linux.intel.com>
---
 lib/intel_batchbuffer.c | 82 +++++++++++++++++++++++++----------------
 1 file changed, 51 insertions(+), 31 deletions(-)

diff --git a/lib/intel_batchbuffer.c b/lib/intel_batchbuffer.c
index 3b25a385b7..5e5cf0b136 100644
--- a/lib/intel_batchbuffer.c
+++ b/lib/intel_batchbuffer.c
@@ -1355,42 +1355,71 @@ void intel_bb_destroy(struct intel_bb *ibb)
 #define XE_OBJ_PXP_BIT (0x100)
 #define XE_OBJ_PXP(rsvd1) ((rsvd1) & (XE_OBJ_PXP_BIT))
 
-static struct drm_xe_vm_bind_op *xe_alloc_bind_ops(struct intel_bb *ibb,
-						   uint32_t op, uint32_t flags,
-						   uint32_t prefetch_region)
+static struct drm_xe_vm_bind_op *__xe_alloc_bind_ops(struct intel_bb *ibb,
+						     uint32_t op, uint32_t flags,
+						     uint32_t prefetch_region,
+						     bool dummy_debug_data)
 {
 	struct drm_i915_gem_exec_object2 **objects = ibb->objects;
-	struct drm_xe_vm_bind_op *bind_ops, *ops;
+	struct drm_xe_vm_bind_op *bind_ops, *bind_op, *ret;
 	bool set_obj = (op & 0xffff) == DRM_XE_VM_BIND_OP_MAP;
 
-	bind_ops = calloc(ibb->num_objects, sizeof(*bind_ops));
+	ret = bind_ops = calloc(ibb->num_objects + (dummy_debug_data ? 1 : 0), sizeof(*bind_ops));
 	igt_assert(bind_ops);
 
+	if (dummy_debug_data) {
+		struct drm_xe_vm_bind_op_ext_debug_data *op_ext;
+
+		bind_op = &bind_ops[0];
+
+		op_ext = calloc(1, sizeof(*op_ext));
+		op_ext->base.name = XE_VM_BIND_OP_EXTENSIONS_DEBUG_DATA;
+		op_ext->flags = DRM_XE_VM_BIND_DEBUG_DATA_FLAG_PSEUDO;
+		op_ext->pseudopath = DRM_XE_VM_BIND_DEBUG_DATA_PSEUDO_SIP_AREA;
+		op_ext->addr = 0;
+		op_ext->range = 1;
+
+		bind_op->op = (op == DRM_XE_VM_BIND_OP_MAP ?
+			DRM_XE_VM_BIND_OP_ADD_DEBUG_DATA :
+			DRM_XE_VM_BIND_OP_REMOVE_DEBUG_DATA);
+		bind_op->extensions = to_user_pointer(op_ext);
+		bind_op->pat_index = intel_get_pat_idx_wb(ibb->fd);
+
+		bind_ops = &bind_ops[1];
+	}
+
 	igt_debug("bind_ops: %s\n", set_obj ? "MAP" : "UNMAP");
 	for (int i = 0; i < ibb->num_objects; i++) {
-		ops = &bind_ops[i];
+		bind_op = &bind_ops[i];
 
 		if (set_obj)
-			ops->obj = objects[i]->handle;
+			bind_op->obj = objects[i]->handle;
 
-		ops->op = op;
-		ops->flags = flags;
+		bind_op->op = op;
+		bind_op->flags = flags;
 
 		if (XE_OBJ_PXP(objects[i]->rsvd1))
-			ops->flags |= DRM_XE_VM_BIND_FLAG_CHECK_PXP;
-		ops->obj_offset = 0;
-		ops->addr = objects[i]->offset;
-		ops->range = XE_OBJ_SIZE(objects[i]->rsvd1);
-		ops->prefetch_mem_region_instance = prefetch_region;
+			bind_op->flags |= DRM_XE_VM_BIND_FLAG_CHECK_PXP;
+		bind_op->obj_offset = 0;
+		bind_op->addr = objects[i]->offset;
+		bind_op->range = XE_OBJ_SIZE(objects[i]->rsvd1);
+		bind_op->prefetch_mem_region_instance = prefetch_region;
 		if (set_obj)
-			ops->pat_index = XE_OBJ_PAT_IDX(objects[i]->rsvd1);
+			bind_op->pat_index = XE_OBJ_PAT_IDX(objects[i]->rsvd1);
 
 		igt_debug("  [%d]: handle: %u, offset: %llx, size: %llx pat_index: %u\n",
-			  i, ops->obj, (long long)ops->addr, (long long)ops->range,
-			  ops->pat_index);
+			  i, bind_op->obj, (long long)bind_op->addr, (long long)bind_op->range,
+			  bind_op->pat_index);
 	}
 
-	return bind_ops;
+	return ret;
+}
+
+static struct drm_xe_vm_bind_op *xe_alloc_bind_ops(struct intel_bb *ibb,
+						   uint32_t op, uint32_t flags,
+						   uint32_t prefetch_region)
+{
+	return __xe_alloc_bind_ops(ibb, op, flags, prefetch_region, false);
 }
 
 static void __unbind_xe_objects(struct intel_bb *ibb)
@@ -2633,19 +2662,10 @@ __xe_lr_bb_exec(struct intel_bb *ibb, uint64_t flags, bool sync)
 	syncs[0].addr = vm_sync_addr;
 	syncs[1].addr = exec_sync_addr;
 
-	if (ibb->num_objects > 1) {
-		bind_ops = xe_alloc_bind_ops(ibb, DRM_XE_VM_BIND_OP_MAP, 0, 0);
-		xe_vm_bind_array(ibb->fd, ibb->vm_id, 0, bind_ops,
-				 ibb->num_objects, syncs, 1);
-		free(bind_ops);
-	} else {
-		igt_debug("bind: MAP\n");
-		igt_debug("  handle: %u, offset: %llx, size: %llx\n",
-			  ibb->handle, (long long)ibb->batch_offset,
-			  (long long)ibb->size);
-		xe_vm_bind_async(ibb->fd, ibb->vm_id, 0, ibb->handle, 0,
-				 ibb->batch_offset, ibb->size, syncs, 1);
-	}
+	bind_ops = __xe_alloc_bind_ops(ibb, DRM_XE_VM_BIND_OP_MAP, 0, 0, true);
+	xe_vm_bind_array(ibb->fd, ibb->vm_id, 0, bind_ops, ibb->num_objects + 1, syncs, 1);
+	free(from_user_pointer(bind_ops[0].extensions));
+	free(bind_ops);
 
 	/* use default vm_bind_exec_queue */
 	xe_wait_ufence(ibb->fd, &sync_data->vm_sync, USER_FENCE_VALUE, 0, -1);
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [PATCH i-g-t 17/21] tests/xe_eudebug_online: Adapt set-breakpoint test to work with new vm bind event interface
  2026-01-12 12:59 [PATCH i-g-t 00/21] eudebug: uapi changes on connect and metadata Mika Kuoppala
                   ` (15 preceding siblings ...)
  2026-01-12 13:00 ` [PATCH i-g-t 16/21] lib/intel_batchbuffer: Add dummy OP_DEBUG_DATA operation to __xe_alloc_bind_ops Mika Kuoppala
@ 2026-01-12 13:00 ` Mika Kuoppala
  2026-01-12 13:00 ` [PATCH i-g-t 18/21] tests/xe_eudebug_online: Adapt several subtests " Mika Kuoppala
                   ` (3 subsequent siblings)
  20 siblings, 0 replies; 23+ messages in thread
From: Mika Kuoppala @ 2026-01-12 13:00 UTC (permalink / raw)
  To: igt-dev
  Cc: christoph.manszewski, dominik.karol.piatkowski, maciej.patelczyk,
	jan.maslak, zbigniew.kempczynski, Mika Kuoppala

From: Christoph Manszewski <christoph.manszewski@intel.com>

Metadata used to be a standalone kernel resource created with a dedicated
ioctl and carried a binary blob as payload. The set-breakpoint testcase
relies on metadata resource creation events for bb ppgtt address and size
passing.

After rework the (now called) debug data can only be passed to the debugger
by mapping it to a vm. Convert the test to use this new interface.

Signed-off-by: Christoph Manszewski <christoph.manszewski@intel.com>
Signed-off-by: Mika Kuoppala <mika.kuoppala@linux.intel.com>
---
 tests/intel/xe_eudebug_online.c | 37 +++++++++++++++++++++++++++++++++
 1 file changed, 37 insertions(+)

diff --git a/tests/intel/xe_eudebug_online.c b/tests/intel/xe_eudebug_online.c
index 34a8ff26e9..a9fa150114 100644
--- a/tests/intel/xe_eudebug_online.c
+++ b/tests/intel/xe_eudebug_online.c
@@ -875,6 +875,32 @@ static void vm_open_trigger(struct xe_eudebug_debugger *d,
 	pthread_mutex_unlock(&data->mutex);
 }
 
+static void online_debug_data_trigger(struct xe_eudebug_debugger *d, struct drm_xe_eudebug_event *e)
+{
+	struct drm_xe_eudebug_event_vm_bind_op_debug_data *ed = (void *)e;
+	struct online_debug_data *data = d->ptr;
+
+	if (!(e->flags & DRM_XE_EUDEBUG_EVENT_CREATE))
+		return;
+
+	igt_assert(ed->flags & DRM_XE_VM_BIND_DEBUG_DATA_FLAG_PSEUDO);
+
+	pthread_mutex_lock(&data->mutex);
+	switch (ed->pseudopath) {
+	case DRM_XE_VM_BIND_DEBUG_DATA_PSEUDO_SBA_AREA:
+		data->bb_offset = ed->addr;
+		data->bb_size = ed->range;
+		break;
+	case DRM_XE_VM_BIND_DEBUG_DATA_PSEUDO_MODULE_AREA:
+		data->target_offset = ed->addr;
+		data->target_size = ed->range;
+		break;
+	default:
+		break;
+	}
+	pthread_mutex_unlock(&data->mutex);
+}
+
 static void overwrite_immediate_value_in_common_target_write(int vm_fd, uint64_t offset,
 							     uint32_t old_val, uint32_t new_val)
 {
@@ -1081,6 +1107,13 @@ static void run_online_client(struct xe_eudebug_client *c)
 
 	create.vm_id = xe_eudebug_client_vm_create(c, vm_flags, 0);
 
+	xe_eudebug_client_vm_bind_debug_data_add(c, create.vm_id, 0, bb_offset, bb_size,
+						 DRM_XE_VM_BIND_DEBUG_DATA_PSEUDO_SBA_AREA,
+						 NULL, NULL, 0);
+	xe_eudebug_client_vm_bind_debug_data_add(c, create.vm_id, 0, target_offset, buf->size,
+						 DRM_XE_VM_BIND_DEBUG_DATA_PSEUDO_MODULE_AREA,
+						 NULL, NULL, 0);
+
 	xe_eudebug_client_exec_queue_create(c, &create);
 
 	ibb = xe_bb_create_on_offset(c->fd,
@@ -1126,6 +1159,8 @@ static void run_online_client(struct xe_eudebug_client *c)
 	intel_bb_destroy(ibb);
 
 	xe_eudebug_client_exec_queue_destroy(c, &create);
+	xe_eudebug_client_vm_bind_debug_data_remove(c, create.vm_id, bb_offset, bb_size);
+	xe_eudebug_client_vm_bind_debug_data_remove(c, create.vm_id, target_offset, buf->size);
 	xe_eudebug_client_vm_destroy(c, create.vm_id);
 
 	intel_buf_destroy(buf);
@@ -1493,6 +1528,8 @@ static void test_set_breakpoint_online(int fd, struct drm_xe_engine_class_instan
 	xe_eudebug_debugger_add_trigger(s->debugger, DRM_XE_EUDEBUG_EVENT_EXEC_QUEUE,
 					exec_queue_trigger);
 	xe_eudebug_debugger_add_trigger(s->debugger, DRM_XE_EUDEBUG_EVENT_VM, vm_open_trigger);
+	xe_eudebug_debugger_add_trigger(s->debugger, DRM_XE_EUDEBUG_EVENT_VM_BIND_OP_DEBUG_DATA,
+					online_debug_data_trigger);
 	xe_eudebug_debugger_add_trigger(s->debugger, DRM_XE_EUDEBUG_EVENT_VM_BIND_UFENCE,
 					ufence_ack_set_bp_trigger);
 	xe_eudebug_debugger_add_trigger(s->debugger, DRM_XE_EUDEBUG_EVENT_EU_ATTENTION,
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [PATCH i-g-t 18/21] tests/xe_eudebug_online: Adapt several subtests to work with new vm bind event interface
  2026-01-12 12:59 [PATCH i-g-t 00/21] eudebug: uapi changes on connect and metadata Mika Kuoppala
                   ` (16 preceding siblings ...)
  2026-01-12 13:00 ` [PATCH i-g-t 17/21] tests/xe_eudebug_online: Adapt set-breakpoint test to work with new vm bind event interface Mika Kuoppala
@ 2026-01-12 13:00 ` Mika Kuoppala
  2026-01-12 13:00 ` [PATCH i-g-t 19/21] lib/xe/xe_eudebug: Add callback for session work Mika Kuoppala
                   ` (2 subsequent siblings)
  20 siblings, 0 replies; 23+ messages in thread
From: Mika Kuoppala @ 2026-01-12 13:00 UTC (permalink / raw)
  To: igt-dev
  Cc: christoph.manszewski, dominik.karol.piatkowski, maciej.patelczyk,
	jan.maslak, zbigniew.kempczynski, Mika Kuoppala

From: Christoph Manszewski <christoph.manszewski@intel.com>

Add 'online_debug_data_trigger' to multiple test functions to adapt the
following subtests to the new debug data passing mechanism:
 - interrupt-all*
 - tdctl-parameters
 - single-step*
 - writes-caching*

Signed-off-by: Christoph Manszewski <christoph.manszewski@intel.com>
Signed-off-by: Mika Kuoppala <mika.kuoppala@linux.intel.com>
---
 tests/intel/xe_eudebug_online.c | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/tests/intel/xe_eudebug_online.c b/tests/intel/xe_eudebug_online.c
index a9fa150114..473c362470 100644
--- a/tests/intel/xe_eudebug_online.c
+++ b/tests/intel/xe_eudebug_online.c
@@ -1596,6 +1596,8 @@ static void test_set_breakpoint_online_sigint_debugger(int fd,
 						ufence_ack_set_bp_trigger);
 		xe_eudebug_debugger_add_trigger(s->debugger, DRM_XE_EUDEBUG_EVENT_EU_ATTENTION,
 						eu_attention_resume_trigger);
+		xe_eudebug_debugger_add_trigger(s->debugger, DRM_XE_EUDEBUG_EVENT_VM_BIND_OP_DEBUG_DATA,
+						online_debug_data_trigger);
 
 		igt_assert_eq(xe_eudebug_debugger_attach(s->debugger, s->client), 0);
 		xe_eudebug_debugger_start_worker(s->debugger);
@@ -1716,6 +1718,8 @@ static void test_pagefault_online(int fd, struct drm_xe_engine_class_instance *h
 	xe_eudebug_debugger_add_trigger(s->debugger, DRM_XE_EUDEBUG_EVENT_EU_ATTENTION,
 					eu_attention_resume_trigger);
 	xe_eudebug_debugger_add_trigger(s->debugger, DRM_XE_EUDEBUG_EVENT_VM, vm_open_trigger);
+	xe_eudebug_debugger_add_trigger(s->debugger, DRM_XE_EUDEBUG_EVENT_VM_BIND_OP_DEBUG_DATA,
+					online_debug_data_trigger);
 	xe_eudebug_debugger_add_trigger(s->debugger, DRM_XE_EUDEBUG_EVENT_VM_BIND_UFENCE,
 					ufence_ack_trigger);
 	xe_eudebug_debugger_add_trigger(s->debugger, DRM_XE_EUDEBUG_EVENT_PAGEFAULT,
@@ -1851,6 +1855,8 @@ static void test_interrupt_all(int fd, struct drm_xe_engine_class_instance *hwe,
 	xe_eudebug_debugger_add_trigger(s->debugger, DRM_XE_EUDEBUG_EVENT_EU_ATTENTION,
 					eu_attention_resume_trigger);
 	xe_eudebug_debugger_add_trigger(s->debugger, DRM_XE_EUDEBUG_EVENT_VM, vm_open_trigger);
+	xe_eudebug_debugger_add_trigger(s->debugger, DRM_XE_EUDEBUG_EVENT_VM_BIND_OP_DEBUG_DATA,
+					online_debug_data_trigger);
 	xe_eudebug_debugger_add_trigger(s->debugger, DRM_XE_EUDEBUG_EVENT_VM_BIND_UFENCE,
 					ufence_ack_trigger);
 
@@ -2024,6 +2030,8 @@ static void test_tdctl_parameters(int fd, struct drm_xe_engine_class_instance *h
 	xe_eudebug_debugger_add_trigger(s->debugger, DRM_XE_EUDEBUG_EVENT_EU_ATTENTION,
 					eu_attention_resume_trigger);
 	xe_eudebug_debugger_add_trigger(s->debugger, DRM_XE_EUDEBUG_EVENT_VM, vm_open_trigger);
+	xe_eudebug_debugger_add_trigger(s->debugger, DRM_XE_EUDEBUG_EVENT_VM_BIND_OP_DEBUG_DATA,
+					online_debug_data_trigger);
 	xe_eudebug_debugger_add_trigger(s->debugger, DRM_XE_EUDEBUG_EVENT_VM_BIND_UFENCE,
 					ufence_ack_trigger);
 
@@ -2237,6 +2245,8 @@ static void test_single_step(int fd, struct drm_xe_engine_class_instance *hwe, i
 	xe_eudebug_debugger_add_trigger(s->debugger, DRM_XE_EUDEBUG_EVENT_EU_ATTENTION,
 					eu_attention_resume_single_step_trigger);
 	xe_eudebug_debugger_add_trigger(s->debugger, DRM_XE_EUDEBUG_EVENT_VM, vm_open_trigger);
+	xe_eudebug_debugger_add_trigger(s->debugger, DRM_XE_EUDEBUG_EVENT_VM_BIND_OP_DEBUG_DATA,
+					online_debug_data_trigger);
 	xe_eudebug_debugger_add_trigger(s->debugger, DRM_XE_EUDEBUG_EVENT_VM_BIND_UFENCE,
 					ufence_ack_trigger);
 
@@ -2334,6 +2344,8 @@ static void test_caching(int fd, struct drm_xe_engine_class_instance *hwe, int f
 	xe_eudebug_debugger_add_trigger(s->debugger, DRM_XE_EUDEBUG_EVENT_EU_ATTENTION,
 					eu_attention_resume_caching_trigger);
 	xe_eudebug_debugger_add_trigger(s->debugger, DRM_XE_EUDEBUG_EVENT_VM, vm_open_trigger);
+	xe_eudebug_debugger_add_trigger(s->debugger, DRM_XE_EUDEBUG_EVENT_VM_BIND_OP_DEBUG_DATA,
+					online_debug_data_trigger);
 	xe_eudebug_debugger_add_trigger(s->debugger, DRM_XE_EUDEBUG_EVENT_VM_BIND_UFENCE,
 					ufence_ack_trigger);
 
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [PATCH i-g-t 19/21] lib/xe/xe_eudebug: Add callback for session work
  2026-01-12 12:59 [PATCH i-g-t 00/21] eudebug: uapi changes on connect and metadata Mika Kuoppala
                   ` (17 preceding siblings ...)
  2026-01-12 13:00 ` [PATCH i-g-t 18/21] tests/xe_eudebug_online: Adapt several subtests " Mika Kuoppala
@ 2026-01-12 13:00 ` Mika Kuoppala
  2026-01-12 13:00 ` [PATCH i-g-t 20/21] tests/intel/xe_eudebug: Add render node testing Mika Kuoppala
  2026-01-12 13:00 ` [PATCH i-g-t 21/21] eudebug: Update xe_drm_eudebug.h uapi Mika Kuoppala
  20 siblings, 0 replies; 23+ messages in thread
From: Mika Kuoppala @ 2026-01-12 13:00 UTC (permalink / raw)
  To: igt-dev
  Cc: christoph.manszewski, dominik.karol.piatkowski, maciej.patelczyk,
	jan.maslak, zbigniew.kempczynski, Mika Kuoppala

If there was a need for special handling during session,
multiple tests baked in the session setup and teardown
into their own boilerplates.

Instead of this, introduce a callback to handle session
work so that tests can avoid the same boilerplate just
in order to have control during the session.

make test_basic_ufence to showcase the new functionality.

TODO: convert other tests

Signed-off-by: Mika Kuoppala <mika.kuoppala@linux.intel.com>
---
 lib/xe/xe_eudebug.c             | 20 ++++++---
 lib/xe/xe_eudebug.h             | 15 +++++--
 tests/intel/xe_eudebug.c        | 75 +++++++++++++++++----------------
 tests/intel/xe_eudebug_online.c | 35 ++++++++-------
 4 files changed, 84 insertions(+), 61 deletions(-)

diff --git a/lib/xe/xe_eudebug.c b/lib/xe/xe_eudebug.c
index f441a3c824..7c1ac38d9c 100644
--- a/lib/xe/xe_eudebug.c
+++ b/lib/xe/xe_eudebug.c
@@ -1744,7 +1744,8 @@ void xe_eudebug_client_wait_stage(struct xe_eudebug_client *c, uint64_t stage)
 /**
  * xe_eudebug_session_create:
  * @fd: Xe file descriptor
- * @work: function passed to the xe_eudebug_client_create
+ * @client_work: function passed to the xe_eudebug_client_create
+ * @session_work: function to add extra session handling (if any)
  * @flags: flags passed to client and debugger
  * @test_private: test's  data, allocated with MAP_SHARED | MAP_ANONYMOUS,
  * passed to client and debugger. Can be NULL.
@@ -1752,7 +1753,8 @@ void xe_eudebug_client_wait_stage(struct xe_eudebug_client *c, uint64_t stage)
  * Creates session together with client and debugger structures.
  */
 struct xe_eudebug_session *xe_eudebug_session_create(int fd,
-						     xe_eudebug_client_work_fn work,
+						     xe_eudebug_client_work_fn client_work,
+						     xe_eudebug_session_work_fn session_work,
 						     unsigned int flags,
 						     void *test_private)
 {
@@ -1761,9 +1763,11 @@ struct xe_eudebug_session *xe_eudebug_session_create(int fd,
 	s = calloc(1, sizeof(*s));
 	igt_assert(s);
 
-	s->client = xe_eudebug_client_create(fd, work, flags, test_private);
+	s->client = xe_eudebug_client_create(fd, client_work, flags, test_private);
 	s->debugger = xe_eudebug_debugger_create(fd, flags, test_private);
+	s->priv = test_private;
 	s->flags = flags;
+	s->session_work = session_work;
 
 	return s;
 }
@@ -1773,8 +1777,10 @@ struct xe_eudebug_session *xe_eudebug_session_create(int fd,
  * @s: pointer to xe_eudebug_session structure
  *
  * Attaches debugger to client's proccess, starts debugger's
- * async event reader, starts client and once client finish
- * it stops debugger worker.
+ * async event reader, starts client. If session work was provided,
+ * it will do extra session work with that callback.
+ * Then session will wait client to finish and stop debugger
+ * and the proceeding with teardown.
  */
 void xe_eudebug_session_run(struct xe_eudebug_session *s)
 {
@@ -1786,6 +1792,10 @@ void xe_eudebug_session_run(struct xe_eudebug_session *s)
 	xe_eudebug_debugger_start_worker(debugger);
 
 	xe_eudebug_client_start(client);
+
+	if (s->session_work)
+		s->session_work(s);
+
 	xe_eudebug_client_wait_done(client);
 
 	xe_eudebug_debugger_stop_worker(debugger);
diff --git a/lib/xe/xe_eudebug.h b/lib/xe/xe_eudebug.h
index acf5bf601d..95d0d023b8 100644
--- a/lib/xe/xe_eudebug.h
+++ b/lib/xe/xe_eudebug.h
@@ -79,16 +79,22 @@ struct xe_eudebug_client {
 	pthread_mutex_t lock;
 };
 
+struct xe_eudebug_session;
+
+typedef void (*xe_eudebug_client_work_fn)(struct xe_eudebug_client *);
+typedef void (*xe_eudebug_trigger_fn)(struct xe_eudebug_debugger *,
+				      struct drm_xe_eudebug_event *);
+typedef void (*xe_eudebug_session_work_fn)(struct xe_eudebug_session *);
+
 struct xe_eudebug_session {
 	uint64_t flags;
+	xe_eudebug_session_work_fn session_work;
+	void *priv;
+
 	struct xe_eudebug_client *client;
 	struct xe_eudebug_debugger *debugger;
 };
 
-typedef void (*xe_eudebug_client_work_fn)(struct xe_eudebug_client *);
-typedef void (*xe_eudebug_trigger_fn)(struct xe_eudebug_debugger *,
-				      struct drm_xe_eudebug_event *);
-
 #define xe_eudebug_for_each_engine(fd__, hwe__) \
 	xe_for_each_engine(fd__, hwe__) \
 		if (hwe__->engine_class == DRM_XE_ENGINE_CLASS_RENDER || \
@@ -261,6 +267,7 @@ void xe_eudebug_client_vm_bind_unmap_with_debug_data(struct xe_eudebug_client *c
 
 struct xe_eudebug_session *xe_eudebug_session_create(int fd,
 						     xe_eudebug_client_work_fn work,
+						     xe_eudebug_session_work_fn session_work,
 						     unsigned int flags,
 						     void *test_private);
 void xe_eudebug_session_destroy(struct xe_eudebug_session *s);
diff --git a/tests/intel/xe_eudebug.c b/tests/intel/xe_eudebug.c
index 9e40f61fcf..4e7ba0348d 100644
--- a/tests/intel/xe_eudebug.c
+++ b/tests/intel/xe_eudebug.c
@@ -890,7 +890,7 @@ static void test_basic_sessions(int fd, unsigned int flags, int count, bool matc
 	igt_assert(s);
 
 	for (i = 0; i < count; i++)
-		s[i] = xe_eudebug_session_create(fd, run_basic_client, flags, NULL);
+		s[i] = xe_eudebug_session_create(fd, run_basic_client, NULL, flags, NULL);
 
 	for (i = 0; i < count; i++)
 		xe_eudebug_session_run(s[i]);
@@ -922,7 +922,8 @@ static void test_basic_discovery(int fd, unsigned int flags, bool match_opposite
 	struct xe_eudebug_session *s;
 	struct xe_eudebug_client *c;
 
-	s = xe_eudebug_session_create(fd, run_basic_client, flags | TEST_DISCOVERY, NULL);
+	s = xe_eudebug_session_create(fd, run_basic_client, NULL,
+				      flags | TEST_DISCOVERY, NULL);
 
 	c = s->client;
 	d = s->debugger;
@@ -1212,7 +1213,8 @@ static void test_empty_discovery(int fd, unsigned int flags, int clients)
 	threads = calloc(clients, sizeof(*threads));
 
 	for (i = 0; i < clients; i++)
-		s[i] = xe_eudebug_session_create(fd, run_discovery_client, flags, NULL);
+		s[i] = xe_eudebug_session_create(fd, run_discovery_client,
+						 NULL, flags, NULL);
 
 	for (i = 0; i < clients; i++) {
 		xe_eudebug_client_start(s[i]->client);
@@ -1262,7 +1264,7 @@ static void test_client_with_trigger(int fd, unsigned int flags, int count,
 	igt_assert(s);
 
 	for (i = 0; i < count; i++)
-		s[i] = xe_eudebug_session_create(fd, client_fn, flags, hwe);
+		s[i] = xe_eudebug_session_create(fd, client_fn, NULL, flags, hwe);
 
 	if (trigger_fn)
 		for (i = 0; i < count; i++)
@@ -1864,6 +1866,31 @@ static int wait_for_ufence_events(struct ufence_priv *priv, int timeout_ms)
 	return ret;
 }
 
+static void ufence_session_work(struct xe_eudebug_session *s)
+{
+	struct ufence_priv *priv = s->priv;
+	struct xe_eudebug_debugger *d = s->debugger;
+	struct xe_eudebug_client *c = s->client;
+
+	xe_eudebug_debugger_wait_stage(s, STAGE_CLIENT_WAIT_ON_UFENCE_DONE);
+	xe_eudebug_assert_f(d,
+			    wait_for_ufence_events(priv, XE_EUDEBUG_DEFAULT_TIMEOUT_SEC * MSEC_PER_SEC) == 0,
+			    "missing ufence events\n");
+
+	if (s->flags & VM_BIND_DELAY_UFENCE_ACK)
+		sleep(XE_EUDEBUG_DEFAULT_TIMEOUT_SEC * 4 / 5);
+
+	if (s->flags & VM_BIND_UFENCE_SIGINT_CLIENT) {
+		kill(c->pid, SIGINT);
+		c->pid = 0;
+		c->done = 1;
+	} else if (s->flags & VM_BIND_UFENCE_DISCONNECT) {
+		close(d->fd);
+	} else {
+		ack_fences(d);
+	}
+}
+
 /**
  * SUBTEST: basic-vm-bind-ufence
  * Functionality: VM bind event
@@ -1890,47 +1917,23 @@ static void test_basic_ufence(int fd, unsigned int flags)
 {
 	struct xe_eudebug_debugger *d;
 	struct xe_eudebug_session *s;
-	struct xe_eudebug_client *c;
 	struct ufence_priv *priv;
 	uint32_t filter = XE_EUDEBUG_FILTER_EVENT_VM_BIND_UFENCE;
 
 	priv = ufence_priv_create();
-	s = xe_eudebug_session_create(fd, basic_ufence_client, flags, priv);
-	c = s->client;
+	s = xe_eudebug_session_create(fd, basic_ufence_client,
+				      ufence_session_work, flags, priv);
 	d = s->debugger;
 
 	xe_eudebug_debugger_add_trigger(d,
 					DRM_XE_EUDEBUG_EVENT_VM_BIND_UFENCE,
 					basic_ufence_trigger);
 
-	igt_assert_eq(xe_eudebug_debugger_attach(d, c), 0);
-	xe_eudebug_debugger_start_worker(d);
-	xe_eudebug_client_start(c);
-
-	xe_eudebug_debugger_wait_stage(s, STAGE_CLIENT_WAIT_ON_UFENCE_DONE);
-	xe_eudebug_assert_f(d, wait_for_ufence_events(priv, XE_EUDEBUG_DEFAULT_TIMEOUT_SEC * MSEC_PER_SEC) == 0,
-			    "missing ufence events\n");
-
-	if (flags & VM_BIND_DELAY_UFENCE_ACK)
-		sleep(XE_EUDEBUG_DEFAULT_TIMEOUT_SEC * 4 / 5);
+	xe_eudebug_session_run(s);
 
-	if (flags & VM_BIND_UFENCE_SIGINT_CLIENT) {
-		filter = XE_EUDEBUG_FILTER_ALL;
-		kill(c->pid, SIGINT);
-		c->pid = 0;
-		c->done = 1;
-	} else if (flags & VM_BIND_UFENCE_DISCONNECT) {
+	if (s->flags & VM_BIND_UFENCE_SIGINT_CLIENT ||
+	    s->flags & VM_BIND_UFENCE_DISCONNECT)
 		filter = XE_EUDEBUG_FILTER_ALL;
-		close(s->debugger->fd);
-	} else {
-		ack_fences(d);
-	}
-
-	xe_eudebug_client_wait_done(c);
-	xe_eudebug_debugger_stop_worker(d);
-
-	xe_eudebug_event_log_print(d->log, true);
-	xe_eudebug_event_log_print(c->log, true);
 
 	xe_eudebug_session_check(s, true, filter);
 
@@ -2211,7 +2214,7 @@ static void test_vm_bind_clear(int fd, uint32_t flags)
 	igt_require(!(flags & TEST_FAULTABLE) || !xe_supports_faults(fd));
 
 	priv = vm_bind_clear_priv_create();
-	s = xe_eudebug_session_create(fd, vm_bind_clear_client, flags, priv);
+	s = xe_eudebug_session_create(fd, vm_bind_clear_client, NULL, flags, priv);
 
 	xe_eudebug_debugger_add_trigger(s->debugger,
 					DRM_XE_EUDEBUG_EVENT_VM_BIND_OP_DEBUG_DATA,
@@ -2443,7 +2446,7 @@ static void test_vma_ufence(int fd, unsigned int flags)
 	igt_require(!(flags & TEST_FAULTABLE) || !xe_supports_faults(fd));
 
 	priv = ufence_priv_create();
-	s = xe_eudebug_session_create(fd, vma_ufence_client, flags, priv);
+	s = xe_eudebug_session_create(fd, vma_ufence_client, NULL, flags, priv);
 
 	xe_eudebug_debugger_add_trigger(s->debugger,
 					DRM_XE_EUDEBUG_EVENT_VM_BIND_OP_DEBUG_DATA,
@@ -2685,7 +2688,7 @@ static void test_debug_data(int fd)
 
 	priv = ufence_priv_create();
 
-	s = xe_eudebug_session_create(fd, debug_data_ufence_client, 0, priv);
+	s = xe_eudebug_session_create(fd, debug_data_ufence_client, NULL, 0, priv);
 
 	xe_eudebug_debugger_add_trigger(s->debugger,
 					DRM_XE_EUDEBUG_EVENT_VM_BIND_OP_DEBUG_DATA,
diff --git a/tests/intel/xe_eudebug_online.c b/tests/intel/xe_eudebug_online.c
index 473c362470..b1690a7397 100644
--- a/tests/intel/xe_eudebug_online.c
+++ b/tests/intel/xe_eudebug_online.c
@@ -1487,8 +1487,9 @@ static void test_basic_online(int fd, struct drm_xe_engine_class_instance *hwe,
 	struct xe_eudebug_session *s;
 	struct online_debug_data *data;
 
+
 	data = online_debug_data_create(fd, hwe, flags);
-	s = xe_eudebug_session_create(fd, run_online_client, flags, data);
+	s = xe_eudebug_session_create(fd, run_online_client, NULL, flags, data);
 
 	xe_eudebug_debugger_add_trigger(s->debugger, DRM_XE_EUDEBUG_EVENT_EU_ATTENTION,
 					eu_attention_debug_trigger);
@@ -1524,7 +1525,8 @@ static void test_set_breakpoint_online(int fd, struct drm_xe_engine_class_instan
 	igt_require(!(flags & FAULTABLE_VM) || !xe_supports_faults(fd));
 
 	data = online_debug_data_create(fd, hwe, flags);
-	s = xe_eudebug_session_create(fd, run_online_client, flags, data);
+	s = xe_eudebug_session_create(fd, run_online_client, NULL, flags, data);
+
 	xe_eudebug_debugger_add_trigger(s->debugger, DRM_XE_EUDEBUG_EVENT_EXEC_QUEUE,
 					exec_queue_trigger);
 	xe_eudebug_debugger_add_trigger(s->debugger, DRM_XE_EUDEBUG_EVENT_VM, vm_open_trigger);
@@ -1585,7 +1587,8 @@ static void test_set_breakpoint_online_sigint_debugger(int fd,
 		igt_debug("Loop %d: SIGINT after %" PRIu64 " us\n", loop_count, sleep_time);
 
 		data = online_debug_data_create(fd, hwe, flags);
-		s = xe_eudebug_session_create(fd, run_online_client, flags, data);
+		s = xe_eudebug_session_create(fd, run_online_client, NULL, flags, data);
+
 		s->client->allow_dead_client = true;
 
 		xe_eudebug_debugger_add_trigger(s->debugger, DRM_XE_EUDEBUG_EVENT_EXEC_QUEUE,
@@ -1709,7 +1712,7 @@ static void test_pagefault_online(int fd, struct drm_xe_engine_class_instance *h
 
 		data->max_subslices_per_slice = DIV_ROUND_UP(max_ss, max_sl);
 	}
-	s = xe_eudebug_session_create(fd, run_online_client, data->flags, data);
+	s = xe_eudebug_session_create(fd, run_online_client, NULL, data->flags, data);
 
 	xe_eudebug_debugger_add_trigger(s->debugger, DRM_XE_EUDEBUG_EVENT_EXEC_QUEUE,
 					exec_queue_trigger);
@@ -1747,7 +1750,8 @@ static void test_preemption(int fd, struct drm_xe_engine_class_instance *hwe)
 	struct xe_eudebug_client *other;
 
 	data = online_debug_data_create(fd, hwe, flags);
-	s = xe_eudebug_session_create(fd, run_online_client, flags, data);
+	s = xe_eudebug_session_create(fd, run_online_client, NULL, flags, data);
+
 	other = xe_eudebug_client_create(fd, run_online_client, SHADER_NOP, data);
 
 	xe_eudebug_debugger_add_trigger(s->debugger, DRM_XE_EUDEBUG_EVENT_EU_ATTENTION,
@@ -1792,7 +1796,7 @@ static void test_reset_with_attention_online(int fd, struct drm_xe_engine_class_
 	struct online_debug_data *data;
 
 	data = online_debug_data_create(fd, hwe, flags);
-	s1 = xe_eudebug_session_create(fd, run_online_client, flags, data);
+	s1 = xe_eudebug_session_create(fd, run_online_client, NULL, flags, data);
 
 	xe_eudebug_debugger_add_trigger(s1->debugger, DRM_XE_EUDEBUG_EVENT_EU_ATTENTION,
 					eu_attention_reset_trigger);
@@ -1802,7 +1806,7 @@ static void test_reset_with_attention_online(int fd, struct drm_xe_engine_class_
 	xe_eudebug_session_run(s1);
 	xe_eudebug_session_destroy(s1);
 
-	s2 = xe_eudebug_session_create(fd, run_online_client, flags, data);
+	s2 = xe_eudebug_session_create(fd, run_online_client, NULL, flags, data);
 	xe_eudebug_debugger_add_trigger(s2->debugger, DRM_XE_EUDEBUG_EVENT_EU_ATTENTION,
 					eu_attention_resume_trigger);
 	xe_eudebug_debugger_add_trigger(s2->debugger, DRM_XE_EUDEBUG_EVENT_VM_BIND_UFENCE,
@@ -1846,7 +1850,7 @@ static void test_interrupt_all(int fd, struct drm_xe_engine_class_instance *hwe,
 	igt_require(!(flags & FAULTABLE_VM) || !xe_supports_faults(fd));
 
 	data = online_debug_data_create(fd, hwe, flags);
-	s = xe_eudebug_session_create(fd, run_online_client, flags, data);
+	s = xe_eudebug_session_create(fd, run_online_client, NULL, flags, data);
 
 	xe_eudebug_debugger_add_trigger(s->debugger, DRM_XE_EUDEBUG_EVENT_EXEC_QUEUE,
 					exec_queue_trigger);
@@ -1934,7 +1938,7 @@ static void test_interrupt_other(int fd, struct drm_xe_engine_class_instance *hw
 	int val;
 
 	data = online_debug_data_create(fd, hwe, flags);
-	s = xe_eudebug_session_create(fd, run_online_client, flags, data);
+	s = xe_eudebug_session_create(fd, run_online_client, NULL, flags, data);
 
 	xe_eudebug_debugger_add_trigger(s->debugger, DRM_XE_EUDEBUG_EVENT_EXEC_QUEUE,
 					exec_queue_trigger);
@@ -2021,7 +2025,7 @@ static void test_tdctl_parameters(int fd, struct drm_xe_engine_class_instance *h
 	igt_assert(attention_bitmask);
 
 	data = online_debug_data_create(fd, hwe, flags);
-	s = xe_eudebug_session_create(fd, run_online_client, flags, data);
+	s = xe_eudebug_session_create(fd, run_online_client, NULL, flags, data);
 
 	xe_eudebug_debugger_add_trigger(s->debugger, DRM_XE_EUDEBUG_EVENT_EXEC_QUEUE,
 					exec_queue_trigger);
@@ -2164,7 +2168,7 @@ static void test_interrupt_reconnect(int fd, struct drm_xe_engine_class_instance
 	uint32_t val;
 
 	data = online_debug_data_create(fd, hwe, flags);
-	s = xe_eudebug_session_create(fd, run_online_client, flags, data);
+	s = xe_eudebug_session_create(fd, run_online_client, NULL, flags, data);
 
 	xe_eudebug_debugger_add_trigger(s->debugger, DRM_XE_EUDEBUG_EVENT_EXEC_QUEUE,
 					exec_queue_trigger);
@@ -2238,7 +2242,7 @@ static void test_single_step(int fd, struct drm_xe_engine_class_instance *hwe, i
 	struct online_debug_data *data;
 
 	data = online_debug_data_create(fd, hwe, flags);
-	s = xe_eudebug_session_create(fd, run_online_client, flags, data);
+	s = xe_eudebug_session_create(fd, run_online_client, NULL, flags, data);
 
 	xe_eudebug_debugger_add_trigger(s->debugger, DRM_XE_EUDEBUG_EVENT_EU_ATTENTION,
 					eu_attention_debug_trigger);
@@ -2286,8 +2290,7 @@ static void test_debugger_reopen(int fd, struct drm_xe_engine_class_instance *hw
 	struct online_debug_data *data;
 
 	data = online_debug_data_create(fd, hwe, flags);
-
-	s = xe_eudebug_session_create(fd, run_online_client, flags, data);
+	s = xe_eudebug_session_create(fd, run_online_client, NULL, flags, data);
 
 	xe_eudebug_debugger_add_trigger(s->debugger, DRM_XE_EUDEBUG_EVENT_EU_ATTENTION,
 					eu_attention_debug_trigger);
@@ -2337,7 +2340,7 @@ static void test_caching(int fd, struct drm_xe_engine_class_instance *hwe, int f
 		igt_skip_on_f(!xe_has_vram(fd), "Device does not have VRAM.\n");
 
 	data = online_debug_data_create(fd, hwe, flags);
-	s = xe_eudebug_session_create(fd, run_online_client, flags, data);
+	s = xe_eudebug_session_create(fd, run_online_client, NULL, flags, data);
 
 	xe_eudebug_debugger_add_trigger(s->debugger, DRM_XE_EUDEBUG_EVENT_EU_ATTENTION,
 					eu_attention_debug_trigger);
@@ -2463,7 +2466,7 @@ static void test_many_sessions_on_tiles(int fd, bool multi_tile)
 
 	for (i = 0; i < n; i++) {
 		data[i] = online_debug_data_create(fd, hwe[i], flags);
-		s[i] = xe_eudebug_session_create(fd, run_online_client, flags, data[i]);
+		s[i] = xe_eudebug_session_create(fd, run_online_client, NULL, flags, data[i]);
 
 		xe_eudebug_debugger_add_trigger(s[i]->debugger, DRM_XE_EUDEBUG_EVENT_EU_ATTENTION,
 						eu_attention_debug_trigger);
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [PATCH i-g-t 20/21] tests/intel/xe_eudebug: Add render node testing
  2026-01-12 12:59 [PATCH i-g-t 00/21] eudebug: uapi changes on connect and metadata Mika Kuoppala
                   ` (18 preceding siblings ...)
  2026-01-12 13:00 ` [PATCH i-g-t 19/21] lib/xe/xe_eudebug: Add callback for session work Mika Kuoppala
@ 2026-01-12 13:00 ` Mika Kuoppala
  2026-01-12 13:00 ` [PATCH i-g-t 21/21] eudebug: Update xe_drm_eudebug.h uapi Mika Kuoppala
  20 siblings, 0 replies; 23+ messages in thread
From: Mika Kuoppala @ 2026-01-12 13:00 UTC (permalink / raw)
  To: igt-dev
  Cc: christoph.manszewski, dominik.karol.piatkowski, maciej.patelczyk,
	jan.maslak, zbigniew.kempczynski, Mika Kuoppala

We need basic-connect to also check if render node is
available for connection.

Signed-off-by: Mika Kuoppala <mika.kuoppala@linux.intel.com>
---
 tests/intel/xe_eudebug.c | 41 ++++++++++++++++++++++++++++++++++------
 1 file changed, 35 insertions(+), 6 deletions(-)

diff --git a/tests/intel/xe_eudebug.c b/tests/intel/xe_eudebug.c
index 4e7ba0348d..01410f3197 100644
--- a/tests/intel/xe_eudebug.c
+++ b/tests/intel/xe_eudebug.c
@@ -460,6 +460,9 @@ static int __debug_connect(int fd, int *debugfd, struct drm_xe_eudebug_connect *
 	return ret;
 }
 
+
+#define TEST_CONNECT_RENDER BIT(0)
+
 /**
  * SUBTEST: basic-connect
  * Functionality: attach
@@ -467,23 +470,34 @@ static int __debug_connect(int fd, int *debugfd, struct drm_xe_eudebug_connect *
  *	Exercise XE_EUDEBUG_CONNECT ioctl with passing
  *	valid and invalid params.
  */
-static void test_connect(int fd)
+static void test_connect(int fd, unsigned int flags)
 {
 	struct drm_xe_eudebug_connect param = {};
-	int debugfd, ret;
+	int debugfd, ret, render_fd, target_fd;
 	pid_t *pid;
 
 	pid = mmap(NULL, sizeof(pid_t), PROT_WRITE,
 		   MAP_SHARED | MAP_ANON, -1, 0);
 
+	if (flags & TEST_CONNECT_RENDER)
+		render_fd = drm_open_driver_render(DRIVER_XE);
+
 	/* get fresh unrelated pid */
-	igt_fork(child, 1)
+	igt_fork(child, 1) {
+		if (flags & TEST_CONNECT_RENDER)
+			close(fd);
 		*pid = getpid();
+		igt_info("client in pid %d\n", *pid);
+		sleep(5);
+	}
 
-	igt_waitchildren();
-	param.fd = xe_eudebug_fd_for_pid(*pid);
+	/* XXX build a sync mechanism */
+	sleep(1);
+	target_fd = xe_eudebug_fd_for_pid(*pid);
+	igt_assert(target_fd >= 0);
 	munmap(pid, sizeof(pid_t));
 
+	param.fd = target_fd + random() + 1;
 	ret = __debug_connect(fd, &debugfd, &param);
 	igt_assert(debugfd == -1);
 	igt_assert_eq(ret, -EBADFD);
@@ -493,7 +507,15 @@ static void test_connect(int fd)
 	igt_assert(debugfd == -1);
 	igt_assert_eq(ret, -EINVAL);
 
+	param.fd = target_fd;
+	ret = __debug_connect(fd, &debugfd, &param);
+	igt_assert_neq(debugfd, -1);
+	igt_assert_eq(ret, 0);
+
+	close(debugfd);
+
 	param.fd = xe_eudebug_fd_for_pid(getpid());
+	igt_assert((int)param.fd >= 0);
 	param.version = -1;
 	ret = __debug_connect(fd, &debugfd, &param);
 	igt_assert(debugfd == -1);
@@ -517,6 +539,10 @@ static void test_connect(int fd)
 	igt_assert_eq(ret, 0);
 
 	close(debugfd);
+	if (flags & TEST_CONNECT_RENDER)
+		close(render_fd);
+
+	igt_waitchildren();
 }
 
 static void switch_user(__uid_t uid, __gid_t gid)
@@ -2789,7 +2815,10 @@ int igt_main()
 		test_sysfs_toggle(fd);
 
 	igt_subtest("basic-connect")
-		test_connect(fd);
+		test_connect(fd, 0);
+
+	igt_subtest("basic-connect-render")
+		test_connect(fd, TEST_CONNECT_RENDER);
 
 	igt_subtest("connect-user")
 		test_connect_user(fd);
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [PATCH i-g-t 21/21] eudebug: Update xe_drm_eudebug.h uapi
  2026-01-12 12:59 [PATCH i-g-t 00/21] eudebug: uapi changes on connect and metadata Mika Kuoppala
                   ` (19 preceding siblings ...)
  2026-01-12 13:00 ` [PATCH i-g-t 20/21] tests/intel/xe_eudebug: Add render node testing Mika Kuoppala
@ 2026-01-12 13:00 ` Mika Kuoppala
  20 siblings, 0 replies; 23+ messages in thread
From: Mika Kuoppala @ 2026-01-12 13:00 UTC (permalink / raw)
  To: igt-dev
  Cc: christoph.manszewski, dominik.karol.piatkowski, maciej.patelczyk,
	jan.maslak, zbigniew.kempczynski, Mika Kuoppala

Take into account bind event member naming change from
num_binds to num_bind_ops. Also documentation and ordering
changes for eudebug uapi.

Signed-off-by: Mika Kuoppala <mika.kuoppala@linux.intel.com>
---
 .../drm-uapi-experimental/xe_drm_eudebug.h    | 155 ++++++++++--------
 lib/xe/xe_eudebug.c                           |  14 +-
 2 files changed, 98 insertions(+), 71 deletions(-)

diff --git a/include/drm-uapi-experimental/xe_drm_eudebug.h b/include/drm-uapi-experimental/xe_drm_eudebug.h
index 43b8d12b47..56a2f6aac9 100644
--- a/include/drm-uapi-experimental/xe_drm_eudebug.h
+++ b/include/drm-uapi-experimental/xe_drm_eudebug.h
@@ -55,12 +55,34 @@ struct drm_xe_eudebug_connect {
  * This ioctl is available in debug version 1.
  */
 #define DRM_XE_EUDEBUG_IOCTL_READ_EVENT		_IO('j', 0x0)
-#define DRM_XE_EUDEBUG_IOCTL_EU_CONTROL		_IOWR('j', 0x2, struct drm_xe_eudebug_eu_control)
-#define DRM_XE_EUDEBUG_IOCTL_ACK_EVENT		_IOW('j', 0x4, struct drm_xe_eudebug_ack_event)
-#define DRM_XE_EUDEBUG_IOCTL_VM_OPEN		_IOW('j', 0x1, struct drm_xe_eudebug_vm_open)
-#define DRM_XE_EUDEBUG_IOCTL_READ_METADATA	_IOWR('j', 0x3, struct drm_xe_eudebug_read_metadata)
+#define DRM_XE_EUDEBUG_IOCTL_ACK_EVENT		_IOW('j', 0x1, struct drm_xe_eudebug_ack_event)
+#define DRM_XE_EUDEBUG_IOCTL_VM_OPEN		_IOW('j', 0x2, struct drm_xe_eudebug_vm_open)
+#define DRM_XE_EUDEBUG_IOCTL_EU_CONTROL		_IOWR('j', 0x3, struct drm_xe_eudebug_eu_control)
 
-/* XXX: Document events to match their internal counterparts when moved to xe_drm.h */
+/**
+ * struct drm_xe_eudebug_event - Base type of event delivered by xe_eudebug.
+ * @len: Length of event, including the base, of event.
+ * @type: Event type
+ * @flags: Flags for the event
+ * @seqno: Sequence number
+ * @reserved: MBZ
+ *
+ * Base event for xe_eudebug interface. To initiate a read, type
+ * needs to be set to DRM_XE_EUDEBUG_EVENT_READ and length
+ * need to be set by userspace to what has been allocated as max.
+ * On successful return the event len will be deliver or -EMSGSIZE
+ * if it does not fit. Seqno can be used to form a timeline
+ * as event delivery order does not guarantee event creation
+ * order.
+ *
+ * flags will indicate if resource was created, destroyed
+ * or its state changed.
+ *
+ * if DRM_XE_EUDEBUG_EVENT_NEED_ACK is set, the xe_eudebug
+ * will held the said resource until it is acked by userspace
+ * using another acking ioctl with the seqno of said event.
+ *
+ */
 struct drm_xe_eudebug_event {
 	__u32 len;
 
@@ -85,6 +107,12 @@ struct drm_xe_eudebug_event {
 	__u64 reserved;
 };
 
+/**
+ * struct drm_xe_eudebug_event_vm - VM resource event
+ * @vm_handle: Handle of a vm that was created/destroyed
+ *
+ * Resource creation/destruction event for a VM.
+ */
 struct drm_xe_eudebug_event_vm {
 	struct drm_xe_eudebug_event base;
 
@@ -101,55 +129,29 @@ struct drm_xe_eudebug_event_exec_queue {
 	__u64 lrc_handle[];
 };
 
-struct drm_xe_eudebug_event_eu_attention {
-	struct drm_xe_eudebug_event base;
-
-	__u64 exec_queue_handle;
-	__u64 lrc_handle;
-	__u32 flags;
-	__u32 bitmask_size;
-	__u8 bitmask[];
-};
-
-struct drm_xe_eudebug_eu_control {
-
-#define DRM_XE_EUDEBUG_EU_CONTROL_CMD_INTERRUPT_ALL	0
-#define DRM_XE_EUDEBUG_EU_CONTROL_CMD_STOPPED		1
-#define DRM_XE_EUDEBUG_EU_CONTROL_CMD_RESUME		2
-	__u32 cmd;
-	__u32 flags;
-
-	__u64 seqno;
-
-	__u64 exec_queue_handle;
-	__u64 lrc_handle;
-	__u32 reserved;
-	__u32 bitmask_size;
-	__u64 bitmask_ptr;
-};
-
 /*
- *  When client (debuggee) does vm_bind_ioctl() following event
- *  sequence will be created (for the debugger):
+ * When the client (debuggee) calls the vm_bind_ioctl with the
+ * DRM_XE_VM_BIND_OP_[ADD|REMOVE]_DEBUG_DATA operation, the following event
+ * sequence will be created (for the debugger):
  *
  *  ┌───────────────────────┐
- *  │  EVENT_VM_BIND        ├───────┬─┬─┐
- *  └───────────────────────┘       │ │ │
- *      ┌───────────────────────┐   │ │ │
- *      │ EVENT_VM_BIND_OP #1   ├───┘ │ │
- *      └───────────────────────┘     │ │
- *                 ...                │ │
- *      ┌───────────────────────┐     │ │
- *      │ EVENT_VM_BIND_OP #n   ├─────┘ │
- *      └───────────────────────┘       │
- *                                      │
- *      ┌───────────────────────┐       │
- *      │ EVENT_UFENCE          ├───────┘
- *      └───────────────────────┘
+ *  │  EVENT_VM_BIND        ├──────────────────┬─┬┄┐
+ *  └───────────────────────┘                  │ │ ┊
+ *      ┌──────────────────────────────────┐   │ │ ┊
+ *      │ EVENT_VM_BIND_OP_DEBUG_DATA #1   ├───┘ │ ┊
+ *      └──────────────────────────────────┘     │ ┊
+ *                      ...                      │ ┊
+ *      ┌──────────────────────────────────┐     │ ┊
+ *      │ EVENT_VM_BIND_OP_DEBUG_DATA #n   ├─────┘ ┊
+ *      └──────────────────────────────────┘       ┊
+ *                                                 ┊
+ *      ┌┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┐       ┊
+ *      ┊ EVENT_UFENCE                     ├┄┄┄┄┄┄┄┘
+ *      └┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┘
  *
  * All the events below VM_BIND will reference the VM_BIND
  * they associate with, by field .vm_bind_ref_seqno.
- * event_ufence will only be included if the client did
+ * EVENT_UFENCE will only be included if the client did
  * attach sync of type UFENCE into its vm_bind_ioctl().
  *
  * When EVENT_UFENCE is sent by the driver, all the OPs of
@@ -173,27 +175,26 @@ struct drm_xe_eudebug_event_vm_bind {
 	struct drm_xe_eudebug_event base;
 
 	__u64 vm_handle;
-
 	__u32 flags;
 #define DRM_XE_EUDEBUG_EVENT_VM_BIND_FLAG_UFENCE (1 << 0)
 
-	__u32 num_binds;
+	__u32 num_bind_ops;
 };
 
 struct drm_xe_eudebug_event_vm_bind_op_debug_data {
-        struct drm_xe_eudebug_event base;
-        __u64 vm_bind_ref_seqno; /* *_event_vm_bind.base.seqno */
-        __u64 num_extensions;
-
-        __u64 addr;
-        __u64 range;
-        __u64 flags;
-        __u32 offset;
-        __u32 reserved;
-        union {
-                __u64 pseudopath;
-                char pathname[PATH_MAX];
-        };
+	struct drm_xe_eudebug_event base;
+	__u64 vm_bind_ref_seqno; /* *_event_vm_bind.base.seqno */
+	__u64 num_extensions;
+
+	__u64 addr;
+	__u64 range;
+	__u64 flags;
+	__u32 offset;
+	__u32 reserved;
+	union {
+		__u64 pseudopath;
+		char pathname[PATH_MAX];
+	};
 };
 
 struct drm_xe_eudebug_event_vm_bind_ufence {
@@ -217,11 +218,37 @@ struct drm_xe_eudebug_vm_open {
 	/** @flags: flags */
 	__u64 flags;
 
-#define DRM_XE_EUDEBUG_VM_SYNC_MAX_TIMEOUT_NSECS (10ULL * NSEC_PER_SEC)
 	/** @timeout_ns: Timeout value in nanoseconds operations (fsync) */
 	__u64 timeout_ns;
 };
 
+struct drm_xe_eudebug_eu_control {
+
+#define DRM_XE_EUDEBUG_EU_CONTROL_CMD_INTERRUPT_ALL	0
+#define DRM_XE_EUDEBUG_EU_CONTROL_CMD_STOPPED		1
+#define DRM_XE_EUDEBUG_EU_CONTROL_CMD_RESUME		2
+	__u32 cmd;
+	__u32 flags;
+
+	__u64 seqno;
+
+	__u64 exec_queue_handle;
+	__u64 lrc_handle;
+	__u32 reserved;
+	__u32 bitmask_size;
+	__u64 bitmask_ptr;
+};
+
+struct drm_xe_eudebug_event_eu_attention {
+	struct drm_xe_eudebug_event base;
+
+	__u64 exec_queue_handle;
+	__u64 lrc_handle;
+	__u32 flags;
+	__u32 bitmask_size;
+	__u8 bitmask[];
+};
+
 struct drm_xe_eudebug_event_pagefault {
 	struct drm_xe_eudebug_event base;
 
diff --git a/lib/xe/xe_eudebug.c b/lib/xe/xe_eudebug.c
index 7c1ac38d9c..1e3cdfe048 100644
--- a/lib/xe/xe_eudebug.c
+++ b/lib/xe/xe_eudebug.c
@@ -146,8 +146,8 @@ static const char *event_members_to_str(struct drm_xe_eudebug_event *e, char *bu
 	case DRM_XE_EUDEBUG_EVENT_VM_BIND: {
 		struct drm_xe_eudebug_event_vm_bind *evmb = igt_container_of(e, evmb, base);
 
-		sprintf(buf, "vm_handle=%llu, flags=0x%x, num_binds=%u",
-			evmb->vm_handle, evmb->flags, evmb->num_binds);
+		sprintf(buf, "vm_handle=%llu, flags=0x%x, num_bind_ops=%u",
+			evmb->vm_handle, evmb->flags, evmb->num_bind_ops);
 		break;
 	}
 	case DRM_XE_EUDEBUG_EVENT_VM_BIND_OP_DEBUG_DATA: {
@@ -596,7 +596,7 @@ static int match_fields(struct drm_xe_eudebug_event *a, void *data)
 		struct drm_xe_eudebug_event_vm_bind *ea = igt_container_of(a, ea, base);
 		struct drm_xe_eudebug_event_vm_bind *eb = igt_container_of(b, eb, base);
 
-		if (ea->num_binds == eb->num_binds)
+		if (ea->num_bind_ops == eb->num_bind_ops)
 			ret = 1;
 		break;
 	}
@@ -699,7 +699,7 @@ static int match_opposite_resource(struct drm_xe_eudebug_event *e, void *data)
 		struct drm_xe_eudebug_event_vm_bind *filter = data;
 
 		if (evmb->vm_handle == filter->vm_handle &&
-		    evmb->num_binds == filter->num_binds)
+		    evmb->num_bind_ops == filter->num_bind_ops)
 			return 1;
 		break;
 	}
@@ -2077,14 +2077,14 @@ void xe_eudebug_client_exec_queue_destroy(struct xe_eudebug_client *c,
  * @event_flags: base event flags
  * @vm: vm handle
  * @bind_flags: bind flags of vm_bind_event
- * @num_binds: number of bind (operations) for event
+ * @num_binds_ops: number of bind (operations) for event
  * @ref_seqno: base vm bind reference seqno
  * Logs vm bind event in client's event log.
  */
 void xe_eudebug_client_vm_bind_event(struct xe_eudebug_client *c,
 				     uint32_t event_flags,
 				     uint32_t vm, uint32_t bind_flags,
-				     uint32_t num_binds, u64 *ref_seqno)
+				     uint32_t num_bind_ops, u64 *ref_seqno)
 {
 	struct drm_xe_eudebug_event_vm_bind evmb;
 
@@ -2095,7 +2095,7 @@ void xe_eudebug_client_vm_bind_event(struct xe_eudebug_client *c,
 		   event_flags, sizeof(evmb));
 	evmb.vm_handle = vm;
 	evmb.flags = bind_flags;
-	evmb.num_binds = num_binds;
+	evmb.num_bind_ops = num_bind_ops;
 
 	*ref_seqno = evmb.base.seqno;
 
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 23+ messages in thread

* RE: [PATCH i-g-t 04/21] tests/intel/xe_eudebug_sriov: Align expected return code
  2026-01-12 12:59 ` [PATCH i-g-t 04/21] tests/intel/xe_eudebug_sriov: Align expected return code Mika Kuoppala
@ 2026-01-12 13:12   ` Piatkowski, Dominik Karol
  0 siblings, 0 replies; 23+ messages in thread
From: Piatkowski, Dominik Karol @ 2026-01-12 13:12 UTC (permalink / raw)
  To: Mika Kuoppala, igt-dev@lists.freedesktop.org
  Cc: Manszewski, Christoph, Patelczyk, Maciej, Maslak, Jan,
	Kempczynski, Zbigniew

Reviewed-by: Dominik Karol Piątkowski <dominik.karol.piatkowski@intel.com>

> -----Original Message-----
> From: Mika Kuoppala <mika.kuoppala@linux.intel.com>
> Sent: Monday, January 12, 2026 2:00 PM
> To: igt-dev@lists.freedesktop.org
> Cc: Manszewski, Christoph <christoph.manszewski@intel.com>; Piatkowski,
> Dominik Karol <dominik.karol.piatkowski@intel.com>; Patelczyk, Maciej
> <maciej.patelczyk@intel.com>; Maslak, Jan <jan.maslak@intel.com>;
> Kempczynski, Zbigniew <zbigniew.kempczynski@intel.com>; Mika Kuoppala
> <mika.kuoppala@linux.intel.com>
> Subject: [PATCH i-g-t 04/21] tests/intel/xe_eudebug_sriov: Align expected
> return code
> 
> From: Christoph Manszewski <christoph.manszewski@intel.com>
> 
> Align with kernel commit 387aba39b7be (drm/xe/pf: Allow to lockdown
> the PF using custom guard).
> 
> Signed-off-by: Christoph Manszewski <christoph.manszewski@intel.com>
> Signed-off-by: Mika Kuoppala <mika.kuoppala@linux.intel.com>
> ---
>  tests/intel/xe_eudebug_sriov.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/tests/intel/xe_eudebug_sriov.c b/tests/intel/xe_eudebug_sriov.c
> index 1f150d0efe..8b318d48b0 100644
> --- a/tests/intel/xe_eudebug_sriov.c
> +++ b/tests/intel/xe_eudebug_sriov.c
> @@ -71,7 +71,7 @@ static void test_deny_eudebug(int fd)
> 
>  	sysfs = igt_sysfs_open(fd);
>  	igt_assert_fd(sysfs);
> -	igt_assert_eq(igt_sysfs_printf(sysfs, "device/enable_eudebug", "1"), -
> EPERM);
> +	igt_assert_eq(igt_sysfs_printf(sysfs, "device/enable_eudebug", "1"), -
> EBUSY);
>  	close(sysfs);
>  }
> 
> --
> 2.43.0


^ permalink raw reply	[flat|nested] 23+ messages in thread

end of thread, other threads:[~2026-01-12 13:12 UTC | newest]

Thread overview: 23+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-01-12 12:59 [PATCH i-g-t 00/21] eudebug: uapi changes on connect and metadata Mika Kuoppala
2026-01-12 12:59 ` [PATCH i-g-t 01/21] lib/xe/xe_eudebug: Dont compare if everything filtered Mika Kuoppala
2026-01-12 12:59 ` [PATCH i-g-t 02/21] lib/xe/xe_eudebug: Make sure debugger drains events Mika Kuoppala
2026-01-12 12:59 ` [PATCH i-g-t 03/21] lib/xe/xe_eudebug: Avoid matching if event is filtered Mika Kuoppala
2026-01-12 12:59 ` [PATCH i-g-t 04/21] tests/intel/xe_eudebug_sriov: Align expected return code Mika Kuoppala
2026-01-12 13:12   ` Piatkowski, Dominik Karol
2026-01-12 12:59 ` [PATCH i-g-t 05/21] eudebug: Remove metadata tests Mika Kuoppala
2026-01-12 12:59 ` [PATCH i-g-t 06/21] eudebug: Remove EVENT_OPEN and adjust tests Mika Kuoppala
2026-01-12 12:59 ` [PATCH i-g-t 07/21] tests/xe_eudebug: Adapt basic-read-event Mika Kuoppala
2026-01-12 12:59 ` [PATCH i-g-t 08/21] tests/intel/xe_eudebug: Fix connect-user test Mika Kuoppala
2026-01-12 12:59 ` [PATCH i-g-t 09/21] tests/intel/xe_eudebug: Mold ufence reconnect test to disconnect Mika Kuoppala
2026-01-12 12:59 ` [PATCH i-g-t 10/21] lib/xe_eudebug: Adapt to vm_bind debug data Mika Kuoppala
2026-01-12 12:59 ` [PATCH i-g-t 11/21] tests/xe_eudebug: Adapt basic-vm-bind and remove basic-vm-bind-extended Mika Kuoppala
2026-01-12 12:59 ` [PATCH i-g-t 12/21] tests/xe_eudebug: Adapt some ufence reliant tests to new vm_bind event interface Mika Kuoppala
2026-01-12 12:59 ` [PATCH i-g-t 13/21] tests/xe_eudebug: Adapt vm-bind-clear* subtests to debug data Mika Kuoppala
2026-01-12 13:00 ` [PATCH i-g-t 14/21] lib/xe_eudebug: Remove unused xe_eudebug_client_vm_bind wrappers Mika Kuoppala
2026-01-12 13:00 ` [PATCH i-g-t 15/21] tests/xe_eudebug: Add vm-bind-debug-data-ufence subtest Mika Kuoppala
2026-01-12 13:00 ` [PATCH i-g-t 16/21] lib/intel_batchbuffer: Add dummy OP_DEBUG_DATA operation to __xe_alloc_bind_ops Mika Kuoppala
2026-01-12 13:00 ` [PATCH i-g-t 17/21] tests/xe_eudebug_online: Adapt set-breakpoint test to work with new vm bind event interface Mika Kuoppala
2026-01-12 13:00 ` [PATCH i-g-t 18/21] tests/xe_eudebug_online: Adapt several subtests " Mika Kuoppala
2026-01-12 13:00 ` [PATCH i-g-t 19/21] lib/xe/xe_eudebug: Add callback for session work Mika Kuoppala
2026-01-12 13:00 ` [PATCH i-g-t 20/21] tests/intel/xe_eudebug: Add render node testing Mika Kuoppala
2026-01-12 13:00 ` [PATCH i-g-t 21/21] eudebug: Update xe_drm_eudebug.h uapi Mika Kuoppala

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox