From d1dd6b13d52b0e02f47ccc6a2d3f0c6b63946260 Mon Sep 17 00:00:00 2001 From: Anatol Belski Date: Mon, 29 Jun 2026 19:14:42 +0200 Subject: [PATCH] virtio-devices: Size the device config capability per device Add a config_size method to VirtioDevice and use it when building the PCI device configuration capability. The transport advertises the size reported by the device and omits the capability entirely when the size is zero, because the virtio driver rejects a zero length capability. The method defaults to None, so every device keeps its current capability size. Signed-off-by: Anatol Belski --- virtio-devices/src/device.rs | 4 +++ virtio-devices/src/transport/pci_device.rs | 29 +++++++++++++--------- 2 files changed, 21 insertions(+), 12 deletions(-) diff --git a/virtio-devices/src/device.rs b/virtio-devices/src/device.rs index 1bcd97463..5c63ad812 100644 --- a/virtio-devices/src/device.rs +++ b/virtio-devices/src/device.rs @@ -108,6 +108,10 @@ pub trait VirtioDevice: Send { let _ = value; } + fn config_size(&self) -> Option { + None + } + /// Reads this device configuration space at `offset`. fn read_config(&self, _offset: u64, _data: &mut [u8]) { warn!( diff --git a/virtio-devices/src/transport/pci_device.rs b/virtio-devices/src/transport/pci_device.rs index be896946d..25cd2e0db 100644 --- a/virtio-devices/src/transport/pci_device.rs +++ b/virtio-devices/src/transport/pci_device.rs @@ -700,7 +700,10 @@ impl VirtioPciDevice { .get_bar_addr(VIRTIO_COMMON_BAR_INDEX.into()) } - fn add_pci_capabilities(&mut self) -> result::Result<(), PciDeviceError> { + fn add_pci_capabilities( + &mut self, + device_config_size: u64, + ) -> result::Result<(), PciDeviceError> { // Add pointers to the different configuration structures from the PCI capabilities. let common_cap = VirtioPciCap::new( PciCapabilityType::Common, @@ -722,16 +725,17 @@ impl VirtioPciDevice { .add_capability(&isr_cap) .map_err(PciDeviceError::CapabilitiesSetup)?; - // TODO(dgreid) - set based on device's configuration size? - let device_cap = VirtioPciCap::new( - PciCapabilityType::Device, - VIRTIO_COMMON_BAR_INDEX, - DEVICE_CONFIG_BAR_OFFSET as u32, - DEVICE_CONFIG_SIZE as u32, - ); - self.configuration - .add_capability(&device_cap) - .map_err(PciDeviceError::CapabilitiesSetup)?; + if device_config_size > 0 { + let device_cap = VirtioPciCap::new( + PciCapabilityType::Device, + VIRTIO_COMMON_BAR_INDEX, + DEVICE_CONFIG_BAR_OFFSET as u32, + device_config_size as u32, + ); + self.configuration + .add_capability(&device_cap) + .map_err(PciDeviceError::CapabilitiesSetup)?; + } let notify_cap = VirtioPciNotifyCap::new( PciCapabilityType::Notify, @@ -1096,7 +1100,8 @@ impl PciDevice for VirtioPciDevice { })?; // Once the BARs are allocated, the capabilities can be added to the PCI configuration. - self.add_pci_capabilities()?; + let device_config_size = device.config_size().unwrap_or(DEVICE_CONFIG_SIZE); + self.add_pci_capabilities(device_config_size)?; } bars.push(bar);