Igt-dev Archive on lore.kernel.org
 help / color / mirror / Atom feed
From: "Laguna, Lukasz" <lukasz.laguna@intel.com>
To: "Piórkowski, Piotr" <piotr.piorkowski@intel.com>,
	igt-dev@lists.freedesktop.org
Subject: Re: [v1,3/4] tests/sriov_pci_config: Add VF core config checks
Date: Thu, 17 Sep 2026 17:38:18 +0200	[thread overview]
Message-ID: <564aeb77-6810-42f4-b2ea-65077e37da29@intel.com> (raw)
In-Reply-To: <20260916115201.1973752-4-piotr.piorkowski@intel.com>


On 9/16/2026 13:52, Piórkowski, Piotr wrote:
> 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 +++++++++++++++++++++++++++++++++++++++

You forgot to update tests/meson.build.
It doesn't compile without it.

>   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,

nit: Validate that FLR is supported, and Phantom Functions Supported, 
Auxiliary Power Detected ... are all zero.

> + * 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);

It seems that we don't need to enable/disable VF and read the config on 
every subtest. It should be sufficient to do it once in the fixture.

> +}
> +
> +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");

Not needed

> +	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");

Not needed

> +	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);
> +	}
> +}
> +

  reply	other threads:[~2026-09-17 15:39 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 ` [PATCH v1 3/4] tests/sriov_pci_config: Add VF core config checks Piórkowski, Piotr
2026-09-17 15:38   ` Laguna, Lukasz [this message]
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=564aeb77-6810-42f4-b2ea-65077e37da29@intel.com \
    --to=lukasz.laguna@intel.com \
    --cc=igt-dev@lists.freedesktop.org \
    --cc=piotr.piorkowski@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