virtio-devices: Fix cap_len for VIRTIO_PCI_CAP_PCI_CFG - #8238
Conversation
VirtioPciCfgCap::new built its inner header via VirtioPciCap::new, which sized cap_len from the bare virtio_pci_cap layout, yielding 16. The emitted capability is VirtioPciCfgCap, which appends a four byte pci_cfg_data window, so the correct value is 20. The virtio 1.2 specification defines this cap as virtio_pci_cap followed by pci_cfg_data[4] and requires cap_len to cover the whole structure. Build the header inline so cap_len reflects the actual emitted size, matching VirtioPciNotifyCap and VirtioPciCap64. Signed-off-by: Anatol Belski <[email protected]>
Regression test for the cap_len fix. The emitted VirtioPciCfgCap must report cap_len 20, covering the trailing pci_cfg_data window per virtio 1.2 section 4.1.4.9. Signed-off-by: Anatol Belski <[email protected]>
Assert the emitted VirtioPciCfgCap carries cfg_type 5, the value assigned to PciCapabilityType::Pci by virtio 1.2 section 4.1.4.1. Signed-off-by: Anatol Belski <[email protected]>
Assert VirtioPciNotifyCap and VirtioPciCap64 size cap_len from their own type. Catches a future regression of the same shape as the VirtioPciCfgCap one in any of the sibling capabilities. Signed-off-by: Anatol Belski <[email protected]>
phip1611
left a comment
There was a problem hiding this comment.
LGTM, thanks!
General question: How could the old behavior fail with a Linux or Windows guest? What is a typical failure one would see/expect?
I dug into the driver code and no guest actually uses Thanks |
The VIRTIO_PCI_CAP_PCI_CFG capability was emitted with cap_len 16 instead of 20. With this change cap_len reflects the full capability size, including the trailing pci_cfg_data window.
Per virtio 1.2 section 4.1.4.9, the PCI configuration access capability is a 16 byte virtio_pci_cap followed by a 4 byte pci_cfg_data window, so its declared cap_len must be 20.