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