Storing PCI(e) VPD Board Serial Numbers
dmitrii.shcherbakov at canonical.com
Fri May 28 19:58:05 UTC 2021
Hello Libvirt Developers,
I am looking for some feedback on a planned enhancement to Libvirt: the aim
to store a portion of PCI(e) Vital Product Data (VPD) for each device along
with other PCI/PCIe device information already collected. Specifically, the
(Serial Number) read-only field of a VPD data structure of a device is of
interest which is described in PCI/PCIe specs (PCI local bus 2.1+ and PCIe
The context for this is the cross-project work in OpenStack (Nova, Neutron),
OVS and OVN to support for off-path SmartNIC DPUs (, , , ). The
Nova specification  provides an overview of the relevant hardware and the
use-case for board serial numbers, however, VPD is the standard capability
the PCI/PCIe specifications not tied to the use-case in particular so the
suggestion from the Nova core team was to aim at introducing means of
collecting this information via Libvirt. It can then be retrieved by the
respective virt driver in Nova via Libvirt without having to introduce this
code into Nova itself.
Quoting the PCI(e) specs:
* "Vital Product Data (VPD) is the information that uniquely defines items
as the hardware, software, and microcode elements of a system.";
* "Vital Product Data is made up of Small and Large Resource Data Types.";
* "Large resource type VPD-R Tag: This tag contains the read only VPD
for an add-in card."
* SN read-only field: "The characters are alphanumeric and represent the
add-in card Serial Number."
The VPD capability is optional per the specification so it may or may not
appear for PCI(e) endpoints. The devices of interest (SmartNIC DPUs),
generally have it exposed.
The PCI/PCIe specs define a binary format for VPD and a sysfs entry exposing
a binary blob in that format has been available since kernel v2.6.26 .
relevant sections of specs are:
* "6.4. Vital Product Data" in the PCI Local Bus specification;
* "6.28 Vital Product Data (VPD)" in the PCIe 4.0 Base Specification.
Note that the serial number stored in VPD is not identical to the
stored in the Device Serial Number (DSN) capability also present in the
as it may identify a component on a board which presents a multi-function
device but the board itself may have multiple components ( also makes a
distinction between a board serial and a device serial).
As a reference, there is some code to parse and print the VPD in lspci 
there is a prototype along those lines in Python , a polished version of
which I plan to use in Nova until the relevant functionality appears in
Likewise, the devlink kernel infrastructure, which is already used in
to query additional device capabilities  (e.g. the presence of an
and its switchdev mode) has a devlink-info API  that exposes a way to
a board serial number if a device driver exposes it (in turn, by querying
controller firmware or via PCIe VPD). This allows doing that in a
bus-independent manner (e.g. it would work for PCIe, platform devices or
I/O interconnects) but in the context of devices that implement devlink API
only (which are not necessarily network devices  but most of them
I would like to suggest the following to be done in Libvirt:
1) adding the code for extracting a serial number from VPD for PCI/PCIe
in general and storing it for exposure via the Libvirt API;
More specifically, I propose adding a nested capability called "vpd" under
<!-- ... other VPD attributes if present -->
<!-- ... -->
2) (optional) implementing functionality to obtain a board serial number via
devlink-info for PCIe devices if they do not expose a VPD capability
but the device driver can retrieve it via firmware. The board serial number
can be stored in the same element as suggested above.
Not all devices expose the devlink API and even fewer do expose board serial
* devlink was added in 4.10 ;
* devlink-info was introduced in 5.1 ;
* querying for board.serial_number was added in kernel 5.9  and iproute2
* Besides the generic devlink infrastructure support above, device drivers
also need to support exposing this field.
Therefore, implementing two approaches (sysfs VPD, devlink) is preferable
for better compatibility.
I would appreciate any feedback on whether this potential addition makes
If so, I can look into implementing this.
-------------- next part --------------
An HTML attachment was scrubbed...
More information about the libvir-list