devices: virtio: reserve preferred PCI address

If the VirtioDevice provided a preferred PCI address, we previously used
it but did not reserve the address in the resource allocator. This could
have resulted in address reuse. Add a case to reserve the preferred PCI
address if it was specified.

BUG=b:237415650
TEST=tools/presubmit --all

Change-Id: Id84a9cee99e8955dae174be4f5a6a6c60fb17bd9
Reviewed-on: https://chromium-review.googlesource.com/c/crosvm/crosvm/+/3781440
Commit-Queue: Daniel Verkamp <dverkamp@chromium.org>
Tested-by: Daniel Verkamp <dverkamp@chromium.org>
Reviewed-by: Keiichi Watanabe <keiichiw@chromium.org>
This commit is contained in:
Daniel Verkamp 2022-07-01 14:45:21 -07:00 committed by crosvm LUCI
parent 4b3db6786c
commit d2fdbedf60

View file

@ -274,6 +274,7 @@ const SHMEM_BAR_NUM: usize = 2;
/// transport for virtio devices.
pub struct VirtioPciDevice {
config_regs: PciConfiguration,
preferred_address: Option<PciAddress>,
pci_address: Option<PciAddress>,
device: Box<dyn VirtioDevice>,
@ -360,7 +361,8 @@ impl VirtioPciDevice {
Ok(VirtioPciDevice {
config_regs,
pci_address: device.pci_address(),
preferred_address: device.pci_address(),
pci_address: None,
device,
device_activated: false,
disable_intx,
@ -543,14 +545,29 @@ impl PciDevice for VirtioPciDevice {
resources: &mut SystemAllocator,
) -> std::result::Result<PciAddress, PciDeviceError> {
if self.pci_address.is_none() {
self.pci_address = match resources.allocate_pci(0, self.debug_label()) {
Some(Alloc::PciBar {
bus,
dev,
func,
bar: _,
}) => Some(PciAddress { bus, dev, func }),
_ => None,
if let Some(address) = self.preferred_address {
if !resources.reserve_pci(
Alloc::PciBar {
bus: address.bus,
dev: address.dev,
func: address.func,
bar: 0,
},
self.debug_label(),
) {
return Err(PciDeviceError::PciAllocationFailed);
}
self.pci_address = Some(address);
} else {
self.pci_address = match resources.allocate_pci(0, self.debug_label()) {
Some(Alloc::PciBar {
bus,
dev,
func,
bar: _,
}) => Some(PciAddress { bus, dev, func }),
_ => None,
}
}
}
self.pci_address.ok_or(PciDeviceError::PciAllocationFailed)