vm-virtio, vmm, vfio: Store GuestMemoryMmap in an Arc<ArcSwap<T>>

This allows us to change the memory map that is being used by the
devices via an atomic swap (by replacing the map with another one). The
ArcSwap provides the mechanism for atomically swapping from to another
whilst still giving good read performace. It is inside an Arc so that we
can use a single ArcSwap for all users.

Not covered by this change is replacing the GuestMemoryMmap itself.

This change also removes some vertical whitespace from use blocks in the
files that this commit also changed. Vertical whitespace was being used
inconsistently and broke rustfmt's behaviour of ordering the imports as
it would only do it within the block.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
This commit is contained in:
Rob Bradford 2019-12-31 10:49:11 +00:00
parent 5c0bb38a65
commit b2589d4f3f
28 changed files with 213 additions and 222 deletions

4
Cargo.lock generated
View File

@ -173,6 +173,7 @@ dependencies = [
name = "cloud-hypervisor" name = "cloud-hypervisor"
version = "0.4.0" version = "0.4.0"
dependencies = [ 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)", "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)", "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)", "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" name = "vfio"
version = "0.0.1" version = "0.0.1"
dependencies = [ 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)", "byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
"devices 0.1.0", "devices 0.1.0",
"kvm-bindings 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "kvm-bindings 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
@ -1091,6 +1093,7 @@ dependencies = [
name = "vm-virtio" name = "vm-virtio"
version = "0.1.0" version = "0.1.0"
dependencies = [ 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)", "byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
"devices 0.1.0", "devices 0.1.0",
"epoll 4.0.1 (registry+https://github.com/rust-lang/crates.io-index)", "epoll 4.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
@ -1114,6 +1117,7 @@ version = "0.1.0"
dependencies = [ dependencies = [
"acpi_tables 0.1.0", "acpi_tables 0.1.0",
"anyhow 1.0.26 (registry+https://github.com/rust-lang/crates.io-index)", "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", "arch 0.1.0",
"clap 2.33.0 (registry+https://github.com/rust-lang/crates.io-index)", "clap 2.33.0 (registry+https://github.com/rust-lang/crates.io-index)",
"devices 0.1.0", "devices 0.1.0",

View File

@ -6,6 +6,7 @@ edition = "2018"
default-run = "cloud-hypervisor" default-run = "cloud-hypervisor"
[dependencies] [dependencies]
arc-swap = ">=0.4.4"
clap = "2.33.0" clap = "2.33.0"
epoll = ">=4.0.1" epoll = ">=4.0.1"
lazy_static = "1.4.0" lazy_static = "1.4.0"

View File

@ -4,6 +4,7 @@ version = "0.0.1"
authors = ["The Cloud Hypervisor Authors"] authors = ["The Cloud Hypervisor Authors"]
[dependencies] [dependencies]
arc-swap = ">=0.4.4"
byteorder = "1.3.2" byteorder = "1.3.2"
devices = { path = "../devices" } devices = { path = "../devices" }
kvm-bindings = "0.2.0" kvm-bindings = "0.2.0"

View File

@ -5,6 +5,7 @@
//#![deny(missing_docs)] //#![deny(missing_docs)]
//! Virtual Function I/O (VFIO) API //! Virtual Function I/O (VFIO) API
extern crate arc_swap;
extern crate byteorder; extern crate byteorder;
extern crate devices; extern crate devices;
extern crate kvm_bindings; extern crate kvm_bindings;

View File

@ -3,6 +3,7 @@
// SPDX-License-Identifier: Apache-2.0 OR BSD-3-Clause // SPDX-License-Identifier: Apache-2.0 OR BSD-3-Clause
// //
use crate::vec_with_array_field; use crate::vec_with_array_field;
use arc_swap::ArcSwap;
use byteorder::{ByteOrder, LittleEndian}; use byteorder::{ByteOrder, LittleEndian};
use kvm_ioctls::*; use kvm_ioctls::*;
use std::collections::HashMap; use std::collections::HashMap;
@ -16,7 +17,7 @@ use std::os::unix::io::{AsRawFd, FromRawFd, RawFd};
use std::os::unix::prelude::FileExt; use std::os::unix::prelude::FileExt;
use std::path::{Path, PathBuf}; use std::path::{Path, PathBuf};
use std::result; use std::result;
use std::sync::{Arc, RwLock}; use std::sync::Arc;
use std::u32; use std::u32;
use vfio_bindings::bindings::vfio::*; use vfio_bindings::bindings::vfio::*;
use vfio_ioctls::*; use vfio_ioctls::*;
@ -514,11 +515,11 @@ impl VfioDeviceInfo {
/// associated with a specific VFIO container. /// associated with a specific VFIO container.
pub struct VfioDmaMapping { pub struct VfioDmaMapping {
container: Arc<VfioContainer>, container: Arc<VfioContainer>,
memory: Arc<RwLock<GuestMemoryMmap>>, memory: Arc<ArcSwap<GuestMemoryMmap>>,
} }
impl VfioDmaMapping { impl VfioDmaMapping {
pub fn new(container: Arc<VfioContainer>, memory: Arc<RwLock<GuestMemoryMmap>>) -> Self { pub fn new(container: Arc<VfioContainer>, memory: Arc<ArcSwap<GuestMemoryMmap>>) -> Self {
VfioDmaMapping { container, memory } VfioDmaMapping { container, memory }
} }
} }
@ -526,7 +527,7 @@ impl VfioDmaMapping {
impl ExternalDmaMapping for VfioDmaMapping { impl ExternalDmaMapping for VfioDmaMapping {
fn map(&self, iova: u64, gpa: u64, size: u64) -> result::Result<(), io::Error> { fn map(&self, iova: u64, gpa: u64, size: u64) -> result::Result<(), io::Error> {
let user_addr = if let Some(addr) = get_host_address_range( let user_addr = if let Some(addr) = get_host_address_range(
&self.memory.read().unwrap(), &self.memory.load(),
GuestAddress(gpa), GuestAddress(gpa),
size.try_into().unwrap(), size.try_into().unwrap(),
) { ) {
@ -577,7 +578,7 @@ pub struct VfioDevice {
group: VfioGroup, group: VfioGroup,
regions: Vec<VfioRegion>, regions: Vec<VfioRegion>,
irqs: HashMap<u32, VfioIrq>, irqs: HashMap<u32, VfioIrq>,
mem: Arc<RwLock<GuestMemoryMmap>>, mem: Arc<ArcSwap<GuestMemoryMmap>>,
iommu_attached: bool, iommu_attached: bool,
} }
@ -588,7 +589,7 @@ impl VfioDevice {
pub fn new( pub fn new(
sysfspath: &Path, sysfspath: &Path,
device_fd: Arc<DeviceFd>, device_fd: Arc<DeviceFd>,
mem: Arc<RwLock<GuestMemoryMmap>>, mem: Arc<ArcSwap<GuestMemoryMmap>>,
iommu_attached: bool, iommu_attached: bool,
) -> Result<Self> { ) -> Result<Self> {
let uuid_path: PathBuf = [sysfspath, Path::new("iommu_group")].iter().collect(); 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 /// then vfio kernel driver could access guest memory from gfn
pub fn setup_dma_map(&self) -> Result<()> { pub fn setup_dma_map(&self) -> Result<()> {
if !self.iommu_attached { if !self.iommu_attached {
self.mem.read().unwrap().with_regions(|_index, region| { self.mem.load().with_regions(|_index, region| {
self.vfio_dma_map( self.vfio_dma_map(
region.start_addr().raw_value(), region.start_addr().raw_value(),
region.len() as u64, region.len() as u64,
@ -860,7 +861,7 @@ impl VfioDevice {
/// then vfio kernel driver couldn't access this guest memory /// then vfio kernel driver couldn't access this guest memory
pub fn unset_dma_map(&self) -> Result<()> { pub fn unset_dma_map(&self) -> Result<()> {
if !self.iommu_attached { 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) self.vfio_dma_unmap(region.start_addr().raw_value(), region.len() as u64)
})?; })?;
} }

View File

@ -10,6 +10,7 @@ pci_support = ["pci"]
mmio_support = [] mmio_support = []
[dependencies] [dependencies]
arc-swap = ">=0.4.4"
byteorder = "1.3.2" byteorder = "1.3.2"
devices = { path = "../devices" } devices = { path = "../devices" }
epoll = ">=4.0.1" epoll = ">=4.0.1"

View File

@ -8,6 +8,13 @@
// //
// SPDX-License-Identifier: Apache-2.0 AND BSD-3-Clause // 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 epoll;
use libc::EFD_NONBLOCK; use libc::EFD_NONBLOCK;
use std::cmp; use std::cmp;
@ -18,15 +25,8 @@ use std::os::unix::io::AsRawFd;
use std::path::PathBuf; use std::path::PathBuf;
use std::result; use std::result;
use std::sync::atomic::{AtomicBool, Ordering}; use std::sync::atomic::{AtomicBool, Ordering};
use std::sync::{Arc, RwLock}; use std::sync::Arc;
use std::thread; 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 virtio_bindings::bindings::virtio_blk::*;
use vm_device::{Migratable, MigratableError, Pausable, Snapshotable}; use vm_device::{Migratable, MigratableError, Pausable, Snapshotable};
use vm_memory::{Bytes, GuestAddress, GuestMemory, GuestMemoryError, GuestMemoryMmap}; use vm_memory::{Bytes, GuestAddress, GuestMemory, GuestMemoryError, GuestMemoryMmap};
@ -324,7 +324,7 @@ impl Request {
struct BlockEpollHandler<T: DiskFile> { struct BlockEpollHandler<T: DiskFile> {
queues: Vec<Queue>, queues: Vec<Queue>,
mem: Arc<RwLock<GuestMemoryMmap>>, mem: Arc<ArcSwap<GuestMemoryMmap>>,
disk_image: T, disk_image: T,
disk_nsectors: u64, disk_nsectors: u64,
interrupt_cb: Arc<VirtioInterrupt>, interrupt_cb: Arc<VirtioInterrupt>,
@ -339,7 +339,7 @@ impl<T: DiskFile> BlockEpollHandler<T> {
let mut used_desc_heads = [(0, 0); QUEUE_SIZE as usize]; let mut used_desc_heads = [(0, 0); QUEUE_SIZE as usize];
let mut used_count = 0; let mut used_count = 0;
let mem = self.mem.read().unwrap(); let mem = self.mem.load();
for avail_desc in queue.iter(&mem) { for avail_desc in queue.iter(&mem) {
let len; let len;
match Request::parse(&avail_desc, &mem) { match Request::parse(&avail_desc, &mem) {
@ -647,7 +647,7 @@ impl<T: 'static + DiskFile + Send> VirtioDevice for Block<T> {
fn activate( fn activate(
&mut self, &mut self,
mem: Arc<RwLock<GuestMemoryMmap>>, mem: Arc<ArcSwap<GuestMemoryMmap>>,
interrupt_cb: Arc<VirtioInterrupt>, interrupt_cb: Arc<VirtioInterrupt>,
queues: Vec<Queue>, queues: Vec<Queue>,
mut queue_evts: Vec<EventFd>, mut queue_evts: Vec<EventFd>,

View File

@ -1,6 +1,13 @@
// Copyright 2019 Intel Corporation. All Rights Reserved. // Copyright 2019 Intel Corporation. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0 // 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 epoll;
use libc::EFD_NONBLOCK; use libc::EFD_NONBLOCK;
use std; use std;
@ -11,16 +18,9 @@ use std::io::Write;
use std::ops::DerefMut; use std::ops::DerefMut;
use std::os::unix::io::AsRawFd; use std::os::unix::io::AsRawFd;
use std::result; 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::atomic::{AtomicBool, AtomicU64, Ordering};
use std::sync::{Arc, Mutex};
use std::thread;
use vm_device::{Migratable, MigratableError, Pausable, Snapshotable}; use vm_device::{Migratable, MigratableError, Pausable, Snapshotable};
use vm_memory::{ByteValued, Bytes, GuestMemoryMmap}; use vm_memory::{ByteValued, Bytes, GuestMemoryMmap};
use vmm_sys_util::eventfd::EventFd; use vmm_sys_util::eventfd::EventFd;
@ -58,7 +58,7 @@ unsafe impl ByteValued for VirtioConsoleConfig {}
struct ConsoleEpollHandler { struct ConsoleEpollHandler {
queues: Vec<Queue>, queues: Vec<Queue>,
mem: Arc<RwLock<GuestMemoryMmap>>, mem: Arc<ArcSwap<GuestMemoryMmap>>,
interrupt_cb: Arc<VirtioInterrupt>, interrupt_cb: Arc<VirtioInterrupt>,
in_buffer: Arc<Mutex<VecDeque<u8>>>, in_buffer: Arc<Mutex<VecDeque<u8>>>,
out: Arc<Mutex<Box<dyn io::Write + Send + Sync + 'static>>>, out: Arc<Mutex<Box<dyn io::Write + Send + Sync + 'static>>>,
@ -85,7 +85,7 @@ impl ConsoleEpollHandler {
let mut used_count = 0; let mut used_count = 0;
let mut write_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) { for avail_desc in recv_queue.iter(&mem) {
let len; let len;
@ -132,7 +132,7 @@ impl ConsoleEpollHandler {
let mut used_desc_heads = [(0, 0); QUEUE_SIZE as usize]; let mut used_desc_heads = [(0, 0); QUEUE_SIZE as usize];
let mut used_count = 0; let mut used_count = 0;
let mem = self.mem.read().unwrap(); let mem = self.mem.load();
for avail_desc in trans_queue.iter(&mem) { for avail_desc in trans_queue.iter(&mem) {
let len; let len;
let mut out = self.out.lock().unwrap(); let mut out = self.out.lock().unwrap();
@ -473,7 +473,7 @@ impl VirtioDevice for Console {
fn activate( fn activate(
&mut self, &mut self,
mem: Arc<RwLock<GuestMemoryMmap>>, mem: Arc<ArcSwap<GuestMemoryMmap>>,
interrupt_cb: Arc<VirtioInterrupt>, interrupt_cb: Arc<VirtioInterrupt>,
queues: Vec<Queue>, queues: Vec<Queue>,
mut queue_evts: Vec<EventFd>, mut queue_evts: Vec<EventFd>,

View File

@ -7,7 +7,8 @@
// SPDX-License-Identifier: Apache-2.0 AND BSD-3-Clause // SPDX-License-Identifier: Apache-2.0 AND BSD-3-Clause
use super::*; use super::*;
use std::sync::{Arc, RwLock}; use arc_swap::ArcSwap;
use std::sync::Arc;
use vm_memory::{GuestAddress, GuestMemoryMmap, GuestUsize}; use vm_memory::{GuestAddress, GuestMemoryMmap, GuestUsize};
use vmm_sys_util::eventfd::EventFd; use vmm_sys_util::eventfd::EventFd;
@ -70,7 +71,7 @@ pub trait VirtioDevice: Send {
/// Activates this device for real usage. /// Activates this device for real usage.
fn activate( fn activate(
&mut self, &mut self,
mem: Arc<RwLock<GuestMemoryMmap>>, mem: Arc<ArcSwap<GuestMemoryMmap>>,
interrupt_evt: Arc<VirtioInterrupt>, interrupt_evt: Arc<VirtioInterrupt>,
queues: Vec<Queue>, queues: Vec<Queue>,
queue_evts: Vec<EventFd>, queue_evts: Vec<EventFd>,

View File

@ -2,6 +2,13 @@
// //
// SPDX-License-Identifier: Apache-2.0 AND BSD-3-Clause // 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 epoll;
use libc::EFD_NONBLOCK; use libc::EFD_NONBLOCK;
use std::cmp; use std::cmp;
@ -15,13 +22,6 @@ use std::result;
use std::sync::atomic::{AtomicBool, Ordering}; use std::sync::atomic::{AtomicBool, Ordering};
use std::sync::{Arc, RwLock}; use std::sync::{Arc, RwLock};
use std::thread; 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_device::{ExternalDmaMapping, Migratable, MigratableError, Pausable, Snapshotable};
use vm_memory::{Address, ByteValued, Bytes, GuestAddress, GuestMemoryError, GuestMemoryMmap}; use vm_memory::{Address, ByteValued, Bytes, GuestAddress, GuestMemoryError, GuestMemoryMmap};
use vmm_sys_util::eventfd::EventFd; use vmm_sys_util::eventfd::EventFd;
@ -531,7 +531,7 @@ impl Request {
struct IommuEpollHandler { struct IommuEpollHandler {
queues: Vec<Queue>, queues: Vec<Queue>,
mem: Arc<RwLock<GuestMemoryMmap>>, mem: Arc<ArcSwap<GuestMemoryMmap>>,
interrupt_cb: Arc<VirtioInterrupt>, interrupt_cb: Arc<VirtioInterrupt>,
queue_evts: Vec<EventFd>, queue_evts: Vec<EventFd>,
kill_evt: EventFd, kill_evt: EventFd,
@ -545,7 +545,7 @@ impl IommuEpollHandler {
fn request_queue(&mut self) -> bool { fn request_queue(&mut self) -> bool {
let mut used_desc_heads = [(0, 0); QUEUE_SIZE as usize]; let mut used_desc_heads = [(0, 0); QUEUE_SIZE as usize];
let mut used_count = 0; 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) { for avail_desc in self.queues[0].iter(&mem) {
let len = match Request::parse( let len = match Request::parse(
&avail_desc, &avail_desc,
@ -863,7 +863,7 @@ impl VirtioDevice for Iommu {
fn activate( fn activate(
&mut self, &mut self,
mem: Arc<RwLock<GuestMemoryMmap>>, mem: Arc<ArcSwap<GuestMemoryMmap>>,
interrupt_cb: Arc<VirtioInterrupt>, interrupt_cb: Arc<VirtioInterrupt>,
queues: Vec<Queue>, queues: Vec<Queue>,
queue_evts: Vec<EventFd>, queue_evts: Vec<EventFd>,

View File

@ -9,6 +9,8 @@
// SPDX-License-Identifier: Apache-2.0 AND BSD-3-Clause // SPDX-License-Identifier: Apache-2.0 AND BSD-3-Clause
//! Implements virtio devices, queues, and transport mechanisms. //! Implements virtio devices, queues, and transport mechanisms.
extern crate arc_swap;
extern crate epoll; extern crate epoll;
#[macro_use] #[macro_use]
extern crate log; extern crate log;

View File

@ -5,9 +5,18 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the THIRD-PARTY file. // 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 epoll;
use libc::EAGAIN; use libc::EAGAIN;
use libc::EFD_NONBLOCK; use libc::EFD_NONBLOCK;
use net_gen;
use net_util::{MacAddr, Tap, TapError, MAC_ADDR_LEN};
use std::cmp; use std::cmp;
use std::io::Read; use std::io::Read;
use std::io::{self, Write}; use std::io::{self, Write};
@ -16,19 +25,9 @@ use std::net::Ipv4Addr;
use std::os::unix::io::{AsRawFd, RawFd}; use std::os::unix::io::{AsRawFd, RawFd};
use std::result; use std::result;
use std::sync::atomic::{AtomicBool, Ordering}; use std::sync::atomic::{AtomicBool, Ordering};
use std::sync::{Arc, RwLock}; use std::sync::Arc;
use std::thread; use std::thread;
use std::vec::Vec; 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 virtio_bindings::bindings::virtio_net::*;
use vm_device::{Migratable, MigratableError, Pausable, Snapshotable}; use vm_device::{Migratable, MigratableError, Pausable, Snapshotable};
use vm_memory::{Bytes, GuestAddress, GuestMemoryMmap}; use vm_memory::{Bytes, GuestAddress, GuestMemoryMmap};
@ -119,7 +118,7 @@ fn vnet_hdr_len() -> usize {
} }
struct NetEpollHandler { struct NetEpollHandler {
mem: Arc<RwLock<GuestMemoryMmap>>, mem: Arc<ArcSwap<GuestMemoryMmap>>,
tap: Tap, tap: Tap,
rx: RxVirtio, rx: RxVirtio,
tx: TxVirtio, tx: TxVirtio,
@ -142,7 +141,7 @@ impl NetEpollHandler {
// if a buffer was used, and false if the frame must be deferred until a buffer // if a buffer was used, and false if the frame must be deferred until a buffer
// is made available by the driver. // is made available by the driver.
fn rx_single_frame(&mut self) -> bool { 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(); let mut next_desc = self.rx.queue.iter(&mem).next();
if next_desc.is_none() { if next_desc.is_none() {
@ -251,7 +250,7 @@ impl NetEpollHandler {
} }
fn process_tx(&mut self) -> result::Result<(), DeviceError> { 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() { while let Some(avail_desc) = self.tx.queue.iter(&mem).next() {
let head_index = avail_desc.index; let head_index = avail_desc.index;
let mut read_count = 0; let mut read_count = 0;
@ -613,7 +612,7 @@ impl VirtioDevice for Net {
fn activate( fn activate(
&mut self, &mut self,
mem: Arc<RwLock<GuestMemoryMmap>>, mem: Arc<ArcSwap<GuestMemoryMmap>>,
interrupt_cb: Arc<VirtioInterrupt>, interrupt_cb: Arc<VirtioInterrupt>,
mut queues: Vec<Queue>, mut queues: Vec<Queue>,
mut queue_evts: Vec<EventFd>, mut queue_evts: Vec<EventFd>,

View File

@ -6,6 +6,13 @@
// //
// SPDX-License-Identifier: Apache-2.0 AND BSD-3-Clause // 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 epoll;
use libc::EFD_NONBLOCK; use libc::EFD_NONBLOCK;
use std::cmp; use std::cmp;
@ -16,15 +23,8 @@ use std::mem::size_of;
use std::os::unix::io::AsRawFd; use std::os::unix::io::AsRawFd;
use std::result; use std::result;
use std::sync::atomic::{AtomicBool, Ordering}; use std::sync::atomic::{AtomicBool, Ordering};
use std::sync::{Arc, RwLock}; use std::sync::Arc;
use std::thread; 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_device::{Migratable, MigratableError, Pausable, Snapshotable};
use vm_memory::{ use vm_memory::{
Address, ByteValued, Bytes, GuestAddress, GuestMemoryError, GuestMemoryMmap, GuestUsize, Address, ByteValued, Bytes, GuestAddress, GuestMemoryError, GuestMemoryMmap, GuestUsize,
@ -158,7 +158,7 @@ impl Request {
struct PmemEpollHandler { struct PmemEpollHandler {
queue: Queue, queue: Queue,
mem: Arc<RwLock<GuestMemoryMmap>>, mem: Arc<ArcSwap<GuestMemoryMmap>>,
disk: File, disk: File,
interrupt_cb: Arc<VirtioInterrupt>, interrupt_cb: Arc<VirtioInterrupt>,
queue_evt: EventFd, queue_evt: EventFd,
@ -170,7 +170,7 @@ impl PmemEpollHandler {
fn process_queue(&mut self) -> bool { fn process_queue(&mut self) -> bool {
let mut used_desc_heads = [(0, 0); QUEUE_SIZE as usize]; let mut used_desc_heads = [(0, 0); QUEUE_SIZE as usize];
let mut used_count = 0; let mut used_count = 0;
let mem = self.mem.read().unwrap(); let mem = self.mem.load();
for avail_desc in self.queue.iter(&mem) { for avail_desc in self.queue.iter(&mem) {
let len = match Request::parse(&avail_desc, &mem) { let len = match Request::parse(&avail_desc, &mem) {
Ok(ref req) if (req.type_ == RequestType::Flush) => { Ok(ref req) if (req.type_ == RequestType::Flush) => {
@ -421,7 +421,7 @@ impl VirtioDevice for Pmem {
fn activate( fn activate(
&mut self, &mut self,
mem: Arc<RwLock<GuestMemoryMmap>>, mem: Arc<ArcSwap<GuestMemoryMmap>>,
interrupt_cb: Arc<VirtioInterrupt>, interrupt_cb: Arc<VirtioInterrupt>,
mut queues: Vec<Queue>, mut queues: Vec<Queue>,
mut queue_evts: Vec<EventFd>, mut queue_evts: Vec<EventFd>,

View File

@ -2,6 +2,13 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // 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 epoll;
use libc::EFD_NONBLOCK; use libc::EFD_NONBLOCK;
use std; use std;
@ -10,15 +17,8 @@ use std::io;
use std::os::unix::io::AsRawFd; use std::os::unix::io::AsRawFd;
use std::result; use std::result;
use std::sync::atomic::{AtomicBool, Ordering}; use std::sync::atomic::{AtomicBool, Ordering};
use std::sync::{Arc, RwLock}; use std::sync::Arc;
use std::thread; 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_device::{Migratable, MigratableError, Pausable, Snapshotable};
use vm_memory::{Bytes, GuestMemoryMmap}; use vm_memory::{Bytes, GuestMemoryMmap};
use vmm_sys_util::eventfd::EventFd; use vmm_sys_util::eventfd::EventFd;
@ -36,7 +36,7 @@ const PAUSE_EVENT: DeviceEventT = 2;
struct RngEpollHandler { struct RngEpollHandler {
queues: Vec<Queue>, queues: Vec<Queue>,
mem: Arc<RwLock<GuestMemoryMmap>>, mem: Arc<ArcSwap<GuestMemoryMmap>>,
random_file: File, random_file: File,
interrupt_cb: Arc<VirtioInterrupt>, interrupt_cb: Arc<VirtioInterrupt>,
queue_evt: EventFd, queue_evt: EventFd,
@ -50,7 +50,7 @@ impl RngEpollHandler {
let mut used_desc_heads = [(0, 0); QUEUE_SIZE as usize]; let mut used_desc_heads = [(0, 0); QUEUE_SIZE as usize];
let mut used_count = 0; let mut used_count = 0;
let mem = self.mem.read().unwrap(); let mem = self.mem.load();
for avail_desc in queue.iter(&mem) { for avail_desc in queue.iter(&mem) {
let mut len = 0; let mut len = 0;
@ -272,7 +272,7 @@ impl VirtioDevice for Rng {
fn activate( fn activate(
&mut self, &mut self,
mem: Arc<RwLock<GuestMemoryMmap>>, mem: Arc<ArcSwap<GuestMemoryMmap>>,
interrupt_cb: Arc<VirtioInterrupt>, interrupt_cb: Arc<VirtioInterrupt>,
queues: Vec<Queue>, queues: Vec<Queue>,
mut queue_evts: Vec<EventFd>, mut queue_evts: Vec<EventFd>,

View File

@ -2,20 +2,19 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // 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::transport::{VirtioTransport, NOTIFY_REG_OFFSET};
use crate::{ use crate::{
Queue, VirtioDevice, VirtioInterrupt, VirtioInterruptType, DEVICE_ACKNOWLEDGE, DEVICE_DRIVER, Queue, VirtioDevice, VirtioInterrupt, VirtioInterruptType, DEVICE_ACKNOWLEDGE, DEVICE_DRIVER,
DEVICE_DRIVER_OK, DEVICE_FAILED, DEVICE_FEATURES_OK, DEVICE_INIT, DEVICE_DRIVER_OK, DEVICE_FAILED, DEVICE_FEATURES_OK, DEVICE_INIT,
INTERRUPT_STATUS_CONFIG_CHANGED, INTERRUPT_STATUS_USED_RING, INTERRUPT_STATUS_CONFIG_CHANGED, INTERRUPT_STATUS_USED_RING,
}; };
use arc_swap::ArcSwap;
use byteorder::{ByteOrder, LittleEndian};
use devices::{BusDevice, Interrupt}; 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_device::{Migratable, MigratableError, Pausable, Snapshotable};
use vm_memory::{GuestAddress, GuestMemoryMmap}; use vm_memory::{GuestAddress, GuestMemoryMmap};
use vmm_sys_util::{errno::Result, eventfd::EventFd}; use vmm_sys_util::{errno::Result, eventfd::EventFd};
@ -52,13 +51,13 @@ pub struct MmioDevice {
config_generation: u32, config_generation: u32,
queues: Vec<Queue>, queues: Vec<Queue>,
queue_evts: Vec<EventFd>, queue_evts: Vec<EventFd>,
mem: Option<Arc<RwLock<GuestMemoryMmap>>>, mem: Option<Arc<ArcSwap<GuestMemoryMmap>>>,
} }
impl MmioDevice { impl MmioDevice {
/// Constructs a new MMIO transport for the given virtio device. /// Constructs a new MMIO transport for the given virtio device.
pub fn new( pub fn new(
mem: Arc<RwLock<GuestMemoryMmap>>, mem: Arc<ArcSwap<GuestMemoryMmap>>,
device: Arc<Mutex<dyn VirtioDevice>>, device: Arc<Mutex<dyn VirtioDevice>>,
) -> Result<MmioDevice> { ) -> Result<MmioDevice> {
let device_clone = device.clone(); let device_clone = device.clone();
@ -102,7 +101,7 @@ impl MmioDevice {
fn are_queues_valid(&self) -> bool { fn are_queues_valid(&self) -> bool {
if let Some(mem) = self.mem.as_ref() { 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 { } else {
false false
} }

View File

@ -7,13 +7,12 @@
// SPDX-License-Identifier: Apache-2.0 AND BSD-3-Clause // SPDX-License-Identifier: Apache-2.0 AND BSD-3-Clause
extern crate byteorder; extern crate byteorder;
use crate::{Queue, VirtioDevice};
use byteorder::{ByteOrder, LittleEndian}; use byteorder::{ByteOrder, LittleEndian};
use std::sync::atomic::{AtomicU16, Ordering}; use std::sync::atomic::{AtomicU16, Ordering};
use std::sync::{Arc, Mutex}; use std::sync::{Arc, Mutex};
use vm_memory::GuestAddress; use vm_memory::GuestAddress;
use crate::{Queue, VirtioDevice};
/// Contains the data for reading and writing the common configuration structure of a virtio PCI /// Contains the data for reading and writing the common configuration structure of a virtio PCI
/// device. /// device.
/// ///
@ -255,8 +254,8 @@ impl VirtioPciCommonConfig {
mod tests { mod tests {
use super::*; use super::*;
use crate::{ActivateResult, VirtioInterrupt}; use crate::{ActivateResult, VirtioInterrupt};
use arc_swap::ArcSwap;
use std::sync::{Arc, RwLock}; use std::sync::Arc;
use vm_memory::GuestMemoryMmap; use vm_memory::GuestMemoryMmap;
use vmm_sys_util::eventfd::EventFd; use vmm_sys_util::eventfd::EventFd;
@ -273,7 +272,7 @@ mod tests {
} }
fn activate( fn activate(
&mut self, &mut self,
_mem: Arc<RwLock<GuestMemoryMmap>>, _mem: Arc<ArcSwap<GuestMemoryMmap>>,
_interrupt_evt: Arc<VirtioInterrupt>, _interrupt_evt: Arc<VirtioInterrupt>,
_queues: Vec<Queue>, _queues: Vec<Queue>,
_queue_evts: Vec<EventFd>, _queue_evts: Vec<EventFd>,

View File

@ -13,19 +13,19 @@ extern crate vm_allocator;
extern crate vm_memory; extern crate vm_memory;
extern crate vmm_sys_util; extern crate vmm_sys_util;
use libc::EFD_NONBLOCK; use arc_swap::ArcSwap;
use std::any::Any;
use std::result;
use std::sync::atomic::{AtomicU16, AtomicUsize, Ordering};
use std::sync::{Arc, Mutex, RwLock};
use devices::BusDevice; use devices::BusDevice;
use libc::EFD_NONBLOCK;
use pci::{ use pci::{
BarReprogrammingParams, InterruptDelivery, InterruptParameters, MsixCap, MsixConfig, BarReprogrammingParams, InterruptDelivery, InterruptParameters, MsixCap, MsixConfig,
PciBarConfiguration, PciBarRegionType, PciCapability, PciCapabilityID, PciClassCode, PciBarConfiguration, PciBarRegionType, PciCapability, PciCapabilityID, PciClassCode,
PciConfiguration, PciDevice, PciDeviceError, PciHeaderType, PciInterruptPin, PciConfiguration, PciDevice, PciDeviceError, PciHeaderType, PciInterruptPin,
PciMassStorageSubclass, PciNetworkControllerSubclass, PciSubclass, 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_allocator::SystemAllocator;
use vm_device::{Migratable, MigratableError, Pausable, Snapshotable}; use vm_device::{Migratable, MigratableError, Pausable, Snapshotable};
use vm_memory::{Address, ByteValued, GuestAddress, GuestMemoryMmap, GuestUsize, Le32}; use vm_memory::{Address, ByteValued, GuestAddress, GuestMemoryMmap, GuestUsize, Le32};
@ -239,7 +239,7 @@ pub struct VirtioPciDevice {
queue_evts: Vec<EventFd>, queue_evts: Vec<EventFd>,
// Guest memory // Guest memory
memory: Option<Arc<RwLock<GuestMemoryMmap>>>, memory: Option<Arc<ArcSwap<GuestMemoryMmap>>>,
// Setting PCI BAR // Setting PCI BAR
settings_bar: u8, settings_bar: u8,
@ -251,7 +251,7 @@ pub struct VirtioPciDevice {
impl VirtioPciDevice { impl VirtioPciDevice {
/// Constructs a new PCI transport for the given virtio device. /// Constructs a new PCI transport for the given virtio device.
pub fn new( pub fn new(
memory: Arc<RwLock<GuestMemoryMmap>>, memory: Arc<ArcSwap<GuestMemoryMmap>>,
device: Arc<Mutex<dyn VirtioDevice>>, device: Arc<Mutex<dyn VirtioDevice>>,
msix_num: u16, msix_num: u16,
iommu_mapping_cb: Option<Arc<VirtioIommuRemapping>>, iommu_mapping_cb: Option<Arc<VirtioIommuRemapping>>,
@ -361,7 +361,7 @@ impl VirtioPciDevice {
fn are_queues_valid(&self) -> bool { fn are_queues_valid(&self) -> bool {
if let Some(mem) = self.memory.as_ref() { 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 { } else {
false false
} }

View File

@ -1,35 +1,32 @@
// Copyright 2019 Intel Corporation. All Rights Reserved. // Copyright 2019 Intel Corporation. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0 // 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::super::{ActivateError, ActivateResult, Queue, VirtioDevice, VirtioDeviceType};
use super::handler::*; use super::handler::*;
use super::vu_common_ctrl::*; use super::vu_common_ctrl::*;
use super::Error as DeviceError;
use super::{Error, Result}; 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::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::VhostUserConfigFlags;
use vhost_rs::vhost_user::message::{VhostUserProtocolFeatures, VhostUserVirtioFeatures}; use vhost_rs::vhost_user::message::{VhostUserProtocolFeatures, VhostUserVirtioFeatures};
use vhost_rs::vhost_user::{Master, VhostUserMaster, VhostUserMasterReqHandler}; use vhost_rs::vhost_user::{Master, VhostUserMaster, VhostUserMasterReqHandler};
use vhost_rs::VhostBackend; use vhost_rs::VhostBackend;
use virtio_bindings::bindings::virtio_blk::*; 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 { macro_rules! offset_of {
($ty:ty, $field:ident) => { ($ty:ty, $field:ident) => {
@ -222,7 +219,7 @@ impl VirtioDevice for Blk {
fn activate( fn activate(
&mut self, &mut self,
mem: Arc<RwLock<GuestMemoryMmap>>, mem: Arc<ArcSwap<GuestMemoryMmap>>,
interrupt_cb: Arc<VirtioInterrupt>, interrupt_cb: Arc<VirtioInterrupt>,
queues: Vec<Queue>, queues: Vec<Queue>,
queue_evts: Vec<EventFd>, queue_evts: Vec<EventFd>,
@ -260,7 +257,7 @@ impl VirtioDevice for Blk {
let vu_interrupt_list = setup_vhost_user( let vu_interrupt_list = setup_vhost_user(
&mut self.vhost_user_blk, &mut self.vhost_user_blk,
&mem.read().unwrap(), mem.load().as_ref(),
queues, queues,
queue_evts, queue_evts,
self.acked_features, self.acked_features,

View File

@ -9,6 +9,7 @@ use crate::{
ActivateError, ActivateResult, Queue, VirtioDevice, VirtioDeviceType, VirtioInterrupt, ActivateError, ActivateResult, Queue, VirtioDevice, VirtioDeviceType, VirtioInterrupt,
VirtioSharedMemoryList, VIRTIO_F_VERSION_1, VirtioSharedMemoryList, VIRTIO_F_VERSION_1,
}; };
use arc_swap::ArcSwap;
use libc::{self, EFD_NONBLOCK}; use libc::{self, EFD_NONBLOCK};
use std::cmp; use std::cmp;
use std::io; use std::io;
@ -16,7 +17,7 @@ use std::io::Write;
use std::os::unix::io::RawFd; use std::os::unix::io::RawFd;
use std::result; use std::result;
use std::sync::atomic::{AtomicBool, Ordering}; use std::sync::atomic::{AtomicBool, Ordering};
use std::sync::{Arc, Mutex, RwLock}; use std::sync::{Arc, Mutex};
use std::thread; use std::thread;
use vhost_rs::vhost_user::message::{ use vhost_rs::vhost_user::message::{
VhostUserFSSlaveMsg, VhostUserProtocolFeatures, VhostUserVirtioFeatures, VhostUserFSSlaveMsg, VhostUserProtocolFeatures, VhostUserVirtioFeatures,
@ -295,7 +296,7 @@ impl VirtioDevice for Fs {
fn activate( fn activate(
&mut self, &mut self,
mem: Arc<RwLock<GuestMemoryMmap>>, mem: Arc<ArcSwap<GuestMemoryMmap>>,
interrupt_cb: Arc<VirtioInterrupt>, interrupt_cb: Arc<VirtioInterrupt>,
queues: Vec<Queue>, queues: Vec<Queue>,
queue_evts: Vec<EventFd>, queue_evts: Vec<EventFd>,
@ -342,7 +343,7 @@ impl VirtioDevice for Fs {
let vu_call_evt_queue_list = setup_vhost_user( let vu_call_evt_queue_list = setup_vhost_user(
&mut self.vu, &mut self.vu,
&mem.read().unwrap(), mem.load().as_ref(),
queues, queues,
queue_evts, queue_evts,
self.acked_features, self.acked_features,

View File

@ -1,33 +1,31 @@
// Copyright 2019 Intel Corporation. All Rights Reserved. // Copyright 2019 Intel Corporation. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0 // 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::super::{ActivateError, ActivateResult, Queue, VirtioDevice, VirtioDeviceType};
use super::handler::*; use super::handler::*;
use super::vu_common_ctrl::*; use super::vu_common_ctrl::*;
use super::Error as DeviceError;
use super::{Error, Result}; 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::message::{VhostUserProtocolFeatures, VhostUserVirtioFeatures};
use vhost_rs::vhost_user::{Master, VhostUserMaster, VhostUserMasterReqHandler}; use vhost_rs::vhost_user::{Master, VhostUserMaster, VhostUserMasterReqHandler};
use vhost_rs::VhostBackend; use vhost_rs::VhostBackend;
use virtio_bindings::bindings::virtio_net; use virtio_bindings::bindings::virtio_net;
use virtio_bindings::bindings::virtio_ring; 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 {} struct SlaveReqHandler {}
impl VhostUserMasterReqHandler for SlaveReqHandler {} impl VhostUserMasterReqHandler for SlaveReqHandler {}
@ -206,7 +204,7 @@ impl VirtioDevice for Net {
fn activate( fn activate(
&mut self, &mut self,
mem: Arc<RwLock<GuestMemoryMmap>>, mem: Arc<ArcSwap<GuestMemoryMmap>>,
interrupt_cb: Arc<VirtioInterrupt>, interrupt_cb: Arc<VirtioInterrupt>,
queues: Vec<Queue>, queues: Vec<Queue>,
queue_evts: Vec<EventFd>, queue_evts: Vec<EventFd>,
@ -244,7 +242,7 @@ impl VirtioDevice for Net {
let vu_interrupt_list = setup_vhost_user( let vu_interrupt_list = setup_vhost_user(
&mut self.vhost_user_net, &mut self.vhost_user_net,
&mem.read().unwrap(), mem.load().as_ref(),
queues, queues,
queue_evts, queue_evts,
self.acked_features & self.backend_features, self.acked_features & self.backend_features,

View File

@ -8,6 +8,13 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the THIRD-PARTY file. // 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 /// This is the `VirtioDevice` implementation for our vsock device. It handles the virtio-level
/// device logic: feature negociation, device configuration, and device activation. /// device logic: feature negociation, device configuration, and device activation.
/// The run-time device logic (i.e. event-driven data handling) is implemented by /// The run-time device logic (i.e. event-driven data handling) is implemented by
@ -27,6 +34,8 @@
/// - an event queue FD; and /// - an event queue FD; and
/// - a backend FD. /// - a backend FD.
/// ///
use arc_swap::ArcSwap;
use byteorder::{ByteOrder, LittleEndian};
use epoll; use epoll;
use libc::EFD_NONBLOCK; use libc::EFD_NONBLOCK;
use std; use std;
@ -36,15 +45,6 @@ use std::result;
use std::sync::atomic::{AtomicBool, Ordering}; use std::sync::atomic::{AtomicBool, Ordering};
use std::sync::{Arc, RwLock}; use std::sync::{Arc, RwLock};
use std::thread; 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_device::{Migratable, MigratableError, Pausable, Snapshotable};
use vm_memory::GuestMemoryMmap; use vm_memory::GuestMemoryMmap;
use vmm_sys_util::eventfd::EventFd; 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. /// - again, attempt to fetch any incoming packets queued by the backend into virtio RX buffers.
/// ///
pub struct VsockEpollHandler<B: VsockBackend> { pub struct VsockEpollHandler<B: VsockBackend> {
pub mem: Arc<RwLock<GuestMemoryMmap>>, pub mem: Arc<ArcSwap<GuestMemoryMmap>>,
pub queues: Vec<Queue>, pub queues: Vec<Queue>,
pub queue_evts: Vec<EventFd>, pub queue_evts: Vec<EventFd>,
pub kill_evt: EventFd, pub kill_evt: EventFd,
@ -119,7 +119,7 @@ where
let mut used_desc_heads = [(0, 0); QUEUE_SIZE as usize]; let mut used_desc_heads = [(0, 0); QUEUE_SIZE as usize];
let mut used_count = 0; 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) { for avail_desc in self.queues[0].iter(&mem) {
let used_len = match VsockPacket::from_rx_virtq_head(&avail_desc) { let used_len = match VsockPacket::from_rx_virtq_head(&avail_desc) {
Ok(mut pkt) => { Ok(mut pkt) => {
@ -161,7 +161,7 @@ where
let mut used_desc_heads = [(0, 0); QUEUE_SIZE as usize]; let mut used_desc_heads = [(0, 0); QUEUE_SIZE as usize];
let mut used_count = 0; 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) { for avail_desc in self.queues[1].iter(&mem) {
let pkt = match VsockPacket::from_tx_virtq_head(&avail_desc) { let pkt = match VsockPacket::from_tx_virtq_head(&avail_desc) {
Ok(pkt) => pkt, Ok(pkt) => pkt,
@ -496,7 +496,7 @@ where
fn activate( fn activate(
&mut self, &mut self,
mem: Arc<RwLock<GuestMemoryMmap>>, mem: Arc<ArcSwap<GuestMemoryMmap>>,
interrupt_cb: Arc<VirtioInterrupt>, interrupt_cb: Arc<VirtioInterrupt>,
queues: Vec<Queue>, queues: Vec<Queue>,
queue_evts: Vec<EventFd>, queue_evts: Vec<EventFd>,
@ -664,7 +664,7 @@ mod tests {
// Test a bad activation. // Test a bad activation.
let bad_activate = ctx.device.activate( let bad_activate = ctx.device.activate(
Arc::new(RwLock::new(ctx.mem.clone())), Arc::new(ArcSwap::from(Arc::new(ctx.mem.clone()))),
Arc::new( Arc::new(
Box::new(move |_: &VirtioInterruptType, _: Option<&Queue>| Ok(())) Box::new(move |_: &VirtioInterruptType, _: Option<&Queue>| Ok(()))
as VirtioInterrupt, as VirtioInterrupt,
@ -680,7 +680,7 @@ mod tests {
// Test a correct activation. // Test a correct activation.
ctx.device ctx.device
.activate( .activate(
Arc::new(RwLock::new(ctx.mem.clone())), Arc::new(ArcSwap::new(Arc::new(ctx.mem.clone()))),
Arc::new( Arc::new(
Box::new(move |_: &VirtioInterruptType, _: Option<&Queue>| Ok(())) Box::new(move |_: &VirtioInterruptType, _: Option<&Queue>| Ok(()))
as VirtioInterrupt, as VirtioInterrupt,

View File

@ -17,9 +17,8 @@ pub use self::device::Vsock;
pub use self::unix::VsockUnixBackend; pub use self::unix::VsockUnixBackend;
pub use self::unix::VsockUnixError; pub use self::unix::VsockUnixError;
use std::os::unix::io::RawFd;
use packet::VsockPacket; use packet::VsockPacket;
use std::os::unix::io::RawFd;
mod defs { mod defs {
@ -158,22 +157,20 @@ pub trait VsockBackend: VsockChannel + VsockEpollListener + Send {}
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use libc::EFD_NONBLOCK;
use super::device::{VsockEpollHandler, RX_QUEUE_EVENT, TX_QUEUE_EVENT}; use super::device::{VsockEpollHandler, RX_QUEUE_EVENT, TX_QUEUE_EVENT};
use super::packet::VSOCK_PKT_HDR_SIZE; use super::packet::VSOCK_PKT_HDR_SIZE;
use super::*; 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::device::{VirtioInterrupt, VirtioInterruptType};
use crate::queue::tests::VirtQueue as GuestQ; use crate::queue::tests::VirtQueue as GuestQ;
use crate::queue::Queue; use crate::queue::Queue;
use crate::{VIRTQ_DESC_F_NEXT, VIRTQ_DESC_F_WRITE}; 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 vm_memory::{GuestAddress, GuestMemoryMmap};
use vmm_sys_util::eventfd::EventFd;
pub struct TestBackend { pub struct TestBackend {
pub evfd: EventFd, pub evfd: EventFd,
@ -303,7 +300,7 @@ mod tests {
guest_txvq, guest_txvq,
guest_evvq, guest_evvq,
handler: VsockEpollHandler { handler: VsockEpollHandler {
mem: Arc::new(RwLock::new(self.mem.clone())), mem: Arc::new(ArcSwap::new(Arc::new(self.mem.clone()))),
queues, queues,
queue_evts, queue_evts,
kill_evt: EventFd::new(EFD_NONBLOCK).unwrap(), kill_evt: EventFd::new(EFD_NONBLOCK).unwrap(),

View File

@ -12,6 +12,7 @@ mmio_support = ["vm-virtio/mmio_support"]
cmos = ["devices/cmos"] cmos = ["devices/cmos"]
[dependencies] [dependencies]
arc-swap = ">=0.4.4"
clap = "2.33.0" clap = "2.33.0"
acpi_tables = { path = "../acpi_tables", optional = true } acpi_tables = { path = "../acpi_tables", optional = true }
anyhow = "1.0" anyhow = "1.0"

View File

@ -8,27 +8,23 @@
// //
// SPDX-License-Identifier: Apache-2.0 AND BSD-3-Clause // 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; use crate::device_manager::DeviceManager;
#[cfg(feature = "acpi")] #[cfg(feature = "acpi")]
use acpi_tables::{aml, aml::Aml, sdt::SDT}; use acpi_tables::{aml, aml::Aml, sdt::SDT};
use arc_swap::ArcSwap;
use arch::layout; use arch::layout;
use devices::{ioapic, BusDevice}; use devices::{ioapic, BusDevice};
use kvm_bindings::CpuId; use kvm_bindings::CpuId;
use kvm_ioctls::*; 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_device::{Migratable, MigratableError, Pausable, Snapshotable};
use vm_memory::{Address, GuestAddress, GuestMemoryMmap}; use vm_memory::{Address, GuestAddress, GuestMemoryMmap};
use vmm_sys_util::eventfd::EventFd; use vmm_sys_util::eventfd::EventFd;
use vmm_sys_util::signal::{register_signal_handler, SIGRTMIN}; use vmm_sys_util::signal::{register_signal_handler, SIGRTMIN};
@ -279,7 +275,7 @@ impl Vcpu {
pub fn configure( pub fn configure(
&mut self, &mut self,
kernel_start_addr: Option<GuestAddress>, kernel_start_addr: Option<GuestAddress>,
vm_memory: &Arc<RwLock<GuestMemoryMmap>>, vm_memory: &Arc<ArcSwap<GuestMemoryMmap>>,
cpuid: CpuId, cpuid: CpuId,
) -> Result<()> { ) -> Result<()> {
let mut cpuid = cpuid; let mut cpuid = cpuid;
@ -299,7 +295,7 @@ impl Vcpu {
) )
.map_err(Error::REGSConfiguration)?; .map_err(Error::REGSConfiguration)?;
arch::x86_64::regs::setup_fpu(&self.fd).map_err(Error::FPUConfiguration)?; 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)?; .map_err(Error::SREGSConfiguration)?;
} }
arch::x86_64::interrupts::set_lint(&self.fd).map_err(Error::LocalIntConfiguration)?; arch::x86_64::interrupts::set_lint(&self.fd).map_err(Error::LocalIntConfiguration)?;
@ -378,7 +374,7 @@ pub struct CpuManager {
io_bus: Weak<devices::Bus>, io_bus: Weak<devices::Bus>,
mmio_bus: Arc<devices::Bus>, mmio_bus: Arc<devices::Bus>,
ioapic: Option<Arc<Mutex<ioapic::Ioapic>>>, ioapic: Option<Arc<Mutex<ioapic::Ioapic>>>,
vm_memory: Arc<RwLock<GuestMemoryMmap>>, vm_memory: Arc<ArcSwap<GuestMemoryMmap>>,
cpuid: CpuId, cpuid: CpuId,
fd: Arc<VmFd>, fd: Arc<VmFd>,
vcpus_kill_signalled: Arc<AtomicBool>, vcpus_kill_signalled: Arc<AtomicBool>,
@ -498,7 +494,7 @@ impl CpuManager {
boot_vcpus: u8, boot_vcpus: u8,
max_vcpus: u8, max_vcpus: u8,
device_manager: &DeviceManager, device_manager: &DeviceManager,
guest_memory: Arc<RwLock<GuestMemoryMmap>>, guest_memory: Arc<ArcSwap<GuestMemoryMmap>>,
fd: Arc<VmFd>, fd: Arc<VmFd>,
cpuid: CpuId, cpuid: CpuId,
reset_evt: EventFd, reset_evt: EventFd,

View File

@ -16,13 +16,14 @@ use crate::memory_manager::{Error as MemoryManagerError, MemoryManager};
use crate::vm::VmInfo; use crate::vm::VmInfo;
#[cfg(feature = "acpi")] #[cfg(feature = "acpi")]
use acpi_tables::{aml, aml::Aml}; use acpi_tables::{aml, aml::Aml};
use arc_swap::ArcSwap;
use arch::layout; use arch::layout;
use arch::layout::{APIC_START, IOAPIC_SIZE, IOAPIC_START};
use devices::{ioapic, HotPlugNotificationType}; use devices::{ioapic, HotPlugNotificationType};
use kvm_bindings::kvm_irq_routing_entry; use kvm_bindings::kvm_irq_routing_entry;
use kvm_ioctls::*; use kvm_ioctls::*;
use libc::O_TMPFILE; use libc::O_TMPFILE;
use libc::TIOCGWINSZ; use libc::TIOCGWINSZ;
use net_util::Tap; use net_util::Tap;
#[cfg(feature = "pci_support")] #[cfg(feature = "pci_support")]
use pci::{ use pci::{
@ -30,20 +31,17 @@ use pci::{
PciConfigIo, PciConfigMmio, PciDevice, PciRoot, PciConfigIo, PciConfigMmio, PciDevice, PciRoot,
}; };
use qcow::{self, ImageType, QcowFile}; 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::cmp;
use std::collections::HashMap; 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::fs::OpenOptionsExt;
use std::os::unix::io::AsRawFd; use std::os::unix::io::AsRawFd;
use std::ptr::null_mut; use std::ptr::null_mut;
use std::result; use std::result;
#[cfg(feature = "pci_support")] #[cfg(feature = "pci_support")]
use std::sync::Weak; use std::sync::Weak;
use std::sync::{Arc, Mutex, RwLock}; use std::sync::{Arc, Mutex};
#[cfg(feature = "pci_support")] #[cfg(feature = "pci_support")]
use vfio::{VfioDevice, VfioDmaMapping, VfioPciDevice, VfioPciError}; use vfio::{VfioDevice, VfioDmaMapping, VfioPciDevice, VfioPciError};
use vm_allocator::SystemAllocator; use vm_allocator::SystemAllocator;
@ -741,7 +739,7 @@ impl DeviceManager {
{ {
// Add a CMOS emulated device // Add a CMOS emulated device
use vm_memory::GuestMemory; 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_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); 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)] #[allow(clippy::too_many_arguments)]
fn add_virtio_pci_device( fn add_virtio_pci_device(
virtio_device: Arc<Mutex<dyn vm_virtio::VirtioDevice>>, virtio_device: Arc<Mutex<dyn vm_virtio::VirtioDevice>>,
memory: &Arc<RwLock<GuestMemoryMmap>>, memory: &Arc<ArcSwap<GuestMemoryMmap>>,
address_manager: &Arc<AddressManager>, address_manager: &Arc<AddressManager>,
vm_fd: &Arc<VmFd>, vm_fd: &Arc<VmFd>,
pci: &mut PciBus, pci: &mut PciBus,
@ -1523,7 +1521,7 @@ impl DeviceManager {
#[cfg(feature = "mmio_support")] #[cfg(feature = "mmio_support")]
fn add_virtio_mmio_device( fn add_virtio_mmio_device(
virtio_device: Arc<Mutex<dyn vm_virtio::VirtioDevice>>, virtio_device: Arc<Mutex<dyn vm_virtio::VirtioDevice>>,
memory: &Arc<RwLock<GuestMemoryMmap>>, memory: &Arc<ArcSwap<GuestMemoryMmap>>,
address_manager: &Arc<AddressManager>, address_manager: &Arc<AddressManager>,
vm_fd: &Arc<VmFd>, vm_fd: &Arc<VmFd>,
interrupt_info: &InterruptInfo, interrupt_info: &InterruptInfo,

View File

@ -3,9 +3,9 @@
// SPDX-License-Identifier: Apache-2.0 // SPDX-License-Identifier: Apache-2.0
// //
extern crate arc_swap;
#[macro_use] #[macro_use]
extern crate lazy_static; extern crate lazy_static;
#[macro_use] #[macro_use]
extern crate log; extern crate log;
extern crate serde; extern crate serde;

View File

@ -3,12 +3,15 @@
// SPDX-License-Identifier: Apache-2.0 // SPDX-License-Identifier: Apache-2.0
// //
use arc_swap::ArcSwap;
use arch::RegionType; use arch::RegionType;
use kvm_bindings::kvm_userspace_memory_region;
use kvm_ioctls::*;
use std::fs::{File, OpenOptions}; use std::fs::{File, OpenOptions};
use std::io; use std::io;
use std::os::unix::io::FromRawFd; use std::os::unix::io::FromRawFd;
use std::path::PathBuf; use std::path::PathBuf;
use std::sync::{Arc, Mutex, RwLock}; use std::sync::{Arc, Mutex};
use vm_allocator::SystemAllocator; use vm_allocator::SystemAllocator;
use vm_memory::guest_memory::FileOffset; use vm_memory::guest_memory::FileOffset;
use vm_memory::{ use vm_memory::{
@ -16,11 +19,8 @@ use vm_memory::{
GuestUsize, GuestUsize,
}; };
use kvm_bindings::kvm_userspace_memory_region;
use kvm_ioctls::*;
pub struct MemoryManager { pub struct MemoryManager {
guest_memory: Arc<RwLock<GuestMemoryMmap>>, guest_memory: Arc<ArcSwap<GuestMemoryMmap>>,
next_kvm_memory_slot: u32, next_kvm_memory_slot: u32,
start_of_device_area: GuestAddress, start_of_device_area: GuestAddress,
end_of_device_area: GuestAddress, end_of_device_area: GuestAddress,
@ -131,11 +131,7 @@ impl MemoryManager {
mem_end.unchecked_add(1) mem_end.unchecked_add(1)
}; };
// Convert the guest memory into an Arc. The point being able to use it let guest_memory = Arc::new(ArcSwap::new(Arc::new(guest_memory)));
// 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 memory_manager = Arc::new(Mutex::new(MemoryManager { let memory_manager = Arc::new(Mutex::new(MemoryManager {
guest_memory: guest_memory.clone(), guest_memory: guest_memory.clone(),
@ -145,7 +141,7 @@ impl MemoryManager {
fd, fd,
})); }));
guest_memory.read().unwrap().with_regions(|_, region| { guest_memory.load().with_regions(|_, region| {
let _ = memory_manager.lock().unwrap().create_userspace_mapping( let _ = memory_manager.lock().unwrap().create_userspace_mapping(
region.start_addr().raw_value(), region.start_addr().raw_value(),
region.len() as u64, region.len() as u64,
@ -167,7 +163,7 @@ impl MemoryManager {
Ok(memory_manager) Ok(memory_manager)
} }
pub fn guest_memory(&self) -> Arc<RwLock<GuestMemoryMmap>> { pub fn guest_memory(&self) -> Arc<ArcSwap<GuestMemoryMmap>> {
self.guest_memory.clone() self.guest_memory.clone()
} }

View File

@ -29,19 +29,17 @@ use crate::cpu;
use crate::device_manager::{get_win_size, Console, DeviceManager, DeviceManagerError}; use crate::device_manager::{get_win_size, Console, DeviceManager, DeviceManagerError};
use crate::memory_manager::{get_host_cpu_phys_bits, Error as MemoryManagerError, MemoryManager}; use crate::memory_manager::{get_host_cpu_phys_bits, Error as MemoryManagerError, MemoryManager};
use anyhow::anyhow; use anyhow::anyhow;
use arc_swap::ArcSwap;
use arch::layout; use arch::layout;
use devices::{ioapic, HotPlugNotificationType}; use devices::{ioapic, HotPlugNotificationType};
use kvm_bindings::{kvm_enable_cap, kvm_userspace_memory_region, KVM_CAP_SPLIT_IRQCHIP}; use kvm_bindings::{kvm_enable_cap, kvm_userspace_memory_region, KVM_CAP_SPLIT_IRQCHIP};
use kvm_ioctls::*; use kvm_ioctls::*;
use linux_loader::cmdline::Cmdline; use linux_loader::cmdline::Cmdline;
use linux_loader::loader::KernelLoader; use linux_loader::loader::KernelLoader;
use signal_hook::{iterator::Signals, SIGINT, SIGTERM, SIGWINCH}; use signal_hook::{iterator::Signals, SIGINT, SIGTERM, SIGWINCH};
use std::ffi::CString; use std::ffi::CString;
use std::fs::File; use std::fs::File;
use std::io; use std::io;
use std::ops::Deref;
use std::sync::{Arc, Mutex, RwLock}; use std::sync::{Arc, Mutex, RwLock};
use std::{result, str, thread}; use std::{result, str, thread};
use vm_allocator::{GsiApic, SystemAllocator}; use vm_allocator::{GsiApic, SystemAllocator};
@ -159,7 +157,7 @@ pub enum Error {
pub type Result<T> = result::Result<T, Error>; pub type Result<T> = result::Result<T, Error>;
pub struct VmInfo<'a> { pub struct VmInfo<'a> {
pub memory: &'a Arc<RwLock<GuestMemoryMmap>>, pub memory: &'a Arc<ArcSwap<GuestMemoryMmap>>,
pub vm_fd: &'a Arc<VmFd>, pub vm_fd: &'a Arc<VmFd>,
pub vm_cfg: Arc<Mutex<VmConfig>>, pub vm_cfg: Arc<Mutex<VmConfig>>,
} }
@ -371,9 +369,9 @@ impl Vm {
let cmdline_cstring = CString::new(cmdline).map_err(|_| Error::CmdLine)?; let cmdline_cstring = CString::new(cmdline).map_err(|_| Error::CmdLine)?;
let guest_memory = self.memory_manager.lock().as_ref().unwrap().guest_memory(); 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( let entry_addr = match linux_loader::loader::Elf::load(
mem.deref(), mem.as_ref(),
None, None,
&mut self.kernel, &mut self.kernel,
Some(arch::layout::HIGH_RAM_START), Some(arch::layout::HIGH_RAM_START),
@ -381,7 +379,7 @@ impl Vm {
Ok(entry_addr) => entry_addr, Ok(entry_addr) => entry_addr,
Err(linux_loader::loader::Error::InvalidElfMagicNumber) => { Err(linux_loader::loader::Error::InvalidElfMagicNumber) => {
linux_loader::loader::BzImage::load( linux_loader::loader::BzImage::load(
mem.deref(), mem.as_ref(),
None, None,
&mut self.kernel, &mut self.kernel,
Some(arch::layout::HIGH_RAM_START), Some(arch::layout::HIGH_RAM_START),
@ -392,7 +390,7 @@ impl Vm {
}; };
linux_loader::loader::load_cmdline( linux_loader::loader::load_cmdline(
mem.deref(), mem.as_ref(),
arch::layout::CMDLINE_START, arch::layout::CMDLINE_START,
&cmdline_cstring, &cmdline_cstring,
) )