stratovirt/virtio-fix-dev_id-initialization-for-virtio-pci-and-.patch
Jie Yang 2d9d03c21a Update version to 2.0.0-6
Signed-off-by: Jie Yang <yangjieyj.yang@huawei.com>
(cherry picked from commit 6158eab66897bf7fb11ce7ae8c3b568f8de0e2dd)
2021-08-30 21:19:11 +08:00

615 lines
24 KiB
Diff

From 4ba032f8967c660b8eafb3adaf9b44b95474c7c3 Mon Sep 17 00:00:00 2001
From: Ming Yang <yangming73@huawei.com>
Date: Wed, 11 Aug 2021 14:52:26 +0800
Subject: [PATCH 8/8] virtio: fix dev_id initialization for virtio-pci and vfio
device on aarch64 platform
On aarch64 platform, dev_id information is necessary for virtio-pci device
to send msix.
This commit fixes the dev_id initialization in virtio_pci transport module,
and set dev_id information according to the number of bus where the device
is attached to.
Signed-off-by: Ming Yang <yangming73@huawei.com>
---
pci/src/config.rs | 2 +
pci/src/msix.rs | 63 ++++++++++++++------
pci/src/root_port.rs | 10 +---
vfio/src/vfio_pci.rs | 34 +++++++----
virtio/src/virtio_pci.rs | 123 ++++++++++++++++++++++++---------------
5 files changed, 150 insertions(+), 82 deletions(-)
diff --git a/pci/src/config.rs b/pci/src/config.rs
index d7bd348..873fe7a 100644
--- a/pci/src/config.rs
+++ b/pci/src/config.rs
@@ -221,6 +221,7 @@ pub enum RegionType {
}
/// Registered bar.
+#[derive(Clone)]
pub struct Bar {
region_type: RegionType,
address: u64,
@@ -266,6 +267,7 @@ pub enum PcieDevType {
}
/// Configuration space of PCI/PCIe device.
+#[derive(Clone)]
pub struct PciConfig {
/// Configuration space data.
pub config: Vec<u8>,
diff --git a/pci/src/msix.rs b/pci/src/msix.rs
index 2831af4..5c04575 100644
--- a/pci/src/msix.rs
+++ b/pci/src/msix.rs
@@ -10,16 +10,19 @@
// NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
// See the Mulan PSL v2 for more details.
-use std::sync::{Arc, Mutex};
+use std::sync::atomic::{AtomicU16, Ordering};
+use std::sync::{Arc, Mutex, Weak};
use address_space::{GuestAddress, Region, RegionOps};
use hypervisor::{MsiVector, KVM_FDS};
use migration::{DeviceStateDesc, FieldDesc, MigrationHook, MigrationManager, StateTransfer};
use util::{byte_code::ByteCode, num_ops::round_up};
-use crate::config::{CapId, PciConfig, RegionType};
+use crate::config::{CapId, PciConfig, RegionType, SECONDARY_BUS_NUM};
use crate::errors::{Result, ResultExt};
-use crate::{le_read_u16, le_read_u32, le_read_u64, le_write_u16, le_write_u32, le_write_u64};
+use crate::{
+ le_read_u16, le_read_u32, le_read_u64, le_write_u16, le_write_u32, le_write_u64, PciBus,
+};
pub const MSIX_TABLE_ENTRY_SIZE: u16 = 16;
pub const MSIX_TABLE_SIZE_MAX: u16 = 0x7ff;
@@ -71,7 +74,7 @@ pub struct Msix {
pub func_masked: bool,
pub enabled: bool,
pub msix_cap_offset: u16,
- pub dev_id: u16,
+ pub dev_id: Arc<AtomicU16>,
}
impl Msix {
@@ -90,7 +93,7 @@ impl Msix {
func_masked: true,
enabled: true,
msix_cap_offset,
- dev_id,
+ dev_id: Arc::new(AtomicU16::new(dev_id)),
};
msix.mask_all_vectors();
msix
@@ -148,7 +151,11 @@ impl Msix {
le_write_u64(&mut self.pba, offset, old_val & pending_bit).unwrap();
}
- fn register_memory_region(msix: Arc<Mutex<Self>>, region: &Region, dev_id: u16) -> Result<()> {
+ fn register_memory_region(
+ msix: Arc<Mutex<Self>>,
+ region: &Region,
+ dev_id: Arc<AtomicU16>,
+ ) -> Result<()> {
let locked_msix = msix.lock().unwrap();
let table_size = locked_msix.table.len() as u64;
let pba_size = locked_msix.pba.len() as u64;
@@ -170,7 +177,7 @@ impl Msix {
let is_masked: bool = locked_msix.is_vector_masked(vector);
if was_masked && !is_masked {
locked_msix.clear_pending_vector(vector);
- locked_msix.notify(vector, dev_id);
+ locked_msix.notify(vector, dev_id.load(Ordering::Acquire));
}
true
@@ -264,7 +271,7 @@ impl StateTransfer for Msix {
state.func_masked = self.func_masked;
state.enabled = self.enabled;
state.msix_cap_offset = self.msix_cap_offset;
- state.dev_id = self.dev_id;
+ state.dev_id = self.dev_id.load(Ordering::Acquire);
Ok(state.as_bytes().to_vec())
}
@@ -280,7 +287,7 @@ impl StateTransfer for Msix {
self.func_masked = msix_state.func_masked;
self.enabled = msix_state.enabled;
self.msix_cap_offset = msix_state.msix_cap_offset;
- self.dev_id = msix_state.dev_id;
+ self.dev_id = Arc::new(AtomicU16::new(msix_state.dev_id));
Ok(())
}
@@ -318,7 +325,7 @@ impl MigrationHook for Msix {
msg_data: msg.data,
masked: false,
#[cfg(target_arch = "aarch64")]
- dev_id: self.dev_id as u32,
+ dev_id: self.dev_id.load(Ordering::Acquire) as u32,
};
if let Err(e) = locked_irq_table.add_msi_route(allocated_gsi, msi_vector) {
bail!("Failed to add msi route to global irq routing table: {}", e);
@@ -330,7 +337,7 @@ impl MigrationHook for Msix {
if self.is_vector_pending(vector) {
self.clear_pending_vector(vector);
- send_msix(msg, self.dev_id);
+ send_msix(msg, self.dev_id.load(Ordering::Acquire));
}
}
}
@@ -377,7 +384,12 @@ fn send_msix(msg: Message, dev_id: u16) {
}
/// MSI-X initialization.
-pub fn init_msix(bar_id: usize, vector_nr: u32, config: &mut PciConfig, dev_id: u16) -> Result<()> {
+pub fn init_msix(
+ bar_id: usize,
+ vector_nr: u32,
+ config: &mut PciConfig,
+ dev_id: Arc<AtomicU16>,
+) -> Result<()> {
if vector_nr > MSIX_TABLE_SIZE_MAX as u32 + 1 {
bail!("Too many msix vectors.");
}
@@ -401,7 +413,7 @@ pub fn init_msix(bar_id: usize, vector_nr: u32, config: &mut PciConfig, dev_id:
table_size,
pba_size,
msix_cap_offset as u16,
- dev_id,
+ dev_id.load(Ordering::Acquire),
)));
let bar_size = ((table_size + pba_size) as u64).next_power_of_two();
let region = Region::init_container_region(bar_size);
@@ -415,6 +427,17 @@ pub fn init_msix(bar_id: usize, vector_nr: u32, config: &mut PciConfig, dev_id:
Ok(())
}
+pub fn update_dev_id(parent_bus: &Weak<Mutex<PciBus>>, devfn: u8, dev_id: &Arc<AtomicU16>) {
+ let bus_num = parent_bus
+ .upgrade()
+ .unwrap()
+ .lock()
+ .unwrap()
+ .number(SECONDARY_BUS_NUM as usize);
+ let device_id = ((bus_num as u16) << 8) | (devfn as u16);
+ dev_id.store(device_id, Ordering::Release);
+}
+
#[cfg(test)]
mod tests {
use super::*;
@@ -425,9 +448,15 @@ mod tests {
let mut pci_config = PciConfig::new(PCI_CONFIG_SPACE_SIZE, 2);
// Too many vectors.
- assert!(init_msix(0, MSIX_TABLE_SIZE_MAX as u32 + 2, &mut pci_config, 0).is_err());
-
- init_msix(1, 2, &mut pci_config, 0).unwrap();
+ assert!(init_msix(
+ 0,
+ MSIX_TABLE_SIZE_MAX as u32 + 2,
+ &mut pci_config,
+ Arc::new(AtomicU16::new(0))
+ )
+ .is_err());
+
+ init_msix(1, 2, &mut pci_config, Arc::new(AtomicU16::new(0))).unwrap();
let msix_cap_start = 64_u8;
assert_eq!(pci_config.last_cap_end, 64 + MSIX_CAP_SIZE as u16);
// Capabilities pointer
@@ -492,7 +521,7 @@ mod tests {
#[test]
fn test_write_config() {
let mut pci_config = PciConfig::new(PCI_CONFIG_SPACE_SIZE, 2);
- init_msix(0, 2, &mut pci_config, 0).unwrap();
+ init_msix(0, 2, &mut pci_config, Arc::new(AtomicU16::new(0))).unwrap();
let msix = pci_config.msix.as_ref().unwrap();
let mut locked_msix = msix.lock().unwrap();
locked_msix.enabled = false;
diff --git a/pci/src/root_port.rs b/pci/src/root_port.rs
index ba1b5f7..948e31d 100644
--- a/pci/src/root_port.rs
+++ b/pci/src/root_port.rs
@@ -10,6 +10,7 @@
// NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
// See the Mulan PSL v2 for more details.
+use std::sync::atomic::AtomicU16;
use std::sync::{Arc, Mutex, Weak};
use address_space::Region;
@@ -117,13 +118,8 @@ impl PciDevOps for RootPort {
config_space[PREF_MEMORY_LIMIT as usize] = PREF_MEM_RANGE_64BIT;
self.config
.add_pcie_cap(self.devfn, self.port_num, PcieDevType::RootPort as u8)?;
- #[cfg(target_arch = "aarch64")]
- {
- self.dev_id = self.set_dev_id(0, self.devfn);
- init_msix(0, 1, &mut self.config, self.dev_id)?;
- }
- #[cfg(target_arch = "x86_64")]
- init_msix(0, 1, &mut self.config, 0)?;
+
+ init_msix(0, 1, &mut self.config, Arc::new(AtomicU16::new(0)))?;
let parent_bus = self.parent_bus.upgrade().unwrap();
let mut locked_parent_bus = parent_bus.lock().unwrap();
diff --git a/vfio/src/vfio_pci.rs b/vfio/src/vfio_pci.rs
index 5cc674a..640ff20 100644
--- a/vfio/src/vfio_pci.rs
+++ b/vfio/src/vfio_pci.rs
@@ -14,6 +14,7 @@ use std::collections::HashMap;
use std::mem::size_of;
use std::os::unix::io::{AsRawFd, RawFd};
use std::path::Path;
+use std::sync::atomic::{AtomicU16, Ordering};
use std::sync::{Arc, Mutex, Weak};
use byteorder::{ByteOrder, LittleEndian};
@@ -36,9 +37,9 @@ use pci::config::{
};
use pci::errors::Result as PciResult;
use pci::msix::{
- is_msix_enabled, Msix, MSIX_CAP_CONTROL, MSIX_CAP_ENABLE, MSIX_CAP_FUNC_MASK, MSIX_CAP_ID,
- MSIX_CAP_SIZE, MSIX_CAP_TABLE, MSIX_TABLE_BIR, MSIX_TABLE_ENTRY_SIZE, MSIX_TABLE_OFFSET,
- MSIX_TABLE_SIZE_MAX,
+ is_msix_enabled, update_dev_id, Msix, MSIX_CAP_CONTROL, MSIX_CAP_ENABLE, MSIX_CAP_FUNC_MASK,
+ MSIX_CAP_ID, MSIX_CAP_SIZE, MSIX_CAP_TABLE, MSIX_TABLE_BIR, MSIX_TABLE_ENTRY_SIZE,
+ MSIX_TABLE_OFFSET, MSIX_TABLE_SIZE_MAX,
};
use pci::{
le_read_u16, le_read_u32, le_write_u16, le_write_u32, ranges_overlap, PciBus, PciDevOps,
@@ -93,7 +94,7 @@ pub struct VfioPciDevice {
// Maintains a list of GSI with irqfds that are registered to kvm.
gsi_msi_routes: Arc<Mutex<Vec<GsiMsiRoute>>>,
devfn: u8,
- dev_id: u16,
+ dev_id: Arc<AtomicU16>,
name: String,
parent_bus: Weak<Mutex<PciBus>>,
}
@@ -119,7 +120,7 @@ impl VfioPciDevice {
vfio_bars: Arc::new(Mutex::new(Vec::with_capacity(PCI_NUM_BARS as usize))),
gsi_msi_routes: Arc::new(Mutex::new(Vec::new())),
devfn,
- dev_id: 0,
+ dev_id: Arc::new(AtomicU16::new(0)),
name,
parent_bus,
})
@@ -404,7 +405,7 @@ impl VfioPciDevice {
table_size,
table_size / 128,
cap_offset as u16,
- self.dev_id,
+ self.dev_id.load(Ordering::Acquire),
)));
self.pci_config.msix = Some(msix.clone());
@@ -418,6 +419,9 @@ impl VfioPciDevice {
let cloned_dev = self.vfio_device.clone();
let cloned_gsi_routes = self.gsi_msi_routes.clone();
+ let parent_bus = self.parent_bus.clone();
+ let dev_id = self.dev_id.clone();
+ let devfn = self.devfn;
let write = move |data: &[u8], _: GuestAddress, offset: u64| -> bool {
let mut locked_msix = msix.lock().unwrap();
locked_msix.table[offset as usize..(offset as usize + data.len())]
@@ -429,13 +433,15 @@ impl VfioPciDevice {
}
let entry = locked_msix.get_message(vector as u16);
+
+ update_dev_id(&parent_bus, devfn, &dev_id);
let msix_vector = MsiVector {
msg_addr_lo: entry.address_lo,
msg_addr_hi: entry.address_hi,
msg_data: entry.data,
masked: false,
#[cfg(target_arch = "aarch64")]
- dev_id: locked_msix.dev_id as u32,
+ dev_id: dev_id.load(Ordering::Acquire) as u32,
};
let mut locked_gsi_routes = cloned_gsi_routes.lock().unwrap();
@@ -707,7 +713,7 @@ impl PciDevOps for VfioPciDevice {
.lock()
.unwrap()
.number(SECONDARY_BUS_NUM as usize);
- self.dev_id = self.set_dev_id(bus_num, self.devfn);
+ self.dev_id = Arc::new(AtomicU16::new(self.set_dev_id(bus_num, self.devfn)));
}
self.msix_info = Some(PciResultExt::chain_err(self.get_msix_info(), || {
@@ -799,7 +805,8 @@ impl PciDevOps for VfioPciDevice {
}
if ranges_overlap(offset, end, COMMAND as usize, COMMAND as usize + 4) {
- self.pci_config.write(offset, data, self.dev_id);
+ self.pci_config
+ .write(offset, data, self.dev_id.load(Ordering::Acquire));
if le_read_u32(&self.pci_config.config, offset).unwrap() & COMMAND_MEMORY_SPACE as u32
!= 0
@@ -822,7 +829,8 @@ impl PciDevOps for VfioPciDevice {
}
}
} else if ranges_overlap(offset, end, BAR_0 as usize, (BAR_5 as usize) + REG_SIZE) {
- self.pci_config.write(offset, data, self.dev_id);
+ self.pci_config
+ .write(offset, data, self.dev_id.load(Ordering::Acquire));
if size == 4 && LittleEndian::read_u32(data) != 0xffff_ffff {
let parent_bus = self.parent_bus.upgrade().unwrap();
@@ -838,7 +846,8 @@ impl PciDevOps for VfioPciDevice {
}
} else if ranges_overlap(offset, end, cap_offset, cap_offset + MSIX_CAP_SIZE as usize) {
let was_enable = is_msix_enabled(cap_offset, &self.pci_config.config);
- self.pci_config.write(offset, data, self.dev_id);
+ self.pci_config
+ .write(offset, data, self.dev_id.load(Ordering::Acquire));
let is_enable = is_msix_enabled(cap_offset, &self.pci_config.config);
if !was_enable && is_enable {
@@ -853,7 +862,8 @@ impl PciDevOps for VfioPciDevice {
}
}
} else {
- self.pci_config.write(offset, data, self.dev_id);
+ self.pci_config
+ .write(offset, data, self.dev_id.load(Ordering::Acquire));
}
}
diff --git a/virtio/src/virtio_pci.rs b/virtio/src/virtio_pci.rs
index 03645dc..aaf009e 100644
--- a/virtio/src/virtio_pci.rs
+++ b/virtio/src/virtio_pci.rs
@@ -24,6 +24,7 @@ use pci::config::{
VENDOR_ID,
};
use pci::errors::{ErrorKind, Result as PciResult, ResultExt};
+use pci::msix::update_dev_id;
use pci::{config::PciConfig, init_msix, le_write_u16, ranges_overlap, PciBus, PciDevOps};
use util::byte_code::ByteCode;
use vmm_sys_util::eventfd::EventFd;
@@ -459,13 +460,14 @@ pub struct VirtioPciState {
}
/// Virtio-PCI device structure
+#[derive(Clone)]
pub struct VirtioPciDevice {
/// Name of this device
name: String,
/// The entity of virtio device
device: Arc<Mutex<dyn VirtioDevice>>,
/// Device id
- dev_id: u16,
+ dev_id: Arc<AtomicU16>,
/// Devfn
devfn: u8,
/// If this device is activated or not.
@@ -500,7 +502,7 @@ impl VirtioPciDevice {
VirtioPciDevice {
name,
device,
- dev_id: 0_u16,
+ dev_id: Arc::new(AtomicU16::new(0)),
devfn,
device_activated: Arc::new(AtomicBool::new(false)),
sys_mem,
@@ -518,7 +520,7 @@ impl VirtioPciDevice {
fn assign_interrupt_cb(&mut self) {
let cloned_common_cfg = self.common_config.clone();
let cloned_msix = self.config.msix.clone();
- let dev_id = self.dev_id;
+ let dev_id = self.dev_id.clone();
let cb = Arc::new(Box::new(
move |int_type: &VirtioInterruptType, queue: Option<&Queue>| {
let vector = match int_type {
@@ -533,7 +535,9 @@ impl VirtioPciDevice {
};
if let Some(msix) = &cloned_msix {
- msix.lock().unwrap().notify(vector, dev_id);
+ msix.lock()
+ .unwrap()
+ .notify(vector, dev_id.load(Ordering::Acquire));
} else {
bail!("Failed to send interrupt, msix does not exist");
}
@@ -618,14 +622,7 @@ impl VirtioPciDevice {
true
};
- let cloned_virtio_dev = self.device.clone();
- let cloned_common_cfg = self.common_config.clone();
- let cloned_virtio_queue = self.queues.clone();
- let cloned_activated_flag = self.device_activated.clone();
- let cloned_notify_evts = self.notify_eventfds.clone();
- let cloned_sys_mem = self.sys_mem.clone();
- let cloned_int_cb = self.interrupt_cb.clone();
- let cloned_msix = self.config.msix.as_ref().unwrap().clone();
+ let cloned_pci_device = self.clone();
let common_write = move |data: &[u8], _addr: GuestAddress, offset: u64| -> bool {
let value = match data.len() {
1 => data[0] as u32,
@@ -639,13 +636,18 @@ impl VirtioPciDevice {
return false;
}
};
- let old_dev_status = cloned_common_cfg.lock().unwrap().device_status;
+ let old_dev_status = cloned_pci_device
+ .common_config
+ .lock()
+ .unwrap()
+ .device_status;
- if let Err(e) = cloned_common_cfg.lock().unwrap().write_common_config(
- &cloned_virtio_dev,
- offset,
- value,
- ) {
+ if let Err(e) = cloned_pci_device
+ .common_config
+ .lock()
+ .unwrap()
+ .write_common_config(&cloned_pci_device.device.clone(), offset, value)
+ {
error!(
"Failed to read common config of virtio-pci device, error is {}",
e.display_chain(),
@@ -653,21 +655,29 @@ impl VirtioPciDevice {
return false;
}
- if !cloned_activated_flag.load(Ordering::Acquire)
- && cloned_common_cfg.lock().unwrap().check_device_status(
- CONFIG_STATUS_ACKNOWLEDGE
- | CONFIG_STATUS_DRIVER
- | CONFIG_STATUS_DRIVER_OK
- | CONFIG_STATUS_FEATURES_OK,
- CONFIG_STATUS_FAILED,
- )
+ if !cloned_pci_device.device_activated.load(Ordering::Acquire)
+ && cloned_pci_device
+ .common_config
+ .lock()
+ .unwrap()
+ .check_device_status(
+ CONFIG_STATUS_ACKNOWLEDGE
+ | CONFIG_STATUS_DRIVER
+ | CONFIG_STATUS_DRIVER_OK
+ | CONFIG_STATUS_FEATURES_OK,
+ CONFIG_STATUS_FAILED,
+ )
{
- let queue_type = cloned_common_cfg.lock().unwrap().queue_type;
- let queues_config = &cloned_common_cfg.lock().unwrap().queues_config;
- let mut locked_queues = cloned_virtio_queue.lock().unwrap();
+ let queue_type = cloned_pci_device.common_config.lock().unwrap().queue_type;
+ let queues_config = &cloned_pci_device
+ .common_config
+ .lock()
+ .unwrap()
+ .queues_config;
+ let mut locked_queues = cloned_pci_device.queues.lock().unwrap();
for q_config in queues_config.iter() {
let queue = Queue::new(*q_config, queue_type).unwrap();
- if !queue.is_valid(&cloned_sys_mem) {
+ if !queue.is_valid(&cloned_pci_device.sys_mem) {
error!("Failed to activate device: Invalid queue");
return false;
}
@@ -675,10 +685,10 @@ impl VirtioPciDevice {
locked_queues.push(arc_queue.clone());
}
- let queue_evts = cloned_notify_evts.clone().events;
- if let Some(cb) = cloned_int_cb.clone() {
- if let Err(e) = cloned_virtio_dev.lock().unwrap().activate(
- cloned_sys_mem.clone(),
+ let queue_evts = cloned_pci_device.notify_eventfds.clone().events;
+ if let Some(cb) = cloned_pci_device.interrupt_cb.clone() {
+ if let Err(e) = cloned_pci_device.device.lock().unwrap().activate(
+ cloned_pci_device.sys_mem.clone(),
cb,
&locked_queues,
queue_evts,
@@ -689,20 +699,43 @@ impl VirtioPciDevice {
error!("Failed to activate device: No interrupt callback");
return false;
}
- cloned_activated_flag.store(true, Ordering::Release);
+ cloned_pci_device
+ .device_activated
+ .store(true, Ordering::Release);
+
+ update_dev_id(
+ &cloned_pci_device.parent_bus,
+ cloned_pci_device.devfn,
+ &cloned_pci_device.dev_id,
+ );
}
- if old_dev_status != 0 && cloned_common_cfg.lock().unwrap().device_status == 0 {
- let mut locked_queues = cloned_virtio_queue.lock().unwrap();
+ if old_dev_status != 0
+ && cloned_pci_device
+ .common_config
+ .lock()
+ .unwrap()
+ .device_status
+ == 0
+ {
+ let mut locked_queues = cloned_pci_device.queues.lock().unwrap();
locked_queues.clear();
- cloned_activated_flag.store(false, Ordering::Release);
+ cloned_pci_device
+ .device_activated
+ .store(false, Ordering::Release);
+ let cloned_msix = cloned_pci_device.config.msix.as_ref().unwrap().clone();
cloned_msix.lock().unwrap().reset();
- if let Err(e) = cloned_virtio_dev.lock().unwrap().reset() {
+ if let Err(e) = cloned_pci_device.device.lock().unwrap().reset() {
error!(
"Failed to reset virtio device, error is {}",
e.display_chain()
);
}
+ update_dev_id(
+ &cloned_pci_device.parent_bus,
+ cloned_pci_device.devfn,
+ &cloned_pci_device.dev_id,
+ );
}
true
@@ -874,15 +907,12 @@ impl PciDevOps for VirtioPciDevice {
self.modern_mem_region_map(notify_cap)?;
let nvectors = self.device.lock().unwrap().queue_num() + 1;
- #[cfg(target_arch = "aarch64")]
- {
- self.dev_id = self.set_dev_id(0, self.devfn);
- }
+
init_msix(
VIRTIO_PCI_MSIX_BAR_IDX as usize,
nvectors as u32,
&mut self.config,
- self.dev_id,
+ self.dev_id.clone(),
)?;
self.assign_interrupt_cb();
@@ -950,7 +980,8 @@ impl PciDevOps for VirtioPciDevice {
return;
}
- self.config.write(offset, data, self.dev_id);
+ self.config
+ .write(offset, data, self.dev_id.clone().load(Ordering::Acquire));
if ranges_overlap(
offset,
end,
@@ -1388,7 +1419,7 @@ mod tests {
VIRTIO_PCI_MSIX_BAR_IDX as usize,
virtio_pci.device.lock().unwrap().queue_num() as u32 + 1,
&mut virtio_pci.config,
- virtio_pci.dev_id,
+ virtio_pci.dev_id.clone(),
)
.unwrap();
// Prepare valid queue config
--
2.25.1