Re: [PATCH v2] vfio/pci: Add DVSEC PCI Extended Config Capability to user visible list.
From: Alex Williamson
Date: Tue Apr 11 2023 - 15:29:12 EST
On Fri, 17 Mar 2023 08:22:22 +0000
"K V P, Satyanarayana" <satyanarayana.k.v.p@xxxxxxxxx> wrote:
> The Designated Vendor-Specific Extended Capability (DVSEC Capability) is an
> optional Extended Capability that is permitted to be implemented by any PCI
> Express Function. This allows PCI Express component vendors to use
> the Extended Capability mechanism to expose vendor-specific registers that can
> be present in components by a variety of vendors. A DVSEC Capability structure
> can tell vendor-specific software which features a particular component
> supports.
>
> An example usage of DVSEC is Intel Platform Monitoring Technology (PMT) for
> enumerating and accessing hardware monitoring capabilities on a device.
> PMT encompasses three device monitoring features, Telemetry (device metrics),
> Watcher (sampling/tracing), and Crashlog. The DVSEC is used to discover these
> features and provide a BAR offset to their registers with the Intel vendor code.
>
> The current VFIO driver does not pass DVSEC capabilities to Virtual Machine (VM)
> which makes PMT not to work inside the virtual machine. This series adds DVSEC
> capability to user visible list to allow its use with VFIO. VFIO supports
> passing of Vendor Specific Extended Capability (VSEC) and raw write access to
> device. DVSEC also passed to VM in the same way as of VSEC.
>
> Signed-off-by: K V P Satyanarayana <satyanarayana.k.v.p@xxxxxxxxx>
>
> Changes since Version V2:
> - Added support for raw pci write for DVSEC same as VSEC.
> ---
> drivers/vfio/pci/vfio_pci_config.c | 7 +++++++
> 1 file changed, 7 insertions(+)
Applied to vfio next branch for v6.4. Thanks,
Alex
>
> diff --git a/drivers/vfio/pci/vfio_pci_config.c b/drivers/vfio/pci/vfio_pci_config.c
> index 523e0144c86f..948cdd464f4e 100644
> --- a/drivers/vfio/pci/vfio_pci_config.c
> +++ b/drivers/vfio/pci/vfio_pci_config.c
> @@ -96,6 +96,7 @@ static const u16 pci_ext_cap_length[PCI_EXT_CAP_ID_MAX + 1] = {
> [PCI_EXT_CAP_ID_SECPCI] = 0, /* not yet */
> [PCI_EXT_CAP_ID_PMUX] = 0, /* not yet */
> [PCI_EXT_CAP_ID_PASID] = 0, /* not yet */
> + [PCI_EXT_CAP_ID_DVSEC] = 0xFF,
> };
>
> /*
> @@ -1101,6 +1102,7 @@ int __init vfio_pci_init_perm_bits(void)
> ret |= init_pci_ext_cap_err_perm(&ecap_perms[PCI_EXT_CAP_ID_ERR]);
> ret |= init_pci_ext_cap_pwr_perm(&ecap_perms[PCI_EXT_CAP_ID_PWR]);
> ecap_perms[PCI_EXT_CAP_ID_VNDR].writefn = vfio_raw_config_write;
> + ecap_perms[PCI_EXT_CAP_ID_DVSEC].writefn = vfio_raw_config_write;
>
> if (ret)
> vfio_pci_uninit_perm_bits();
> @@ -1440,6 +1442,11 @@ static int vfio_ext_cap_len(struct vfio_pci_core_device *vdev, u16 ecap, u16 epo
> return PCI_TPH_BASE_SIZEOF + (sts * 2) + 2;
> }
> return PCI_TPH_BASE_SIZEOF;
> + case PCI_EXT_CAP_ID_DVSEC:
> + ret = pci_read_config_dword(pdev, epos + PCI_DVSEC_HEADER1, &dword);
> + if (ret)
> + return pcibios_err_to_errno(ret);
> + return PCI_DVSEC_HEADER1_LEN(dword);
> default:
> pci_warn(pdev, "%s: unknown length for PCI ecap %#x@%#x\n",
> __func__, ecap, epos);