diff --git a/Cargo.lock b/Cargo.lock index d44406b3b..54a1d053c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -173,6 +173,7 @@ dependencies = [ name = "cloud-hypervisor" version = "0.4.0" dependencies = [ + "arc-swap 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)", "clap 2.33.0 (registry+https://github.com/rust-lang/crates.io-index)", "credibility 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", "dirs 2.0.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -991,6 +992,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" name = "vfio" version = "0.0.1" dependencies = [ + "arc-swap 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)", "byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)", "devices 0.1.0", "kvm-bindings 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1091,6 +1093,7 @@ dependencies = [ name = "vm-virtio" version = "0.1.0" dependencies = [ + "arc-swap 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)", "byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)", "devices 0.1.0", "epoll 4.0.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1114,6 +1117,7 @@ version = "0.1.0" dependencies = [ "acpi_tables 0.1.0", "anyhow 1.0.26 (registry+https://github.com/rust-lang/crates.io-index)", + "arc-swap 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)", "arch 0.1.0", "clap 2.33.0 (registry+https://github.com/rust-lang/crates.io-index)", "devices 0.1.0", diff --git a/Cargo.toml b/Cargo.toml index 12007d847..a08e9205f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -6,6 +6,7 @@ edition = "2018" default-run = "cloud-hypervisor" [dependencies] +arc-swap = ">=0.4.4" clap = "2.33.0" epoll = ">=4.0.1" lazy_static = "1.4.0" diff --git a/vfio/Cargo.toml b/vfio/Cargo.toml index 044a4c0d7..7f6af2c70 100644 --- a/vfio/Cargo.toml +++ b/vfio/Cargo.toml @@ -4,6 +4,7 @@ version = "0.0.1" authors = ["The Cloud Hypervisor Authors"] [dependencies] +arc-swap = ">=0.4.4" byteorder = "1.3.2" devices = { path = "../devices" } kvm-bindings = "0.2.0" diff --git a/vfio/src/lib.rs b/vfio/src/lib.rs index b2feea786..80988745a 100644 --- a/vfio/src/lib.rs +++ b/vfio/src/lib.rs @@ -5,6 +5,7 @@ //#![deny(missing_docs)] //! Virtual Function I/O (VFIO) API +extern crate arc_swap; extern crate byteorder; extern crate devices; extern crate kvm_bindings; diff --git a/vfio/src/vfio_device.rs b/vfio/src/vfio_device.rs index 1dc17fa17..a78d4b8a8 100644 --- a/vfio/src/vfio_device.rs +++ b/vfio/src/vfio_device.rs @@ -3,6 +3,7 @@ // SPDX-License-Identifier: Apache-2.0 OR BSD-3-Clause // use crate::vec_with_array_field; +use arc_swap::ArcSwap; use byteorder::{ByteOrder, LittleEndian}; use kvm_ioctls::*; use std::collections::HashMap; @@ -16,7 +17,7 @@ use std::os::unix::io::{AsRawFd, FromRawFd, RawFd}; use std::os::unix::prelude::FileExt; use std::path::{Path, PathBuf}; use std::result; -use std::sync::{Arc, RwLock}; +use std::sync::Arc; use std::u32; use vfio_bindings::bindings::vfio::*; use vfio_ioctls::*; @@ -514,11 +515,11 @@ impl VfioDeviceInfo { /// associated with a specific VFIO container. pub struct VfioDmaMapping { container: Arc, - memory: Arc>, + memory: Arc>, } impl VfioDmaMapping { - pub fn new(container: Arc, memory: Arc>) -> Self { + pub fn new(container: Arc, memory: Arc>) -> Self { VfioDmaMapping { container, memory } } } @@ -526,7 +527,7 @@ impl VfioDmaMapping { impl ExternalDmaMapping for VfioDmaMapping { fn map(&self, iova: u64, gpa: u64, size: u64) -> result::Result<(), io::Error> { let user_addr = if let Some(addr) = get_host_address_range( - &self.memory.read().unwrap(), + &self.memory.load(), GuestAddress(gpa), size.try_into().unwrap(), ) { @@ -577,7 +578,7 @@ pub struct VfioDevice { group: VfioGroup, regions: Vec, irqs: HashMap, - mem: Arc>, + mem: Arc>, iommu_attached: bool, } @@ -588,7 +589,7 @@ impl VfioDevice { pub fn new( sysfspath: &Path, device_fd: Arc, - mem: Arc>, + mem: Arc>, iommu_attached: bool, ) -> Result { let uuid_path: PathBuf = [sysfspath, Path::new("iommu_group")].iter().collect(); @@ -845,7 +846,7 @@ impl VfioDevice { /// then vfio kernel driver could access guest memory from gfn pub fn setup_dma_map(&self) -> Result<()> { if !self.iommu_attached { - self.mem.read().unwrap().with_regions(|_index, region| { + self.mem.load().with_regions(|_index, region| { self.vfio_dma_map( region.start_addr().raw_value(), region.len() as u64, @@ -860,7 +861,7 @@ impl VfioDevice { /// then vfio kernel driver couldn't access this guest memory pub fn unset_dma_map(&self) -> Result<()> { if !self.iommu_attached { - self.mem.read().unwrap().with_regions(|_index, region| { + self.mem.load().with_regions(|_index, region| { self.vfio_dma_unmap(region.start_addr().raw_value(), region.len() as u64) })?; } diff --git a/vm-virtio/Cargo.toml b/vm-virtio/Cargo.toml index 4ed5e6605..c5df246de 100644 --- a/vm-virtio/Cargo.toml +++ b/vm-virtio/Cargo.toml @@ -10,6 +10,7 @@ pci_support = ["pci"] mmio_support = [] [dependencies] +arc-swap = ">=0.4.4" byteorder = "1.3.2" devices = { path = "../devices" } epoll = ">=4.0.1" diff --git a/vm-virtio/src/block.rs b/vm-virtio/src/block.rs index 6be95641f..e3149a0b8 100755 --- a/vm-virtio/src/block.rs +++ b/vm-virtio/src/block.rs @@ -8,6 +8,13 @@ // // SPDX-License-Identifier: Apache-2.0 AND BSD-3-Clause +use super::Error as DeviceError; +use super::{ + ActivateError, ActivateResult, DescriptorChain, DeviceEventT, Queue, VirtioDevice, + VirtioDeviceType, VirtioInterruptType, +}; +use crate::VirtioInterrupt; +use arc_swap::ArcSwap; use epoll; use libc::EFD_NONBLOCK; use std::cmp; @@ -18,15 +25,8 @@ use std::os::unix::io::AsRawFd; use std::path::PathBuf; use std::result; use std::sync::atomic::{AtomicBool, Ordering}; -use std::sync::{Arc, RwLock}; +use std::sync::Arc; use std::thread; - -use super::Error as DeviceError; -use super::{ - ActivateError, ActivateResult, DescriptorChain, DeviceEventT, Queue, VirtioDevice, - VirtioDeviceType, VirtioInterruptType, -}; -use crate::VirtioInterrupt; use virtio_bindings::bindings::virtio_blk::*; use vm_device::{Migratable, MigratableError, Pausable, Snapshotable}; use vm_memory::{Bytes, GuestAddress, GuestMemory, GuestMemoryError, GuestMemoryMmap}; @@ -324,7 +324,7 @@ impl Request { struct BlockEpollHandler { queues: Vec, - mem: Arc>, + mem: Arc>, disk_image: T, disk_nsectors: u64, interrupt_cb: Arc, @@ -339,7 +339,7 @@ impl BlockEpollHandler { let mut used_desc_heads = [(0, 0); QUEUE_SIZE as usize]; let mut used_count = 0; - let mem = self.mem.read().unwrap(); + let mem = self.mem.load(); for avail_desc in queue.iter(&mem) { let len; match Request::parse(&avail_desc, &mem) { @@ -647,7 +647,7 @@ impl VirtioDevice for Block { fn activate( &mut self, - mem: Arc>, + mem: Arc>, interrupt_cb: Arc, queues: Vec, mut queue_evts: Vec, diff --git a/vm-virtio/src/console.rs b/vm-virtio/src/console.rs index 7da90fe25..994357044 100755 --- a/vm-virtio/src/console.rs +++ b/vm-virtio/src/console.rs @@ -1,6 +1,13 @@ // Copyright 2019 Intel Corporation. All Rights Reserved. // SPDX-License-Identifier: Apache-2.0 +use super::Error as DeviceError; +use super::{ + ActivateError, ActivateResult, DeviceEventT, Queue, VirtioDevice, VirtioDeviceType, + VirtioInterruptType, VIRTIO_F_IOMMU_PLATFORM, VIRTIO_F_VERSION_1, +}; +use crate::VirtioInterrupt; +use arc_swap::ArcSwap; use epoll; use libc::EFD_NONBLOCK; use std; @@ -11,16 +18,9 @@ use std::io::Write; use std::ops::DerefMut; use std::os::unix::io::AsRawFd; use std::result; -use std::sync::{Arc, Mutex, RwLock}; -use std::thread; - -use super::Error as DeviceError; -use super::{ - ActivateError, ActivateResult, DeviceEventT, Queue, VirtioDevice, VirtioDeviceType, - VirtioInterruptType, VIRTIO_F_IOMMU_PLATFORM, VIRTIO_F_VERSION_1, -}; -use crate::VirtioInterrupt; use std::sync::atomic::{AtomicBool, AtomicU64, Ordering}; +use std::sync::{Arc, Mutex}; +use std::thread; use vm_device::{Migratable, MigratableError, Pausable, Snapshotable}; use vm_memory::{ByteValued, Bytes, GuestMemoryMmap}; use vmm_sys_util::eventfd::EventFd; @@ -58,7 +58,7 @@ unsafe impl ByteValued for VirtioConsoleConfig {} struct ConsoleEpollHandler { queues: Vec, - mem: Arc>, + mem: Arc>, interrupt_cb: Arc, in_buffer: Arc>>, out: Arc>>, @@ -85,7 +85,7 @@ impl ConsoleEpollHandler { let mut used_count = 0; let mut write_count = 0; - let mem = self.mem.read().unwrap(); + let mem = self.mem.load(); for avail_desc in recv_queue.iter(&mem) { let len; @@ -132,7 +132,7 @@ impl ConsoleEpollHandler { let mut used_desc_heads = [(0, 0); QUEUE_SIZE as usize]; let mut used_count = 0; - let mem = self.mem.read().unwrap(); + let mem = self.mem.load(); for avail_desc in trans_queue.iter(&mem) { let len; let mut out = self.out.lock().unwrap(); @@ -473,7 +473,7 @@ impl VirtioDevice for Console { fn activate( &mut self, - mem: Arc>, + mem: Arc>, interrupt_cb: Arc, queues: Vec, mut queue_evts: Vec, diff --git a/vm-virtio/src/device.rs b/vm-virtio/src/device.rs index fd3830065..0585dcd86 100644 --- a/vm-virtio/src/device.rs +++ b/vm-virtio/src/device.rs @@ -7,7 +7,8 @@ // SPDX-License-Identifier: Apache-2.0 AND BSD-3-Clause use super::*; -use std::sync::{Arc, RwLock}; +use arc_swap::ArcSwap; +use std::sync::Arc; use vm_memory::{GuestAddress, GuestMemoryMmap, GuestUsize}; use vmm_sys_util::eventfd::EventFd; @@ -70,7 +71,7 @@ pub trait VirtioDevice: Send { /// Activates this device for real usage. fn activate( &mut self, - mem: Arc>, + mem: Arc>, interrupt_evt: Arc, queues: Vec, queue_evts: Vec, diff --git a/vm-virtio/src/iommu.rs b/vm-virtio/src/iommu.rs index fb2ce7bbc..7c8a45229 100644 --- a/vm-virtio/src/iommu.rs +++ b/vm-virtio/src/iommu.rs @@ -2,6 +2,13 @@ // // SPDX-License-Identifier: Apache-2.0 AND BSD-3-Clause +use super::Error as DeviceError; +use super::{ + ActivateError, ActivateResult, DescriptorChain, DeviceEventT, Queue, VirtioDevice, + VirtioDeviceType, VIRTIO_F_VERSION_1, +}; +use crate::{DmaRemapping, VirtioInterrupt, VirtioInterruptType}; +use arc_swap::ArcSwap; use epoll; use libc::EFD_NONBLOCK; use std::cmp; @@ -15,13 +22,6 @@ use std::result; use std::sync::atomic::{AtomicBool, Ordering}; use std::sync::{Arc, RwLock}; use std::thread; - -use super::Error as DeviceError; -use super::{ - ActivateError, ActivateResult, DescriptorChain, DeviceEventT, Queue, VirtioDevice, - VirtioDeviceType, VIRTIO_F_VERSION_1, -}; -use crate::{DmaRemapping, VirtioInterrupt, VirtioInterruptType}; use vm_device::{ExternalDmaMapping, Migratable, MigratableError, Pausable, Snapshotable}; use vm_memory::{Address, ByteValued, Bytes, GuestAddress, GuestMemoryError, GuestMemoryMmap}; use vmm_sys_util::eventfd::EventFd; @@ -531,7 +531,7 @@ impl Request { struct IommuEpollHandler { queues: Vec, - mem: Arc>, + mem: Arc>, interrupt_cb: Arc, queue_evts: Vec, kill_evt: EventFd, @@ -545,7 +545,7 @@ impl IommuEpollHandler { fn request_queue(&mut self) -> bool { let mut used_desc_heads = [(0, 0); QUEUE_SIZE as usize]; let mut used_count = 0; - let mem = self.mem.read().unwrap(); + let mem = self.mem.load(); for avail_desc in self.queues[0].iter(&mem) { let len = match Request::parse( &avail_desc, @@ -863,7 +863,7 @@ impl VirtioDevice for Iommu { fn activate( &mut self, - mem: Arc>, + mem: Arc>, interrupt_cb: Arc, queues: Vec, queue_evts: Vec, diff --git a/vm-virtio/src/lib.rs b/vm-virtio/src/lib.rs index be077016e..d4bbc2552 100755 --- a/vm-virtio/src/lib.rs +++ b/vm-virtio/src/lib.rs @@ -9,6 +9,8 @@ // SPDX-License-Identifier: Apache-2.0 AND BSD-3-Clause //! Implements virtio devices, queues, and transport mechanisms. + +extern crate arc_swap; extern crate epoll; #[macro_use] extern crate log; diff --git a/vm-virtio/src/net.rs b/vm-virtio/src/net.rs index 3f523107a..e822f0b86 100644 --- a/vm-virtio/src/net.rs +++ b/vm-virtio/src/net.rs @@ -5,9 +5,18 @@ // Use of this source code is governed by a BSD-style license that can be // found in the THIRD-PARTY file. +use super::Error as DeviceError; +use super::{ + ActivateError, ActivateResult, DeviceEventT, Queue, VirtioDevice, VirtioDeviceType, + VirtioInterruptType, +}; +use crate::VirtioInterrupt; +use arc_swap::ArcSwap; use epoll; use libc::EAGAIN; use libc::EFD_NONBLOCK; +use net_gen; +use net_util::{MacAddr, Tap, TapError, MAC_ADDR_LEN}; use std::cmp; use std::io::Read; use std::io::{self, Write}; @@ -16,19 +25,9 @@ use std::net::Ipv4Addr; use std::os::unix::io::{AsRawFd, RawFd}; use std::result; use std::sync::atomic::{AtomicBool, Ordering}; -use std::sync::{Arc, RwLock}; +use std::sync::Arc; use std::thread; use std::vec::Vec; - -use net_gen; - -use super::Error as DeviceError; -use super::{ - ActivateError, ActivateResult, DeviceEventT, Queue, VirtioDevice, VirtioDeviceType, - VirtioInterruptType, -}; -use crate::VirtioInterrupt; -use net_util::{MacAddr, Tap, TapError, MAC_ADDR_LEN}; use virtio_bindings::bindings::virtio_net::*; use vm_device::{Migratable, MigratableError, Pausable, Snapshotable}; use vm_memory::{Bytes, GuestAddress, GuestMemoryMmap}; @@ -119,7 +118,7 @@ fn vnet_hdr_len() -> usize { } struct NetEpollHandler { - mem: Arc>, + mem: Arc>, tap: Tap, rx: RxVirtio, tx: TxVirtio, @@ -142,7 +141,7 @@ impl NetEpollHandler { // if a buffer was used, and false if the frame must be deferred until a buffer // is made available by the driver. fn rx_single_frame(&mut self) -> bool { - let mem = self.mem.read().unwrap(); + let mem = self.mem.load(); let mut next_desc = self.rx.queue.iter(&mem).next(); if next_desc.is_none() { @@ -251,7 +250,7 @@ impl NetEpollHandler { } fn process_tx(&mut self) -> result::Result<(), DeviceError> { - let mem = self.mem.read().unwrap(); + let mem = self.mem.load(); while let Some(avail_desc) = self.tx.queue.iter(&mem).next() { let head_index = avail_desc.index; let mut read_count = 0; @@ -613,7 +612,7 @@ impl VirtioDevice for Net { fn activate( &mut self, - mem: Arc>, + mem: Arc>, interrupt_cb: Arc, mut queues: Vec, mut queue_evts: Vec, diff --git a/vm-virtio/src/pmem.rs b/vm-virtio/src/pmem.rs index 6c734faf9..a50d5560e 100644 --- a/vm-virtio/src/pmem.rs +++ b/vm-virtio/src/pmem.rs @@ -6,6 +6,13 @@ // // SPDX-License-Identifier: Apache-2.0 AND BSD-3-Clause +use super::Error as DeviceError; +use super::{ + ActivateError, ActivateResult, DescriptorChain, DeviceEventT, Queue, VirtioDevice, + VirtioDeviceType, VIRTIO_F_IOMMU_PLATFORM, VIRTIO_F_VERSION_1, +}; +use crate::{VirtioInterrupt, VirtioInterruptType}; +use arc_swap::ArcSwap; use epoll; use libc::EFD_NONBLOCK; use std::cmp; @@ -16,15 +23,8 @@ use std::mem::size_of; use std::os::unix::io::AsRawFd; use std::result; use std::sync::atomic::{AtomicBool, Ordering}; -use std::sync::{Arc, RwLock}; +use std::sync::Arc; use std::thread; - -use super::Error as DeviceError; -use super::{ - ActivateError, ActivateResult, DescriptorChain, DeviceEventT, Queue, VirtioDevice, - VirtioDeviceType, VIRTIO_F_IOMMU_PLATFORM, VIRTIO_F_VERSION_1, -}; -use crate::{VirtioInterrupt, VirtioInterruptType}; use vm_device::{Migratable, MigratableError, Pausable, Snapshotable}; use vm_memory::{ Address, ByteValued, Bytes, GuestAddress, GuestMemoryError, GuestMemoryMmap, GuestUsize, @@ -158,7 +158,7 @@ impl Request { struct PmemEpollHandler { queue: Queue, - mem: Arc>, + mem: Arc>, disk: File, interrupt_cb: Arc, queue_evt: EventFd, @@ -170,7 +170,7 @@ impl PmemEpollHandler { fn process_queue(&mut self) -> bool { let mut used_desc_heads = [(0, 0); QUEUE_SIZE as usize]; let mut used_count = 0; - let mem = self.mem.read().unwrap(); + let mem = self.mem.load(); for avail_desc in self.queue.iter(&mem) { let len = match Request::parse(&avail_desc, &mem) { Ok(ref req) if (req.type_ == RequestType::Flush) => { @@ -421,7 +421,7 @@ impl VirtioDevice for Pmem { fn activate( &mut self, - mem: Arc>, + mem: Arc>, interrupt_cb: Arc, mut queues: Vec, mut queue_evts: Vec, diff --git a/vm-virtio/src/rng.rs b/vm-virtio/src/rng.rs index b10c1d8c4..fc2e4ff09 100755 --- a/vm-virtio/src/rng.rs +++ b/vm-virtio/src/rng.rs @@ -2,6 +2,13 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +use super::Error as DeviceError; +use super::{ + ActivateError, ActivateResult, DeviceEventT, Queue, VirtioDevice, VirtioDeviceType, + VIRTIO_F_IOMMU_PLATFORM, VIRTIO_F_VERSION_1, +}; +use crate::{VirtioInterrupt, VirtioInterruptType}; +use arc_swap::ArcSwap; use epoll; use libc::EFD_NONBLOCK; use std; @@ -10,15 +17,8 @@ use std::io; use std::os::unix::io::AsRawFd; use std::result; use std::sync::atomic::{AtomicBool, Ordering}; -use std::sync::{Arc, RwLock}; +use std::sync::Arc; use std::thread; - -use super::Error as DeviceError; -use super::{ - ActivateError, ActivateResult, DeviceEventT, Queue, VirtioDevice, VirtioDeviceType, - VIRTIO_F_IOMMU_PLATFORM, VIRTIO_F_VERSION_1, -}; -use crate::{VirtioInterrupt, VirtioInterruptType}; use vm_device::{Migratable, MigratableError, Pausable, Snapshotable}; use vm_memory::{Bytes, GuestMemoryMmap}; use vmm_sys_util::eventfd::EventFd; @@ -36,7 +36,7 @@ const PAUSE_EVENT: DeviceEventT = 2; struct RngEpollHandler { queues: Vec, - mem: Arc>, + mem: Arc>, random_file: File, interrupt_cb: Arc, queue_evt: EventFd, @@ -50,7 +50,7 @@ impl RngEpollHandler { let mut used_desc_heads = [(0, 0); QUEUE_SIZE as usize]; let mut used_count = 0; - let mem = self.mem.read().unwrap(); + let mem = self.mem.load(); for avail_desc in queue.iter(&mem) { let mut len = 0; @@ -272,7 +272,7 @@ impl VirtioDevice for Rng { fn activate( &mut self, - mem: Arc>, + mem: Arc>, interrupt_cb: Arc, queues: Vec, mut queue_evts: Vec, diff --git a/vm-virtio/src/transport/mmio.rs b/vm-virtio/src/transport/mmio.rs index 0c3901837..42fcf6718 100644 --- a/vm-virtio/src/transport/mmio.rs +++ b/vm-virtio/src/transport/mmio.rs @@ -2,20 +2,19 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -use std::result; -use std::sync::atomic::{AtomicUsize, Ordering}; -use std::sync::{Arc, Mutex, RwLock}; - -use byteorder::{ByteOrder, LittleEndian}; -use libc::EFD_NONBLOCK; - use crate::transport::{VirtioTransport, NOTIFY_REG_OFFSET}; use crate::{ Queue, VirtioDevice, VirtioInterrupt, VirtioInterruptType, DEVICE_ACKNOWLEDGE, DEVICE_DRIVER, DEVICE_DRIVER_OK, DEVICE_FAILED, DEVICE_FEATURES_OK, DEVICE_INIT, INTERRUPT_STATUS_CONFIG_CHANGED, INTERRUPT_STATUS_USED_RING, }; +use arc_swap::ArcSwap; +use byteorder::{ByteOrder, LittleEndian}; use devices::{BusDevice, Interrupt}; +use libc::EFD_NONBLOCK; +use std::result; +use std::sync::atomic::{AtomicUsize, Ordering}; +use std::sync::{Arc, Mutex}; use vm_device::{Migratable, MigratableError, Pausable, Snapshotable}; use vm_memory::{GuestAddress, GuestMemoryMmap}; use vmm_sys_util::{errno::Result, eventfd::EventFd}; @@ -52,13 +51,13 @@ pub struct MmioDevice { config_generation: u32, queues: Vec, queue_evts: Vec, - mem: Option>>, + mem: Option>>, } impl MmioDevice { /// Constructs a new MMIO transport for the given virtio device. pub fn new( - mem: Arc>, + mem: Arc>, device: Arc>, ) -> Result { let device_clone = device.clone(); @@ -102,7 +101,7 @@ impl MmioDevice { fn are_queues_valid(&self) -> bool { if let Some(mem) = self.mem.as_ref() { - self.queues.iter().all(|q| q.is_valid(&mem.read().unwrap())) + self.queues.iter().all(|q| q.is_valid(mem.load().as_ref())) } else { false } diff --git a/vm-virtio/src/transport/pci_common_config.rs b/vm-virtio/src/transport/pci_common_config.rs index 82047a0b6..a5c837747 100644 --- a/vm-virtio/src/transport/pci_common_config.rs +++ b/vm-virtio/src/transport/pci_common_config.rs @@ -7,13 +7,12 @@ // SPDX-License-Identifier: Apache-2.0 AND BSD-3-Clause extern crate byteorder; +use crate::{Queue, VirtioDevice}; use byteorder::{ByteOrder, LittleEndian}; use std::sync::atomic::{AtomicU16, Ordering}; use std::sync::{Arc, Mutex}; use vm_memory::GuestAddress; -use crate::{Queue, VirtioDevice}; - /// Contains the data for reading and writing the common configuration structure of a virtio PCI /// device. /// @@ -255,8 +254,8 @@ impl VirtioPciCommonConfig { mod tests { use super::*; use crate::{ActivateResult, VirtioInterrupt}; - - use std::sync::{Arc, RwLock}; + use arc_swap::ArcSwap; + use std::sync::Arc; use vm_memory::GuestMemoryMmap; use vmm_sys_util::eventfd::EventFd; @@ -273,7 +272,7 @@ mod tests { } fn activate( &mut self, - _mem: Arc>, + _mem: Arc>, _interrupt_evt: Arc, _queues: Vec, _queue_evts: Vec, diff --git a/vm-virtio/src/transport/pci_device.rs b/vm-virtio/src/transport/pci_device.rs index d5e555de8..15f976b85 100755 --- a/vm-virtio/src/transport/pci_device.rs +++ b/vm-virtio/src/transport/pci_device.rs @@ -13,19 +13,19 @@ extern crate vm_allocator; extern crate vm_memory; extern crate vmm_sys_util; -use libc::EFD_NONBLOCK; -use std::any::Any; -use std::result; -use std::sync::atomic::{AtomicU16, AtomicUsize, Ordering}; -use std::sync::{Arc, Mutex, RwLock}; - +use arc_swap::ArcSwap; use devices::BusDevice; +use libc::EFD_NONBLOCK; use pci::{ BarReprogrammingParams, InterruptDelivery, InterruptParameters, MsixCap, MsixConfig, PciBarConfiguration, PciBarRegionType, PciCapability, PciCapabilityID, PciClassCode, PciConfiguration, PciDevice, PciDeviceError, PciHeaderType, PciInterruptPin, PciMassStorageSubclass, PciNetworkControllerSubclass, PciSubclass, }; +use std::any::Any; +use std::result; +use std::sync::atomic::{AtomicU16, AtomicUsize, Ordering}; +use std::sync::{Arc, Mutex}; use vm_allocator::SystemAllocator; use vm_device::{Migratable, MigratableError, Pausable, Snapshotable}; use vm_memory::{Address, ByteValued, GuestAddress, GuestMemoryMmap, GuestUsize, Le32}; @@ -239,7 +239,7 @@ pub struct VirtioPciDevice { queue_evts: Vec, // Guest memory - memory: Option>>, + memory: Option>>, // Setting PCI BAR settings_bar: u8, @@ -251,7 +251,7 @@ pub struct VirtioPciDevice { impl VirtioPciDevice { /// Constructs a new PCI transport for the given virtio device. pub fn new( - memory: Arc>, + memory: Arc>, device: Arc>, msix_num: u16, iommu_mapping_cb: Option>, @@ -361,7 +361,7 @@ impl VirtioPciDevice { fn are_queues_valid(&self) -> bool { if let Some(mem) = self.memory.as_ref() { - self.queues.iter().all(|q| q.is_valid(&mem.read().unwrap())) + self.queues.iter().all(|q| q.is_valid(mem.load().as_ref())) } else { false } diff --git a/vm-virtio/src/vhost_user/blk.rs b/vm-virtio/src/vhost_user/blk.rs index 3938247c9..e14894ed9 100644 --- a/vm-virtio/src/vhost_user/blk.rs +++ b/vm-virtio/src/vhost_user/blk.rs @@ -1,35 +1,32 @@ // Copyright 2019 Intel Corporation. All Rights Reserved. // SPDX-License-Identifier: Apache-2.0 -use libc; -use libc::EFD_NONBLOCK; -use std::cmp; -use std::io::Write; -use std::ptr::null; -use std::result; -use std::sync::atomic::{AtomicBool, Ordering}; -use std::sync::{Arc, RwLock}; -use std::thread; -use std::vec::Vec; - -use crate::VirtioInterrupt; - -use super::Error as DeviceError; - -use vm_device::{Migratable, MigratableError, Pausable, Snapshotable}; -use vm_memory::GuestMemoryMmap; -use vmm_sys_util::eventfd::EventFd; - use super::super::{ActivateError, ActivateResult, Queue, VirtioDevice, VirtioDeviceType}; use super::handler::*; use super::vu_common_ctrl::*; +use super::Error as DeviceError; use super::{Error, Result}; +use crate::VirtioInterrupt; +use arc_swap::ArcSwap; +use libc; +use libc::EFD_NONBLOCK; +use std::cmp; +use std::io::Write; use std::mem; +use std::ptr::null; +use std::result; +use std::sync::atomic::{AtomicBool, Ordering}; +use std::sync::Arc; +use std::thread; +use std::vec::Vec; use vhost_rs::vhost_user::message::VhostUserConfigFlags; use vhost_rs::vhost_user::message::{VhostUserProtocolFeatures, VhostUserVirtioFeatures}; use vhost_rs::vhost_user::{Master, VhostUserMaster, VhostUserMasterReqHandler}; use vhost_rs::VhostBackend; use virtio_bindings::bindings::virtio_blk::*; +use vm_device::{Migratable, MigratableError, Pausable, Snapshotable}; +use vm_memory::GuestMemoryMmap; +use vmm_sys_util::eventfd::EventFd; macro_rules! offset_of { ($ty:ty, $field:ident) => { @@ -222,7 +219,7 @@ impl VirtioDevice for Blk { fn activate( &mut self, - mem: Arc>, + mem: Arc>, interrupt_cb: Arc, queues: Vec, queue_evts: Vec, @@ -260,7 +257,7 @@ impl VirtioDevice for Blk { let vu_interrupt_list = setup_vhost_user( &mut self.vhost_user_blk, - &mem.read().unwrap(), + mem.load().as_ref(), queues, queue_evts, self.acked_features, diff --git a/vm-virtio/src/vhost_user/fs.rs b/vm-virtio/src/vhost_user/fs.rs index 025161f99..85bdda6ae 100644 --- a/vm-virtio/src/vhost_user/fs.rs +++ b/vm-virtio/src/vhost_user/fs.rs @@ -9,6 +9,7 @@ use crate::{ ActivateError, ActivateResult, Queue, VirtioDevice, VirtioDeviceType, VirtioInterrupt, VirtioSharedMemoryList, VIRTIO_F_VERSION_1, }; +use arc_swap::ArcSwap; use libc::{self, EFD_NONBLOCK}; use std::cmp; use std::io; @@ -16,7 +17,7 @@ use std::io::Write; use std::os::unix::io::RawFd; use std::result; use std::sync::atomic::{AtomicBool, Ordering}; -use std::sync::{Arc, Mutex, RwLock}; +use std::sync::{Arc, Mutex}; use std::thread; use vhost_rs::vhost_user::message::{ VhostUserFSSlaveMsg, VhostUserProtocolFeatures, VhostUserVirtioFeatures, @@ -295,7 +296,7 @@ impl VirtioDevice for Fs { fn activate( &mut self, - mem: Arc>, + mem: Arc>, interrupt_cb: Arc, queues: Vec, queue_evts: Vec, @@ -342,7 +343,7 @@ impl VirtioDevice for Fs { let vu_call_evt_queue_list = setup_vhost_user( &mut self.vu, - &mem.read().unwrap(), + mem.load().as_ref(), queues, queue_evts, self.acked_features, diff --git a/vm-virtio/src/vhost_user/net.rs b/vm-virtio/src/vhost_user/net.rs index 7cc8a2e97..9d52d3e26 100644 --- a/vm-virtio/src/vhost_user/net.rs +++ b/vm-virtio/src/vhost_user/net.rs @@ -1,33 +1,31 @@ // Copyright 2019 Intel Corporation. All Rights Reserved. // SPDX-License-Identifier: Apache-2.0 -use libc; -use libc::EFD_NONBLOCK; -use std::cmp; -use std::io::Write; -use std::result; -use std::sync::atomic::{AtomicBool, Ordering}; -use std::sync::{Arc, RwLock}; -use std::thread; -use std::vec::Vec; - -use super::Error as DeviceError; -use crate::VirtioInterrupt; -use net_util::{MacAddr, MAC_ADDR_LEN}; - -use vm_device::{Migratable, MigratableError, Pausable, Snapshotable}; -use vm_memory::GuestMemoryMmap; -use vmm_sys_util::eventfd::EventFd; - use super::super::{ActivateError, ActivateResult, Queue, VirtioDevice, VirtioDeviceType}; use super::handler::*; use super::vu_common_ctrl::*; +use super::Error as DeviceError; use super::{Error, Result}; +use crate::VirtioInterrupt; +use arc_swap::ArcSwap; +use libc; +use libc::EFD_NONBLOCK; +use net_util::{MacAddr, MAC_ADDR_LEN}; +use std::cmp; +use std::io::Write; +use std::result; +use std::sync::atomic::{AtomicBool, Ordering}; +use std::sync::Arc; +use std::thread; +use std::vec::Vec; use vhost_rs::vhost_user::message::{VhostUserProtocolFeatures, VhostUserVirtioFeatures}; use vhost_rs::vhost_user::{Master, VhostUserMaster, VhostUserMasterReqHandler}; use vhost_rs::VhostBackend; use virtio_bindings::bindings::virtio_net; use virtio_bindings::bindings::virtio_ring; +use vm_device::{Migratable, MigratableError, Pausable, Snapshotable}; +use vm_memory::GuestMemoryMmap; +use vmm_sys_util::eventfd::EventFd; struct SlaveReqHandler {} impl VhostUserMasterReqHandler for SlaveReqHandler {} @@ -206,7 +204,7 @@ impl VirtioDevice for Net { fn activate( &mut self, - mem: Arc>, + mem: Arc>, interrupt_cb: Arc, queues: Vec, queue_evts: Vec, @@ -244,7 +242,7 @@ impl VirtioDevice for Net { let vu_interrupt_list = setup_vhost_user( &mut self.vhost_user_net, - &mem.read().unwrap(), + mem.load().as_ref(), queues, queue_evts, self.acked_features & self.backend_features, diff --git a/vm-virtio/src/vsock/device.rs b/vm-virtio/src/vsock/device.rs index b0061616d..8e40edbf2 100644 --- a/vm-virtio/src/vsock/device.rs +++ b/vm-virtio/src/vsock/device.rs @@ -8,6 +8,13 @@ // Use of this source code is governed by a BSD-style license that can be // found in the THIRD-PARTY file. +use super::{VsockBackend, VsockPacket}; +use crate::Error as DeviceError; +use crate::VirtioInterrupt; +use crate::{ + ActivateError, ActivateResult, DeviceEventT, Queue, VirtioDevice, VirtioDeviceType, + VirtioInterruptType, VIRTIO_F_IN_ORDER, VIRTIO_F_IOMMU_PLATFORM, VIRTIO_F_VERSION_1, +}; /// This is the `VirtioDevice` implementation for our vsock device. It handles the virtio-level /// device logic: feature negociation, device configuration, and device activation. /// The run-time device logic (i.e. event-driven data handling) is implemented by @@ -27,6 +34,8 @@ /// - an event queue FD; and /// - a backend FD. /// +use arc_swap::ArcSwap; +use byteorder::{ByteOrder, LittleEndian}; use epoll; use libc::EFD_NONBLOCK; use std; @@ -36,15 +45,6 @@ use std::result; use std::sync::atomic::{AtomicBool, Ordering}; use std::sync::{Arc, RwLock}; use std::thread; - -use super::{VsockBackend, VsockPacket}; -use crate::Error as DeviceError; -use crate::VirtioInterrupt; -use crate::{ - ActivateError, ActivateResult, DeviceEventT, Queue, VirtioDevice, VirtioDeviceType, - VirtioInterruptType, VIRTIO_F_IN_ORDER, VIRTIO_F_IOMMU_PLATFORM, VIRTIO_F_VERSION_1, -}; -use byteorder::{ByteOrder, LittleEndian}; use vm_device::{Migratable, MigratableError, Pausable, Snapshotable}; use vm_memory::GuestMemoryMmap; use vmm_sys_util::eventfd::EventFd; @@ -86,7 +86,7 @@ pub const EVENTS_LEN: usize = 6; /// - again, attempt to fetch any incoming packets queued by the backend into virtio RX buffers. /// pub struct VsockEpollHandler { - pub mem: Arc>, + pub mem: Arc>, pub queues: Vec, pub queue_evts: Vec, pub kill_evt: EventFd, @@ -119,7 +119,7 @@ where let mut used_desc_heads = [(0, 0); QUEUE_SIZE as usize]; let mut used_count = 0; - let mem = self.mem.read().unwrap(); + let mem = self.mem.load(); for avail_desc in self.queues[0].iter(&mem) { let used_len = match VsockPacket::from_rx_virtq_head(&avail_desc) { Ok(mut pkt) => { @@ -161,7 +161,7 @@ where let mut used_desc_heads = [(0, 0); QUEUE_SIZE as usize]; let mut used_count = 0; - let mem = self.mem.read().unwrap(); + let mem = self.mem.load(); for avail_desc in self.queues[1].iter(&mem) { let pkt = match VsockPacket::from_tx_virtq_head(&avail_desc) { Ok(pkt) => pkt, @@ -496,7 +496,7 @@ where fn activate( &mut self, - mem: Arc>, + mem: Arc>, interrupt_cb: Arc, queues: Vec, queue_evts: Vec, @@ -664,7 +664,7 @@ mod tests { // Test a bad activation. let bad_activate = ctx.device.activate( - Arc::new(RwLock::new(ctx.mem.clone())), + Arc::new(ArcSwap::from(Arc::new(ctx.mem.clone()))), Arc::new( Box::new(move |_: &VirtioInterruptType, _: Option<&Queue>| Ok(())) as VirtioInterrupt, @@ -680,7 +680,7 @@ mod tests { // Test a correct activation. ctx.device .activate( - Arc::new(RwLock::new(ctx.mem.clone())), + Arc::new(ArcSwap::new(Arc::new(ctx.mem.clone()))), Arc::new( Box::new(move |_: &VirtioInterruptType, _: Option<&Queue>| Ok(())) as VirtioInterrupt, diff --git a/vm-virtio/src/vsock/mod.rs b/vm-virtio/src/vsock/mod.rs index 9b7c5c562..e2426af78 100644 --- a/vm-virtio/src/vsock/mod.rs +++ b/vm-virtio/src/vsock/mod.rs @@ -17,9 +17,8 @@ pub use self::device::Vsock; pub use self::unix::VsockUnixBackend; pub use self::unix::VsockUnixError; -use std::os::unix::io::RawFd; - use packet::VsockPacket; +use std::os::unix::io::RawFd; mod defs { @@ -158,22 +157,20 @@ pub trait VsockBackend: VsockChannel + VsockEpollListener + Send {} #[cfg(test)] mod tests { - use libc::EFD_NONBLOCK; - use super::device::{VsockEpollHandler, RX_QUEUE_EVENT, TX_QUEUE_EVENT}; use super::packet::VSOCK_PKT_HDR_SIZE; use super::*; - - use std::os::unix::io::AsRawFd; - use std::sync::atomic::AtomicBool; - use std::sync::{Arc, RwLock}; - use vmm_sys_util::eventfd::EventFd; - use crate::device::{VirtioInterrupt, VirtioInterruptType}; use crate::queue::tests::VirtQueue as GuestQ; use crate::queue::Queue; use crate::{VIRTQ_DESC_F_NEXT, VIRTQ_DESC_F_WRITE}; + use arc_swap::ArcSwap; + use libc::EFD_NONBLOCK; + use std::os::unix::io::AsRawFd; + use std::sync::atomic::AtomicBool; + use std::sync::{Arc, RwLock}; use vm_memory::{GuestAddress, GuestMemoryMmap}; + use vmm_sys_util::eventfd::EventFd; pub struct TestBackend { pub evfd: EventFd, @@ -303,7 +300,7 @@ mod tests { guest_txvq, guest_evvq, handler: VsockEpollHandler { - mem: Arc::new(RwLock::new(self.mem.clone())), + mem: Arc::new(ArcSwap::new(Arc::new(self.mem.clone()))), queues, queue_evts, kill_evt: EventFd::new(EFD_NONBLOCK).unwrap(), diff --git a/vmm/Cargo.toml b/vmm/Cargo.toml index 521745b59..2109e033e 100644 --- a/vmm/Cargo.toml +++ b/vmm/Cargo.toml @@ -12,6 +12,7 @@ mmio_support = ["vm-virtio/mmio_support"] cmos = ["devices/cmos"] [dependencies] +arc-swap = ">=0.4.4" clap = "2.33.0" acpi_tables = { path = "../acpi_tables", optional = true } anyhow = "1.0" diff --git a/vmm/src/cpu.rs b/vmm/src/cpu.rs index 9e84e749e..7eae968dc 100644 --- a/vmm/src/cpu.rs +++ b/vmm/src/cpu.rs @@ -8,27 +8,23 @@ // // SPDX-License-Identifier: Apache-2.0 AND BSD-3-Clause // - -use std::cmp; -use std::os::unix::thread::JoinHandleExt; -use std::sync::atomic::{AtomicBool, Ordering}; -use std::sync::{Arc, Barrier, Mutex, RwLock, Weak}; -use std::thread; -use std::{fmt, io, result}; - -use libc::{c_void, siginfo_t}; - use crate::device_manager::DeviceManager; #[cfg(feature = "acpi")] use acpi_tables::{aml, aml::Aml, sdt::SDT}; +use arc_swap::ArcSwap; use arch::layout; use devices::{ioapic, BusDevice}; use kvm_bindings::CpuId; use kvm_ioctls::*; - +use libc::{c_void, siginfo_t}; +use std::cmp; +use std::os::unix::thread::JoinHandleExt; +use std::sync::atomic::{AtomicBool, Ordering}; +use std::sync::{Arc, Barrier, Mutex, Weak}; +use std::thread; +use std::{fmt, io, result}; use vm_device::{Migratable, MigratableError, Pausable, Snapshotable}; use vm_memory::{Address, GuestAddress, GuestMemoryMmap}; - use vmm_sys_util::eventfd::EventFd; use vmm_sys_util::signal::{register_signal_handler, SIGRTMIN}; @@ -279,7 +275,7 @@ impl Vcpu { pub fn configure( &mut self, kernel_start_addr: Option, - vm_memory: &Arc>, + vm_memory: &Arc>, cpuid: CpuId, ) -> Result<()> { let mut cpuid = cpuid; @@ -299,7 +295,7 @@ impl Vcpu { ) .map_err(Error::REGSConfiguration)?; arch::x86_64::regs::setup_fpu(&self.fd).map_err(Error::FPUConfiguration)?; - arch::x86_64::regs::setup_sregs(&vm_memory.read().unwrap(), &self.fd) + arch::x86_64::regs::setup_sregs(&vm_memory.load(), &self.fd) .map_err(Error::SREGSConfiguration)?; } arch::x86_64::interrupts::set_lint(&self.fd).map_err(Error::LocalIntConfiguration)?; @@ -378,7 +374,7 @@ pub struct CpuManager { io_bus: Weak, mmio_bus: Arc, ioapic: Option>>, - vm_memory: Arc>, + vm_memory: Arc>, cpuid: CpuId, fd: Arc, vcpus_kill_signalled: Arc, @@ -498,7 +494,7 @@ impl CpuManager { boot_vcpus: u8, max_vcpus: u8, device_manager: &DeviceManager, - guest_memory: Arc>, + guest_memory: Arc>, fd: Arc, cpuid: CpuId, reset_evt: EventFd, diff --git a/vmm/src/device_manager.rs b/vmm/src/device_manager.rs index e009df791..37a5e61b5 100644 --- a/vmm/src/device_manager.rs +++ b/vmm/src/device_manager.rs @@ -16,13 +16,14 @@ use crate::memory_manager::{Error as MemoryManagerError, MemoryManager}; use crate::vm::VmInfo; #[cfg(feature = "acpi")] use acpi_tables::{aml, aml::Aml}; +use arc_swap::ArcSwap; use arch::layout; +use arch::layout::{APIC_START, IOAPIC_SIZE, IOAPIC_START}; use devices::{ioapic, HotPlugNotificationType}; use kvm_bindings::kvm_irq_routing_entry; use kvm_ioctls::*; use libc::O_TMPFILE; use libc::TIOCGWINSZ; - use net_util::Tap; #[cfg(feature = "pci_support")] use pci::{ @@ -30,20 +31,17 @@ use pci::{ PciConfigIo, PciConfigMmio, PciDevice, PciRoot, }; use qcow::{self, ImageType, QcowFile}; - -use std::fs::{File, OpenOptions}; -use std::io::{self, sink, stdout}; - -use arch::layout::{APIC_START, IOAPIC_SIZE, IOAPIC_START}; use std::cmp; use std::collections::HashMap; +use std::fs::{File, OpenOptions}; +use std::io::{self, sink, stdout}; use std::os::unix::fs::OpenOptionsExt; use std::os::unix::io::AsRawFd; use std::ptr::null_mut; use std::result; #[cfg(feature = "pci_support")] use std::sync::Weak; -use std::sync::{Arc, Mutex, RwLock}; +use std::sync::{Arc, Mutex}; #[cfg(feature = "pci_support")] use vfio::{VfioDevice, VfioDmaMapping, VfioPciDevice, VfioPciError}; use vm_allocator::SystemAllocator; @@ -741,7 +739,7 @@ impl DeviceManager { { // Add a CMOS emulated device use vm_memory::GuestMemory; - let mem_size = _vm_info.memory.as_ref().read().unwrap().end_addr().0 + 1; + let mem_size = _vm_info.memory.load().end_addr().0 + 1; let mem_below_4g = std::cmp::min(arch::layout::MEM_32BIT_RESERVED_START.0, mem_size); let mem_above_4g = mem_size.saturating_sub(arch::layout::RAM_64BIT_START.0); @@ -1402,7 +1400,7 @@ impl DeviceManager { #[allow(clippy::too_many_arguments)] fn add_virtio_pci_device( virtio_device: Arc>, - memory: &Arc>, + memory: &Arc>, address_manager: &Arc, vm_fd: &Arc, pci: &mut PciBus, @@ -1523,7 +1521,7 @@ impl DeviceManager { #[cfg(feature = "mmio_support")] fn add_virtio_mmio_device( virtio_device: Arc>, - memory: &Arc>, + memory: &Arc>, address_manager: &Arc, vm_fd: &Arc, interrupt_info: &InterruptInfo, diff --git a/vmm/src/lib.rs b/vmm/src/lib.rs index 6be3659c0..f36424e20 100644 --- a/vmm/src/lib.rs +++ b/vmm/src/lib.rs @@ -3,9 +3,9 @@ // SPDX-License-Identifier: Apache-2.0 // +extern crate arc_swap; #[macro_use] extern crate lazy_static; - #[macro_use] extern crate log; extern crate serde; diff --git a/vmm/src/memory_manager.rs b/vmm/src/memory_manager.rs index ab1a3fe7a..e74974fcd 100644 --- a/vmm/src/memory_manager.rs +++ b/vmm/src/memory_manager.rs @@ -3,12 +3,15 @@ // SPDX-License-Identifier: Apache-2.0 // +use arc_swap::ArcSwap; use arch::RegionType; +use kvm_bindings::kvm_userspace_memory_region; +use kvm_ioctls::*; use std::fs::{File, OpenOptions}; use std::io; use std::os::unix::io::FromRawFd; use std::path::PathBuf; -use std::sync::{Arc, Mutex, RwLock}; +use std::sync::{Arc, Mutex}; use vm_allocator::SystemAllocator; use vm_memory::guest_memory::FileOffset; use vm_memory::{ @@ -16,11 +19,8 @@ use vm_memory::{ GuestUsize, }; -use kvm_bindings::kvm_userspace_memory_region; -use kvm_ioctls::*; - pub struct MemoryManager { - guest_memory: Arc>, + guest_memory: Arc>, next_kvm_memory_slot: u32, start_of_device_area: GuestAddress, end_of_device_area: GuestAddress, @@ -131,11 +131,7 @@ impl MemoryManager { mem_end.unchecked_add(1) }; - // Convert the guest memory into an Arc. The point being able to use it - // anywhere in the code, no matter which thread might use it. - // Add the RwLock aspect to guest memory as we might want to perform - // additions to the memory during runtime. - let guest_memory = Arc::new(RwLock::new(guest_memory)); + let guest_memory = Arc::new(ArcSwap::new(Arc::new(guest_memory))); let memory_manager = Arc::new(Mutex::new(MemoryManager { guest_memory: guest_memory.clone(), @@ -145,7 +141,7 @@ impl MemoryManager { fd, })); - guest_memory.read().unwrap().with_regions(|_, region| { + guest_memory.load().with_regions(|_, region| { let _ = memory_manager.lock().unwrap().create_userspace_mapping( region.start_addr().raw_value(), region.len() as u64, @@ -167,7 +163,7 @@ impl MemoryManager { Ok(memory_manager) } - pub fn guest_memory(&self) -> Arc> { + pub fn guest_memory(&self) -> Arc> { self.guest_memory.clone() } diff --git a/vmm/src/vm.rs b/vmm/src/vm.rs index e15c7acf4..03e63be92 100755 --- a/vmm/src/vm.rs +++ b/vmm/src/vm.rs @@ -29,19 +29,17 @@ use crate::cpu; use crate::device_manager::{get_win_size, Console, DeviceManager, DeviceManagerError}; use crate::memory_manager::{get_host_cpu_phys_bits, Error as MemoryManagerError, MemoryManager}; use anyhow::anyhow; +use arc_swap::ArcSwap; use arch::layout; use devices::{ioapic, HotPlugNotificationType}; use kvm_bindings::{kvm_enable_cap, kvm_userspace_memory_region, KVM_CAP_SPLIT_IRQCHIP}; use kvm_ioctls::*; - use linux_loader::cmdline::Cmdline; use linux_loader::loader::KernelLoader; use signal_hook::{iterator::Signals, SIGINT, SIGTERM, SIGWINCH}; use std::ffi::CString; use std::fs::File; use std::io; -use std::ops::Deref; - use std::sync::{Arc, Mutex, RwLock}; use std::{result, str, thread}; use vm_allocator::{GsiApic, SystemAllocator}; @@ -159,7 +157,7 @@ pub enum Error { pub type Result = result::Result; pub struct VmInfo<'a> { - pub memory: &'a Arc>, + pub memory: &'a Arc>, pub vm_fd: &'a Arc, pub vm_cfg: Arc>, } @@ -371,9 +369,9 @@ impl Vm { let cmdline_cstring = CString::new(cmdline).map_err(|_| Error::CmdLine)?; let guest_memory = self.memory_manager.lock().as_ref().unwrap().guest_memory(); - let mem = guest_memory.read().unwrap(); + let mem = guest_memory.load_full(); let entry_addr = match linux_loader::loader::Elf::load( - mem.deref(), + mem.as_ref(), None, &mut self.kernel, Some(arch::layout::HIGH_RAM_START), @@ -381,7 +379,7 @@ impl Vm { Ok(entry_addr) => entry_addr, Err(linux_loader::loader::Error::InvalidElfMagicNumber) => { linux_loader::loader::BzImage::load( - mem.deref(), + mem.as_ref(), None, &mut self.kernel, Some(arch::layout::HIGH_RAM_START), @@ -392,7 +390,7 @@ impl Vm { }; linux_loader::loader::load_cmdline( - mem.deref(), + mem.as_ref(), arch::layout::CMDLINE_START, &cmdline_cstring, )