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

View file

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

View file

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

View file

@ -249,7 +249,7 @@ fn create_virtio_devs(
_exit_evt: &EventFd, _exit_evt: &EventFd,
wayland_device_socket: UnixDatagram, wayland_device_socket: UnixDatagram,
balloon_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"; static DEFAULT_PIVOT_ROOT: &'static str = "/var/empty";
let mut devs = Vec::new(); let mut devs = Vec::new();
@ -620,17 +620,11 @@ fn create_virtio_devs(
devs.push(VirtioDeviceStub { dev: p9_box, jail }); 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 { for stub in devs {
let pci_dev = let pci_dev =
Box::new(VirtioPciDevice::new((*mem).clone(), stub.dev).map_err(Error::VirtioPciDev)?); Box::new(VirtioPciDevice::new((*mem).clone(), stub.dev).map_err(Error::VirtioPciDev)?);
pci_devices.push((pci_dev, stub.jail));
// 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));
} }
Ok(pci_devices) Ok(pci_devices)

View file

@ -263,7 +263,8 @@ fn arch_memory_regions(size: u64) -> Vec<(GuestAddress, u64)> {
impl arch::LinuxArch for X8664arch { impl arch::LinuxArch for X8664arch {
fn build_vm<F>(mut components: VmComponents, virtio_devs: F) -> Result<RunnableLinuxVm> fn build_vm<F>(mut components: VmComponents, virtio_devs: F) -> Result<RunnableLinuxVm>
where 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 = let mut resources =
Self::get_resource_allocator(components.memory_mb, components.wayland_dmabuf); Self::get_resource_allocator(components.memory_mb, components.wayland_dmabuf);