pci: Move VfioWrapper to VfioCommon

Extend VfioCommon to simplify the overall code, and also in preparation
for supporting the restore code path.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
This commit is contained in:
Sebastien Boeuf 2022-04-22 11:28:34 +02:00
parent e6aa792c01
commit 4a99d3dbaf
2 changed files with 81 additions and 91 deletions

View File

@ -236,7 +236,7 @@ pub enum VfioError {
VfioUser(#[source] vfio_user::Error), VfioUser(#[source] vfio_user::Error),
} }
pub(crate) trait Vfio { pub(crate) trait Vfio: Send + Sync {
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);
@ -357,6 +357,7 @@ pub(crate) struct VfioCommon {
pub(crate) interrupt: Interrupt, pub(crate) interrupt: Interrupt,
pub(crate) msi_interrupt_manager: Arc<dyn InterruptManager<GroupConfig = MsiIrqGroupConfig>>, pub(crate) msi_interrupt_manager: Arc<dyn InterruptManager<GroupConfig = MsiIrqGroupConfig>>,
pub(crate) legacy_interrupt_group: Option<Arc<dyn InterruptSourceGroup>>, pub(crate) legacy_interrupt_group: Option<Arc<dyn InterruptSourceGroup>>,
pub(crate) vfio_wrapper: Arc<dyn Vfio>,
} }
impl VfioCommon { impl VfioCommon {
@ -364,7 +365,6 @@ impl VfioCommon {
&mut self, &mut self,
allocator: &Arc<Mutex<SystemAllocator>>, allocator: &Arc<Mutex<SystemAllocator>>,
mmio_allocator: &mut AddressAllocator, mmio_allocator: &mut AddressAllocator,
vfio_wrapper: &dyn Vfio,
resources: Option<Vec<Resource>>, resources: Option<Vec<Resource>>,
) -> Result<Vec<PciBarConfiguration>, PciDeviceError> { ) -> Result<Vec<PciBarConfiguration>, PciDeviceError> {
let mut bars = Vec::new(); let mut bars = Vec::new();
@ -410,7 +410,7 @@ impl VfioCommon {
}; };
// First read flags // First read flags
flags = vfio_wrapper.read_config_dword(bar_offset); flags = self.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 {
@ -430,10 +430,11 @@ impl VfioCommon {
}; };
// To get size write all 1s // To get size write all 1s
vfio_wrapper.write_config_dword(bar_offset, 0xffff_ffff); self.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_wrapper.read_config_dword(bar_offset); let mut lower = self.vfio_wrapper.read_config_dword(bar_offset);
if io_bar { if io_bar {
// Mask flag bits (lowest 2 for I/O bars) // Mask flag bits (lowest 2 for I/O bars)
@ -456,8 +457,9 @@ 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_wrapper.write_config_dword(upper_offset, 0xffff_ffff); self.vfio_wrapper
let upper = vfio_wrapper.read_config_dword(upper_offset); .write_config_dword(upper_offset, 0xffff_ffff);
let upper = self.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);
@ -583,12 +585,12 @@ impl VfioCommon {
Ok(()) Ok(())
} }
pub(crate) fn parse_msix_capabilities(&mut self, cap: u8, vfio_wrapper: &dyn Vfio) -> MsixCap { pub(crate) fn parse_msix_capabilities(&mut self, cap: u8) -> MsixCap {
let msg_ctl = vfio_wrapper.read_config_word((cap + 2).into()); let msg_ctl = self.vfio_wrapper.read_config_word((cap + 2).into());
let table = vfio_wrapper.read_config_dword((cap + 4).into()); let table = self.vfio_wrapper.read_config_dword((cap + 4).into());
let pba = vfio_wrapper.read_config_dword((cap + 8).into()); let pba = self.vfio_wrapper.read_config_dword((cap + 8).into());
MsixCap { MsixCap {
msg_ctl, msg_ctl,
@ -620,8 +622,8 @@ impl VfioCommon {
}); });
} }
pub(crate) fn parse_msi_capabilities(&mut self, cap: u8, vfio_wrapper: &dyn Vfio) -> u16 { pub(crate) fn parse_msi_capabilities(&mut self, cap: u8) -> u16 {
vfio_wrapper.read_config_word((cap + 2).into()) self.vfio_wrapper.read_config_word((cap + 2).into())
} }
pub(crate) fn initialize_msi(&mut self, msg_ctl: u16, cap_offset: u32) { pub(crate) fn initialize_msi(&mut self, msg_ctl: u16, cap_offset: u32) {
@ -642,29 +644,32 @@ impl VfioCommon {
}); });
} }
pub(crate) fn parse_capabilities(&mut self, vfio_wrapper: &dyn Vfio, bdf: PciBdf) { pub(crate) fn parse_capabilities(&mut self, bdf: PciBdf) {
let mut cap_next = vfio_wrapper.read_config_byte(PCI_CONFIG_CAPABILITY_OFFSET); let mut cap_next = self
.vfio_wrapper
.read_config_byte(PCI_CONFIG_CAPABILITY_OFFSET);
while cap_next != 0 { while cap_next != 0 {
let cap_id = vfio_wrapper.read_config_byte(cap_next.into()); let cap_id = self.vfio_wrapper.read_config_byte(cap_next.into());
match PciCapabilityId::from(cap_id) { match PciCapabilityId::from(cap_id) {
PciCapabilityId::MessageSignalledInterrupts => { PciCapabilityId::MessageSignalledInterrupts => {
if let Some(irq_info) = vfio_wrapper.get_irq_info(VFIO_PCI_MSI_IRQ_INDEX) { if let Some(irq_info) = self.vfio_wrapper.get_irq_info(VFIO_PCI_MSI_IRQ_INDEX) {
if irq_info.count > 0 { if irq_info.count > 0 {
// Parse capability only if the VFIO device // Parse capability only if the VFIO device
// supports MSI. // supports MSI.
let msg_ctl = self.parse_msi_capabilities(cap_next, vfio_wrapper); let msg_ctl = self.parse_msi_capabilities(cap_next);
self.initialize_msi(msg_ctl, cap_next as u32); self.initialize_msi(msg_ctl, cap_next as u32);
} }
} }
} }
PciCapabilityId::MsiX => { PciCapabilityId::MsiX => {
if let Some(irq_info) = vfio_wrapper.get_irq_info(VFIO_PCI_MSIX_IRQ_INDEX) { if let Some(irq_info) = self.vfio_wrapper.get_irq_info(VFIO_PCI_MSIX_IRQ_INDEX)
{
if irq_info.count > 0 { if irq_info.count > 0 {
// Parse capability only if the VFIO device // Parse capability only if the VFIO device
// supports MSI-X. // supports MSI-X.
let msix_cap = self.parse_msix_capabilities(cap_next, vfio_wrapper); let msix_cap = self.parse_msix_capabilities(cap_next);
self.initialize_msix(msix_cap, cap_next as u32, bdf); self.initialize_msix(msix_cap, cap_next as u32, bdf);
} }
} }
@ -672,15 +677,15 @@ impl VfioCommon {
_ => {} _ => {}
}; };
cap_next = vfio_wrapper.read_config_byte((cap_next + 1).into()); cap_next = self.vfio_wrapper.read_config_byte((cap_next + 1).into());
} }
} }
pub(crate) fn enable_intx(&mut self, wrapper: &dyn Vfio) -> Result<(), VfioPciError> { pub(crate) fn enable_intx(&mut self) -> Result<(), VfioPciError> {
if let Some(intx) = &mut self.interrupt.intx { if let Some(intx) = &mut self.interrupt.intx {
if !intx.enabled { if !intx.enabled {
if let Some(eventfd) = intx.interrupt_source_group.notifier(0) { if let Some(eventfd) = intx.interrupt_source_group.notifier(0) {
wrapper self.vfio_wrapper
.enable_irq(VFIO_PCI_INTX_IRQ_INDEX, vec![&eventfd]) .enable_irq(VFIO_PCI_INTX_IRQ_INDEX, vec![&eventfd])
.map_err(VfioPciError::EnableIntx)?; .map_err(VfioPciError::EnableIntx)?;
@ -694,10 +699,10 @@ impl VfioCommon {
Ok(()) Ok(())
} }
pub(crate) fn disable_intx(&mut self, wrapper: &dyn Vfio) { pub(crate) fn disable_intx(&mut self) {
if let Some(intx) = &mut self.interrupt.intx { if let Some(intx) = &mut self.interrupt.intx {
if intx.enabled { if intx.enabled {
if let Err(e) = wrapper.disable_irq(VFIO_PCI_INTX_IRQ_INDEX) { if let Err(e) = self.vfio_wrapper.disable_irq(VFIO_PCI_INTX_IRQ_INDEX) {
error!("Could not disable INTx: {}", e); error!("Could not disable INTx: {}", e);
} else { } else {
intx.enabled = false; intx.enabled = false;
@ -706,7 +711,7 @@ impl VfioCommon {
} }
} }
pub(crate) fn enable_msi(&self, wrapper: &dyn Vfio) -> Result<(), VfioPciError> { pub(crate) fn enable_msi(&self) -> Result<(), VfioPciError> {
if let Some(msi) = &self.interrupt.msi { if let Some(msi) = &self.interrupt.msi {
let mut irq_fds: Vec<EventFd> = Vec::new(); let mut irq_fds: Vec<EventFd> = Vec::new();
for i in 0..msi.cfg.num_enabled_vectors() { for i in 0..msi.cfg.num_enabled_vectors() {
@ -717,7 +722,7 @@ impl VfioCommon {
} }
} }
wrapper self.vfio_wrapper
.enable_msi(irq_fds.iter().collect()) .enable_msi(irq_fds.iter().collect())
.map_err(VfioPciError::EnableMsi)?; .map_err(VfioPciError::EnableMsi)?;
} }
@ -725,13 +730,13 @@ impl VfioCommon {
Ok(()) Ok(())
} }
pub(crate) fn disable_msi(&self, wrapper: &dyn Vfio) { pub(crate) fn disable_msi(&self) {
if let Err(e) = wrapper.disable_msi() { if let Err(e) = self.vfio_wrapper.disable_msi() {
error!("Could not disable MSI: {}", e); error!("Could not disable MSI: {}", e);
} }
} }
pub(crate) fn enable_msix(&self, wrapper: &dyn Vfio) -> Result<(), VfioPciError> { pub(crate) fn enable_msix(&self) -> Result<(), VfioPciError> {
if let Some(msix) = &self.interrupt.msix { if let Some(msix) = &self.interrupt.msix {
let mut irq_fds: Vec<EventFd> = Vec::new(); let mut irq_fds: Vec<EventFd> = Vec::new();
for i in 0..msix.bar.table_entries.len() { for i in 0..msix.bar.table_entries.len() {
@ -742,7 +747,7 @@ impl VfioCommon {
} }
} }
wrapper self.vfio_wrapper
.enable_msix(irq_fds.iter().collect()) .enable_msix(irq_fds.iter().collect())
.map_err(VfioPciError::EnableMsix)?; .map_err(VfioPciError::EnableMsix)?;
} }
@ -750,17 +755,14 @@ impl VfioCommon {
Ok(()) Ok(())
} }
pub(crate) fn disable_msix(&self, wrapper: &dyn Vfio) { pub(crate) fn disable_msix(&self) {
if let Err(e) = wrapper.disable_msix() { if let Err(e) = self.vfio_wrapper.disable_msix() {
error!("Could not disable MSI-X: {}", e); error!("Could not disable MSI-X: {}", e);
} }
} }
pub(crate) fn initialize_legacy_interrupt( pub(crate) fn initialize_legacy_interrupt(&mut self) -> Result<(), VfioPciError> {
&mut self, if let Some(irq_info) = self.vfio_wrapper.get_irq_info(VFIO_PCI_INTX_IRQ_INDEX) {
wrapper: &dyn Vfio,
) -> Result<(), VfioPciError> {
if let Some(irq_info) = wrapper.get_irq_info(VFIO_PCI_INTX_IRQ_INDEX) {
if irq_info.count == 0 { if irq_info.count == 0 {
// A count of 0 means the INTx IRQ is not supported, therefore // A count of 0 means the INTx IRQ is not supported, therefore
// it shouldn't be initialized. // it shouldn't be initialized.
@ -774,7 +776,7 @@ impl VfioCommon {
enabled: false, enabled: false,
}); });
self.enable_intx(wrapper)?; self.enable_intx()?;
} }
Ok(()) Ok(())
@ -784,18 +786,17 @@ impl VfioCommon {
&mut self, &mut self,
offset: u64, offset: u64,
data: &[u8], data: &[u8],
wrapper: &dyn Vfio,
) -> Result<(), VfioPciError> { ) -> Result<(), VfioPciError> {
match self.interrupt.update_msi(offset, data) { match self.interrupt.update_msi(offset, data) {
Some(InterruptUpdateAction::EnableMsi) => { Some(InterruptUpdateAction::EnableMsi) => {
// Disable INTx before we can enable MSI // Disable INTx before we can enable MSI
self.disable_intx(wrapper); self.disable_intx();
self.enable_msi(wrapper)?; self.enable_msi()?;
} }
Some(InterruptUpdateAction::DisableMsi) => { Some(InterruptUpdateAction::DisableMsi) => {
// Fallback onto INTx when disabling MSI // Fallback onto INTx when disabling MSI
self.disable_msi(wrapper); self.disable_msi();
self.enable_intx(wrapper)?; self.enable_intx()?;
} }
_ => {} _ => {}
} }
@ -807,18 +808,17 @@ impl VfioCommon {
&mut self, &mut self,
offset: u64, offset: u64,
data: &[u8], data: &[u8],
wrapper: &dyn Vfio,
) -> Result<(), VfioPciError> { ) -> Result<(), VfioPciError> {
match self.interrupt.update_msix(offset, data) { match self.interrupt.update_msix(offset, data) {
Some(InterruptUpdateAction::EnableMsix) => { Some(InterruptUpdateAction::EnableMsix) => {
// Disable INTx before we can enable MSI-X // Disable INTx before we can enable MSI-X
self.disable_intx(wrapper); self.disable_intx();
self.enable_msix(wrapper)?; self.enable_msix()?;
} }
Some(InterruptUpdateAction::DisableMsix) => { Some(InterruptUpdateAction::DisableMsix) => {
// Fallback onto INTx when disabling MSI-X // Fallback onto INTx when disabling MSI-X
self.disable_msix(wrapper); self.disable_msix();
self.enable_intx(wrapper)?; self.enable_intx()?;
} }
_ => {} _ => {}
} }
@ -837,7 +837,7 @@ impl VfioCommon {
None None
} }
pub(crate) fn read_bar(&mut self, base: u64, offset: u64, data: &mut [u8], wrapper: &dyn Vfio) { pub(crate) fn read_bar(&mut self, base: u64, offset: u64, data: &mut [u8]) {
let addr = base + offset; let addr = base + offset;
if let Some(region) = self.find_region(addr) { if let Some(region) = self.find_region(addr) {
let offset = addr - region.start.raw_value(); let offset = addr - region.start.raw_value();
@ -845,7 +845,7 @@ impl VfioCommon {
if self.interrupt.msix_table_accessed(region.index, offset) { if self.interrupt.msix_table_accessed(region.index, offset) {
self.interrupt.msix_read_table(offset, data); self.interrupt.msix_read_table(offset, data);
} else { } else {
wrapper.region_read(region.index, offset, data); self.vfio_wrapper.region_read(region.index, offset, data);
} }
} }
@ -853,7 +853,7 @@ impl VfioCommon {
// The guest reading from the BAR potentially means the interrupt has // The guest reading from the BAR potentially means the interrupt has
// been received and can be acknowledged. // been received and can be acknowledged.
if self.interrupt.intx_in_use() { if self.interrupt.intx_in_use() {
if let Err(e) = wrapper.unmask_irq(VFIO_PCI_INTX_IRQ_INDEX) { if let Err(e) = self.vfio_wrapper.unmask_irq(VFIO_PCI_INTX_IRQ_INDEX) {
error!("Failed unmasking INTx IRQ: {}", e); error!("Failed unmasking INTx IRQ: {}", e);
} }
} }
@ -864,7 +864,6 @@ impl VfioCommon {
base: u64, base: u64,
offset: u64, offset: u64,
data: &[u8], data: &[u8],
wrapper: &dyn Vfio,
) -> Option<Arc<Barrier>> { ) -> Option<Arc<Barrier>> {
let addr = base + offset; let addr = base + offset;
if let Some(region) = self.find_region(addr) { if let Some(region) = self.find_region(addr) {
@ -874,7 +873,7 @@ impl VfioCommon {
if self.interrupt.msix_table_accessed(region.index, offset) { if self.interrupt.msix_table_accessed(region.index, offset) {
self.interrupt.msix_write_table(offset, data); self.interrupt.msix_write_table(offset, data);
} else { } else {
wrapper.region_write(region.index, offset, data); self.vfio_wrapper.region_write(region.index, offset, data);
} }
} }
@ -882,7 +881,7 @@ impl VfioCommon {
// The guest writing to the BAR potentially means the interrupt has // The guest writing to the BAR potentially means the interrupt has
// been received and can be acknowledged. // been received and can be acknowledged.
if self.interrupt.intx_in_use() { if self.interrupt.intx_in_use() {
if let Err(e) = wrapper.unmask_irq(VFIO_PCI_INTX_IRQ_INDEX) { if let Err(e) = self.vfio_wrapper.unmask_irq(VFIO_PCI_INTX_IRQ_INDEX) {
error!("Failed unmasking INTx IRQ: {}", e); error!("Failed unmasking INTx IRQ: {}", e);
} }
} }
@ -895,7 +894,6 @@ impl VfioCommon {
reg_idx: usize, reg_idx: usize,
offset: u64, offset: u64,
data: &[u8], data: &[u8],
wrapper: &dyn Vfio,
) -> Option<Arc<Barrier>> { ) -> Option<Arc<Barrier>> {
// When the guest wants to write to a BAR, we trap it into // When the guest wants to write to a BAR, we trap it into
// our local configuration space. We're not reprogramming // our local configuration space. We're not reprogramming
@ -921,12 +919,12 @@ impl VfioCommon {
let cap_offset: u64 = reg - cap_base + offset; let cap_offset: u64 = reg - cap_base + offset;
match cap_id { match cap_id {
PciCapabilityId::MessageSignalledInterrupts => { PciCapabilityId::MessageSignalledInterrupts => {
if let Err(e) = self.update_msi_capabilities(cap_offset, data, wrapper) { if let Err(e) = self.update_msi_capabilities(cap_offset, data) {
error!("Could not update MSI capabilities: {}", e); error!("Could not update MSI capabilities: {}", e);
} }
} }
PciCapabilityId::MsiX => { PciCapabilityId::MsiX => {
if let Err(e) = self.update_msix_capabilities(cap_offset, data, wrapper) { if let Err(e) = self.update_msix_capabilities(cap_offset, data) {
error!("Could not update MSI-X capabilities: {}", e); error!("Could not update MSI-X capabilities: {}", e);
} }
} }
@ -942,12 +940,12 @@ impl VfioCommon {
// 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.
wrapper.write_config((reg + offset) as u32, data); self.vfio_wrapper.write_config((reg + offset) as u32, data);
None None
} }
pub(crate) fn read_config_register(&mut self, reg_idx: usize, wrapper: &dyn Vfio) -> u32 { pub(crate) fn read_config_register(&mut self, reg_idx: usize) -> u32 {
// When reading the BARs, we trap it and return what comes // When reading the BARs, we trap it and return what comes
// from our local configuration space. We want the guest to // from our local configuration space. We want the guest to
// use that and not the VFIO device BARs as it does not map // use that and not the VFIO device BARs as it does not map
@ -968,7 +966,7 @@ impl VfioCommon {
}; };
// The config register read comes from the VFIO device itself. // The config register read comes from the VFIO device itself.
wrapper.read_config_dword((reg_idx * 4) as u32) & mask self.vfio_wrapper.read_config_dword((reg_idx * 4) as u32) & mask
} }
} }
@ -983,7 +981,6 @@ 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_wrapper: VfioDeviceWrapper,
common: VfioCommon, common: VfioCommon,
iommu_attached: bool, iommu_attached: bool,
} }
@ -1029,17 +1026,17 @@ impl VfioPciDevice {
}, },
msi_interrupt_manager, msi_interrupt_manager,
legacy_interrupt_group, legacy_interrupt_group,
vfio_wrapper: Arc::new(vfio_wrapper) as Arc<dyn Vfio>,
}; };
common.parse_capabilities(&vfio_wrapper, bdf); common.parse_capabilities(bdf);
common.initialize_legacy_interrupt(&vfio_wrapper)?; common.initialize_legacy_interrupt()?;
let vfio_pci_device = VfioPciDevice { let vfio_pci_device = VfioPciDevice {
id, id,
vm: vm.clone(), vm: vm.clone(),
device, device,
container, container,
vfio_wrapper,
common, common,
iommu_attached, iommu_attached,
}; };
@ -1299,18 +1296,18 @@ impl Drop for VfioPciDevice {
if let Some(msix) = &self.common.interrupt.msix { if let Some(msix) = &self.common.interrupt.msix {
if msix.bar.enabled() { if msix.bar.enabled() {
self.common.disable_msix(&self.vfio_wrapper); self.common.disable_msix();
} }
} }
if let Some(msi) = &self.common.interrupt.msi { if let Some(msi) = &self.common.interrupt.msi {
if msi.cfg.enabled() { if msi.cfg.enabled() {
self.common.disable_msi(&self.vfio_wrapper) self.common.disable_msi()
} }
} }
if self.common.interrupt.intx_in_use() { if self.common.interrupt.intx_in_use() {
self.common.disable_intx(&self.vfio_wrapper); self.common.disable_intx();
} }
} }
} }
@ -1352,7 +1349,7 @@ impl PciDevice for VfioPciDevice {
resources: Option<Vec<Resource>>, resources: Option<Vec<Resource>>,
) -> Result<Vec<PciBarConfiguration>, PciDeviceError> { ) -> Result<Vec<PciBarConfiguration>, PciDeviceError> {
self.common self.common
.allocate_bars(allocator, mmio_allocator, &self.vfio_wrapper, resources) .allocate_bars(allocator, mmio_allocator, resources)
} }
fn free_bars( fn free_bars(
@ -1369,13 +1366,11 @@ impl PciDevice for VfioPciDevice {
offset: u64, offset: u64,
data: &[u8], data: &[u8],
) -> Option<Arc<Barrier>> { ) -> Option<Arc<Barrier>> {
self.common self.common.write_config_register(reg_idx, offset, data)
.write_config_register(reg_idx, offset, data, &self.vfio_wrapper)
} }
fn read_config_register(&mut self, reg_idx: usize) -> u32 { fn read_config_register(&mut self, reg_idx: usize) -> u32 {
self.common self.common.read_config_register(reg_idx)
.read_config_register(reg_idx, &self.vfio_wrapper)
} }
fn detect_bar_reprogramming( fn detect_bar_reprogramming(
@ -1389,12 +1384,11 @@ impl PciDevice for VfioPciDevice {
} }
fn read_bar(&mut self, base: u64, offset: u64, data: &mut [u8]) { fn read_bar(&mut self, base: u64, offset: u64, data: &mut [u8]) {
self.common.read_bar(base, offset, data, &self.vfio_wrapper) self.common.read_bar(base, offset, data)
} }
fn write_bar(&mut self, base: u64, offset: u64, data: &[u8]) -> Option<Arc<Barrier>> { fn write_bar(&mut self, base: u64, offset: u64, data: &[u8]) -> Option<Arc<Barrier>> {
self.common self.common.write_bar(base, offset, data)
.write_bar(base, offset, data, &self.vfio_wrapper)
} }
fn move_bar(&mut self, old_base: u64, new_base: u64) -> Result<(), io::Error> { fn move_bar(&mut self, old_base: u64, new_base: u64) -> Result<(), io::Error> {

View File

@ -32,7 +32,6 @@ pub struct VfioUserPciDevice {
id: String, id: String,
vm: Arc<dyn hypervisor::Vm>, vm: Arc<dyn hypervisor::Vm>,
client: Arc<Mutex<Client>>, client: Arc<Mutex<Client>>,
vfio_wrapper: VfioUserClientWrapper,
common: VfioCommon, common: VfioCommon,
} }
@ -106,18 +105,18 @@ impl VfioUserPciDevice {
}, },
msi_interrupt_manager, msi_interrupt_manager,
legacy_interrupt_group, legacy_interrupt_group,
vfio_wrapper: Arc::new(vfio_wrapper) as Arc<dyn Vfio>,
}; };
common.parse_capabilities(&vfio_wrapper, bdf); common.parse_capabilities(bdf);
common common
.initialize_legacy_interrupt(&vfio_wrapper) .initialize_legacy_interrupt()
.map_err(VfioUserPciDeviceError::InitializeLegacyInterrupts)?; .map_err(VfioUserPciDeviceError::InitializeLegacyInterrupts)?;
Ok(Self { Ok(Self {
id, id,
vm: vm.clone(), vm: vm.clone(),
client, client,
vfio_wrapper,
common, common,
}) })
} }
@ -399,7 +398,7 @@ impl PciDevice for VfioUserPciDevice {
resources: Option<Vec<Resource>>, resources: Option<Vec<Resource>>,
) -> Result<Vec<PciBarConfiguration>, PciDeviceError> { ) -> Result<Vec<PciBarConfiguration>, PciDeviceError> {
self.common self.common
.allocate_bars(allocator, mmio_allocator, &self.vfio_wrapper, resources) .allocate_bars(allocator, mmio_allocator, resources)
} }
fn free_bars( fn free_bars(
@ -430,22 +429,19 @@ impl PciDevice for VfioUserPciDevice {
offset: u64, offset: u64,
data: &[u8], data: &[u8],
) -> Option<Arc<Barrier>> { ) -> Option<Arc<Barrier>> {
self.common self.common.write_config_register(reg_idx, offset, data)
.write_config_register(reg_idx, offset, data, &self.vfio_wrapper)
} }
fn read_config_register(&mut self, reg_idx: usize) -> u32 { fn read_config_register(&mut self, reg_idx: usize) -> u32 {
self.common self.common.read_config_register(reg_idx)
.read_config_register(reg_idx, &self.vfio_wrapper)
} }
fn read_bar(&mut self, base: u64, offset: u64, data: &mut [u8]) { fn read_bar(&mut self, base: u64, offset: u64, data: &mut [u8]) {
self.common.read_bar(base, offset, data, &self.vfio_wrapper) self.common.read_bar(base, offset, data)
} }
fn write_bar(&mut self, base: u64, offset: u64, data: &[u8]) -> Option<Arc<Barrier>> { fn write_bar(&mut self, base: u64, offset: u64, data: &[u8]) -> Option<Arc<Barrier>> {
self.common self.common.write_bar(base, offset, data)
.write_bar(base, offset, data, &self.vfio_wrapper)
} }
fn move_bar(&mut self, old_base: u64, new_base: u64) -> Result<(), std::io::Error> { fn move_bar(&mut self, old_base: u64, new_base: u64) -> Result<(), std::io::Error> {
@ -502,18 +498,18 @@ impl Drop for VfioUserPciDevice {
if let Some(msix) = &self.common.interrupt.msix { if let Some(msix) = &self.common.interrupt.msix {
if msix.bar.enabled() { if msix.bar.enabled() {
self.common.disable_msix(&self.vfio_wrapper); self.common.disable_msix();
} }
} }
if let Some(msi) = &self.common.interrupt.msi { if let Some(msi) = &self.common.interrupt.msi {
if msi.cfg.enabled() { if msi.cfg.enabled() {
self.common.disable_msi(&self.vfio_wrapper) self.common.disable_msi()
} }
} }
if self.common.interrupt.intx_in_use() { if self.common.interrupt.intx_in_use() {
self.common.disable_intx(&self.vfio_wrapper); self.common.disable_intx();
} }
if let Err(e) = self.client.lock().unwrap().shutdown() { if let Err(e) = self.client.lock().unwrap().shutdown() {