vmm: Use PciBdf throughout in order to remove manual bit manipulation

In particular use the accessor for getting the device id from the bdf.
As a side effect the VIOT table is now segment aware.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
This commit is contained in:
Rob Bradford 2021-10-18 17:29:42 +01:00
parent 79e43ac534
commit ae83e3b383
6 changed files with 70 additions and 78 deletions

View File

@ -140,12 +140,8 @@ impl PciBus {
Ok(()) Ok(())
} }
pub fn add_device( pub fn add_device(&mut self, device_id: u32, device: Arc<Mutex<dyn PciDevice>>) -> Result<()> {
&mut self, self.devices.insert(device_id, device);
pci_device_bdf: u32,
device: Arc<Mutex<dyn PciDevice>>,
) -> Result<()> {
self.devices.insert(pci_device_bdf >> 3, device);
Ok(()) Ok(())
} }

View File

@ -16,6 +16,7 @@ use arch::DeviceType;
use arch::NumaNodes; use arch::NumaNodes;
use bitflags::bitflags; use bitflags::bitflags;
use pci::PciBdf;
use std::sync::{Arc, Mutex}; use std::sync::{Arc, Mutex};
use vm_memory::{Address, ByteValued, Bytes, GuestAddress, GuestMemoryRegion}; use vm_memory::{Address, ByteValued, Bytes, GuestAddress, GuestMemoryRegion};
@ -438,7 +439,7 @@ fn create_iort_table() -> Sdt {
iort iort
} }
fn create_viot_table(iommu_bdf: u32, devices_bdf: &[u32]) -> Sdt { fn create_viot_table(iommu_bdf: &PciBdf, devices_bdf: &[PciBdf]) -> Sdt {
// VIOT // VIOT
let mut viot = Sdt::new(*b"VIOT", 36, 0, *b"CLOUDH", *b"CHVIOT ", 0); let mut viot = Sdt::new(*b"VIOT", 36, 0, *b"CLOUDH", *b"CHVIOT ", 0);
// Node count // Node count
@ -452,8 +453,8 @@ fn create_viot_table(iommu_bdf: u32, devices_bdf: &[u32]) -> Sdt {
viot.append(ViotVirtioPciNode { viot.append(ViotVirtioPciNode {
type_: 3, type_: 3,
length: 16, length: 16,
pci_segment: 0, pci_segment: iommu_bdf.segment(),
pci_bdf_number: iommu_bdf as u16, pci_bdf_number: iommu_bdf.into(),
..Default::default() ..Default::default()
}); });
@ -461,11 +462,11 @@ fn create_viot_table(iommu_bdf: u32, devices_bdf: &[u32]) -> Sdt {
viot.append(ViotPciRangeNode { viot.append(ViotPciRangeNode {
type_: 1, type_: 1,
length: 24, length: 24,
endpoint_start: *device_bdf, endpoint_start: device_bdf.into(),
pci_segment_start: 0, pci_segment_start: device_bdf.segment(),
pci_segment_end: 0, pci_segment_end: device_bdf.segment(),
pci_bdf_start: *device_bdf as u16, pci_bdf_start: device_bdf.into(),
pci_bdf_end: *device_bdf as u16, pci_bdf_end: device_bdf.into(),
output_node: 48, output_node: 48,
..Default::default() ..Default::default()
}); });
@ -619,7 +620,7 @@ pub fn create_acpi_tables(
// VIOT // VIOT
if let Some((iommu_bdf, devices_bdf)) = device_manager.lock().unwrap().iommu_attached_devices() if let Some((iommu_bdf, devices_bdf)) = device_manager.lock().unwrap().iommu_attached_devices()
{ {
let viot = create_viot_table(*iommu_bdf, devices_bdf); let viot = create_viot_table(iommu_bdf, devices_bdf);
let viot_offset = prev_tbl_off.checked_add(prev_tbl_len).unwrap(); let viot_offset = prev_tbl_off.checked_add(prev_tbl_len).unwrap();
guest_mem guest_mem

View File

@ -70,7 +70,7 @@ use libc::{
#[cfg(target_arch = "x86_64")] #[cfg(target_arch = "x86_64")]
use pci::PciConfigIo; use pci::PciConfigIo;
use pci::{ use pci::{
DeviceRelocation, PciBarRegionType, PciDevice, VfioPciDevice, VfioUserDmaMapping, DeviceRelocation, PciBarRegionType, PciBdf, PciDevice, VfioPciDevice, VfioUserDmaMapping,
VfioUserPciDevice, VfioUserPciDeviceError, VfioUserPciDevice, VfioUserPciDeviceError,
}; };
use seccompiler::SeccompAction; use seccompiler::SeccompAction;
@ -865,7 +865,7 @@ pub struct DeviceManager {
// It contains the virtual IOMMU PCI BDF along with the list of PCI BDF // It contains the virtual IOMMU PCI BDF along with the list of PCI BDF
// representing the devices attached to the virtual IOMMU. This is useful // representing the devices attached to the virtual IOMMU. This is useful
// information for filling the ACPI VIOT table. // information for filling the ACPI VIOT table.
iommu_attached_devices: Option<(u32, Vec<u32>)>, iommu_attached_devices: Option<(PciBdf, Vec<PciBdf>)>,
// Tree of devices, representing the dependencies between devices. // Tree of devices, representing the dependencies between devices.
// Useful for introspection, snapshot and restore. // Useful for introspection, snapshot and restore.
@ -2829,7 +2829,7 @@ impl DeviceManager {
fn add_passthrough_device( fn add_passthrough_device(
&mut self, &mut self,
device_cfg: &mut DeviceConfig, device_cfg: &mut DeviceConfig,
) -> DeviceManagerResult<(u32, String)> { ) -> DeviceManagerResult<(PciBdf, String)> {
// If the passthrough device has not been created yet, it is created // If the passthrough device has not been created yet, it is created
// here and stored in the DeviceManager structure for future needs. // here and stored in the DeviceManager structure for future needs.
if self.passthrough_device.is_none() { if self.passthrough_device.is_none() {
@ -2877,7 +2877,7 @@ impl DeviceManager {
fn add_vfio_device( fn add_vfio_device(
&mut self, &mut self,
device_cfg: &mut DeviceConfig, device_cfg: &mut DeviceConfig,
) -> DeviceManagerResult<(u32, String)> { ) -> DeviceManagerResult<(PciBdf, String)> {
let pci_segment_id = device_cfg.pci_segment; let pci_segment_id = device_cfg.pci_segment;
let pci_device_bdf = self.pci_segments[pci_segment_id as usize].next_device_bdf()?; let pci_device_bdf = self.pci_segments[pci_segment_id as usize].next_device_bdf()?;
@ -2903,7 +2903,7 @@ impl DeviceManager {
iommu iommu
.lock() .lock()
.unwrap() .unwrap()
.add_external_mapping(pci_device_bdf, vfio_mapping); .add_external_mapping(pci_device_bdf.into(), vfio_mapping);
} else { } else {
return Err(DeviceManagerError::MissingVirtualIommu); return Err(DeviceManagerError::MissingVirtualIommu);
} }
@ -2961,7 +2961,7 @@ impl DeviceManager {
legacy_interrupt_manager legacy_interrupt_manager
.create_group(LegacyIrqGroupConfig { .create_group(LegacyIrqGroupConfig {
irq: self.pci_segments[pci_segment_id as usize].pci_irq_slots irq: self.pci_segments[pci_segment_id as usize].pci_irq_slots
[(pci_device_bdf >> 3) as usize] [pci_device_bdf.device() as usize]
as InterruptIndex, as InterruptIndex,
}) })
.map_err(DeviceManagerError::CreateInterruptGroup)?, .map_err(DeviceManagerError::CreateInterruptGroup)?,
@ -3018,7 +3018,7 @@ impl DeviceManager {
}); });
} }
node.pci_bdf = Some(pci_device_bdf); node.pci_bdf = Some(pci_device_bdf.into());
node.pci_segment_id = Some(pci_segment_id); node.pci_segment_id = Some(pci_segment_id);
node.pci_device_handle = Some(PciDeviceHandle::Vfio(vfio_pci_device)); node.pci_device_handle = Some(PciDeviceHandle::Vfio(vfio_pci_device));
@ -3035,7 +3035,7 @@ impl DeviceManager {
bus_device: Arc<Mutex<dyn BusDevice>>, bus_device: Arc<Mutex<dyn BusDevice>>,
pci_device: Arc<Mutex<dyn PciDevice>>, pci_device: Arc<Mutex<dyn PciDevice>>,
segment_id: u16, segment_id: u16,
bdf: u32, bdf: PciBdf,
) -> DeviceManagerResult<Vec<(GuestAddress, GuestUsize, PciBarRegionType)>> { ) -> DeviceManagerResult<Vec<(GuestAddress, GuestUsize, PciBarRegionType)>> {
let bars = pci_device let bars = pci_device
.lock() .lock()
@ -3055,7 +3055,7 @@ impl DeviceManager {
.unwrap(); .unwrap();
pci_bus pci_bus
.add_device(bdf, pci_device) .add_device(bdf.device() as u32, pci_device)
.map_err(DeviceManagerError::AddPciDevice)?; .map_err(DeviceManagerError::AddPciDevice)?;
self.bus_devices.push(Arc::clone(&bus_device)); self.bus_devices.push(Arc::clone(&bus_device));
@ -3073,7 +3073,7 @@ impl DeviceManager {
Ok(bars) Ok(bars)
} }
fn add_vfio_devices(&mut self) -> DeviceManagerResult<Vec<u32>> { fn add_vfio_devices(&mut self) -> DeviceManagerResult<Vec<PciBdf>> {
let mut iommu_attached_device_ids = Vec::new(); let mut iommu_attached_device_ids = Vec::new();
let mut devices = self.config.lock().unwrap().devices.clone(); let mut devices = self.config.lock().unwrap().devices.clone();
@ -3095,7 +3095,7 @@ impl DeviceManager {
fn add_vfio_user_device( fn add_vfio_user_device(
&mut self, &mut self,
device_cfg: &mut UserDeviceConfig, device_cfg: &mut UserDeviceConfig,
) -> DeviceManagerResult<(u32, String)> { ) -> DeviceManagerResult<(PciBdf, String)> {
let pci_segment_id = device_cfg.pci_segment; let pci_segment_id = device_cfg.pci_segment;
let pci_device_bdf = self.pci_segments[pci_segment_id as usize].next_device_bdf()?; let pci_device_bdf = self.pci_segments[pci_segment_id as usize].next_device_bdf()?;
@ -3105,7 +3105,7 @@ impl DeviceManager {
legacy_interrupt_manager legacy_interrupt_manager
.create_group(LegacyIrqGroupConfig { .create_group(LegacyIrqGroupConfig {
irq: self.pci_segments[pci_segment_id as usize].pci_irq_slots irq: self.pci_segments[pci_segment_id as usize].pci_irq_slots
[(pci_device_bdf >> 3) as usize] [pci_device_bdf.device() as usize]
as InterruptIndex, as InterruptIndex,
}) })
.map_err(DeviceManagerError::CreateInterruptGroup)?, .map_err(DeviceManagerError::CreateInterruptGroup)?,
@ -3140,7 +3140,7 @@ impl DeviceManager {
.lock() .lock()
.unwrap() .unwrap()
.add_dma_mapping_handler( .add_dma_mapping_handler(
VirtioMemMappingSource::Device(pci_device_bdf), VirtioMemMappingSource::Device(pci_device_bdf.into()),
vfio_user_mapping.clone(), vfio_user_mapping.clone(),
) )
.map_err(DeviceManagerError::AddDmaMappingHandlerVirtioMem)?; .map_err(DeviceManagerError::AddDmaMappingHandlerVirtioMem)?;
@ -3177,7 +3177,7 @@ impl DeviceManager {
let mut node = device_node!(vfio_user_name); let mut node = device_node!(vfio_user_name);
node.pci_bdf = Some(pci_device_bdf); node.pci_bdf = Some(pci_device_bdf.into());
node.pci_segment_id = Some(pci_segment_id); node.pci_segment_id = Some(pci_segment_id);
node.pci_device_handle = Some(PciDeviceHandle::VfioUser(vfio_user_pci_device)); node.pci_device_handle = Some(PciDeviceHandle::VfioUser(vfio_user_pci_device));
@ -3189,7 +3189,7 @@ impl DeviceManager {
Ok((pci_device_bdf, vfio_user_name)) Ok((pci_device_bdf, vfio_user_name))
} }
fn add_user_devices(&mut self) -> DeviceManagerResult<Vec<u32>> { fn add_user_devices(&mut self) -> DeviceManagerResult<Vec<PciBdf>> {
let mut user_devices = self.config.lock().unwrap().user_devices.clone(); let mut user_devices = self.config.lock().unwrap().user_devices.clone();
if let Some(device_list_cfg) = &mut user_devices { if let Some(device_list_cfg) = &mut user_devices {
@ -3210,7 +3210,7 @@ impl DeviceManager {
iommu_mapping: &Option<Arc<IommuMapping>>, iommu_mapping: &Option<Arc<IommuMapping>>,
virtio_device_id: String, virtio_device_id: String,
pci_segment_id: u16, pci_segment_id: u16,
) -> DeviceManagerResult<u32> { ) -> DeviceManagerResult<PciBdf> {
let id = format!("{}-{}", VIRTIO_PCI_DEVICE_NAME_PREFIX, virtio_device_id); let id = format!("{}-{}", VIRTIO_PCI_DEVICE_NAME_PREFIX, virtio_device_id);
// Add the new virtio-pci node to the device tree. // Add the new virtio-pci node to the device tree.
@ -3223,9 +3223,10 @@ impl DeviceManager {
self.device_tree.lock().unwrap().get(&id) self.device_tree.lock().unwrap().get(&id)
{ {
info!("Restoring virtio-pci {} resources", id); info!("Restoring virtio-pci {} resources", id);
let pci_device_bdf = node let pci_device_bdf: PciBdf = node
.pci_bdf .pci_bdf
.ok_or(DeviceManagerError::MissingDeviceNodePciBdf)?; .ok_or(DeviceManagerError::MissingDeviceNodePciBdf)?
.into();
let pci_segment_id = node let pci_segment_id = node
.pci_segment_id .pci_segment_id
.ok_or(DeviceManagerError::MissingDeviceNodePciSegmentId)?; .ok_or(DeviceManagerError::MissingDeviceNodePciSegmentId)?;
@ -3234,7 +3235,7 @@ impl DeviceManager {
.pci_bus .pci_bus
.lock() .lock()
.unwrap() .unwrap()
.get_device_id((pci_device_bdf >> 3) as usize) .get_device_id(pci_device_bdf.device() as usize)
.map_err(DeviceManagerError::GetPciDeviceId)?; .map_err(DeviceManagerError::GetPciDeviceId)?;
if node.resources.is_empty() { if node.resources.is_empty() {
@ -3276,7 +3277,7 @@ impl DeviceManager {
let access_platform: Option<Arc<dyn AccessPlatform>> = if let Some(mapping) = iommu_mapping let access_platform: Option<Arc<dyn AccessPlatform>> = if let Some(mapping) = iommu_mapping
{ {
Some(Arc::new(AccessPlatformMapping::new( Some(Arc::new(AccessPlatformMapping::new(
pci_device_bdf, pci_device_bdf.into(),
mapping.clone(), mapping.clone(),
))) )))
} else { } else {
@ -3292,7 +3293,7 @@ impl DeviceManager {
msix_num, msix_num,
access_platform, access_platform,
&self.msi_interrupt_manager, &self.msi_interrupt_manager,
pci_device_bdf, pci_device_bdf.into(),
self.activate_evt self.activate_evt
.try_clone() .try_clone()
.map_err(DeviceManagerError::EventFd)?, .map_err(DeviceManagerError::EventFd)?,
@ -3335,7 +3336,7 @@ impl DeviceManager {
}); });
} }
node.migratable = Some(Arc::clone(&virtio_pci_device) as Arc<Mutex<dyn Migratable>>); node.migratable = Some(Arc::clone(&virtio_pci_device) as Arc<Mutex<dyn Migratable>>);
node.pci_bdf = Some(pci_device_bdf); node.pci_bdf = Some(pci_device_bdf.into());
node.pci_segment_id = Some(pci_segment_id); node.pci_segment_id = Some(pci_segment_id);
node.pci_device_handle = Some(PciDeviceHandle::Virtio(virtio_pci_device)); node.pci_device_handle = Some(PciDeviceHandle::Virtio(virtio_pci_device));
self.device_tree.lock().unwrap().insert(id, node); self.device_tree.lock().unwrap().insert(id, node);
@ -3463,14 +3464,14 @@ impl DeviceManager {
&mut self, &mut self,
device_cfg: &mut DeviceConfig, device_cfg: &mut DeviceConfig,
) -> DeviceManagerResult<PciDeviceInfo> { ) -> DeviceManagerResult<PciDeviceInfo> {
let (device_id, device_name) = self.add_passthrough_device(device_cfg)?; let (bdf, device_name) = self.add_passthrough_device(device_cfg)?;
// Update the PCIU bitmap // Update the PCIU bitmap
self.pci_segments[device_cfg.pci_segment as usize].pci_devices_up |= 1 << (device_id >> 3); self.pci_segments[device_cfg.pci_segment as usize].pci_devices_up |= 1 << bdf.device();
Ok(PciDeviceInfo { Ok(PciDeviceInfo {
id: device_name, id: device_name,
bdf: device_id, bdf,
}) })
} }
@ -3478,14 +3479,14 @@ impl DeviceManager {
&mut self, &mut self,
device_cfg: &mut UserDeviceConfig, device_cfg: &mut UserDeviceConfig,
) -> DeviceManagerResult<PciDeviceInfo> { ) -> DeviceManagerResult<PciDeviceInfo> {
let (device_id, device_name) = self.add_vfio_user_device(device_cfg)?; let (bdf, device_name) = self.add_vfio_user_device(device_cfg)?;
// Update the PCIU bitmap // Update the PCIU bitmap
self.pci_segments[device_cfg.pci_segment as usize].pci_devices_up |= 1 << (device_id >> 3); self.pci_segments[device_cfg.pci_segment as usize].pci_devices_up |= 1 << bdf.device();
Ok(PciDeviceInfo { Ok(PciDeviceInfo {
id: device_name, id: device_name,
bdf: device_id, bdf,
}) })
} }
@ -3511,9 +3512,10 @@ impl DeviceManager {
.ok_or(DeviceManagerError::MissingNode)? .ok_or(DeviceManagerError::MissingNode)?
}; };
let pci_device_bdf = pci_device_node let pci_device_bdf: PciBdf = pci_device_node
.pci_bdf .pci_bdf
.ok_or(DeviceManagerError::MissingDeviceNodePciBdf)?; .ok_or(DeviceManagerError::MissingDeviceNodePciBdf)?
.into();
let pci_segment_id = pci_device_node let pci_segment_id = pci_device_node
.pci_segment_id .pci_segment_id
.ok_or(DeviceManagerError::MissingDeviceNodePciSegmentId)?; .ok_or(DeviceManagerError::MissingDeviceNodePciSegmentId)?;
@ -3544,7 +3546,7 @@ impl DeviceManager {
} }
// Update the PCID bitmap // Update the PCID bitmap
self.pci_segments[pci_segment_id as usize].pci_devices_down |= 1 << (pci_device_bdf >> 3); self.pci_segments[pci_segment_id as usize].pci_devices_down |= 1 << pci_device_bdf.device();
Ok(()) Ok(())
} }
@ -3556,7 +3558,7 @@ impl DeviceManager {
); );
// Convert the device ID into the corresponding b/d/f. // Convert the device ID into the corresponding b/d/f.
let pci_device_bdf = (device_id as u32) << 3; let pci_device_bdf = PciBdf::new(pci_segment_id, 0, device_id, 0);
// Give the PCI device ID back to the PCI bus. // Give the PCI device ID back to the PCI bus.
self.pci_segments[pci_segment_id as usize] self.pci_segments[pci_segment_id as usize]
@ -3569,7 +3571,7 @@ impl DeviceManager {
// Remove the device from the device tree along with its children. // Remove the device from the device tree along with its children.
let mut device_tree = self.device_tree.lock().unwrap(); let mut device_tree = self.device_tree.lock().unwrap();
let pci_device_node = device_tree let pci_device_node = device_tree
.remove_node_by_pci_bdf(pci_segment_id, pci_device_bdf) .remove_node_by_pci_bdf(pci_segment_id, pci_device_bdf.into())
.ok_or(DeviceManagerError::MissingPciDevice)?; .ok_or(DeviceManagerError::MissingPciDevice)?;
for child in pci_device_node.children.iter() { for child in pci_device_node.children.iter() {
device_tree.remove(child); device_tree.remove(child);
@ -3614,7 +3616,9 @@ impl DeviceManager {
virtio_mem_device virtio_mem_device
.lock() .lock()
.unwrap() .unwrap()
.remove_dma_mapping_handler(VirtioMemMappingSource::Device(pci_device_bdf)) .remove_dma_mapping_handler(VirtioMemMappingSource::Device(
pci_device_bdf.into(),
))
.map_err(DeviceManagerError::RemoveDmaMappingHandlerVirtioMem)?; .map_err(DeviceManagerError::RemoveDmaMappingHandlerVirtioMem)?;
} }
@ -3709,12 +3713,12 @@ impl DeviceManager {
self.virtio_devices self.virtio_devices
.push((device.clone(), iommu_attached, id.clone(), pci_segment_id)); .push((device.clone(), iommu_attached, id.clone(), pci_segment_id));
let device_id = self.add_virtio_pci_device(device, &None, id.clone(), pci_segment_id)?; let bdf = self.add_virtio_pci_device(device, &None, id.clone(), pci_segment_id)?;
// Update the PCIU bitmap // Update the PCIU bitmap
self.pci_segments[pci_segment_id as usize].pci_devices_up |= 1 << (device_id >> 3); self.pci_segments[pci_segment_id as usize].pci_devices_up |= 1 << bdf.device();
Ok(PciDeviceInfo { id, bdf: device_id }) Ok(PciDeviceInfo { id, bdf })
} }
pub fn add_disk(&mut self, disk_cfg: &mut DiskConfig) -> DeviceManagerResult<PciDeviceInfo> { pub fn add_disk(&mut self, disk_cfg: &mut DiskConfig) -> DeviceManagerResult<PciDeviceInfo> {
@ -3873,7 +3877,7 @@ impl DeviceManager {
} }
} }
pub fn iommu_attached_devices(&self) -> &Option<(u32, Vec<u32>)> { pub fn iommu_attached_devices(&self) -> &Option<(PciBdf, Vec<PciBdf>)> {
&self.iommu_attached_devices &self.iommu_attached_devices
} }
} }

View File

@ -29,6 +29,7 @@ use crate::vm::{Error as VmError, Vm, VmState};
use anyhow::anyhow; use anyhow::anyhow;
use libc::EFD_NONBLOCK; use libc::EFD_NONBLOCK;
use memory_manager::MemoryManagerSnapshotData; use memory_manager::MemoryManagerSnapshotData;
use pci::PciBdf;
use seccompiler::{apply_filter, SeccompAction}; use seccompiler::{apply_filter, SeccompAction};
use serde::ser::{Serialize, SerializeStruct, Serializer}; use serde::ser::{Serialize, SerializeStruct, Serializer};
use std::fs::File; use std::fs::File;
@ -206,7 +207,7 @@ impl AsRawFd for EpollContext {
pub struct PciDeviceInfo { pub struct PciDeviceInfo {
pub id: String, pub id: String,
pub bdf: u32, pub bdf: PciBdf,
} }
impl Serialize for PciDeviceInfo { impl Serialize for PciDeviceInfo {
@ -214,15 +215,7 @@ impl Serialize for PciDeviceInfo {
where where
S: Serializer, S: Serializer,
{ {
// Transform the PCI b/d/f into a standardized string. let bdf_str = self.bdf.to_string();
let segment = (self.bdf >> 16) & 0xffff;
let bus = (self.bdf >> 8) & 0xff;
let device = (self.bdf >> 3) & 0x1f;
let function = self.bdf & 0x7;
let bdf_str = format!(
"{:04x}:{:02x}:{:02x}.{:01x}",
segment, bus, device, function
);
// Serialize the structure. // Serialize the structure.
let mut state = serializer.serialize_struct("PciDeviceInfo", 2)?; let mut state = serializer.serialize_struct("PciDeviceInfo", 2)?;

View File

@ -13,7 +13,7 @@ use crate::device_manager::{AddressManager, DeviceManagerError, DeviceManagerRes
#[cfg(feature = "acpi")] #[cfg(feature = "acpi")]
use acpi_tables::aml::{self, Aml}; use acpi_tables::aml::{self, Aml};
use arch::layout; use arch::layout;
use pci::{DeviceRelocation, PciBus, PciConfigMmio, PciRoot}; use pci::{DeviceRelocation, PciBdf, PciBus, PciConfigMmio, PciRoot};
#[cfg(target_arch = "x86_64")] #[cfg(target_arch = "x86_64")]
use pci::{PciConfigIo, PCI_CONFIG_IO_PORT, PCI_CONFIG_IO_PORT_SIZE}; use pci::{PciConfigIo, PCI_CONFIG_IO_PORT, PCI_CONFIG_IO_PORT_SIZE};
use std::sync::{Arc, Mutex}; use std::sync::{Arc, Mutex};
@ -130,19 +130,17 @@ impl PciSegment {
Self::new(0, address_manager, allocator, pci_irq_slots) Self::new(0, address_manager, allocator, pci_irq_slots)
} }
pub(crate) fn next_device_bdf(&self) -> DeviceManagerResult<u32> { pub(crate) fn next_device_bdf(&self) -> DeviceManagerResult<PciBdf> {
// We need to shift the device id since the 3 first bits Ok(PciBdf::new(
// are dedicated to the PCI function, and we know we don't self.id,
// do multifunction. Also, because we only support one PCI 0,
// bus, the bus 0, we don't need to add anything to the self.pci_bus
// global device ID. .lock()
Ok(self .unwrap()
.pci_bus .next_device_id()
.lock() .map_err(DeviceManagerError::NextPciDeviceId)? as u8,
.unwrap() 0,
.next_device_id() ))
.map_err(DeviceManagerError::NextPciDeviceId)?
<< 3)
} }
pub fn reserve_legacy_interrupts_for_pci_devices( pub fn reserve_legacy_interrupts_for_pci_devices(

View File

@ -1096,7 +1096,7 @@ impl Vm {
device_info, device_info,
&initramfs_config, &initramfs_config,
&pci_space, &pci_space,
virtio_iommu_bdf, virtio_iommu_bdf.map(|bdf| bdf.into()),
&*gic_device, &*gic_device,
&self.numa_nodes, &self.numa_nodes,
) )