pci: vfio: Generalise VfioPciConfig trait wrapper

Rename the wrapper trait and structs since this will be used for more
than reading the PCI config.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
This commit is contained in:
Rob Bradford
2021-07-06 15:49:13 +00:00
committed by Sebastien Boeuf
parent ec1f7189da
commit dc35dac306
+27 -35
View File
@@ -245,7 +245,7 @@ pub struct MmioRegion {
pub(crate) mmap_size: Option<usize>, pub(crate) mmap_size: Option<usize>,
} }
pub(crate) trait VfioPciConfig { pub(crate) trait Vfio {
fn read_config_byte(&self, offset: u32) -> u8 { fn read_config_byte(&self, offset: u32) -> u8 {
let mut data: [u8; 1] = [0]; let mut data: [u8; 1] = [0];
self.read_config(offset, &mut data); self.read_config(offset, &mut data);
@@ -278,17 +278,17 @@ pub(crate) trait VfioPciConfig {
} }
} }
struct VfioPciDeviceConfig { struct VfioDeviceWrapper {
device: Arc<VfioDevice>, device: Arc<VfioDevice>,
} }
impl VfioPciDeviceConfig { impl VfioDeviceWrapper {
fn new(device: Arc<VfioDevice>) -> Self { fn new(device: Arc<VfioDevice>) -> Self {
Self { device } Self { device }
} }
} }
impl VfioPciConfig for VfioPciDeviceConfig { impl Vfio for VfioDeviceWrapper {
fn read_config(&self, offset: u32, data: &mut [u8]) { fn read_config(&self, offset: u32, data: &mut [u8]) {
self.device self.device
.region_read(VFIO_PCI_CONFIG_REGION_INDEX, data.as_mut(), offset.into()); .region_read(VFIO_PCI_CONFIG_REGION_INDEX, data.as_mut(), offset.into());
@@ -310,7 +310,7 @@ impl VfioCommon {
pub(crate) fn allocate_bars( pub(crate) fn allocate_bars(
&mut self, &mut self,
allocator: &mut SystemAllocator, allocator: &mut SystemAllocator,
vfio_pci_config: &dyn VfioPciConfig, vfio_wrapper: &dyn Vfio,
) -> std::result::Result<Vec<(GuestAddress, GuestUsize, PciBarRegionType)>, PciDeviceError> ) -> std::result::Result<Vec<(GuestAddress, GuestUsize, PciBarRegionType)>, PciDeviceError>
{ {
let mut ranges = Vec::new(); let mut ranges = Vec::new();
@@ -331,7 +331,7 @@ impl VfioCommon {
}; };
// First read flags // First read flags
let flags = vfio_pci_config.read_config_dword(bar_offset); let flags = vfio_wrapper.read_config_dword(bar_offset);
// Is this an IO BAR? // Is this an IO BAR?
let io_bar = if bar_id != VFIO_PCI_ROM_REGION_INDEX { let io_bar = if bar_id != VFIO_PCI_ROM_REGION_INDEX {
@@ -354,10 +354,10 @@ impl VfioCommon {
let mut region_type = PciBarRegionType::Memory32BitRegion; let mut region_type = PciBarRegionType::Memory32BitRegion;
// To get size write all 1s // To get size write all 1s
vfio_pci_config.write_config_dword(bar_offset, 0xffff_ffff); vfio_wrapper.write_config_dword(bar_offset, 0xffff_ffff);
// And read back BAR value. The device will write zeros for bits it doesn't care about // And read back BAR value. The device will write zeros for bits it doesn't care about
let mut lower = vfio_pci_config.read_config_dword(bar_offset); let mut lower = vfio_wrapper.read_config_dword(bar_offset);
if io_bar { if io_bar {
#[cfg(target_arch = "x86_64")] #[cfg(target_arch = "x86_64")]
@@ -390,8 +390,8 @@ impl VfioCommon {
// Query size of upper BAR of 64-bit BAR // Query size of upper BAR of 64-bit BAR
let upper_offset: u32 = PCI_CONFIG_BAR_OFFSET + (bar_id + 1) * 4; let upper_offset: u32 = PCI_CONFIG_BAR_OFFSET + (bar_id + 1) * 4;
vfio_pci_config.write_config_dword(upper_offset, 0xffff_ffff); vfio_wrapper.write_config_dword(upper_offset, 0xffff_ffff);
let upper = vfio_pci_config.read_config_dword(upper_offset); let upper = vfio_wrapper.read_config_dword(upper_offset);
let mut combined_size = u64::from(upper) << 32 | u64::from(lower); let mut combined_size = u64::from(upper) << 32 | u64::from(lower);
@@ -499,13 +499,13 @@ impl VfioCommon {
&mut self, &mut self,
cap: u8, cap: u8,
interrupt_manager: &Arc<dyn InterruptManager<GroupConfig = MsiIrqGroupConfig>>, interrupt_manager: &Arc<dyn InterruptManager<GroupConfig = MsiIrqGroupConfig>>,
vfio_pci_config: &dyn VfioPciConfig, vfio_wrapper: &dyn Vfio,
) { ) {
let msg_ctl = vfio_pci_config.read_config_word((cap + 2).into()); let msg_ctl = vfio_wrapper.read_config_word((cap + 2).into());
let table = vfio_pci_config.read_config_dword((cap + 4).into()); let table = vfio_wrapper.read_config_dword((cap + 4).into());
let pba = vfio_pci_config.read_config_dword((cap + 8).into()); let pba = vfio_wrapper.read_config_dword((cap + 8).into());
let msix_cap = MsixCap { let msix_cap = MsixCap {
msg_ctl, msg_ctl,
@@ -534,9 +534,9 @@ impl VfioCommon {
&mut self, &mut self,
cap: u8, cap: u8,
interrupt_manager: &Arc<dyn InterruptManager<GroupConfig = MsiIrqGroupConfig>>, interrupt_manager: &Arc<dyn InterruptManager<GroupConfig = MsiIrqGroupConfig>>,
vfio_pci_config: &dyn VfioPciConfig, vfio_wrapper: &dyn Vfio,
) { ) {
let msg_ctl = vfio_pci_config.read_config_word((cap + 2).into()); let msg_ctl = vfio_wrapper.read_config_word((cap + 2).into());
let interrupt_source_group = interrupt_manager let interrupt_source_group = interrupt_manager
.create_group(MsiIrqGroupConfig { .create_group(MsiIrqGroupConfig {
@@ -565,7 +565,7 @@ pub struct VfioPciDevice {
vm: Arc<dyn hypervisor::Vm>, vm: Arc<dyn hypervisor::Vm>,
device: Arc<VfioDevice>, device: Arc<VfioDevice>,
container: Arc<VfioContainer>, container: Arc<VfioContainer>,
vfio_pci_configuration: VfioPciDeviceConfig, vfio_wrapper: VfioDeviceWrapper,
common: VfioCommon, common: VfioCommon,
iommu_attached: bool, iommu_attached: bool,
} }
@@ -596,13 +596,13 @@ impl VfioPciDevice {
None, None,
); );
let vfio_pci_configuration = VfioPciDeviceConfig::new(Arc::clone(&device)); let vfio_wrapper = VfioDeviceWrapper::new(Arc::clone(&device));
let mut vfio_pci_device = VfioPciDevice { let mut vfio_pci_device = VfioPciDevice {
vm: vm.clone(), vm: vm.clone(),
device, device,
container, container,
vfio_pci_configuration, vfio_wrapper,
common: VfioCommon { common: VfioCommon {
mmio_regions: Vec::new(), mmio_regions: Vec::new(),
configuration, configuration,
@@ -735,13 +735,11 @@ impl VfioPciDevice {
interrupt_manager: &Arc<dyn InterruptManager<GroupConfig = MsiIrqGroupConfig>>, interrupt_manager: &Arc<dyn InterruptManager<GroupConfig = MsiIrqGroupConfig>>,
) { ) {
let mut cap_next = self let mut cap_next = self
.vfio_pci_configuration .vfio_wrapper
.read_config_byte(PCI_CONFIG_CAPABILITY_OFFSET); .read_config_byte(PCI_CONFIG_CAPABILITY_OFFSET);
while cap_next != 0 { while cap_next != 0 {
let cap_id = self let cap_id = self.vfio_wrapper.read_config_byte(cap_next.into());
.vfio_pci_configuration
.read_config_byte(cap_next.into());
match PciCapabilityId::from(cap_id) { match PciCapabilityId::from(cap_id) {
PciCapabilityId::MessageSignalledInterrupts => { PciCapabilityId::MessageSignalledInterrupts => {
@@ -752,7 +750,7 @@ impl VfioPciDevice {
self.common.parse_msi_capabilities( self.common.parse_msi_capabilities(
cap_next, cap_next,
interrupt_manager, interrupt_manager,
&self.vfio_pci_configuration, &self.vfio_wrapper,
); );
} }
} }
@@ -765,7 +763,7 @@ impl VfioPciDevice {
self.common.parse_msix_capabilities( self.common.parse_msix_capabilities(
cap_next, cap_next,
interrupt_manager, interrupt_manager,
&self.vfio_pci_configuration, &self.vfio_wrapper,
); );
} }
} }
@@ -773,9 +771,7 @@ impl VfioPciDevice {
_ => {} _ => {}
}; };
cap_next = self cap_next = self.vfio_wrapper.read_config_byte((cap_next + 1).into());
.vfio_pci_configuration
.read_config_byte((cap_next + 1).into());
} }
} }
@@ -1020,8 +1016,7 @@ impl PciDevice for VfioPciDevice {
allocator: &mut SystemAllocator, allocator: &mut SystemAllocator,
) -> std::result::Result<Vec<(GuestAddress, GuestUsize, PciBarRegionType)>, PciDeviceError> ) -> std::result::Result<Vec<(GuestAddress, GuestUsize, PciBarRegionType)>, PciDeviceError>
{ {
self.common self.common.allocate_bars(allocator, &self.vfio_wrapper)
.allocate_bars(allocator, &self.vfio_pci_configuration)
} }
fn free_bars( fn free_bars(
@@ -1083,8 +1078,7 @@ impl PciDevice for VfioPciDevice {
// enabling this bit, we first need to enable the MSI interrupts with // enabling this bit, we first need to enable the MSI interrupts with
// VFIO through VFIO_DEVICE_SET_IRQS ioctl, and only after we can write // VFIO through VFIO_DEVICE_SET_IRQS ioctl, and only after we can write
// to the device region to update the MSI Enable bit. // to the device region to update the MSI Enable bit.
self.vfio_pci_configuration self.vfio_wrapper.write_config((reg + offset) as u32, data);
.write_config((reg + offset) as u32, data);
None None
} }
@@ -1110,9 +1104,7 @@ impl PciDevice for VfioPciDevice {
}; };
// The config register read comes from the VFIO device itself. // The config register read comes from the VFIO device itself.
self.vfio_pci_configuration self.vfio_wrapper.read_config_dword((reg_idx * 4) as u32) & mask
.read_config_dword((reg_idx * 4) as u32)
& mask
} }
fn detect_bar_reprogramming( fn detect_bar_reprogramming(