All of lore.kernel.org
 help / color / mirror / Atom feed
From: Lukasz Laguna <lukasz.laguna@intel.com>
To: igt-dev@lists.freedesktop.org
Cc: marcin.bernatowicz@linux.intel.com, michal.wajdeczko@intel.com,
	michal.winiarski@intel.com, satyanarayana.k.v.p@intel.com,
	adam.miszczak@linux.intel.com, jakub1.kolakowski@intel.com,
	lukasz.laguna@intel.com
Subject: [PATCH i-g-t 4/4] tests/intel/xe_sriov_vram: Add test checking VF access to VRAM
Date: Thu, 17 Jul 2025 11:08:12 +0200	[thread overview]
Message-ID: <20250717090812.28628-5-lukasz.laguna@intel.com> (raw)
In-Reply-To: <20250717090812.28628-1-lukasz.laguna@intel.com>

Add a test to validate VF access to VRAM via BAR. The following
scenarios are covered:
- VF can access all provisioned memory via the VRAM BAR,
- VF cannot access memory beyond what's provisioned via the VRAM BAR,
- VF can access memory via the VRAM BAR after reprovisioning.

Signed-off-by: Lukasz Laguna <lukasz.laguna@intel.com>
---
 tests/intel/xe_sriov_vram.c | 310 ++++++++++++++++++++++++++++++++++++
 tests/meson.build           |   1 +
 2 files changed, 311 insertions(+)
 create mode 100644 tests/intel/xe_sriov_vram.c

diff --git a/tests/intel/xe_sriov_vram.c b/tests/intel/xe_sriov_vram.c
new file mode 100644
index 000000000..82f0a2f09
--- /dev/null
+++ b/tests/intel/xe_sriov_vram.c
@@ -0,0 +1,310 @@
+// SPDX-License-Identifier: MIT
+/*
+ * Copyright(c) 2025 Intel Corporation. All rights reserved.
+ */
+
+#include "drmtest.h"
+#include "igt_core.h"
+#include "igt_sriov_device.h"
+#include "intel_vram.h"
+#include "xe/xe_sriov_provisioning.h"
+#include "xe/xe_query.h"
+
+/**
+ * TEST: xe_sriov_vram
+ * Category: Core
+ * Mega feature: SR-IOV
+ * Sub-category: LMTT
+ * Functionality: VRAM access
+ * Description: Validate VF access to VRAM
+ *
+ * SUBTEST: vf-access-basic
+ * Description: Verify that VF can access all the provisioned memory via VRAM BAR
+ *
+ * SUBTEST: vf-access-beyond
+ * Description: Verify that VF cannot access memory beyond what's provisioned via VRAM BAR
+ *
+ * SUBTEST: vf-access-after-resize-down
+ * Description: Verify that VF can access the reprovisioned memory (reduced size) via VRAM BAR
+ *
+ * SUBTEST: vf-access-after-resize-up
+ * Description: Verify that VF can access the reprovisioned memory (increased size) via VRAM BAR
+ */
+
+IGT_TEST_DESCRIPTION("Xe tests for VRAM in SR-IOV context");
+
+const size_t STEP = SZ_1M;
+
+static uint64_t get_provisioned_vram(unsigned int pf_fd, unsigned int vf_id)
+{
+	uint64_t size = 0;
+
+	/* TODO: adjust for multitile platforms */
+	size = xe_sriov_pf_get_provisioned_quota(pf_fd, XE_SRIOV_SHARED_RES_LMEM, vf_id, 0);
+
+	return size;
+}
+
+static bool validate_access_basic(struct vram_mapping *vram, unsigned int vf_id,
+				  uint64_t provisioned_lmem)
+{
+	uint8_t read, orig;
+	bool passed = true;
+
+	for (size_t offset = 0; offset < provisioned_lmem; offset += STEP) {
+		orig = intel_vram_read8(vram, offset);
+
+		read = intel_vram_write_readback8(vram, offset, vf_id);
+		if (read != vf_id) {
+			igt_debug("VRAM write/read check failed on VF%u (offset: %#lx, write: %u, read: %u)\n",
+				  vf_id, offset, vf_id, read);
+			passed = false;
+		}
+
+		read = intel_vram_write_readback8(vram, offset, orig);
+		if (read != orig) {
+			igt_debug("Failed to restore original value on VF%u (offset: %#lx, orig: %u, read: %u)\n",
+				  vf_id, offset, orig, read);
+			passed = false;
+		}
+	}
+
+	return passed;
+}
+
+static void access_basic(unsigned int pf_fd, unsigned int num_vfs)
+{
+	uint64_t provisioned_lmem;
+	struct vram_mapping vram;
+	size_t vram_bar_size;
+	bool passed = true;
+
+	igt_sriov_disable_driver_autoprobe(pf_fd);
+	igt_sriov_enable_vfs(pf_fd, num_vfs);
+
+	for_each_sriov_enabled_vf(pf_fd, vf_id) {
+		provisioned_lmem = get_provisioned_vram(pf_fd, vf_id);
+		igt_debug("VF%u provisioned with %" PRIu64 " bytes of VRAM\n",
+			  vf_id, provisioned_lmem);
+
+		vram_bar_size = intel_vram_bar_size(pf_fd, vf_id);
+		igt_debug("VF%u VRAM BAR size: %" PRIu64 "\n", vf_id, vram_bar_size);
+
+		if (vram_bar_size < provisioned_lmem) {
+			igt_sriov_disable_vfs(pf_fd);
+			igt_skip("VRAM BAR size is smaller than provisioned VRAM\n");
+		}
+
+		vram = intel_vram_mmap(pf_fd, vf_id, provisioned_lmem, PROT_READ | PROT_WRITE, 0);
+		igt_assert(vram.addr);
+
+		passed &= validate_access_basic(&vram, vf_id, provisioned_lmem);
+
+		intel_vram_munmap(&vram);
+	}
+
+	igt_sriov_disable_vfs(pf_fd);
+
+	igt_assert(passed);
+}
+
+static bool validate_access_beyond(struct vram_mapping *vram, unsigned int vf_id,
+				   uint64_t provisioned_lmem, size_t vram_bar_size)
+{
+	uint8_t read, orig;
+	bool passed = true;
+
+	for (size_t offset = provisioned_lmem; offset < vram_bar_size; offset += STEP) {
+		orig = intel_vram_read8(vram, offset);
+
+		read = intel_vram_write_readback8(vram, offset, vf_id);
+		if (read == vf_id) {
+			igt_debug("Successful VRAM write above provisioned size on VF%u (offset: %#lx)\n",
+				  vf_id, offset);
+			passed = false;
+
+			read = intel_vram_write_readback8(vram, offset, orig);
+			if (read != orig)
+				igt_debug("Failed to restore original value on VF%u (offset: %#lx, orig: %u, read: %u)\n",
+					  vf_id, offset, orig, read);
+		}
+	}
+
+	return passed;
+}
+
+static void access_beyond(unsigned int pf_fd, unsigned int num_vfs)
+{
+	uint64_t provisioned_lmem;
+	struct vram_mapping vram;
+	size_t vram_bar_size;
+	bool passed = true;
+
+	igt_sriov_disable_driver_autoprobe(pf_fd);
+	igt_sriov_enable_vfs(pf_fd, num_vfs);
+
+	for_each_sriov_enabled_vf(pf_fd, vf_id) {
+		provisioned_lmem = get_provisioned_vram(pf_fd, vf_id);
+		igt_debug("VF%u provisioned with %" PRIu64 " bytes of VRAM\n",
+			  vf_id, provisioned_lmem);
+
+		vram_bar_size = intel_vram_bar_size(pf_fd, vf_id);
+		igt_debug("VF%u VRAM BAR size: %" PRIu64 "\n", vf_id, vram_bar_size);
+
+		if (vram_bar_size <= provisioned_lmem) {
+			igt_sriov_disable_vfs(pf_fd);
+			igt_skip("VRAM BAR size is smaller or equal to provisioned VRAM\n");
+		}
+
+		vram = intel_vram_mmap(pf_fd, vf_id, vram_bar_size, PROT_READ | PROT_WRITE, 0);
+		igt_assert(vram.addr);
+
+		passed &= validate_access_beyond(&vram, vf_id, provisioned_lmem, vram_bar_size);
+
+		intel_vram_munmap(&vram);
+	}
+
+	igt_sriov_disable_vfs(pf_fd);
+
+	igt_assert(passed);
+}
+
+static void resize_and_access(unsigned int pf_fd, bool resize_up)
+{
+	const unsigned int vf_id = 1;
+	uint64_t provisioned_lmem;
+	struct vram_mapping vram;
+	unsigned int total_vfs;
+	size_t vram_bar_size;
+	bool passed;
+
+	total_vfs = igt_sriov_get_total_vfs(pf_fd);
+
+	igt_sriov_disable_driver_autoprobe(pf_fd);
+	igt_sriov_enable_vfs(pf_fd, resize_up ? total_vfs : 1);
+
+	provisioned_lmem = get_provisioned_vram(pf_fd, vf_id);
+	igt_debug("VF%u provisioned with %" PRIu64 " bytes of VRAM\n", vf_id, provisioned_lmem);
+
+	igt_sriov_disable_vfs(pf_fd);
+	igt_sriov_enable_vfs(pf_fd, resize_up ? 1 : total_vfs);
+
+	provisioned_lmem = get_provisioned_vram(pf_fd, vf_id);
+	igt_debug("VF%u provisioned with %" PRIu64 " bytes of VRAM\n", vf_id, provisioned_lmem);
+
+	vram_bar_size = intel_vram_bar_size(pf_fd, vf_id);
+	igt_debug("VF%u VRAM BAR size: %" PRIu64 "\n", vf_id, vram_bar_size);
+
+	if (vram_bar_size <= provisioned_lmem) {
+		igt_sriov_disable_vfs(pf_fd);
+		igt_skip("VRAM BAR size is smaller or equal to provisioned VRAM\n");
+	}
+
+	vram = intel_vram_mmap(pf_fd, vf_id, vram_bar_size, PROT_READ | PROT_WRITE, 0);
+	igt_assert(vram.addr);
+
+	passed = validate_access_basic(&vram, vf_id, provisioned_lmem);
+	passed &= validate_access_beyond(&vram, vf_id, provisioned_lmem, vram_bar_size);
+
+	intel_vram_munmap(&vram);
+
+	igt_sriov_disable_vfs(pf_fd);
+
+	igt_assert(passed);
+}
+
+static bool extended_scope;
+
+static int opts_handler(int opt, int opt_index, void *data)
+{
+	switch (opt) {
+	case 'e':
+		extended_scope = true;
+		break;
+	default:
+		return IGT_OPT_HANDLER_ERROR;
+	}
+
+	return IGT_OPT_HANDLER_SUCCESS;
+}
+
+static const struct option long_opts[] = {
+	{ .name = "extended", .has_arg = false, .val = 'e', },
+	{}
+};
+
+static const char help_str[] =
+	"  --extended\tRun the extended test scope\n";
+
+igt_main_args("", long_opts, help_str, opts_handler, NULL)
+{
+	bool autoprobe;
+	int pf_fd;
+	static struct subtest_resize_variants {
+		const char *name;
+		bool resize_up;
+	} resize_variant[] = {
+		{ "up", true },
+		{ "down", false },
+		{ NULL },
+	};
+
+	igt_fixture {
+		pf_fd = drm_open_driver(DRIVER_XE);
+		igt_require(igt_sriov_is_pf(pf_fd));
+		igt_require(igt_sriov_get_enabled_vfs(pf_fd) == 0);
+		autoprobe = igt_sriov_is_driver_autoprobe_enabled(pf_fd);
+	}
+
+	igt_describe("Verify that VF can access all the provisioned memory via VRAM BAR");
+	igt_subtest_with_dynamic_f("vf-access-basic") {
+		if (extended_scope)
+			for_each_sriov_num_vfs(pf_fd, num_vfs)
+				igt_dynamic_f("numvfs-%d", num_vfs)
+					access_basic(pf_fd, num_vfs);
+
+		for_random_sriov_num_vfs(pf_fd, num_vfs) {
+			igt_dynamic_f("numvfs-random") {
+				igt_debug("numvfs=%u\n", num_vfs);
+				access_basic(pf_fd, num_vfs);
+			}
+		}
+	}
+
+	igt_describe("Verify that VF cannot access memory beyond what's provisioned via VRAM BAR");
+	igt_subtest_with_dynamic_f("vf-access-beyond") {
+		if (extended_scope)
+			for_each_sriov_num_vfs(pf_fd, num_vfs)
+				igt_dynamic_f("numvfs-%d", num_vfs)
+					access_beyond(pf_fd, num_vfs);
+
+		for_random_sriov_num_vfs(pf_fd, num_vfs) {
+			igt_dynamic_f("numvfs-random") {
+				igt_debug("numvfs=%u\n", num_vfs);
+				access_beyond(pf_fd, num_vfs);
+			}
+		}
+	}
+
+	for (const struct subtest_resize_variants *s = resize_variant; s->name; s++) {
+		igt_describe("Verify that VF can access the reprovisioned memory via VRAM BAR");
+		igt_subtest_f("vf-access-after-resize-%s", s->name) {
+			unsigned int total_vfs = igt_sriov_get_total_vfs(pf_fd);
+
+			igt_require(total_vfs > 1);
+
+			resize_and_access(pf_fd, s->resize_up);
+		}
+	}
+
+	igt_fixture {
+		igt_sriov_disable_vfs(pf_fd);
+		/* abort to avoid execution of next tests with enabled VFs */
+		igt_abort_on_f(igt_sriov_get_enabled_vfs(pf_fd) > 0, "Failed to disable VF(s)");
+		autoprobe ? igt_sriov_enable_driver_autoprobe(pf_fd) :
+			    igt_sriov_disable_driver_autoprobe(pf_fd);
+		igt_abort_on_f(autoprobe != igt_sriov_is_driver_autoprobe_enabled(pf_fd),
+			       "Failed to restore sriov_drivers_autoprobe value\n");
+		close(pf_fd);
+	}
+}
diff --git a/tests/meson.build b/tests/meson.build
index 5c01c64e9..6054a2c34 100644
--- a/tests/meson.build
+++ b/tests/meson.build
@@ -329,6 +329,7 @@ intel_xe_progs = [
 	'xe_sriov_auto_provisioning',
 	'xe_sriov_flr',
 	'xe_sriov_scheduling',
+	'xe_sriov_vram',
 	'xe_sysfs_defaults',
 	'xe_sysfs_preempt_timeout',
 	'xe_sysfs_scheduler',
-- 
2.40.0


  parent reply	other threads:[~2025-07-17  9:08 UTC|newest]

Thread overview: 16+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-07-17  9:08 [PATCH i-g-t 0/4] Validate VF accesses to VRAM via BAR Lukasz Laguna
2025-07-17  9:08 ` [PATCH i-g-t 1/4] lib/igt_sriov_device: Add helper to iterate over enabled VFs Lukasz Laguna
2025-07-21 10:05   ` Piotr Piórkowski
2025-07-17  9:08 ` [PATCH i-g-t 2/4] lib/intel_vram: Add library for VRAM accesses Lukasz Laguna
2025-08-21 20:26   ` Bernatowicz, Marcin
2025-07-17  9:08 ` [PATCH i-g-t 3/4] tests/intel/xe_sriov_flr: Use VRAM access helpers from intel_vram library Lukasz Laguna
2025-08-21 20:30   ` Bernatowicz, Marcin
2025-07-17  9:08 ` Lukasz Laguna [this message]
2025-07-31  8:29   ` [PATCH i-g-t 4/4] tests/intel/xe_sriov_vram: Add test checking VF access to VRAM Piotr Piórkowski
2025-08-01 12:43     ` Laguna, Lukasz
2025-08-21 16:53   ` Bernatowicz, Marcin
2025-08-27 13:16     ` Laguna, Lukasz
2025-07-17 12:42 ` ✓ i915.CI.BAT: success for Validate VF accesses to VRAM via BAR Patchwork
2025-07-17 13:56 ` ✓ Xe.CI.BAT: " Patchwork
2025-07-18  1:23 ` ✗ i915.CI.Full: failure " Patchwork
2025-07-18 19:07 ` ✗ Xe.CI.Full: " Patchwork

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=20250717090812.28628-5-lukasz.laguna@intel.com \
    --to=lukasz.laguna@intel.com \
    --cc=adam.miszczak@linux.intel.com \
    --cc=igt-dev@lists.freedesktop.org \
    --cc=jakub1.kolakowski@intel.com \
    --cc=marcin.bernatowicz@linux.intel.com \
    --cc=michal.wajdeczko@intel.com \
    --cc=michal.winiarski@intel.com \
    --cc=satyanarayana.k.v.p@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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.