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: [v4,2/4] tests/sriov_pci_config: Add VF core config checks
Date: Mon, 12 Oct 2026 11:33:49 +0200	[thread overview]
Message-ID: <4e46fc2c-5154-467c-bbf8-08a4d055100b@intel.com> (raw)
In-Reply-To: <20261002113356.3652805-3-piotr.piorkowski@intel.com>


On 10/2/2026 13:33, 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.
>
> v2:
> - Enable the VF and read its configuration once in the fixture.
> - Restore driver autoprobe state and disable the VF during cleanup.
> - Clarify test documentation and shorten runtime descriptions.
> - Remove redundant informational messages.
>
> v3:
> - Move test state from globals to igt_main().
> - Add missing blank lines in the test.
> - Reject a 64-bit memory BAR type in BAR5.
>
> v4:
> - Add the PCI register definitions used by the test to igt_pci_regs.h
>    instead of relying on linux/pci_regs.h.
>
> Signed-off-by: Piotr Piórkowski <piotr.piorkowski@intel.com>
> Assisted-by: GitHub Copilot:GPT-5.6 Luna

Reviewed-by: Lukasz Laguna <lukasz.laguna@intel.com>

> ---
>   lib/igt_pci_regs.h       |  35 +++++++
>   tests/meson.build        |   1 +
>   tests/sriov_pci_config.c | 215 +++++++++++++++++++++++++++++++++++++++
>   3 files changed, 251 insertions(+)
>   create mode 100644 tests/sriov_pci_config.c
>
> diff --git a/lib/igt_pci_regs.h b/lib/igt_pci_regs.h
> index 5d6fece776..9ec548f8d8 100644
> --- a/lib/igt_pci_regs.h
> +++ b/lib/igt_pci_regs.h
> @@ -14,4 +14,39 @@
>   #define PCI_CFG_SPACE_SIZE	256
>   #define PCI_CFG_SPACE_EXP_SIZE	4096
>   
> +#define PCI_VENDOR_ID		0x00	/* 16 bits */
> +#define PCI_DEVICE_ID		0x02	/* 16 bits */
> +#define PCI_COMMAND		0x04	/* 16 bits */
> +#define  PCI_COMMAND_IO		0x1	/* Enable response in I/O space */
> +#define  PCI_COMMAND_MEMORY	0x2	/* Enable response in Memory space */
> +#define  PCI_COMMAND_INTX_DISABLE 0x400 /* INTx Emulation Disable */
> +#define PCI_STATUS		0x06	/* 16 bits */
> +#define  PCI_STATUS_IMM_READY	0x01	/* Immediate Readiness */
> +#define  PCI_STATUS_INTERRUPT	0x08	/* Interrupt status */
> +#define PCI_HEADER_TYPE		0x0e	/* 8 bits */
> +#define  PCI_HEADER_TYPE_MASK		0x7f
> +#define PCI_BIST		0x0f	/* 8 bits */
> +#define  PCI_BIST_CODE_MASK	0x0f	/* Return result */
> +#define PCI_BASE_ADDRESS_0	0x10	/* 32 bits */
> +#define  PCI_BASE_ADDRESS_SPACE		0x01	/* 0 = memory, 1 = I/O */
> +#define  PCI_BASE_ADDRESS_MEM_TYPE_MASK	0x06
> +#define  PCI_BASE_ADDRESS_MEM_TYPE_64	0x04	/* 64 bit address */
> +
> +/* Capability IDs */
> +#define  PCI_CAP_ID_EXP		0x10	/* PCI Express */
> +
> +/* PCI Express capability */
> +#define PCI_EXP_FLAGS		2	/* Capabilities register */
> +#define  PCI_EXP_FLAGS_VERS	0x000f	/* Capability version */
> +#define PCI_EXP_DEVCAP		4	/* Device capabilities */
> +#define  PCI_EXP_DEVCAP_PHANTOM	0x00000018 /* Phantom functions */
> +#define  PCI_EXP_DEVCAP_FLR     0x10000000 /* Function Level Reset */
> +#define PCI_EXP_DEVSTA		10	/* Device Status */
> +#define  PCI_EXP_DEVSTA_AUXPD	0x0010	/* AUX Power Detected */
> +#define PCI_EXP_LNKSTA		18	/* Link Status */
> +#define  PCI_EXP_LNKSTA_CLS	0x000f	/* Current Link Speed */
> +#define  PCI_EXP_LNKSTA_NLW	0x03f0	/* Negotiated Link Width */
> +#define  PCI_EXP_LNKSTA_LABS	0x8000	/* Link Autonomous Bandwidth Status */
> +#define PCI_EXP_LNKSTA2		50	/* Link Status 2 */
> +
>   #endif /* __IGT_PCI_REGS_H__ */
> diff --git a/tests/meson.build b/tests/meson.build
> index 4f5c9be7b4..0e1a3faf32 100644
> --- a/tests/meson.build
> +++ b/tests/meson.build
> @@ -74,6 +74,7 @@ test_progs = [
>   	'meta_test',
>   	'prime_vgem',
>   	'sriov_basic',
> +	'sriov_pci_config',
>   	'syncobj_basic',
>   	'syncobj_eventfd',
>   	'syncobj_wait',
> diff --git a/tests/sriov_pci_config.c b/tests/sriov_pci_config.c
> new file mode 100644
> index 0000000000..925235783d
> --- /dev/null
> +++ b/tests/sriov_pci_config.c
> @@ -0,0 +1,215 @@
> +// SPDX-License-Identifier: MIT
> +/*
> + * Copyright(c) 2026 Intel Corporation. All rights reserved.
> + */
> +
> +#include "drmtest.h"
> +#include "igt.h"
> +#include "igt_pci.h"
> +#include "igt_pci_regs.h"
> +#include "igt_sriov_device.h"
> +
> +#define VF_PCI_EXP_DEVSTA_EPRD		(1 << 6)
> +#define VF_PCI_EXP_LNKSTA2_DEEMPHASIS	(1 << 0)
> +
> +/**
> + * 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, and Phantom Functions Supported,
> + * 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 void read_vf_config(int pf_fd, 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_CFG_SPACE_EXP_SIZE);
> +	free(vf_slot);
> +	igt_assert_f(!ret, "Failed to read VF config space (%d)\n", ret);
> +}
> +
> +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_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_IMM_READY | 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_CODE_MASK),
> +		     "BIST: expected Completion Code 0, got 0x%02x\n", config[PCI_BIST]);
> +}
> +
> +static void check_vf_bars(const uint8_t *config)
> +{
> +	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_io = value & PCI_BASE_ADDRESS_SPACE;
> +		uint32_t attr_mask = is_io ? PCI_BASE_ADDRESS_SPACE : 0xfu;
> +		bool is_mem64 = !is_io &&
> +				(value & PCI_BASE_ADDRESS_MEM_TYPE_MASK) ==
> +				PCI_BASE_ADDRESS_MEM_TYPE_64;
> +
> +		/* Only the address bits are hardwired to zero; attributes are static. */
> +		igt_assert_f(!(value & ~attr_mask), "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(bar < 5, "BAR%d: 64-bit memory type in the last BAR (0x%08x)\n",
> +				     bar, value);
> +			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_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 |
> +					  VF_PCI_EXP_DEVSTA_EPRD)),
> +		     "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)
> +		igt_skip("PCI Express Capability Version 2 is not present\n");
> +
> +	lnksta2 = igt_pci_config_raw_read_u16(config, pcie_cap + PCI_EXP_LNKSTA2);
> +	igt_assert_f(!(lnksta2 & VF_PCI_EXP_LNKSTA2_DEEMPHASIS),
> +		     "Link Status 2: Current De-emphasis Level must be zero (0x%04x)\n",
> +		     lnksta2);
> +}
> +
> +int igt_main()
> +{
> +	uint8_t vf_config[PCI_CFG_SPACE_EXP_SIZE];
> +	int pf_fd = -1;
> +	bool autoprobe = false;
> +
> +	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_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(pf_fd, vf_config);
> +	}
> +
> +	igt_describe("Validate the VF PCI common header");
> +	igt_subtest("vf-common-header") {
> +		check_vf_common_header(vf_config);
> +	}
> +
> +	igt_describe("Validate the VF BARs");
> +	igt_subtest("vf-bars") {
> +		check_vf_bars(vf_config);
> +	}
> +
> +	igt_describe("Validate the VF PCI Express capability");
> +	igt_subtest("vf-pcie-capabilities") {
> +		check_vf_pcie_capabilities(vf_config);
> +	}
> +
> +	igt_describe("Validate the VF PCI Express Capability Version 2 fields");
> +	igt_subtest("vf-pcie-capabilities-2") {
> +		check_vf_pcie_capabilities_2(vf_config);
> +	}
> +
> +	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-10-12  9:35 UTC|newest]

Thread overview: 11+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-10-02 11:33 [PATCH v4 0/4] Add PCI configuration tests for SR-IOV VFs Piórkowski, Piotr
2026-10-02 11:33 ` [PATCH v4 1/4] lib/igt_pci: Add raw configuration space helpers Piórkowski, Piotr
2026-10-06  9:37   ` Bernatowicz, Marcin
2026-10-02 11:33 ` [PATCH v4 2/4] tests/sriov_pci_config: Add VF core config checks Piórkowski, Piotr
2026-10-12  9:33   ` Laguna, Lukasz [this message]
2026-10-02 11:33 ` [PATCH v4 3/4] tests/sriov_pci_config: Add optional capability checks Piórkowski, Piotr
2026-10-02 11:33 ` [PATCH v4 4/4] intel-ci: Block igt@sriov_pci_config.* Piórkowski, Piotr
2026-10-02 12:37 ` ✓ Xe.CI.BAT: success for Add PCI configuration tests for SR-IOV VFs Patchwork
2026-10-02 12:56 ` ✓ i915.CI.BAT: " Patchwork
2026-10-02 13:59 ` ✗ Xe.CI.FULL: failure " Patchwork
2026-10-03 10:52 ` ✗ i915.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=4e46fc2c-5154-467c-bbf8-08a4d055100b@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