devices: add "usb" feature for emulated xHCI
Add a default-enabled "usb" feature to allow compiling out the emulated
USB controller and host device provider when not needed (e.g. for
crosvm-direct).
This reduces the crosvm-direct binary size by about 400 KiB.
BUG=b:173824333
TEST=cargo build --no-default-features
TEST=cargo build # ensure xhci controller is added
Change-Id: I1fc0eeb09c647854e5df57cd2fe7e92140256853
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/crosvm/+/2913136
Tested-by: kokoro <noreply+kokoro@google.com>
Reviewed-by: Tomasz Jeznach <tjeznach@chromium.org>
Reviewed-by: Dylan Reid <dgreid@chromium.org>
Commit-Queue: Daniel Verkamp <dverkamp@chromium.org>
diff --git a/src/linux.rs b/src/linux.rs
index 337af2f..28b2119 100644
--- a/src/linux.rs
+++ b/src/linux.rs
@@ -43,9 +43,11 @@
#[cfg(feature = "audio")]
use devices::Ac97Dev;
use devices::{
- self, HostBackendDeviceProvider, IrqChip, IrqEventIndex, KvmKernelIrqChip, PciDevice,
- VcpuRunState, VfioContainer, VfioDevice, VfioPciDevice, VirtioPciDevice, XhciController,
+ self, IrqChip, IrqEventIndex, KvmKernelIrqChip, PciDevice, VcpuRunState, VfioContainer,
+ VfioDevice, VfioPciDevice, VirtioPciDevice,
};
+#[cfg(feature = "usb")]
+use devices::{HostBackendDeviceProvider, XhciController};
use hypervisor::kvm::{Kvm, KvmVcpu, KvmVm};
use hypervisor::{HypervisorCap, Vcpu, VcpuExit, VcpuRunHandle, Vm, VmCap};
use minijail::{self, Minijail};
@@ -114,6 +116,7 @@
CreateTimer(base::Error),
CreateTpmStorage(PathBuf, io::Error),
CreateTube(TubeError),
+ #[cfg(feature = "usb")]
CreateUsbProvider(devices::usb::host_backend::error::Error),
CreateVcpu(base::Error),
CreateVfioDevice(devices::vfio::VfioError),
@@ -238,6 +241,7 @@
write!(f, "failed to create tpm storage dir {}: {}", p.display(), e)
}
CreateTube(e) => write!(f, "failed to create tube: {}", e),
+ #[cfg(feature = "usb")]
CreateUsbProvider(e) => write!(f, "failed to create usb provider: {}", e),
CreateVcpu(e) => write!(f, "failed to create vcpu: {}", e),
CreateVfioDevice(e) => write!(f, "Failed to create vfio device {}", e),
@@ -1678,7 +1682,7 @@
disk_device_tubes: &mut Vec<Tube>,
pmem_device_tubes: &mut Vec<Tube>,
fs_device_tubes: &mut Vec<Tube>,
- usb_provider: HostBackendDeviceProvider,
+ #[cfg(feature = "usb")] usb_provider: HostBackendDeviceProvider,
map_request: Arc<Mutex<Option<ExternalMapping>>>,
) -> DeviceResult<Vec<(Box<dyn PciDevice>, Option<Minijail>)>> {
let stubs = create_virtio_devices(
@@ -1714,9 +1718,12 @@
pci_devices.push((Box::new(dev), jail));
}
- // Create xhci controller.
- let usb_controller = Box::new(XhciController::new(vm.get_memory().clone(), usb_provider));
- pci_devices.push((usb_controller, simple_jail(&cfg, "xhci")?));
+ #[cfg(feature = "usb")]
+ {
+ // Create xhci controller.
+ let usb_controller = Box::new(XhciController::new(vm.get_memory().clone(), usb_provider));
+ pci_devices.push((usb_controller, simple_jail(&cfg, "xhci")?));
+ }
if !cfg.vfio.is_empty() {
let vfio_container = Arc::new(Mutex::new(
@@ -2446,8 +2453,10 @@
info!("crosvm entering multiprocess mode");
}
+ #[cfg(feature = "usb")]
let (usb_control_tube, usb_provider) =
HostBackendDeviceProvider::new().map_err(Error::CreateUsbProvider)?;
+
// Masking signals is inherently dangerous, since this can persist across clones/execs. Do this
// before any jailed devices have been spawned, so that we can catch any of them that fail very
// quickly.
@@ -2559,6 +2568,7 @@
&mut disk_device_tubes,
&mut pmem_device_tubes,
&mut fs_device_tubes,
+ #[cfg(feature = "usb")]
usb_provider,
Arc::clone(&map_request),
)?;
@@ -2631,6 +2641,7 @@
control_tubes,
balloon_host_tube,
&disk_host_tubes,
+ #[cfg(feature = "usb")]
usb_control_tube,
exit_evt,
sigchld_fd,
@@ -2830,7 +2841,7 @@
mut control_tubes: Vec<TaggedControlTube>,
balloon_host_tube: Tube,
disk_host_tubes: &[Tube],
- usb_control_tube: Tube,
+ #[cfg(feature = "usb")] usb_control_tube: Tube,
exit_evt: Event,
sigchld_fd: SignalFd,
sandbox: bool,
@@ -3109,7 +3120,10 @@
&mut run_mode_opt,
&balloon_host_tube,
disk_host_tubes,
- &usb_control_tube,
+ #[cfg(feature = "usb")]
+ Some(&usb_control_tube),
+ #[cfg(not(feature = "usb"))]
+ None,
&mut linux.bat_control,
);
if let Err(e) = tube.send(&response) {