From: "Piórkowski, Piotr" <piotr.piorkowski@intel.com>
To: <igt-dev@lists.freedesktop.org>
Cc: "Piotr Piórkowski" <piotr.piorkowski@intel.com>
Subject: [PATCH v1 3/4] tests/sriov_pci_config: Add VF core config checks
Date: Wed, 16 Sep 2026 13:52:00 +0200 [thread overview]
Message-ID: <20260916115201.1973752-4-piotr.piorkowski@intel.com> (raw)
In-Reply-To: <20260916115201.1973752-1-piotr.piorkowski@intel.com>
From: Piotr Piórkowski <piotr.piorkowski@intel.com>
Add checks for PCI configuration fields required by SR-IOV VFs.
Cover the common header, BARs, and PCI Express capability fields.
Signed-off-by: Piotr Piórkowski <piotr.piorkowski@intel.com>
Assisted-by: GPT-5.6 Luna
---
tests/sriov_pci_config.c | 234 +++++++++++++++++++++++++++++++++++++++
1 file changed, 234 insertions(+)
create mode 100644 tests/sriov_pci_config.c
diff --git a/tests/sriov_pci_config.c b/tests/sriov_pci_config.c
new file mode 100644
index 0000000000..9f8fd9fb50
--- /dev/null
+++ b/tests/sriov_pci_config.c
@@ -0,0 +1,234 @@
+// SPDX-License-Identifier: MIT
+/*
+ * Copyright(c) 2026 Intel Corporation. All rights reserved.
+ */
+
+#include "drmtest.h"
+#include "igt.h"
+#include "igt_pci.h"
+#include "igt_sriov_device.h"
+
+/**
+ * TEST: SR-IOV PCI configuration
+ * Category: Core
+ * Mega feature: SR-IOV
+ * Sub-category: PCI configuration
+ * Functionality: SR-IOV-related PCI configuration space
+ * Description: Validate PCI configuration fields required for SR-IOV,
+ * including Virtual Functions.
+ *
+ * SUBTEST: vf-common-header
+ * Description: Validate that the VF Vendor ID and Device ID read as 0xffff,
+ * and that the I/O, Memory, and INTx Disable bits in Command, the Immediate
+ * Readiness and Interrupt Status bits in Status, the Header Layout bits in
+ * Header Type, and the BIST Completion Code are all zero.
+ *
+ * SUBTEST: vf-bars
+ * Description: Validate that VF BAR address bits read as zero. The BAR type
+ * and attribute bits are static and may remain set; the upper dword of a
+ * 64-bit BAR must read as zero.
+ *
+ * SUBTEST: vf-pcie-capabilities
+ * Description: Validate that FLR is supported, Phantom Functions Supported is
+ * zero, and Auxiliary Power Detected, Emergency Power Reduction Detected,
+ * Current Link Speed, Negotiated Link Width, and Link Autonomous Bandwidth
+ * Status are all zero.
+ *
+ * SUBTEST: vf-pcie-capabilities-2
+ * Description: Validate that the Current De-emphasis Level field in Link
+ * Status 2 is RsvdZ and therefore reads as zero for PCIe Capability Version 2
+ * and later.
+ */
+
+IGT_TEST_DESCRIPTION("Validate PCI configuration fields required for SR-IOV, "
+ "including Virtual Functions");
+
+static int pf_fd = -1;
+static bool autoprobe;
+
+static void read_vf_config(uint8_t *config)
+{
+ char *vf_slot;
+ int ret;
+
+ vf_slot = igt_sriov_get_vf_pci_slot_alloc(pf_fd, 1);
+ igt_assert(vf_slot);
+ ret = igt_pci_config_raw_read(vf_slot, config, PCI_EXT_CFG_SPACE_SIZE);
+ free(vf_slot);
+ igt_assert_f(!ret, "Failed to read VF config space (%d)\n", ret);
+}
+
+static void skip_vf_test(const char *reason)
+{
+ igt_sriov_disable_vfs(pf_fd);
+ igt_abort_on_f(igt_sriov_get_enabled_vfs(pf_fd),
+ "Failed to disable VF(s) before skipping: %s\n", reason);
+ igt_skip("%s\n", reason);
+}
+
+typedef void (*vf_config_check_fn)(const uint8_t *config);
+
+static void with_vf_config(vf_config_check_fn check)
+{
+ uint8_t config[PCI_EXT_CFG_SPACE_SIZE];
+
+ igt_require(igt_sriov_get_enabled_vfs(pf_fd) == 0);
+ igt_sriov_disable_driver_autoprobe(pf_fd);
+ igt_sriov_enable_vfs(pf_fd, 1);
+ igt_require_f(!igt_pci_system_reinit(), "Failed to refresh PCI state\n");
+
+ read_vf_config(config);
+ check(config);
+ igt_sriov_disable_vfs(pf_fd);
+}
+
+static void check_vf_common_header(const uint8_t *config)
+{
+ uint16_t command = igt_pci_config_raw_read_u16(config, PCI_COMMAND);
+ uint16_t status = igt_pci_config_raw_read_u16(config, PCI_STATUS);
+ uint16_t vendor_id = igt_pci_config_raw_read_u16(config, PCI_VENDOR_ID);
+ uint16_t device_id = igt_pci_config_raw_read_u16(config, PCI_DEVICE_ID);
+
+ igt_info("Checking common header\n");
+ igt_assert_f(vendor_id == 0xffff, "Vendor ID: expected 0xffff, got 0x%04x\n", vendor_id);
+ igt_assert_f(device_id == 0xffff, "Device ID: expected 0xffff, got 0x%04x\n", device_id);
+ igt_assert_f(!(command & (PCI_COMMAND_IO | PCI_COMMAND_MEMORY |
+ PCI_COMMAND_INTX_DISABLE)),
+ "Command: expected I/O, Memory, and INTx Disable bits clear, got 0x%04x\n",
+ command);
+ igt_assert_f(!(status & (PCI_STATUS_IMMEDIATE_READINESS | PCI_STATUS_INTERRUPT)),
+ "Status: expected Immediate Readiness and Interrupt Status bits clear, got 0x%04x\n",
+ status);
+ igt_assert_f(!(config[PCI_HEADER_TYPE] & PCI_HEADER_TYPE_MASK),
+ "Header Type: expected Header Layout 0, got 0x%02x\n",
+ config[PCI_HEADER_TYPE]);
+ igt_assert_f(!(config[PCI_BIST] & PCI_BIST_COMPLETION_CODE),
+ "BIST: expected Completion Code 0, got 0x%02x\n", config[PCI_BIST]);
+}
+
+static void check_vf_bars(const uint8_t *config)
+{
+ igt_info("Checking VF BARs\n");
+ for (int bar = 0; bar < 6; bar++) {
+ uint32_t value =
+ igt_pci_config_raw_read_u32(config,
+ PCI_BASE_ADDRESS_0 + bar * sizeof(uint32_t));
+ bool is_mem64 = !(value & PCI_BASE_ADDRESS_SPACE) &&
+ (value & PCI_BASE_ADDRESS_MEM_TYPE_MASK) ==
+ PCI_BASE_ADDRESS_MEM_TYPE_64;
+
+ /* Only the address bits are hardwired to zero; type/attribute bits are static. */
+ igt_assert_f(!(value & ~0xfu), "BAR%d: expected address 0x00000000, got 0x%08x\n",
+ bar, value);
+
+ /* The upper dword of a 64-bit BAR holds pure address bits, no type bits. */
+ if (is_mem64) {
+ unsigned int upper_offset = PCI_BASE_ADDRESS_0 +
+ (bar + 1) * sizeof(uint32_t);
+ uint32_t upper =
+ igt_pci_config_raw_read_u32(config, upper_offset);
+
+ igt_assert_f(!upper, "BAR%d (upper): expected 0x00000000, got 0x%08x\n",
+ bar + 1, upper);
+ bar++;
+ }
+ }
+}
+
+static int get_pcie_cap(const uint8_t *config)
+{
+ int pcie_cap = igt_pci_config_raw_find_cap_offset(config, PCI_CAP_ID_EXP);
+
+ igt_assert_f(pcie_cap > 0, "VF has no PCI Express capability (%d)\n", pcie_cap);
+
+ return pcie_cap;
+}
+
+static void check_vf_pcie_capabilities(const uint8_t *config)
+{
+ int pcie_cap = get_pcie_cap(config);
+ uint32_t pcie_devcap = igt_pci_config_raw_read_u32(config, pcie_cap + PCI_EXP_DEVCAP);
+ uint16_t pcie_devsta = igt_pci_config_raw_read_u16(config, pcie_cap + PCI_EXP_DEVSTA);
+ uint16_t pcie_lnksta = igt_pci_config_raw_read_u16(config, pcie_cap + PCI_EXP_LNKSTA);
+
+ igt_info("Checking mandatory PCI Express capability\n");
+ igt_assert_f(pcie_devcap & PCI_EXP_DEVCAP_FLR,
+ "Device Capabilities: FLR bit is clear (0x%08x)\n", pcie_devcap);
+ igt_assert_f(!(pcie_devcap & PCI_EXP_DEVCAP_PHANTOM),
+ "Device Capabilities: Phantom Functions Supported must be zero (0x%08x)\n",
+ pcie_devcap);
+ igt_assert_f(!(pcie_devsta & (PCI_EXP_DEVSTA_AUXPD |
+ PCI_EXP_DEVSTA_EMERGENCY_PWR_REDUCED)),
+ "Device Status: Aux Power Detected or Emergency Power Reduction Detected is set (0x%04x)\n",
+ pcie_devsta);
+ igt_assert_f(!(pcie_lnksta & (PCI_EXP_LNKSTA_CLS | PCI_EXP_LNKSTA_NLW |
+ PCI_EXP_LNKSTA_LABS)),
+ "Link Status: Current Link Speed, Negotiated Link Width, or Link Autonomous Bandwidth Status is set (0x%04x)\n",
+ pcie_lnksta);
+}
+
+static void check_vf_pcie_capabilities_2(const uint8_t *config)
+{
+ int pcie_cap = get_pcie_cap(config);
+ uint16_t flags = igt_pci_config_raw_read_u16(config, pcie_cap + PCI_EXP_FLAGS);
+ uint16_t lnksta2;
+
+ if ((flags & PCI_EXP_FLAGS_VERS) < 2)
+ skip_vf_test("PCI Express Capability Version 2 is not present");
+
+ lnksta2 = igt_pci_config_raw_read_u16(config, pcie_cap + PCI_EXP_LNKSTA2);
+ igt_info("Checking PCI Express Capability Version 2\n");
+ igt_assert_f(!(lnksta2 & PCI_EXP_LNKSTA2_CUR_DEEMPHASIS),
+ "Link Status 2: Current De-emphasis Level must be zero (0x%04x)\n",
+ lnksta2);
+}
+
+int igt_main()
+{
+ igt_fixture() {
+ pf_fd = drm_open_driver(DRIVER_ANY);
+ igt_require(igt_sriov_is_pf(pf_fd));
+ igt_require(igt_sriov_vfs_supported(pf_fd));
+ igt_require(igt_sriov_get_enabled_vfs(pf_fd) == 0);
+ autoprobe = igt_sriov_is_driver_autoprobe_enabled(pf_fd);
+ igt_sriov_install_exit_handler(pf_fd, NULL, NULL);
+ }
+
+ igt_describe("Validate the SR-IOV VF requirements for Vendor ID, Device ID, "
+ "Command, Status, Header Type, and BIST fields in the PCI common header");
+ igt_subtest("vf-common-header") {
+ with_vf_config(check_vf_common_header);
+ }
+
+ igt_describe("Validate the SR-IOV VF requirement that BAR address bits are zero "
+ "while static BAR type and attribute bits remain valid");
+ igt_subtest("vf-bars") {
+ with_vf_config(check_vf_bars);
+ }
+
+ igt_describe("Validate the SR-IOV VF requirements for FLR, Phantom Functions, "
+ "Auxiliary Power, Emergency Power Reduction, and PCIe link status fields");
+ igt_subtest("vf-pcie-capabilities") {
+ with_vf_config(check_vf_pcie_capabilities);
+ }
+
+ igt_describe("Validate the RsvdZ requirement for Current De-emphasis Level in "
+ "Link Status 2 of PCI Express Capability Version 2 and later");
+ igt_subtest("vf-pcie-capabilities-2") {
+ with_vf_config(check_vf_pcie_capabilities_2);
+ }
+
+ igt_fixture() {
+ igt_abort_on_f(pf_fd < 0, "Device is not accessible\n");
+ igt_sriov_disable_vfs(pf_fd);
+ igt_abort_on_f(igt_sriov_get_enabled_vfs(pf_fd) > 0,
+ "Failed to disable VF(s)\n");
+ 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");
+ igt_sriov_clear_exit_handler();
+ close(pf_fd);
+ }
+}
+
--
2.34.1
next prev parent reply other threads:[~2026-09-16 11:55 UTC|newest]
Thread overview: 13+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-09-16 11:51 [PATCH v1 0/4] Add PCI configuration tests for SR-IOV VFs Piórkowski, Piotr
2026-09-16 11:51 ` [PATCH v1 1/4] lib/igt_pci: Add raw configuration space helpers Piórkowski, Piotr
2026-09-17 15:33 ` [v1,1/4] " Laguna, Lukasz
2026-09-16 11:51 ` [PATCH v1 2/4] lib/igt_pci: Add PCI extended capability lookup Piórkowski, Piotr
2026-09-17 15:36 ` [v1,2/4] " Laguna, Lukasz
2026-09-16 11:52 ` Piórkowski, Piotr [this message]
2026-09-17 15:38 ` [v1,3/4] tests/sriov_pci_config: Add VF core config checks Laguna, Lukasz
2026-09-16 11:52 ` [PATCH v1 4/4] tests/sriov_pci_config: Add optional capability checks Piórkowski, Piotr
2026-09-17 15:47 ` [v1,4/4] " Laguna, Lukasz
2026-09-16 19:24 ` ✓ Xe.CI.BAT: success for Add PCI configuration tests for SR-IOV VFs Patchwork
2026-09-16 20:10 ` ✓ i915.CI.BAT: " Patchwork
2026-09-16 22:49 ` ✗ Xe.CI.FULL: failure " Patchwork
2026-09-17 4:13 ` ✓ i915.CI.Full: success " 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=20260916115201.1973752-4-piotr.piorkowski@intel.com \
--to=piotr.piorkowski@intel.com \
--cc=igt-dev@lists.freedesktop.org \
/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