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