igt-dev.lists.freedesktop.org archive mirror
 help / color / mirror / Atom feed
From: nishit.sharma@intel.com
To: jonathan.cavitt@intel.com, igt-dev@lists.freedesktop.org,
	nishit.sharma@intel.com
Subject: [PATCH] tests/intel/xe_compute: Add VM page fault property reporting test
Date: Wed,  3 Dec 2025 09:48:20 +0000	[thread overview]
Message-ID: <20251203094820.14800-1-nishit.sharma@intel.com> (raw)

From: Nishit Sharma <nishit.sharma@intel.com>

Add new subtest 'vm-get-property-pagefault-reporting' to validate the
DRM_IOCTL_XE_VM_GET_PROPERTY ioctl for querying VM page fault information.

This test exercises the kernel's page fault tracking mechanism for VMs
created with fault-mode enabled. It verifies:
- Initial page fault count is zero for newly created VMs
- Page faults are correctly tracked and reported after triggering
- Reported fault count respects the maximum limit (≤50 faults)
- All reported faults maintain consistent fault address, access type,
  and fault type
- VM isolation is maintained (faults in VM1 don't affect VM2)

Signed-off-by: Nishit Sharma <nishit.sharma@intel.com>
---
 tests/intel/xe_compute.c | 171 +++++++++++++++++++++++++++++++++++++++
 1 file changed, 171 insertions(+)

diff --git a/tests/intel/xe_compute.c b/tests/intel/xe_compute.c
index 108235637..48c6e032a 100644
--- a/tests/intel/xe_compute.c
+++ b/tests/intel/xe_compute.c
@@ -16,6 +16,7 @@
 #include "igt.h"
 #include "igt_sysfs.h"
 #include "intel_compute.h"
+#include "xe_drm.h"
 #include "xe/xe_ioctl.h"
 #include "xe/xe_query.h"
 
@@ -510,6 +511,173 @@ test_compute_square(int fd)
 		      "GPU not supported\n");
 }
 
+static void print_pf(struct xe_vm_fault *fault)
+{
+        igt_debug("FAULT:\n");
+        igt_debug("address = 0x%08x%08x\n",
+                  upper_32_bits(fault->address),
+                  lower_32_bits(fault->address));
+        igt_debug("address precision = %u\n", fault->address_precision);
+        igt_debug("access type = %u\n", fault->access_type);
+        igt_debug("fault type = %u\n", fault->fault_type);
+        igt_debug("fault level = %u\n", fault->fault_level);
+        igt_debug("\n");
+}
+
+/**
+ * SUBTEST: vm-get-property-pagefault-reporting
+ * Description: Test VM page fault reporting via xe_vm_get_property ioctl
+ * Functionality: VM page fault isolation and query
+ * Test category: functionality test
+ */
+static void test_vm_pagefault_reporting(void)
+{
+	struct drm_xe_engine_class_instance *hwe;
+	struct drm_xe_vm_get_property property = {0};
+	struct xe_vm_fault *faults_1, f0, f;
+	uint32_t vm1, vm2;
+	uint32_t exec_queue1;
+	uint64_t addr = 0x1a0000;
+	struct drm_xe_sync sync = {
+		.type = DRM_XE_SYNC_TYPE_USER_FENCE,
+		.flags = DRM_XE_SYNC_FLAG_SIGNAL,
+	};
+	struct drm_xe_exec exec = {};
+	uint64_t *sync_val;
+	int ret;
+	int fd, fault_count, final_fault_count, check_count;
+	uint32_t bo;
+	bool found_compute = false;
+
+	fd = drm_open_driver(DRIVER_XE);
+	xe_device_get(fd);
+
+	igt_require(xe_has_vram(fd)); /* Fault mode typically needs VRAM */
+
+	/* Create fault-mode VM1 */
+	vm1 = xe_vm_create(fd, DRM_XE_VM_CREATE_FLAG_LR_MODE |
+			   DRM_XE_VM_CREATE_FLAG_FAULT_MODE, 0);
+	igt_assert(vm1);
+
+	/* Step 1: Query initial pagefault count (should be 0) */
+	property.vm_id = vm1;
+	property.property = DRM_XE_VM_GET_PROPERTY_FAULTS;
+	property.data = 0;
+	property.size = 0;
+
+	ret = igt_ioctl(fd, DRM_IOCTL_XE_VM_GET_PROPERTY, &property);
+	igt_assert_eq(ret, 0);
+
+
+	if (property.size > 0) {
+		faults_1 = malloc(property.size);
+		igt_assert(faults_1);
+		property.data = to_user_pointer(faults_1);
+		ret = igt_ioctl(fd, DRM_IOCTL_XE_VM_GET_PROPERTY, &property);
+		igt_assert_eq(ret, 0);
+		free(faults_1);
+	}
+
+	fault_count = property.size / sizeof(struct xe_vm_fault);
+	f0 = faults_1[0];
+
+	for (int i = 0; i < fault_count; i++) {
+		f = faults_1[i];
+		print_pf(&f);
+		igt_assert_eq(f.address, f0.address);
+		igt_assert_eq(f.access_type, f0.access_type);
+		igt_assert_eq(f.fault_type, f0.fault_type);
+	}
+        free(faults_1);
+
+	/* Step 2: Trigger a page fault via compute job */
+	xe_for_each_engine(fd, hwe) {
+		if (hwe->engine_class != DRM_XE_ENGINE_CLASS_COMPUTE)
+			continue;
+		found_compute = true;
+
+		exec_queue1 = xe_exec_queue_create(fd, vm1, hwe, 0);
+		sync_val = mmap(NULL, 4096, PROT_WRITE, MAP_SHARED | MAP_ANON, -1, 0);
+		igt_assert(sync_val != MAP_FAILED);
+		*sync_val = 0;
+		sync.addr = to_user_pointer(sync_val);
+
+		/* Create a faulting job (access unmapped address) */
+		bo = xe_bo_create(fd, vm1, 4096, vram_if_possible(fd, 0), 0);
+		exec.exec_queue_id = exec_queue1;
+		exec.num_batch_buffer = 1;
+		exec.address = addr; /* Unmapped - will fault */
+		exec.syncs = to_user_pointer(&sync);
+
+		/* This exec should trigger page fault */
+		ret = igt_ioctl(fd, DRM_IOCTL_XE_EXEC, &exec);
+
+		/* Wait for fault handling */
+		usleep(100000); /* 100ms for page fault to be recorded */
+
+		gem_close(fd, bo);
+
+		/* Step 3: Query pagefault count after fault */
+		faults_1 = malloc(property.size);
+		igt_assert(faults_1);
+		property.data = to_user_pointer(faults_1);
+		property.size = 0;
+		ret = igt_ioctl(fd, DRM_IOCTL_XE_VM_GET_PROPERTY, &property);
+		igt_assert_eq(ret, 0);
+
+		if (property.size > 0) {
+			faults_1 = malloc(property.size);
+			igt_assert(faults_1);
+			property.data = to_user_pointer(faults_1);
+			ret = igt_ioctl(fd, DRM_IOCTL_XE_VM_GET_PROPERTY, &property);
+			igt_assert_eq(ret, 0);
+
+			final_fault_count = property.size / sizeof(struct xe_vm_fault);
+			check_count = final_fault_count > 50 ? 50 : final_fault_count;
+			f0 = faults_1[0];
+
+			for (int i = 0; i < check_count; i++) {
+				f = faults_1[i];
+				print_pf(&f);
+				igt_assert_eq(f.address, f0.address);
+				igt_assert_eq(f.access_type, f0.access_type);
+				igt_assert_eq(f.fault_type, f0.fault_type);
+			}
+			free(faults_1);
+		}
+
+		munmap(sync_val, 4096);
+		xe_exec_queue_destroy(fd, exec_queue1);
+	}
+	igt_require(found_compute);
+
+	/* Step 4: Create VM2 for isolation test */
+	vm2 = xe_vm_create(fd, DRM_XE_VM_CREATE_FLAG_LR_MODE |
+			DRM_XE_VM_CREATE_FLAG_FAULT_MODE, 0);
+	igt_assert(vm2);
+
+	property.vm_id = vm2;
+	property.property = DRM_XE_VM_GET_PROPERTY_FAULTS;
+	property.data = 0;
+	property.size = 0;
+	ret = igt_ioctl(fd, DRM_IOCTL_XE_VM_GET_PROPERTY, &property);
+	igt_assert_eq(ret, 0);
+
+	if (property.size > 0) {
+		faults_1 = malloc(property.size);
+		igt_assert(faults_1);
+		property.data = to_user_pointer(faults_1);
+		ret = igt_ioctl(fd, DRM_IOCTL_XE_VM_GET_PROPERTY, &property);
+		igt_assert_eq(ret, 0);
+		free(faults_1);
+	}
+
+	/* Cleanup */
+	xe_vm_destroy(fd, vm1);
+	xe_vm_destroy(fd, vm2);
+	drm_close_driver(fd);
+}
+
 igt_main
 {
 	int xe, ccs_mode[4];
@@ -565,6 +733,9 @@ igt_main
 		test_eu_busy(5 * LOOP_DURATION_2s);
 	}
 
+	igt_subtest("vm-get-property-pagefault-reporting")
+		test_vm_pagefault_reporting();
+
 	igt_fixture {
 		if (!sriov_enabled)
 			igt_restore_ccs_mode(ccs_mode, ARRAY_SIZE(ccs_mode));
-- 
2.43.0


                 reply	other threads:[~2025-12-03  9:48 UTC|newest]

Thread overview: [no followups] expand[flat|nested]  mbox.gz  Atom feed

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20251203094820.14800-1-nishit.sharma@intel.com \
    --to=nishit.sharma@intel.com \
    --cc=igt-dev@lists.freedesktop.org \
    --cc=jonathan.cavitt@intel.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).