devices: make PCI work in --disable-sandbox mode

Make the Minijail part of the PCI device tuple optional so that an empty
jail is not created for --disable-sandbox.

BUG=None
TEST=Boot crosvm in both --multiprocess and --disable-sandbox modes

Change-Id: Ibb3f2dbf33ca19910ee7448ea823b2772e09ecc5
Signed-off-by: Daniel Verkamp <dverkamp@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/1290289
Reviewed-by: Dylan Reid <dgreid@chromium.org>
This commit is contained in:
Daniel Verkamp 2018-10-18 16:45:13 -07:00 committed by chrome-bot
parent f02fdd1f66
commit 8eceba31c0
6 changed files with 25 additions and 24 deletions

View file

@ -194,7 +194,8 @@ pub struct AArch64;
impl arch::LinuxArch for AArch64 {
fn build_vm<F>(mut components: VmComponents, virtio_devs: F) -> Result<RunnableLinuxVm>
where
F: FnOnce(&GuestMemory, &EventFd) -> Result<Vec<(Box<PciDevice + 'static>, Minijail)>>,
F: FnOnce(&GuestMemory, &EventFd)
-> Result<Vec<(Box<PciDevice + 'static>, Option<Minijail>)>>,
{
let mut resources =
Self::get_resource_allocator(components.memory_mb, components.wayland_dmabuf);

View file

@ -18,7 +18,8 @@ use std::sync::{Arc, Mutex};
use devices::virtio::VirtioDevice;
use devices::{
Bus, BusError, PciDevice, PciDeviceError, PciInterruptPin, PciRoot, ProxyDevice, Serial,
Bus, BusDevice, BusError, PciDevice, PciDeviceError, PciInterruptPin, PciRoot, ProxyDevice,
Serial,
};
use io_jail::Minijail;
use kvm::{Datamatch, IoeventAddress, Kvm, Vcpu, Vm};
@ -67,7 +68,8 @@ pub trait LinuxArch {
/// * `virtio_devs` - Function to generate a list of virtio devices.
fn build_vm<F>(components: VmComponents, virtio_devs: F) -> Result<RunnableLinuxVm>
where
F: FnOnce(&GuestMemory, &EventFd) -> Result<Vec<(Box<PciDevice + 'static>, Minijail)>>;
F: FnOnce(&GuestMemory, &EventFd)
-> Result<Vec<(Box<PciDevice + 'static>, Option<Minijail>)>>;
}
/// Errors for device manager.
@ -135,7 +137,7 @@ impl fmt::Display for DeviceRegistrationError {
/// Creates a root PCI device for use by this Vm.
pub fn generate_pci_root(
devices: Vec<(Box<PciDevice + 'static>, Minijail)>,
devices: Vec<(Box<PciDevice + 'static>, Option<Minijail>)>,
mmio_bus: &mut Bus,
resources: &mut SystemAllocator,
vm: &mut Vm,
@ -172,9 +174,13 @@ pub fn generate_pci_root(
.map_err(DeviceRegistrationError::RegisterIoevent)?;
keep_fds.push(event.as_raw_fd());
}
let proxy = ProxyDevice::new(device, &jail, keep_fds)
.map_err(DeviceRegistrationError::ProxyDeviceCreation)?;
let arced_dev = Arc::new(Mutex::new(proxy));
let arced_dev: Arc<Mutex<BusDevice>> = if let Some(jail) = jail {
let proxy = ProxyDevice::new(device, &jail, keep_fds)
.map_err(DeviceRegistrationError::ProxyDeviceCreation)?;
Arc::new(Mutex::new(proxy))
} else {
Arc::new(Mutex::new(device))
};
root.add_device(arced_dev.clone());
for range in &ranges {
mmio_bus

View file

@ -8,7 +8,6 @@ use std::sync::{Arc, Mutex};
use byteorder::{ByteOrder, LittleEndian};
use BusDevice;
use ProxyDevice;
use pci::pci_configuration::{PciBridgeSubclass, PciClassCode, PciConfiguration, PciHeaderType};
use pci::pci_device::PciDevice;
@ -40,7 +39,7 @@ pub struct PciRoot {
/// Bus configuration for the root device.
root_configuration: PciRootConfiguration,
/// Devices attached to this bridge.
devices: Vec<Arc<Mutex<ProxyDevice>>>,
devices: Vec<Arc<Mutex<BusDevice>>>,
}
impl PciRoot {
@ -64,7 +63,7 @@ impl PciRoot {
}
/// Add a `device` to this root PCI bus.
pub fn add_device(&mut self, device: Arc<Mutex<ProxyDevice>>) {
pub fn add_device(&mut self, device: Arc<Mutex<BusDevice>>) {
self.devices.push(device);
}

View file

@ -198,8 +198,10 @@ impl ProxyDevice {
.map(|_| ())
.map_err(Error::Io)
}
}
pub fn config_register_write(&mut self, reg_idx: usize, offset: u64, data: &[u8]) {
impl BusDevice for ProxyDevice {
fn config_register_write(&mut self, reg_idx: usize, offset: u64, data: &[u8]) {
let res = self
.send_config_cmd(Command::WriteConfig, reg_idx as u32, offset, data)
.and_then(|_| self.wait());
@ -208,7 +210,7 @@ impl ProxyDevice {
}
}
pub fn config_register_read(&self, reg_idx: usize) -> u32 {
fn config_register_read(&self, reg_idx: usize) -> u32 {
let mut data = [0u8; 4];
let res = self
.send_config_cmd(Command::ReadConfig, reg_idx as u32, 0, &[])
@ -218,9 +220,7 @@ impl ProxyDevice {
}
LittleEndian::read_u32(&data)
}
}
impl BusDevice for ProxyDevice {
fn read(&mut self, offset: u64, data: &mut [u8]) {
let res = self
.send_cmd(Command::Read, offset, data.len() as u32, &[])

View file

@ -249,7 +249,7 @@ fn create_virtio_devs(
_exit_evt: &EventFd,
wayland_device_socket: UnixDatagram,
balloon_device_socket: UnixDatagram,
) -> std::result::Result<Vec<(Box<PciDevice + 'static>, Minijail)>, Box<error::Error>> {
) -> std::result::Result<Vec<(Box<PciDevice + 'static>, Option<Minijail>)>, Box<error::Error>> {
static DEFAULT_PIVOT_ROOT: &'static str = "/var/empty";
let mut devs = Vec::new();
@ -620,17 +620,11 @@ fn create_virtio_devs(
devs.push(VirtioDeviceStub { dev: p9_box, jail });
}
let mut pci_devices: Vec<(Box<PciDevice + 'static>, Minijail)> = Vec::new();
let mut pci_devices: Vec<(Box<PciDevice + 'static>, Option<Minijail>)> = Vec::new();
for stub in devs {
let pci_dev =
Box::new(VirtioPciDevice::new((*mem).clone(), stub.dev).map_err(Error::VirtioPciDev)?);
// TODO(dverkamp): Make this work in non-multiprocess mode without creating an empty jail
let jail = match stub.jail {
Some(j) => j,
None => Minijail::new().unwrap(),
};
pci_devices.push((pci_dev, jail));
pci_devices.push((pci_dev, stub.jail));
}
Ok(pci_devices)

View file

@ -263,7 +263,8 @@ fn arch_memory_regions(size: u64) -> Vec<(GuestAddress, u64)> {
impl arch::LinuxArch for X8664arch {
fn build_vm<F>(mut components: VmComponents, virtio_devs: F) -> Result<RunnableLinuxVm>
where
F: FnOnce(&GuestMemory, &EventFd) -> Result<Vec<(Box<PciDevice + 'static>, Minijail)>>,
F: FnOnce(&GuestMemory, &EventFd)
-> Result<Vec<(Box<PciDevice + 'static>, Option<Minijail>)>>,
{
let mut resources =
Self::get_resource_allocator(components.memory_mb, components.wayland_dmabuf);