mirror of
https://github.com/cloud-hypervisor/cloud-hypervisor.git
synced 2026-08-05 02:19:16 +00:00
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:
committed by
Sebastien Boeuf
parent
ec1f7189da
commit
dc35dac306
+27
-35
@@ -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(
|
||||||
|
|||||||
Reference in New Issue
Block a user