aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDevin Moore <devinmoore@google.com>2023-04-10 23:51:43 +0000
committerAutomerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>2023-04-10 23:51:43 +0000
commitcfcaf8cb174be1174ffca9e3ab5d5c63a62b86d1 (patch)
tree4f3348034ce8537d526fbafd31c9b83c3cb7251b
parent808bedf1e3d4324677c4d4bdd36e18c4bdad4d26 (diff)
parent305ce947f18364eaa808c3c8b7b51699f634227f (diff)
downloadcrosvm-cfcaf8cb174be1174ffca9e3ab5d5c63a62b86d1.tar.gz
Merge remote-tracking branch 'aosp/upstream-main' into merge am: 65b6ac2808 am: e85a740582 am: e4ef6c8d1b am: 305ce947f1
Original change: https://android-review.googlesource.com/c/platform/external/crosvm/+/2529483 Change-Id: I481f140938d8966e0c716b0365d51604b0e053d7 Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
-rw-r--r--base/src/custom_serde.rs23
-rw-r--r--common/balloon_control/src/lib.rs3
-rw-r--r--crosvm_control/src/lib.rs7
-rw-r--r--devices/src/cmos.rs19
-rw-r--r--devices/src/pci/pci_configuration.rs39
-rw-r--r--devices/src/virtio/balloon.rs47
-rw-r--r--devices/src/virtio/gpu/mod.rs12
-rw-r--r--devices/src/virtio/gpu/parameters.rs38
-rw-r--r--devices/src/virtio/net.rs25
-rw-r--r--rutabaga_gfx/ffi/Makefile3
-rw-r--r--rutabaga_gfx/ffi/src/.clang-format6
-rw-r--r--rutabaga_gfx/ffi/src/include/rutabaga_gfx_ffi.h122
-rw-r--r--rutabaga_gfx/ffi/src/tests/rutabaga_test.c581
-rw-r--r--rutabaga_gfx/src/cross_domain/cross_domain.rs6
-rw-r--r--rutabaga_gfx/src/gfxstream.rs4
-rw-r--r--rutabaga_gfx/src/lib.rs4
-rw-r--r--rutabaga_gfx/src/rutabaga_2d.rs2
-rw-r--r--rutabaga_gfx/src/rutabaga_core.rs28
-rw-r--r--rutabaga_gfx/src/rutabaga_utils.rs1
-rw-r--r--rutabaga_gfx/src/virgl_renderer.rs8
-rw-r--r--src/crosvm/cmdline.rs92
-rw-r--r--src/crosvm/config.rs18
-rw-r--r--src/crosvm/gpu_config.rs2
-rw-r--r--src/crosvm/plugin/mod.rs50
-rw-r--r--src/crosvm/sys/unix.rs44
-rw-r--r--src/crosvm/sys/unix/config.rs14
26 files changed, 623 insertions, 575 deletions
diff --git a/base/src/custom_serde.rs b/base/src/custom_serde.rs
index 9d69d48b8..129392d50 100644
--- a/base/src/custom_serde.rs
+++ b/base/src/custom_serde.rs
@@ -7,6 +7,9 @@
use std::result::Result;
use std::sync::Arc;
+use serde::de::Error;
+use serde::Deserialize;
+use serde::Deserializer;
use serde::Serialize;
use serde::Serializer;
use sync::Mutex;
@@ -41,3 +44,23 @@ where
{
serde::Serialize::serialize(&data[..], serializer)
}
+
+/// Deserialize sequence of T into an Array of SIZE == Size of sequence.
+/// This function is a workaround to the serde limitation on array size (32) deserialization.
+pub fn deserialize_seq_to_arr<
+ 'de,
+ D,
+ T: Sized + Deserialize<'de> + std::fmt::Debug,
+ const SIZE: usize,
+>(
+ deserializer: D,
+) -> Result<[T; SIZE], D::Error>
+where
+ D: Deserializer<'de>,
+{
+ let vals_vec: Vec<T> = serde::Deserialize::deserialize(deserializer)?;
+ let vals_arr: [T; SIZE] = vals_vec.try_into().map_err(|_| {
+ <D as Deserializer>::Error::custom("failed to convert vector to array while deserializing")
+ })?;
+ Ok(vals_arr)
+}
diff --git a/common/balloon_control/src/lib.rs b/common/balloon_control/src/lib.rs
index ceae4e704..78ecef9c4 100644
--- a/common/balloon_control/src/lib.rs
+++ b/common/balloon_control/src/lib.rs
@@ -52,12 +52,13 @@ pub struct BalloonStats {
// TODO(b/276353613): remove and refactor bins into Vec
pub const VIRTIO_BALLOON_WSS_NUM_BINS: usize = 4;
+pub const VIRTIO_BALLOON_WSS_CONFIG_SIZE: usize = 5;
// WSSBucket stores information about a bucket (or bin) of the working set size.
#[derive(Default, Serialize, Deserialize, Debug, Clone, Copy)]
pub struct WSSBucket {
pub age: u64,
- pub bytes: u64,
+ pub bytes: [u64; 2],
}
// BalloonWSS holds WSS returned from the wss_queue.
diff --git a/crosvm_control/src/lib.rs b/crosvm_control/src/lib.rs
index a1e0e9864..ba8b12f47 100644
--- a/crosvm_control/src/lib.rs
+++ b/crosvm_control/src/lib.rs
@@ -448,12 +448,15 @@ pub extern "C" fn crosvm_client_balloon_stats(
#[repr(C)]
pub struct WSSBucketFfi {
age: u64,
- bytes: u64,
+ bytes: [u64; 2],
}
impl WSSBucketFfi {
fn new() -> Self {
- Self { age: 0, bytes: 0 }
+ Self {
+ age: 0,
+ bytes: [0, 0],
+ }
}
}
diff --git a/devices/src/cmos.rs b/devices/src/cmos.rs
index 58360f688..3bfa778b4 100644
--- a/devices/src/cmos.rs
+++ b/devices/src/cmos.rs
@@ -8,6 +8,8 @@ use std::time::Duration;
use anyhow::anyhow;
use anyhow::Context;
+use base::custom_serde::deserialize_seq_to_arr;
+use base::custom_serde::serialize_arr;
use base::error;
use base::Event;
use base::EventToken;
@@ -22,7 +24,6 @@ use chrono::Timelike;
use chrono::Utc;
use serde::Deserialize;
use serde::Serialize;
-use serde::Serializer;
use sync::Mutex;
use vm_control::VmResponse;
@@ -85,14 +86,6 @@ pub struct Cmos {
worker: Option<WorkerThread<AlarmFn>>,
}
-fn serialize_arr<S>(data: &[u8; DATA_LEN], serializer: S) -> Result<S::Ok, S::Error>
-where
- S: Serializer,
-{
- let vec = data.to_vec();
- serde::Serialize::serialize(&vec, serializer)
-}
-
struct AlarmFn {
irq: IrqEdgeEvent,
vm_control: Tube,
@@ -386,16 +379,14 @@ impl Suspendable for Cmos {
#[derive(Deserialize)]
struct CmosIndex {
index: u8,
- data: Vec<u8>,
+ #[serde(deserialize_with = "deserialize_seq_to_arr")]
+ data: [u8; DATA_LEN],
}
let deser: CmosIndex =
serde_json::from_value(data).context("failed to deserialize Cmos")?;
self.index = deser.index;
- self.data = deser
- .data
- .try_into()
- .map_err(|_| anyhow!("invalid cmos data"))?;
+ self.data = deser.data;
self.set_alarm();
Ok(())
diff --git a/devices/src/pci/pci_configuration.rs b/devices/src/pci/pci_configuration.rs
index 69c4fd5ce..b9dbfc6e3 100644
--- a/devices/src/pci/pci_configuration.rs
+++ b/devices/src/pci/pci_configuration.rs
@@ -5,8 +5,8 @@
use std::convert::TryFrom;
use std::convert::TryInto;
-use anyhow::anyhow;
use anyhow::Context;
+use base::custom_serde::deserialize_seq_to_arr;
use base::custom_serde::serialize_arr;
use base::warn;
use remain::sorted;
@@ -245,11 +245,17 @@ pub trait PciCapability {
/// Contains the configuration space of a PCI node.
/// See the [specification](https://en.wikipedia.org/wiki/PCI_configuration_space).
/// The configuration space is accessed with DWORD reads and writes from the guest.
-#[derive(Serialize)]
+#[derive(Serialize, Deserialize)]
pub struct PciConfiguration {
- #[serde(serialize_with = "serialize_arr")]
+ #[serde(
+ serialize_with = "serialize_arr",
+ deserialize_with = "deserialize_seq_to_arr"
+ )]
registers: [u32; NUM_CONFIGURATION_REGISTERS],
- #[serde(serialize_with = "serialize_arr")]
+ #[serde(
+ serialize_with = "serialize_arr",
+ deserialize_with = "deserialize_seq_to_arr"
+ )]
writable_bits: [u32; NUM_CONFIGURATION_REGISTERS], // writable bits for each register.
bar_used: [bool; NUM_BAR_REGS],
bar_configs: [Option<PciBarConfiguration>; NUM_BAR_REGS],
@@ -674,30 +680,9 @@ impl PciConfiguration {
}
pub fn restore(&mut self, data: serde_json::Value) -> anyhow::Result<()> {
- // Due to serde's limitation on array size, we're transforming the array to a slice for
- // deserialization.
- #[derive(Deserialize)]
- pub struct PciConfigSerializable {
- registers: Vec<u32>,
- writable_bits: Vec<u32>,
- bar_used: [bool; NUM_BAR_REGS],
- bar_configs: [Option<PciBarConfiguration>; NUM_BAR_REGS],
- last_capability: Option<(usize, usize)>,
- }
-
- let deser: PciConfigSerializable =
+ let deser: PciConfiguration =
serde_json::from_value(data).context("failed to deserialize PciConfiguration")?;
- self.registers = deser
- .registers
- .try_into()
- .map_err(|_| anyhow!("invalid registers"))?;
- self.writable_bits = deser
- .writable_bits
- .try_into()
- .map_err(|_| anyhow!("invalid registers"))?;
- self.bar_used = deser.bar_used;
- self.bar_configs = deser.bar_configs;
- self.last_capability = deser.last_capability;
+ *self = deser;
Ok(())
}
}
diff --git a/devices/src/virtio/balloon.rs b/devices/src/virtio/balloon.rs
index 71d2d72ac..31c44277f 100644
--- a/devices/src/virtio/balloon.rs
+++ b/devices/src/virtio/balloon.rs
@@ -13,6 +13,7 @@ use balloon_control::BalloonStats;
use balloon_control::BalloonTubeCommand;
use balloon_control::BalloonTubeResult;
use balloon_control::BalloonWSS;
+use balloon_control::VIRTIO_BALLOON_WSS_CONFIG_SIZE;
use balloon_control::VIRTIO_BALLOON_WSS_NUM_BINS;
use base::error;
use base::warn;
@@ -210,7 +211,8 @@ struct virtio_balloon_wss {
// https://crsrc.org/o/src/third_party/kernel/v5.15/include/uapi/linux/virtio_balloon.h;l=105
_reserved: [u8; 4],
idle_age_ms: Le64,
- memory_size_bytes: Le64,
+ // TODO(b/273973298): these should become separate fields - bytes for ANON and FILE
+ memory_size_bytes: [Le64; 2],
}
impl virtio_balloon_wss {
@@ -223,13 +225,14 @@ impl virtio_balloon_wss {
return;
}
wss.wss[index].age = self.idle_age_ms.to_native();
- wss.wss[index].bytes = self.memory_size_bytes.to_native();
+ wss.wss[index].bytes[0] = self.memory_size_bytes[0].to_native();
+ wss.wss[index].bytes[1] = self.memory_size_bytes[1].to_native();
}
}
const _VIRTIO_BALLOON_WSS_OP_INVALID: u16 = 0;
const VIRTIO_BALLOON_WSS_OP_REQUEST: u16 = 1;
-const VIRTIO_BALLOON_WSS_OP_INTERVALS: u16 = 2;
+const VIRTIO_BALLOON_WSS_OP_CONFIG: u16 = 2;
const _VIRTIO_BALLOON_WSS_OP_DISCARD: u16 = 3;
// virtio_balloon_op is used to serialize to the wss cmd vq.
@@ -585,9 +588,9 @@ async fn handle_wss_queue(
interrupt: Interrupt,
) -> Result<()> {
if let Err(e) =
- send_initial_wss_intervals(mem, &mut queue, &mut queue_event, interrupt.clone()).await
+ send_initial_wss_config(mem, &mut queue, &mut queue_event, interrupt.clone()).await
{
- error!("unable to send initial WSS intervals to guest: {}", e);
+ error!("unable to send initial WSS config to guest: {}", e);
}
loop {
@@ -728,24 +731,29 @@ async fn handle_wss_data_queue(
}
}
-async fn send_wss_intervals(
+async fn send_wss_config(
writer: &mut Writer,
- intervals: [u64; VIRTIO_BALLOON_WSS_NUM_BINS],
-) -> Result<usize> {
+ config: [u64; VIRTIO_BALLOON_WSS_CONFIG_SIZE],
+ queue: &mut Queue,
+ mem: &GuestMemory,
+ index: u16,
+ interrupt: Interrupt,
+) -> Result<()> {
let cmd = virtio_balloon_op {
- type_: VIRTIO_BALLOON_WSS_OP_INTERVALS.into(),
+ type_: VIRTIO_BALLOON_WSS_OP_CONFIG.into(),
};
writer.write_obj(cmd).map_err(BalloonError::WriteQueue)?;
- writer
- .write_obj(intervals)
- .map_err(BalloonError::WriteQueue)?;
+ writer.write_obj(config).map_err(BalloonError::WriteQueue)?;
+
+ queue.add_used(mem, index, writer.bytes_written() as u32);
+ queue.trigger_interrupt(mem, &interrupt);
- Ok(writer.bytes_written())
+ Ok(())
}
-async fn send_initial_wss_intervals(
+async fn send_initial_wss_config(
mem: &GuestMemory,
queue: &mut Queue,
queue_event: &mut EventAsync,
@@ -760,15 +768,10 @@ async fn send_initial_wss_intervals(
let mut writer = Writer::new(mem.clone(), avail_desc).map_err(BalloonError::Descriptor)?;
// NOTE: first VIRTIO_BALLOON_WSS_NUM_BINS - 1 values are the
- // interval boundaries, last value is the staleness_idx.
- let intervals: [u64; VIRTIO_BALLOON_WSS_NUM_BINS] = [1, 5, 10, 1];
-
- let bytes_written = send_wss_intervals(&mut writer, intervals).await?;
+ // interval boundaries, then refresh and reporting thresholds.
+ let config: [u64; VIRTIO_BALLOON_WSS_CONFIG_SIZE] = [1, 5, 10, 750, 1000];
- queue.add_used(mem, index, bytes_written as u32);
- queue.trigger_interrupt(mem, &interrupt);
-
- Ok(())
+ send_wss_config(&mut writer, config, queue, mem, index, interrupt).await
}
// Async task that handles the command socket. The command socket handles messages from the host
diff --git a/devices/src/virtio/gpu/mod.rs b/devices/src/virtio/gpu/mod.rs
index 49c1ea911..179f8b1d3 100644
--- a/devices/src/virtio/gpu/mod.rs
+++ b/devices/src/virtio/gpu/mod.rs
@@ -1074,7 +1074,7 @@ pub struct Gpu {
base_features: u64,
udmabuf: bool,
rutabaga_server_descriptor: Option<SafeDescriptor>,
- context_mask: u64,
+ capset_mask: u64,
#[cfg(unix)]
gpu_cgroup_path: Option<PathBuf>,
}
@@ -1127,7 +1127,7 @@ impl Gpu {
let use_render_server = rutabaga_server_descriptor.is_some();
- let rutabaga_builder = RutabagaBuilder::new(component, gpu_parameters.context_mask)
+ let rutabaga_builder = RutabagaBuilder::new(component, gpu_parameters.capset_mask)
.set_display_width(display_width)
.set_display_height(display_height)
.set_rutabaga_channels(rutabaga_channels_opt)
@@ -1166,7 +1166,7 @@ impl Gpu {
base_features,
udmabuf: gpu_parameters.udmabuf,
rutabaga_server_descriptor,
- context_mask: gpu_parameters.context_mask,
+ capset_mask: gpu_parameters.capset_mask,
#[cfg(unix)]
gpu_cgroup_path: gpu_cgroup_path.cloned(),
}
@@ -1207,7 +1207,7 @@ impl Gpu {
events_read |= VIRTIO_GPU_EVENT_DISPLAY;
}
- let num_capsets = match self.context_mask {
+ let num_capsets = match self.capset_mask {
0 => {
match self.rutabaga_component {
RutabagaComponentType::Rutabaga2D => 0,
@@ -1231,7 +1231,7 @@ impl Gpu {
}
}
}
- _ => self.context_mask.count_ones(),
+ _ => self.capset_mask.count_ones(),
};
virtio_gpu_config {
@@ -1310,7 +1310,7 @@ impl VirtioDevice for Gpu {
// If a non-2D component is specified, enable 3D features. It is possible to run display
// contexts without 3D backend (i.e, gfxstream / virglrender), so check for that too.
- if self.rutabaga_component != RutabagaComponentType::Rutabaga2D || self.context_mask != 0 {
+ if self.rutabaga_component != RutabagaComponentType::Rutabaga2D || self.capset_mask != 0 {
virtio_gpu_features |= 1 << VIRTIO_GPU_F_VIRGL
| 1 << VIRTIO_GPU_F_RESOURCE_UUID
| 1 << VIRTIO_GPU_F_RESOURCE_BLOB
diff --git a/devices/src/virtio/gpu/parameters.rs b/devices/src/virtio/gpu/parameters.rs
index 3158c9fab..bdb670429 100644
--- a/devices/src/virtio/gpu/parameters.rs
+++ b/devices/src/virtio/gpu/parameters.rs
@@ -17,14 +17,14 @@ use vm_control::gpu::DisplayParameters;
use super::GpuMode;
-mod serde_context_mask {
+mod serde_capset_mask {
use super::*;
- pub fn serialize<S>(context_mask: &u64, serializer: S) -> Result<S::Ok, S::Error>
+ pub fn serialize<S>(capset_mask: &u64, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
- let context_types = rutabaga_gfx::calculate_context_types(*context_mask).join(":");
+ let context_types = rutabaga_gfx::calculate_capset_names(*capset_mask).join(":");
serializer.serialize_str(context_types.as_str())
}
@@ -33,7 +33,7 @@ mod serde_context_mask {
let s = String::deserialize(deserializer)?;
let context_types: Vec<String> = s.split(':').map(|s| s.to_string()).collect();
- Ok(rutabaga_gfx::calculate_context_mask(context_types))
+ Ok(rutabaga_gfx::calculate_capset_mask(context_types))
}
}
@@ -73,8 +73,8 @@ pub struct GpuParameters {
pub cache_path: Option<String>,
pub cache_size: Option<String>,
pub pci_bar_size: u64,
- #[serde(rename = "context-types", with = "serde_context_mask")]
- pub context_mask: u64,
+ #[serde(rename = "context-types", with = "serde_capset_mask")]
+ pub capset_mask: u64,
}
impl Default for GpuParameters {
@@ -98,7 +98,7 @@ impl Default for GpuParameters {
cache_size: None,
pci_bar_size: (1 << 33),
udmabuf: false,
- context_mask: 0,
+ capset_mask: 0,
}
}
}
@@ -110,26 +110,24 @@ mod tests {
use super::*;
#[test]
- fn context_mask_serialize_deserialize() {
+ fn capset_mask_serialize_deserialize() {
#[derive(Debug, Serialize, Deserialize, PartialEq, Eq)]
- struct ContextMask {
- #[serde(rename = "context-types", with = "serde_context_mask")]
+ struct CapsetMask {
+ #[serde(rename = "context-types", with = "serde_capset_mask")]
pub value: u64,
}
- // Capset "virgl", id: 1, context_mask: 0b0010
- // Capset "gfxstream", id: 3, context_mask: 0b1000
- const CONTEXT_MASK: u64 = 0b1010;
- const SERIALIZED_CONTEXT_MASK: &str = "{\"context-types\":\"virgl:gfxstream\"}";
+ // Capset "virgl", id: 1, capset_mask: 0b0010
+ // Capset "gfxstream", id: 3, capset_mask: 0b1000
+ const CAPSET_MASK: u64 = 0b1010;
+ const SERIALIZED_CAPSET_MASK: &str = "{\"context-types\":\"virgl:gfxstream\"}";
- let context_mask = ContextMask {
- value: CONTEXT_MASK,
- };
+ let capset_mask = CapsetMask { value: CAPSET_MASK };
- assert_eq!(to_string(&context_mask).unwrap(), SERIALIZED_CONTEXT_MASK);
+ assert_eq!(to_string(&capset_mask).unwrap(), SERIALIZED_CAPSET_MASK);
assert_eq!(
- from_str::<ContextMask>(SERIALIZED_CONTEXT_MASK).unwrap(),
- context_mask
+ from_str::<CapsetMask>(SERIALIZED_CAPSET_MASK).unwrap(),
+ capset_mask
);
}
}
diff --git a/devices/src/virtio/net.rs b/devices/src/virtio/net.rs
index e42e1af74..b380e3d18 100644
--- a/devices/src/virtio/net.rs
+++ b/devices/src/virtio/net.rs
@@ -168,6 +168,7 @@ pub struct NetParameters {
pub mode: NetParametersMode,
#[serde(default)]
pub vhost_net: bool,
+ pub vq_pairs: Option<u16>,
}
impl FromStr for NetParameters {
@@ -790,6 +791,7 @@ mod tests {
params,
NetParameters {
vhost_net: false,
+ vq_pairs: None,
mode: NetParametersMode::TapName {
tap_name: "tap".to_string(),
mac: None
@@ -802,6 +804,7 @@ mod tests {
params,
NetParameters {
vhost_net: false,
+ vq_pairs: None,
mode: NetParametersMode::TapName {
tap_name: "tap".to_string(),
mac: Some(MacAddress::from_str("3d:70:eb:61:1a:91").unwrap())
@@ -814,6 +817,7 @@ mod tests {
params,
NetParameters {
vhost_net: false,
+ vq_pairs: None,
mode: NetParametersMode::TapFd {
tap_fd: 12,
mac: None
@@ -826,6 +830,7 @@ mod tests {
params,
NetParameters {
vhost_net: false,
+ vq_pairs: None,
mode: NetParametersMode::TapFd {
tap_fd: 12,
mac: Some(MacAddress::from_str("3d:70:eb:61:1a:91").unwrap())
@@ -841,6 +846,7 @@ mod tests {
params,
NetParameters {
vhost_net: false,
+ vq_pairs: None,
mode: NetParametersMode::RawConfig {
host_ip: Ipv4Addr::from_str("192.168.10.1").unwrap(),
netmask: Ipv4Addr::from_str("255.255.255.0").unwrap(),
@@ -860,6 +866,7 @@ mod tests {
params,
NetParameters {
vhost_net: true,
+ vq_pairs: None,
mode: NetParametersMode::RawConfig {
host_ip: Ipv4Addr::from_str("192.168.10.1").unwrap(),
netmask: Ipv4Addr::from_str("255.255.255.0").unwrap(),
@@ -873,6 +880,7 @@ mod tests {
params,
NetParameters {
vhost_net: true,
+ vq_pairs: None,
mode: NetParametersMode::TapFd {
tap_fd: 3,
mac: None
@@ -885,6 +893,21 @@ mod tests {
params,
NetParameters {
vhost_net: false,
+ vq_pairs: None,
+ mode: NetParametersMode::TapFd {
+ tap_fd: 4,
+ mac: Some(MacAddress::from_str("3d:70:eb:61:1a:91").unwrap())
+ }
+ }
+ );
+
+ let params =
+ from_net_arg("tap-fd=4,vhost-net=false,mac=\"3d:70:eb:61:1a:91\",vq-pairs=16").unwrap();
+ assert_eq!(
+ params,
+ NetParameters {
+ vhost_net: false,
+ vq_pairs: Some(16),
mode: NetParametersMode::TapFd {
tap_fd: 4,
mac: Some(MacAddress::from_str("3d:70:eb:61:1a:91").unwrap())
@@ -897,6 +920,7 @@ mod tests {
params,
NetParameters {
vhost_net: true,
+ vq_pairs: None,
mode: NetParametersMode::TapName {
tap_name: "crosvm_tap".to_owned(),
mac: None
@@ -910,6 +934,7 @@ mod tests {
params,
NetParameters {
vhost_net: true,
+ vq_pairs: None,
mode: NetParametersMode::TapName {
tap_name: "crosvm_tap".to_owned(),
mac: Some(MacAddress::from_str("3d:70:eb:61:1a:91").unwrap())
diff --git a/rutabaga_gfx/ffi/Makefile b/rutabaga_gfx/ffi/Makefile
index 85fde5bc8..f4e575862 100644
--- a/rutabaga_gfx/ffi/Makefile
+++ b/rutabaga_gfx/ffi/Makefile
@@ -4,7 +4,7 @@
prefix ?= /usr/local
libdir = ${prefix}/lib
-includedir = ${prefix}/include
+includedir = ${prefix}/include/rutabaga_gfx
ifdef debug
release :=
@@ -29,7 +29,6 @@ build:
cargo build --features=gfxstream $(release)
install: build
- mkdir -p $(DESTDIR)$(prefix)
install -D -m 755 $(OUT)/$(LIB_NAME) $(DESTDIR)$(libdir)
ln -sf $(DESTDIR)$(prefix)/$(LIB_NAME) $(DESTDIR)$(libdir)/$(LIB_NAME).$(RUTABAGA_VERSION)
ln -sf $(DESTDIR)$(prefix)/$(LIB_NAME) $(DESTDIR)$(libdir)/$(LIB_NAME).$(RUTABAGA_VERSION_MAJOR)
diff --git a/rutabaga_gfx/ffi/src/.clang-format b/rutabaga_gfx/ffi/src/.clang-format
index 37a48b02d..05120f017 100644
--- a/rutabaga_gfx/ffi/src/.clang-format
+++ b/rutabaga_gfx/ffi/src/.clang-format
@@ -8,8 +8,8 @@ AllowShortIfStatementsOnASingleLine: false
AllowShortLoopsOnASingleLine: false
BreakBeforeBraces: Linux
ColumnLimit: 100
-IndentWidth: 8
-TabWidth: 8
-UseTab: Always
+IndentWidth: 4
+TabWidth: 4
+UseTab: Never
Cpp11BracedListStyle: false
IndentCaseLabels: false
diff --git a/rutabaga_gfx/ffi/src/include/rutabaga_gfx_ffi.h b/rutabaga_gfx/ffi/src/include/rutabaga_gfx_ffi.h
index 9b2d1ce59..d06d2981c 100644
--- a/rutabaga_gfx/ffi/src/include/rutabaga_gfx_ffi.h
+++ b/rutabaga_gfx/ffi/src/include/rutabaga_gfx_ffi.h
@@ -11,8 +11,8 @@
#if defined(__WIN32__)
struct iovec {
- void *iov_base; /* Starting address */
- size_t iov_len; /* Length in bytes */
+ void *iov_base; /* Starting address */
+ size_t iov_len; /* Length in bytes */
};
#else
#include <sys/uio.h>
@@ -86,53 +86,53 @@ extern "C" {
struct rutabaga;
struct rutabaga_fence {
- uint32_t flags;
- uint64_t fence_id;
- uint32_t ctx_id;
- uint32_t ring_idx;
+ uint32_t flags;
+ uint64_t fence_id;
+ uint32_t ctx_id;
+ uint32_t ring_idx;
};
struct rutabaga_create_blob {
- uint32_t blob_mem;
- uint32_t blob_flags;
- uint64_t blob_id;
- uint64_t size;
+ uint32_t blob_mem;
+ uint32_t blob_flags;
+ uint64_t blob_id;
+ uint64_t size;
};
struct rutabaga_create_3d {
- uint32_t target;
- uint32_t format;
- uint32_t bind;
- uint32_t width;
- uint32_t height;
- uint32_t depth;
- uint32_t array_size;
- uint32_t last_level;
- uint32_t nr_samples;
- uint32_t flags;
+ uint32_t target;
+ uint32_t format;
+ uint32_t bind;
+ uint32_t width;
+ uint32_t height;
+ uint32_t depth;
+ uint32_t array_size;
+ uint32_t last_level;
+ uint32_t nr_samples;
+ uint32_t flags;
};
struct rutabaga_transfer {
- uint32_t x;
- uint32_t y;
- uint32_t z;
- uint32_t w;
- uint32_t h;
- uint32_t d;
- uint32_t level;
- uint32_t stride;
- uint32_t layer_stride;
- uint64_t offset;
+ uint32_t x;
+ uint32_t y;
+ uint32_t z;
+ uint32_t w;
+ uint32_t h;
+ uint32_t d;
+ uint32_t level;
+ uint32_t stride;
+ uint32_t layer_stride;
+ uint64_t offset;
};
struct rutabaga_iovecs {
- struct iovec *iovecs;
- size_t num_iovecs;
+ struct iovec *iovecs;
+ size_t num_iovecs;
};
struct rutabaga_handle {
- int64_t os_handle;
- uint32_t handle_type;
+ int64_t os_handle;
+ uint32_t handle_type;
};
struct rutabaga_mapping {
@@ -144,13 +144,13 @@ struct rutabaga_mapping {
* Assumes null-terminated C-string.
*/
struct rutabaga_channel {
- const char *channel_name;
- uint32_t channel_type;
+ const char *channel_name;
+ uint32_t channel_type;
};
struct rutabaga_channels {
- struct rutabaga_channel *channels;
- size_t num_channels;
+ struct rutabaga_channel *channels;
+ size_t num_channels;
};
/**
@@ -159,13 +159,13 @@ struct rutabaga_channels {
typedef void (*write_fence_cb)(uint64_t user_data, struct rutabaga_fence fence_data);
struct rutabaga_builder {
- // Required for correct functioning
- uint64_t user_data;
- uint64_t capset_mask;
- write_fence_cb fence_cb;
+ // Required for correct functioning
+ uint64_t user_data;
+ uint64_t capset_mask;
+ write_fence_cb fence_cb;
- // Optional and platform specific
- struct rutabaga_channels *channels;
+ // Optional and platform specific
+ struct rutabaga_channels *channels;
};
/**
@@ -185,14 +185,14 @@ int32_t rutabaga_finish(struct rutabaga **ptr);
int32_t rutabaga_get_num_capsets(struct rutabaga *ptr, uint32_t *num_capsets);
int32_t rutabaga_get_capset_info(struct rutabaga *ptr, uint32_t capset_index, uint32_t *capset_id,
- uint32_t *capset_version, uint32_t *capset_size);
+ uint32_t *capset_version, uint32_t *capset_size);
/**
* # Safety
* - `capset` must point an array of bytes of size `capset_size`.
*/
int32_t rutabaga_get_capset(struct rutabaga *ptr, uint32_t capset_id, uint32_t version,
- uint8_t *capset, uint32_t capset_size);
+ uint8_t *capset, uint32_t capset_size);
/**
* # Safety
@@ -200,18 +200,18 @@ int32_t rutabaga_get_capset(struct rutabaga *ptr, uint32_t capset_id, uint32_t v
* `context_name_len` bytes encoding a UTF-8 string.
*/
int32_t rutabaga_context_create(struct rutabaga *ptr, uint32_t ctx_id, uint32_t context_init,
- const char *context_name, uint32_t context_name_len);
+ const char *context_name, uint32_t context_name_len);
int32_t rutabaga_context_destroy(struct rutabaga *ptr, uint32_t ctx_id);
int32_t rutabaga_context_attach_resource(struct rutabaga *ptr, uint32_t ctx_id,
- uint32_t resource_id);
+ uint32_t resource_id);
int32_t rutabaga_context_detach_resource(struct rutabaga *ptr, uint32_t ctx_id,
- uint32_t resource_id);
+ uint32_t resource_id);
int32_t rutabaga_resource_create_3d(struct rutabaga *ptr, uint32_t resource_id,
- const struct rutabaga_create_3d *create_3d);
+ const struct rutabaga_create_3d *create_3d);
/**
* # Safety
@@ -222,7 +222,7 @@ int32_t rutabaga_resource_create_3d(struct rutabaga *ptr, uint32_t resource_id,
* is unreferenced.
*/
int32_t rutabaga_resource_attach_backing(struct rutabaga *ptr, uint32_t resource_id,
- const struct rutabaga_iovecs *iovecs);
+ const struct rutabaga_iovecs *iovecs);
int32_t rutabaga_resource_detach_backing(struct rutabaga *ptr, uint32_t resource_id);
@@ -232,12 +232,12 @@ int32_t rutabaga_resource_detach_backing(struct rutabaga *ptr, uint32_t resource
* iovecs of size `(*iovecs).num_iovecs`.
*/
int32_t rutabaga_resource_transfer_read(struct rutabaga *ptr, uint32_t ctx_id, uint32_t resource_id,
- const struct rutabaga_transfer *transfer,
- const struct iovec *iovec);
+ const struct rutabaga_transfer *transfer,
+ const struct iovec *iovec);
int32_t rutabaga_resource_transfer_write(struct rutabaga *ptr, uint32_t ctx_id,
- uint32_t resource_id,
- const struct rutabaga_transfer *transfer);
+ uint32_t resource_id,
+ const struct rutabaga_transfer *transfer);
/**
* # Safety
@@ -249,9 +249,9 @@ int32_t rutabaga_resource_transfer_write(struct rutabaga *ptr, uint32_t ctx_id,
* is unreferenced.
*/
int32_t rutabaga_resource_create_blob(struct rutabaga *ptr, uint32_t ctx_id, uint32_t resource_id,
- const struct rutabaga_create_blob *rutabaga_create_blob,
- const struct rutabaga_iovecs *iovecs,
- const struct rutabaga_handle *handle);
+ const struct rutabaga_create_blob *rutabaga_create_blob,
+ const struct rutabaga_iovecs *iovecs,
+ const struct rutabaga_handle *handle);
int32_t rutabaga_resource_unref(struct rutabaga *ptr, uint32_t resource_id);
@@ -260,10 +260,10 @@ int32_t rutabaga_resource_unref(struct rutabaga *ptr, uint32_t resource_id);
* Caller owns raw descriptor on success and is responsible for closing it.
*/
int32_t rutabaga_resource_export_blob(struct rutabaga *ptr, uint32_t resource_id,
- struct rutabaga_handle *handle);
+ struct rutabaga_handle *handle);
int32_t rutabaga_resource_map(struct rutabaga *ptr, uint32_t resource_id,
- struct rutabaga_mapping *mapping);
+ struct rutabaga_mapping *mapping);
int32_t rutabaga_resource_unmap(struct rutabaga *ptr, uint32_t resource_id);
@@ -274,7 +274,7 @@ int32_t rutabaga_resource_map_info(struct rutabaga *ptr, uint32_t resource_id, u
* - `commands` must point to a contiguous memory region of `size` bytes.
*/
int32_t rutabaga_submit_command(struct rutabaga *ptr, uint32_t ctx_id, uint8_t *commands,
- size_t size);
+ size_t size);
int32_t rutabaga_create_fence(struct rutabaga *ptr, const struct rutabaga_fence *fence);
diff --git a/rutabaga_gfx/ffi/src/tests/rutabaga_test.c b/rutabaga_gfx/ffi/src/tests/rutabaga_test.c
index 0c7496e5b..fb3f7f483 100644
--- a/rutabaga_gfx/ffi/src/tests/rutabaga_test.c
+++ b/rutabaga_gfx/ffi/src/tests/rutabaga_test.c
@@ -13,25 +13,25 @@
#include <string.h>
#include <unistd.h>
-#include "../include/rutabaga_gfx_ffi.h"
+#include <rutabaga_gfx/rutabaga_gfx_ffi.h>
+
#include "virtgpu_cross_domain_protocol.h"
#define CHECK_RESULT(result) \
- do { \
- if (result) { \
- printf("CHECK_RESULT failed in %s() %s:%d\n", __func__, __FILE__, \
- __LINE__); \
- return result; \
- } \
- } while (0)
+ do { \
+ if (result) { \
+ printf("CHECK_RESULT failed in %s() %s:%d\n", __func__, __FILE__, __LINE__); \
+ return result; \
+ } \
+ } while (0)
#define CHECK(cond) \
- do { \
- if (!(cond)) { \
- printf("CHECK failed in %s() %s:%d\n", __func__, __FILE__, __LINE__); \
- return -EINVAL; \
- } \
- } while (0)
+ do { \
+ if (!(cond)) { \
+ printf("CHECK failed in %s() %s:%d\n", __func__, __FILE__, __LINE__); \
+ return -EINVAL; \
+ } \
+ } while (0)
#define DEFAULT_BUFFER_SIZE 4096
#define WIDTH 512
@@ -41,7 +41,7 @@
#define GBM_BO_USE_LINEAR (1 << 4)
#define GBM_BO_USE_SCANOUT (1 << 5)
#define fourcc_code(a, b, c, d) \
- ((uint32_t)(a) | ((uint32_t)(b) << 8) | ((uint32_t)(c) << 16) | ((uint32_t)(d) << 24))
+ ((uint32_t)(a) | ((uint32_t)(b) << 8) | ((uint32_t)(c) << 16) | ((uint32_t)(d) << 24))
#define DRM_FORMAT_XRGB8888 fourcc_code('X', 'R', '2', '4');
#define PIPE_TEXTURE_2D 2
@@ -57,359 +57,352 @@ static char *s_wayland_path = "/run/user/1000/wayland-0";
#endif
struct rutabaga_test {
- struct rutabaga *rutabaga;
- uint32_t ctx_id;
- uint64_t value;
- uint32_t guest_blob_resource_id;
- struct iovec *guest_iovecs;
+ struct rutabaga *rutabaga;
+ uint32_t ctx_id;
+ uint64_t value;
+ uint32_t guest_blob_resource_id;
+ struct iovec *guest_iovecs;
};
static void rutabaga_test_write_fence(uint64_t user_data, struct rutabaga_fence fence_data)
{
- struct rutabaga_test *test = (void *)(uintptr_t)user_data;
- test->value = fence_data.fence_id;
+ struct rutabaga_test *test = (void *)(uintptr_t)user_data;
+ test->value = fence_data.fence_id;
}
static int test_rutabaga_init(struct rutabaga_test *test, uint64_t capset_mask)
{
- int result;
- struct rutabaga_builder builder = { 0 };
- struct rutabaga_channels channels = { 0 };
+ int result;
+ struct rutabaga_builder builder = { 0 };
+ struct rutabaga_channels channels = { 0 };
- builder.fence_cb = rutabaga_test_write_fence;
- builder.capset_mask = capset_mask;
- if (capset_mask & (1 << RUTABAGA_CAPSET_CROSS_DOMAIN)) {
- builder.user_data = (uint64_t)(uintptr_t *)(void *)test;
- channels.channels =
- (struct rutabaga_channel *)calloc(1, sizeof(struct rutabaga_channel));
- channels.num_channels = 1;
+ builder.fence_cb = rutabaga_test_write_fence;
+ builder.capset_mask = capset_mask;
+ if (capset_mask & (1 << RUTABAGA_CAPSET_CROSS_DOMAIN)) {
+ builder.user_data = (uint64_t)(uintptr_t *)(void *)test;
+ channels.channels = (struct rutabaga_channel *)calloc(1, sizeof(struct rutabaga_channel));
+ channels.num_channels = 1;
- channels.channels[0].channel_name = s_wayland_path;
- channels.channels[0].channel_type = RUTABAGA_CHANNEL_TYPE_WAYLAND;
+ channels.channels[0].channel_name = s_wayland_path;
+ channels.channels[0].channel_type = RUTABAGA_CHANNEL_TYPE_WAYLAND;
- builder.channels = &channels;
- }
+ builder.channels = &channels;
+ }
- result = rutabaga_init(&builder, &test->rutabaga);
+ result = rutabaga_init(&builder, &test->rutabaga);
- if (capset_mask & (1 << RUTABAGA_CAPSET_CROSS_DOMAIN))
- free(channels.channels);
+ if (capset_mask & (1 << RUTABAGA_CAPSET_CROSS_DOMAIN))
+ free(channels.channels);
- CHECK_RESULT(result);
- return 0;
+ CHECK_RESULT(result);
+ return 0;
}
static int test_create_context(struct rutabaga_test *test, const char *context_name)
{
- int result;
- uint32_t num_capsets;
- uint32_t capset_id, capset_version, capset_size;
- bool found_cross_domain = false;
- struct CrossDomainCapabilities *capset;
-
- result = rutabaga_get_num_capsets(test->rutabaga, &num_capsets);
- CHECK_RESULT(result);
- CHECK(num_capsets == 1);
-
- for (uint32_t i = 0; i < num_capsets; i++) {
- result = rutabaga_get_capset_info(test->rutabaga, i, &capset_id, &capset_version,
- &capset_size);
- CHECK_RESULT(result);
- if (capset_id == RUTABAGA_CAPSET_CROSS_DOMAIN) {
- found_cross_domain = true;
- CHECK(capset_size == (uint32_t)sizeof(struct CrossDomainCapabilities));
- }
- }
-
- CHECK(found_cross_domain);
- CHECK_RESULT(result);
-
- capset = (struct CrossDomainCapabilities *)calloc(1, capset_size);
- result = rutabaga_get_capset(test->rutabaga, RUTABAGA_CAPSET_CROSS_DOMAIN, 0,
- (uint8_t *)capset, capset_size);
- CHECK_RESULT(result);
-
- CHECK(capset->version == 1);
- free(capset);
-
- size_t context_name_len = 0;
- if (context_name)
- context_name_len = strlen(context_name);
-
- result = rutabaga_context_create(test->rutabaga, test->ctx_id, RUTABAGA_CAPSET_CROSS_DOMAIN,
- context_name, context_name_len);
- CHECK_RESULT(result);
-
- return 0;
+ int result;
+ uint32_t num_capsets;
+ uint32_t capset_id, capset_version, capset_size;
+ bool found_cross_domain = false;
+ struct CrossDomainCapabilities *capset;
+
+ result = rutabaga_get_num_capsets(test->rutabaga, &num_capsets);
+ CHECK_RESULT(result);
+ CHECK(num_capsets == 1);
+
+ for (uint32_t i = 0; i < num_capsets; i++) {
+ result =
+ rutabaga_get_capset_info(test->rutabaga, i, &capset_id, &capset_version, &capset_size);
+ CHECK_RESULT(result);
+ if (capset_id == RUTABAGA_CAPSET_CROSS_DOMAIN) {
+ found_cross_domain = true;
+ CHECK(capset_size == (uint32_t)sizeof(struct CrossDomainCapabilities));
+ }
+ }
+
+ CHECK(found_cross_domain);
+ CHECK_RESULT(result);
+
+ capset = (struct CrossDomainCapabilities *)calloc(1, capset_size);
+ result = rutabaga_get_capset(test->rutabaga, RUTABAGA_CAPSET_CROSS_DOMAIN, 0, (uint8_t *)capset,
+ capset_size);
+ CHECK_RESULT(result);
+
+ CHECK(capset->version == 1);
+ free(capset);
+
+ size_t context_name_len = 0;
+ if (context_name)
+ context_name_len = strlen(context_name);
+
+ result = rutabaga_context_create(test->rutabaga, test->ctx_id, RUTABAGA_CAPSET_CROSS_DOMAIN,
+ context_name, context_name_len);
+ CHECK_RESULT(result);
+
+ return 0;
}
static int test_init_context(struct rutabaga_test *test)
{
- int result;
- struct rutabaga_create_blob rc_blob = { 0 };
- struct rutabaga_iovecs vecs = { 0 };
- struct CrossDomainInit cmd_init = { { 0 } };
-
- struct iovec *iovecs = (struct iovec *)calloc(1, sizeof(struct iovec));
- iovecs[0].iov_base = calloc(1, DEFAULT_BUFFER_SIZE);
- iovecs[0].iov_len = DEFAULT_BUFFER_SIZE;
-
- test->guest_iovecs = iovecs;
- rc_blob.blob_mem = RUTABAGA_BLOB_MEM_GUEST;
- rc_blob.blob_flags = RUTABAGA_BLOB_FLAG_USE_MAPPABLE;
- rc_blob.size = DEFAULT_BUFFER_SIZE;
-
- vecs.iovecs = iovecs;
- vecs.num_iovecs = 1;
-
- result = rutabaga_resource_create_blob(test->rutabaga, 0, test->guest_blob_resource_id,
- &rc_blob, &vecs, NULL);
- CHECK_RESULT(result);
-
- result = rutabaga_context_attach_resource(test->rutabaga, test->ctx_id,
- test->guest_blob_resource_id);
- CHECK_RESULT(result);
-
- cmd_init.hdr.cmd = CROSS_DOMAIN_CMD_INIT;
- cmd_init.hdr.cmd_size = sizeof(struct CrossDomainInit);
- cmd_init.ring_id = test->guest_blob_resource_id;
- cmd_init.channel_type = CROSS_DOMAIN_CHANNEL_TYPE_WAYLAND;
-
- result = rutabaga_submit_command(test->rutabaga, test->ctx_id, (uint8_t *)&cmd_init,
- cmd_init.hdr.cmd_size);
- CHECK_RESULT(result);
- return 0;
+ int result;
+ struct rutabaga_create_blob rc_blob = { 0 };
+ struct rutabaga_iovecs vecs = { 0 };
+ struct CrossDomainInit cmd_init = { { 0 } };
+
+ struct iovec *iovecs = (struct iovec *)calloc(1, sizeof(struct iovec));
+ iovecs[0].iov_base = calloc(1, DEFAULT_BUFFER_SIZE);
+ iovecs[0].iov_len = DEFAULT_BUFFER_SIZE;
+
+ test->guest_iovecs = iovecs;
+ rc_blob.blob_mem = RUTABAGA_BLOB_MEM_GUEST;
+ rc_blob.blob_flags = RUTABAGA_BLOB_FLAG_USE_MAPPABLE;
+ rc_blob.size = DEFAULT_BUFFER_SIZE;
+
+ vecs.iovecs = iovecs;
+ vecs.num_iovecs = 1;
+
+ result = rutabaga_resource_create_blob(test->rutabaga, 0, test->guest_blob_resource_id,
+ &rc_blob, &vecs, NULL);
+ CHECK_RESULT(result);
+
+ result = rutabaga_context_attach_resource(test->rutabaga, test->ctx_id,
+ test->guest_blob_resource_id);
+ CHECK_RESULT(result);
+
+ cmd_init.hdr.cmd = CROSS_DOMAIN_CMD_INIT;
+ cmd_init.hdr.cmd_size = sizeof(struct CrossDomainInit);
+ cmd_init.ring_id = test->guest_blob_resource_id;
+ cmd_init.channel_type = CROSS_DOMAIN_CHANNEL_TYPE_WAYLAND;
+
+ result = rutabaga_submit_command(test->rutabaga, test->ctx_id, (uint8_t *)&cmd_init,
+ cmd_init.hdr.cmd_size);
+ CHECK_RESULT(result);
+ return 0;
}
static int test_command_submission(struct rutabaga_test *test)
{
- int result;
- struct CrossDomainGetImageRequirements cmd_get_reqs = { 0 };
- struct CrossDomainImageRequirements *image_reqs = (void *)test->guest_iovecs[0].iov_base;
- struct rutabaga_create_blob rc_blob = { 0 };
- struct rutabaga_fence fence;
- struct rutabaga_handle handle = { 0 };
- uint32_t map_info;
-
- fence.flags = RUTABAGA_FLAG_FENCE | RUTABAGA_FLAG_INFO_RING_IDX;
- fence.ctx_id = test->ctx_id;
- fence.ring_idx = 0;
-
- cmd_get_reqs.hdr.cmd = CROSS_DOMAIN_CMD_GET_IMAGE_REQUIREMENTS;
- cmd_get_reqs.hdr.cmd_size = sizeof(struct CrossDomainGetImageRequirements);
-
- for (uint32_t i = 0; i < NUM_ITERATIONS; i++) {
- for (uint32_t j = 0; j < NUM_ITERATIONS; j++) {
- fence.fence_id = s_fence_id;
- map_info = 0;
-
- cmd_get_reqs.width = WIDTH * i;
- cmd_get_reqs.height = HEIGHT * j;
- cmd_get_reqs.drm_format = DRM_FORMAT_XRGB8888;
-
- cmd_get_reqs.flags = GBM_BO_USE_LINEAR | GBM_BO_USE_SCANOUT;
-
- result = rutabaga_submit_command(test->rutabaga, test->ctx_id,
- (uint8_t *)&cmd_get_reqs,
- cmd_get_reqs.hdr.cmd_size);
-
- CHECK(test->value < fence.fence_id);
- result = rutabaga_create_fence(test->rutabaga, &fence);
-
- CHECK_RESULT(result);
- for (;;) {
- if (fence.fence_id == test->value)
- break;
- }
-
- CHECK(image_reqs->strides[0] >= cmd_get_reqs.width * 4);
- CHECK(image_reqs->size >= (cmd_get_reqs.width * 4) * cmd_get_reqs.height);
-
- rc_blob.blob_mem = RUTABAGA_BLOB_MEM_HOST3D;
- rc_blob.blob_flags =
- RUTABAGA_BLOB_FLAG_USE_MAPPABLE | RUTABAGA_BLOB_FLAG_USE_SHAREABLE;
- rc_blob.blob_id = image_reqs->blob_id;
- rc_blob.size = image_reqs->size;
-
- result = rutabaga_resource_create_blob(test->rutabaga, test->ctx_id,
- s_resource_id, &rc_blob, NULL, NULL);
- CHECK_RESULT(result);
-
- result = rutabaga_context_attach_resource(test->rutabaga, test->ctx_id,
- s_resource_id);
- CHECK_RESULT(result);
-
- result =
- rutabaga_resource_map_info(test->rutabaga, s_resource_id, &map_info);
- CHECK_RESULT(result);
- CHECK(map_info > 0);
-
- result =
- rutabaga_resource_export_blob(test->rutabaga, s_resource_id, &handle);
- CHECK_RESULT(result);
- CHECK(handle.os_handle >= 0);
-
- result = close(handle.os_handle);
- CHECK_RESULT(result);
-
- result = rutabaga_context_detach_resource(test->rutabaga, test->ctx_id,
- s_resource_id);
- CHECK_RESULT(result);
-
- result = rutabaga_resource_unref(test->rutabaga, s_resource_id);
- CHECK_RESULT(result);
-
- s_resource_id++;
- s_fence_id++;
- }
- }
-
- return 0;
+ int result;
+ struct CrossDomainGetImageRequirements cmd_get_reqs = { 0 };
+ struct CrossDomainImageRequirements *image_reqs = (void *)test->guest_iovecs[0].iov_base;
+ struct rutabaga_create_blob rc_blob = { 0 };
+ struct rutabaga_fence fence;
+ struct rutabaga_handle handle = { 0 };
+ uint32_t map_info;
+
+ fence.flags = RUTABAGA_FLAG_FENCE | RUTABAGA_FLAG_INFO_RING_IDX;
+ fence.ctx_id = test->ctx_id;
+ fence.ring_idx = 0;
+
+ cmd_get_reqs.hdr.cmd = CROSS_DOMAIN_CMD_GET_IMAGE_REQUIREMENTS;
+ cmd_get_reqs.hdr.cmd_size = sizeof(struct CrossDomainGetImageRequirements);
+
+ for (uint32_t i = 0; i < NUM_ITERATIONS; i++) {
+ for (uint32_t j = 0; j < NUM_ITERATIONS; j++) {
+ fence.fence_id = s_fence_id;
+ map_info = 0;
+
+ cmd_get_reqs.width = WIDTH * i;
+ cmd_get_reqs.height = HEIGHT * j;
+ cmd_get_reqs.drm_format = DRM_FORMAT_XRGB8888;
+
+ cmd_get_reqs.flags = GBM_BO_USE_LINEAR | GBM_BO_USE_SCANOUT;
+
+ result = rutabaga_submit_command(test->rutabaga, test->ctx_id, (uint8_t *)&cmd_get_reqs,
+ cmd_get_reqs.hdr.cmd_size);
+
+ CHECK(test->value < fence.fence_id);
+ result = rutabaga_create_fence(test->rutabaga, &fence);
+
+ CHECK_RESULT(result);
+ for (;;) {
+ if (fence.fence_id == test->value)
+ break;
+ }
+
+ CHECK(image_reqs->strides[0] >= cmd_get_reqs.width * 4);
+ CHECK(image_reqs->size >= (cmd_get_reqs.width * 4) * cmd_get_reqs.height);
+
+ rc_blob.blob_mem = RUTABAGA_BLOB_MEM_HOST3D;
+ rc_blob.blob_flags = RUTABAGA_BLOB_FLAG_USE_MAPPABLE | RUTABAGA_BLOB_FLAG_USE_SHAREABLE;
+ rc_blob.blob_id = image_reqs->blob_id;
+ rc_blob.size = image_reqs->size;
+
+ result = rutabaga_resource_create_blob(test->rutabaga, test->ctx_id, s_resource_id,
+ &rc_blob, NULL, NULL);
+ CHECK_RESULT(result);
+
+ result = rutabaga_context_attach_resource(test->rutabaga, test->ctx_id, s_resource_id);
+ CHECK_RESULT(result);
+
+ result = rutabaga_resource_map_info(test->rutabaga, s_resource_id, &map_info);
+ CHECK_RESULT(result);
+ CHECK(map_info > 0);
+
+ result = rutabaga_resource_export_blob(test->rutabaga, s_resource_id, &handle);
+ CHECK_RESULT(result);
+ CHECK(handle.os_handle >= 0);
+
+ result = close(handle.os_handle);
+ CHECK_RESULT(result);
+
+ result = rutabaga_context_detach_resource(test->rutabaga, test->ctx_id, s_resource_id);
+ CHECK_RESULT(result);
+
+ result = rutabaga_resource_unref(test->rutabaga, s_resource_id);
+ CHECK_RESULT(result);
+
+ s_resource_id++;
+ s_fence_id++;
+ }
+ }
+
+ return 0;
}
static int test_context_finish(struct rutabaga_test *test)
{
- int result;
+ int result;
- result = rutabaga_context_detach_resource(test->rutabaga, test->ctx_id,
- test->guest_blob_resource_id);
- CHECK_RESULT(result);
+ result = rutabaga_context_detach_resource(test->rutabaga, test->ctx_id,
+ test->guest_blob_resource_id);
+ CHECK_RESULT(result);
- result = rutabaga_resource_unref(test->rutabaga, test->guest_blob_resource_id);
- CHECK_RESULT(result);
+ result = rutabaga_resource_unref(test->rutabaga, test->guest_blob_resource_id);
+ CHECK_RESULT(result);
- free(test->guest_iovecs[0].iov_base);
+ free(test->guest_iovecs[0].iov_base);
- result = rutabaga_context_destroy(test->rutabaga, test->ctx_id);
- CHECK_RESULT(result);
+ result = rutabaga_context_destroy(test->rutabaga, test->ctx_id);
+ CHECK_RESULT(result);
- return 0;
+ return 0;
}
static int test_rutabaga_2d(struct rutabaga_test *test)
{
- struct rutabaga_create_3d rc_3d = { 0 };
- struct rutabaga_transfer transfer = { 0 };
- int result;
- uint32_t resource_id = s_resource_id++;
+ struct rutabaga_create_3d rc_3d = { 0 };
+ struct rutabaga_transfer transfer = { 0 };
+ int result;
+ uint32_t resource_id = s_resource_id++;
- struct rutabaga_iovecs vecs = { 0 };
- struct iovec *iovecs = (struct iovec *)calloc(1, sizeof(struct iovec));
- uint8_t *test_data;
- struct iovec result_iovec;
+ struct rutabaga_iovecs vecs = { 0 };
+ struct iovec *iovecs = (struct iovec *)calloc(1, sizeof(struct iovec));
+ uint8_t *test_data;
+ struct iovec result_iovec;
- iovecs[0].iov_base = calloc(1, DEFAULT_BUFFER_SIZE);
- iovecs[0].iov_len = DEFAULT_BUFFER_SIZE;
- result_iovec.iov_base = calloc(1, DEFAULT_BUFFER_SIZE);
- result_iovec.iov_len = DEFAULT_BUFFER_SIZE;
- test_data = (uint8_t *)result_iovec.iov_base;
+ iovecs[0].iov_base = calloc(1, DEFAULT_BUFFER_SIZE);
+ iovecs[0].iov_len = DEFAULT_BUFFER_SIZE;
+ result_iovec.iov_base = calloc(1, DEFAULT_BUFFER_SIZE);
+ result_iovec.iov_len = DEFAULT_BUFFER_SIZE;
+ test_data = (uint8_t *)result_iovec.iov_base;
- vecs.iovecs = iovecs;
- vecs.num_iovecs = 1;
+ vecs.iovecs = iovecs;
+ vecs.num_iovecs = 1;
- rc_3d.target = PIPE_TEXTURE_2D;
- rc_3d.bind = PIPE_BIND_RENDER_TARGET;
- rc_3d.format = VIRTIO_GPU_FORMAT_B8G8R8A8_UNORM;
- rc_3d.width = DEFAULT_BUFFER_SIZE / 16;
- rc_3d.height = 4;
+ rc_3d.target = PIPE_TEXTURE_2D;
+ rc_3d.bind = PIPE_BIND_RENDER_TARGET;
+ rc_3d.format = VIRTIO_GPU_FORMAT_B8G8R8A8_UNORM;
+ rc_3d.width = DEFAULT_BUFFER_SIZE / 16;
+ rc_3d.height = 4;
- transfer.w = DEFAULT_BUFFER_SIZE / 16;
- transfer.h = 4;
- transfer.d = 1;
+ transfer.w = DEFAULT_BUFFER_SIZE / 16;
+ transfer.h = 4;
+ transfer.d = 1;
- result = rutabaga_resource_create_3d(test->rutabaga, resource_id, &rc_3d);
- CHECK_RESULT(result);
+ result = rutabaga_resource_create_3d(test->rutabaga, resource_id, &rc_3d);
+ CHECK_RESULT(result);
- result = rutabaga_resource_attach_backing(test->rutabaga, resource_id, &vecs);
- CHECK_RESULT(result);
+ result = rutabaga_resource_attach_backing(test->rutabaga, resource_id, &vecs);
+ CHECK_RESULT(result);
- memset(iovecs[0].iov_base, 8, DEFAULT_BUFFER_SIZE);
+ memset(iovecs[0].iov_base, 8, DEFAULT_BUFFER_SIZE);
- result = rutabaga_resource_transfer_read(test->rutabaga, 0, resource_id, &transfer,
- &result_iovec);
- CHECK_RESULT(result);
+ result =
+ rutabaga_resource_transfer_read(test->rutabaga, 0, resource_id, &transfer, &result_iovec);
+ CHECK_RESULT(result);
- CHECK(test_data[0] == 0);
+ CHECK(test_data[0] == 0);
- result = rutabaga_resource_transfer_write(test->rutabaga, 0, resource_id, &transfer);
- CHECK_RESULT(result);
+ result = rutabaga_resource_transfer_write(test->rutabaga, 0, resource_id, &transfer);
+ CHECK_RESULT(result);
- result = rutabaga_resource_transfer_read(test->rutabaga, 0, resource_id, &transfer,
- &result_iovec);
- CHECK_RESULT(result);
+ result =
+ rutabaga_resource_transfer_read(test->rutabaga, 0, resource_id, &transfer, &result_iovec);
+ CHECK_RESULT(result);
- CHECK(test_data[0] == 8);
+ CHECK(test_data[0] == 8);
- result = rutabaga_resource_detach_backing(test->rutabaga, resource_id);
- CHECK_RESULT(result);
+ result = rutabaga_resource_detach_backing(test->rutabaga, resource_id);
+ CHECK_RESULT(result);
- result = rutabaga_resource_unref(test->rutabaga, resource_id);
- CHECK_RESULT(result);
+ result = rutabaga_resource_unref(test->rutabaga, resource_id);
+ CHECK_RESULT(result);
- free(iovecs[0].iov_base);
- free(iovecs);
- free(test_data);
- return 0;
+ free(iovecs[0].iov_base);
+ free(iovecs);
+ free(test_data);
+ return 0;
}
static int test_rutabaga_finish(struct rutabaga_test *test)
{
- int result;
+ int result;
- result = rutabaga_finish(&test->rutabaga);
- CHECK_RESULT(result);
- CHECK(test->rutabaga == NULL);
- return 0;
+ result = rutabaga_finish(&test->rutabaga);
+ CHECK_RESULT(result);
+ CHECK(test->rutabaga == NULL);
+ return 0;
}
int main(int argc, char *argv[])
{
- struct rutabaga_test test = { 0 };
- test.ctx_id = 1;
- test.guest_blob_resource_id = s_resource_id++;
+ struct rutabaga_test test = { 0 };
+ test.ctx_id = 1;
+ test.guest_blob_resource_id = s_resource_id++;
- int result;
+ int result;
- const char *context_names[] = {
- NULL,
- "test_context",
- };
- const uint32_t num_context_names = 2;
+ const char *context_names[] = {
+ NULL,
+ "test_context",
+ };
+ const uint32_t num_context_names = 2;
- for (uint32_t i = 0; i < num_context_names; i++) {
- const char *context_name = context_names[i];
- for (uint32_t j = 0; j < NUM_ITERATIONS; j++) {
- result = test_rutabaga_init(&test, 1 << RUTABAGA_CAPSET_CROSS_DOMAIN);
- CHECK_RESULT(result);
+ for (uint32_t i = 0; i < num_context_names; i++) {
+ const char *context_name = context_names[i];
+ for (uint32_t j = 0; j < NUM_ITERATIONS; j++) {
+ result = test_rutabaga_init(&test, 1 << RUTABAGA_CAPSET_CROSS_DOMAIN);
+ CHECK_RESULT(result);
- result |= test_create_context(&test, context_name);
- CHECK_RESULT(result);
+ result |= test_create_context(&test, context_name);
+ CHECK_RESULT(result);
- result |= test_init_context(&test);
- CHECK_RESULT(result);
+ result |= test_init_context(&test);
+ CHECK_RESULT(result);
- result |= test_command_submission(&test);
- CHECK_RESULT(result);
+ result |= test_command_submission(&test);
+ CHECK_RESULT(result);
- result |= test_context_finish(&test);
- CHECK_RESULT(result);
+ result |= test_context_finish(&test);
+ CHECK_RESULT(result);
- result |= test_rutabaga_finish(&test);
- CHECK_RESULT(result);
- }
- }
+ result |= test_rutabaga_finish(&test);
+ CHECK_RESULT(result);
+ }
+ }
- for (uint32_t i = 0; i < NUM_ITERATIONS; i++) {
- result = test_rutabaga_init(&test, 0);
- CHECK_RESULT(result);
+ for (uint32_t i = 0; i < NUM_ITERATIONS; i++) {
+ result = test_rutabaga_init(&test, 0);
+ CHECK_RESULT(result);
- result |= test_rutabaga_2d(&test);
- CHECK_RESULT(result);
+ result |= test_rutabaga_2d(&test);
+ CHECK_RESULT(result);
- result |= test_rutabaga_finish(&test);
- CHECK_RESULT(result);
- }
+ result |= test_rutabaga_finish(&test);
+ CHECK_RESULT(result);
+ }
- printf("[ PASSED ] rutabaga_test success\n");
- return 0;
+ printf("[ PASSED ] rutabaga_test success\n");
+ return 0;
}
diff --git a/rutabaga_gfx/src/cross_domain/cross_domain.rs b/rutabaga_gfx/src/cross_domain/cross_domain.rs
index afc1afad1..cd0b2ffce 100644
--- a/rutabaga_gfx/src/cross_domain/cross_domain.rs
+++ b/rutabaga_gfx/src/cross_domain/cross_domain.rs
@@ -663,7 +663,7 @@ impl RutabagaContext for CrossDomainContext {
info_3d: Some(info_3d),
vulkan_info: reqs.vulkan_info,
backing_iovecs: None,
- import_mask: 0,
+ component_mask: 1 << (RutabagaComponentType::CrossDomain as u8),
})
}
_ => Err(RutabagaError::InvalidCrossDomainItemType),
@@ -695,7 +695,7 @@ impl RutabagaContext for CrossDomainContext {
info_3d: None,
vulkan_info: None,
backing_iovecs: None,
- import_mask: 0,
+ component_mask: 1 << (RutabagaComponentType::CrossDomain as u8),
})
}
_ => Err(RutabagaError::InvalidCrossDomainItemType),
@@ -871,7 +871,7 @@ impl RutabagaComponent for CrossDomain {
info_3d: None,
vulkan_info: None,
backing_iovecs: iovec_opt,
- import_mask: 0,
+ component_mask: 1 << (RutabagaComponentType::CrossDomain as u8),
})
}
diff --git a/rutabaga_gfx/src/gfxstream.rs b/rutabaga_gfx/src/gfxstream.rs
index c0c548d83..3ecf1c6f1 100644
--- a/rutabaga_gfx/src/gfxstream.rs
+++ b/rutabaga_gfx/src/gfxstream.rs
@@ -431,7 +431,7 @@ impl RutabagaComponent for Gfxstream {
info_3d: None,
vulkan_info: None,
backing_iovecs: None,
- import_mask: 0,
+ component_mask: 1 << (RutabagaComponentType::Gfxstream as u8),
})
}
@@ -617,7 +617,7 @@ impl RutabagaComponent for Gfxstream {
info_3d: None,
vulkan_info: self.vulkan_info(resource_id).ok(),
backing_iovecs: iovec_opt,
- import_mask: 0,
+ component_mask: 1 << (RutabagaComponentType::Gfxstream as u8),
})
}
diff --git a/rutabaga_gfx/src/lib.rs b/rutabaga_gfx/src/lib.rs
index b981ca0ac..eda34651f 100644
--- a/rutabaga_gfx/src/lib.rs
+++ b/rutabaga_gfx/src/lib.rs
@@ -20,8 +20,8 @@ mod rutabaga_os;
mod rutabaga_utils;
mod virgl_renderer;
-pub use crate::rutabaga_core::calculate_context_mask;
-pub use crate::rutabaga_core::calculate_context_types;
+pub use crate::rutabaga_core::calculate_capset_mask;
+pub use crate::rutabaga_core::calculate_capset_names;
pub use crate::rutabaga_core::Rutabaga;
pub use crate::rutabaga_core::RutabagaBuilder;
pub use crate::rutabaga_gralloc::DrmFormat;
diff --git a/rutabaga_gfx/src/rutabaga_2d.rs b/rutabaga_gfx/src/rutabaga_2d.rs
index f2b294ce0..2164c8bf7 100644
--- a/rutabaga_gfx/src/rutabaga_2d.rs
+++ b/rutabaga_gfx/src/rutabaga_2d.rs
@@ -178,7 +178,7 @@ impl RutabagaComponent for Rutabaga2D {
info_3d: None,
vulkan_info: None,
backing_iovecs: None,
- import_mask: 0,
+ component_mask: 1 << (RutabagaComponentType::Rutabaga2D as u8),
})
}
diff --git a/rutabaga_gfx/src/rutabaga_core.rs b/rutabaga_gfx/src/rutabaga_core.rs
index dd2469cac..fa64a6a6f 100644
--- a/rutabaga_gfx/src/rutabaga_core.rs
+++ b/rutabaga_gfx/src/rutabaga_core.rs
@@ -42,7 +42,7 @@ pub struct RutabagaResource {
pub backing_iovecs: Option<Vec<RutabagaIovec>>,
/// Bitmask of components that have already imported this resource
- pub import_mask: u32,
+ pub component_mask: u8,
}
/// A RutabagaComponent is a building block of the Virtual Graphics Interface (VGI). Each component
@@ -102,7 +102,7 @@ pub trait RutabagaComponent {
info_3d: None,
vulkan_info: None,
backing_iovecs: None,
- import_mask: 0,
+ component_mask: 0,
})
}
@@ -263,21 +263,21 @@ const RUTABAGA_CAPSETS: [RutabagaCapsetInfo; 6] = [
},
];
-pub fn calculate_context_mask(context_names: Vec<String>) -> u64 {
- let mut context_mask = 0;
+pub fn calculate_capset_mask(context_names: Vec<String>) -> u64 {
+ let mut capset_mask = 0;
context_names.into_iter().for_each(|name| {
if let Some(capset) = RUTABAGA_CAPSETS.iter().find(|capset| capset.name == name) {
- context_mask |= 1 << capset.capset_id;
+ capset_mask |= 1 << capset.capset_id;
};
});
- context_mask
+ capset_mask
}
-pub fn calculate_context_types(context_mask: u64) -> Vec<String> {
+pub fn calculate_capset_names(capset_mask: u64) -> Vec<String> {
RUTABAGA_CAPSETS
.iter()
- .filter(|capset| context_mask & (1 << capset.capset_id) != 0)
+ .filter(|capset| capset_mask & (1 << capset.capset_id) != 0)
.map(|capset| capset.name.to_string())
.collect()
}
@@ -773,13 +773,13 @@ pub struct RutabagaBuilder {
default_component: RutabagaComponentType,
gfxstream_flags: GfxstreamFlags,
virglrenderer_flags: VirglRendererFlags,
- context_mask: u64,
+ capset_mask: u64,
channels: Option<Vec<RutabagaChannel>>,
}
impl RutabagaBuilder {
/// Create new a RutabagaBuilder.
- pub fn new(default_component: RutabagaComponentType, context_mask: u64) -> RutabagaBuilder {
+ pub fn new(default_component: RutabagaComponentType, capset_mask: u64) -> RutabagaBuilder {
let virglrenderer_flags = VirglRendererFlags::new()
.use_thread_sync(true)
.use_async_fence_cb(true);
@@ -791,7 +791,7 @@ impl RutabagaBuilder {
default_component,
gfxstream_flags,
virglrenderer_flags,
- context_mask,
+ capset_mask,
channels: None,
}
}
@@ -906,14 +906,14 @@ impl RutabagaBuilder {
let mut rutabaga_capsets: Vec<RutabagaCapsetInfo> = Default::default();
let capset_enabled =
- |capset_id: u32| -> bool { (self.context_mask & (1 << capset_id)) != 0 };
+ |capset_id: u32| -> bool { (self.capset_mask & (1 << capset_id)) != 0 };
let mut push_capset = |capset_id: u32| {
if let Some(capset) = RUTABAGA_CAPSETS
.iter()
.find(|capset| capset_id == capset.capset_id)
{
- if self.context_mask != 0 {
+ if self.capset_mask != 0 {
if capset_enabled(capset.capset_id) {
rutabaga_capsets.push(*capset);
}
@@ -925,7 +925,7 @@ impl RutabagaBuilder {
};
};
- if self.context_mask != 0 {
+ if self.capset_mask != 0 {
let supports_gfxstream = capset_enabled(RUTABAGA_CAPSET_GFXSTREAM);
let supports_virglrenderer = capset_enabled(RUTABAGA_CAPSET_VIRGL2)
| capset_enabled(RUTABAGA_CAPSET_VENUS)
diff --git a/rutabaga_gfx/src/rutabaga_utils.rs b/rutabaga_gfx/src/rutabaga_utils.rs
index 51a1adbbc..cda309ac4 100644
--- a/rutabaga_gfx/src/rutabaga_utils.rs
+++ b/rutabaga_gfx/src/rutabaga_utils.rs
@@ -610,6 +610,7 @@ pub struct RutabagaChannel {
}
/// Enumeration of possible rutabaga components.
+#[repr(u8)]
#[derive(Copy, Clone, Eq, PartialEq, PartialOrd, Ord)]
pub enum RutabagaComponentType {
Rutabaga2D,
diff --git a/rutabaga_gfx/src/virgl_renderer.rs b/rutabaga_gfx/src/virgl_renderer.rs
index f8f9ab2c6..31e2780d9 100644
--- a/rutabaga_gfx/src/virgl_renderer.rs
+++ b/rutabaga_gfx/src/virgl_renderer.rs
@@ -48,7 +48,7 @@ struct VirglRendererContext {
}
fn import_resource(resource: &mut RutabagaResource) -> RutabagaResult<()> {
- if (resource.import_mask & (1 << (RutabagaComponentType::VirglRenderer as u32))) != 0 {
+ if (resource.component_mask & (1 << (RutabagaComponentType::VirglRenderer as u8))) != 0 {
return Ok(());
}
@@ -77,7 +77,7 @@ fn import_resource(resource: &mut RutabagaResource) -> RutabagaResult<()> {
libc::close(dmabuf_fd);
return Ok(());
}
- resource.import_mask |= 1 << (RutabagaComponentType::VirglRenderer as u32);
+ resource.component_mask |= 1 << (RutabagaComponentType::VirglRenderer as u8);
}
}
}
@@ -454,7 +454,7 @@ impl RutabagaComponent for VirglRenderer {
info_3d: self.query(resource_id).ok(),
vulkan_info: None,
backing_iovecs: None,
- import_mask: 1 << (RutabagaComponentType::VirglRenderer as u32),
+ component_mask: 1 << (RutabagaComponentType::VirglRenderer as u8),
})
}
@@ -622,7 +622,7 @@ impl RutabagaComponent for VirglRenderer {
info_3d: self.query(resource_id).ok(),
vulkan_info: None,
backing_iovecs: iovec_opt,
- import_mask: 1 << (RutabagaComponentType::VirglRenderer as u32),
+ component_mask: 1 << (RutabagaComponentType::VirglRenderer as u8),
})
}
#[cfg(not(feature = "virgl_renderer_next"))]
diff --git a/src/crosvm/cmdline.rs b/src/crosvm/cmdline.rs
index 7a66bdd19..6c017ab6e 100644
--- a/src/crosvm/cmdline.rs
+++ b/src/crosvm/cmdline.rs
@@ -46,6 +46,8 @@ use devices::virtio::GpuDisplayParameters;
use devices::virtio::GpuParameters;
#[cfg(unix)]
use devices::virtio::NetParameters;
+#[cfg(unix)]
+use devices::virtio::NetParametersMode;
#[cfg(feature = "audio")]
use devices::Ac97Parameters;
use devices::PflashParameters;
@@ -1391,7 +1393,7 @@ pub struct RunCommand {
#[cfg(unix)]
#[argh(
option,
- arg_name = "(tap-name=TAP_NAME,mac=MAC_ADDRESS|tap-fd=TAP_FD,mac=MAC_ADDRESS|host-ip=IP,netmask=NETMASK,mac=MAC_ADDRESS),vhost-net=VHOST_NET"
+ arg_name = "(tap-name=TAP_NAME,mac=MAC_ADDRESS|tap-fd=TAP_FD,mac=MAC_ADDRESS|host-ip=IP,netmask=NETMASK,mac=MAC_ADDRESS),vhost-net=VHOST_NET,vq-pairs=N"
)]
#[serde(default)]
#[merge(strategy = append)]
@@ -1419,6 +1421,8 @@ pub struct RunCommand {
/// AND
/// vhost-net=BOOL - whether enable vhost_net or not.
/// Default: false. [Optional]
+ /// vq-pairs=N - number of rx/tx queue pairs.
+ /// Default: 1. [Optional]
///
/// Either one tap_name, one tap_fd or a triplet of host_ip,
/// netmask and mac must be specified.
@@ -1426,7 +1430,7 @@ pub struct RunCommand {
#[cfg(unix)]
#[argh(option, arg_name = "N")]
- #[serde(skip)] // TODO(b/255223604)
+ #[serde(skip)] // Deprecated - use `net` instead.
#[merge(strategy = overwrite_option)]
/// virtio net virtual queue pairs. (default: 1)
pub net_vq_pairs: Option<u16>,
@@ -2039,8 +2043,9 @@ pub struct RunCommand {
/// path to sysfs of platform pass through
pub vfio_platform: Vec<VfioOption>,
+ #[cfg(unix)]
#[argh(switch)]
- #[serde(skip)] // TODO(b/255223604)
+ #[serde(skip)] // Deprecated - use `net` instead.
#[merge(strategy = overwrite_false)]
/// use vhost for networking
pub vhost_net: bool,
@@ -2651,8 +2656,6 @@ impl TryFrom<RunCommand> for super::config::Config {
}
}
- cfg.vhost_net = cmd.vhost_net;
-
#[cfg(feature = "tpm")]
{
cfg.software_tpm = cmd.software_tpm;
@@ -2747,12 +2750,79 @@ impl TryFrom<RunCommand> for super::config::Config {
cfg.shared_dirs = cmd.shared_dir;
cfg.net = cmd.net;
- cfg.host_ip = cmd.host_ip;
- cfg.netmask = cmd.netmask;
- cfg.mac_address = cmd.mac_address;
- cfg.tap_name = cmd.tap_name;
- cfg.tap_fd = cmd.tap_fd;
+ let vhost_net_msg = match cmd.vhost_net {
+ true => ",vhost-net=true",
+ false => "",
+ };
+ let vq_pairs_msg = match cmd.net_vq_pairs {
+ Some(n) => format!(",vq-pairs={}", n),
+ None => "".to_string(),
+ };
+
+ for tap_name in cmd.tap_name {
+ log::warn!(
+ "`--tap-name` is deprecated; please use \
+ `--net tap-name={tap_name}{vhost_net_msg}{vq_pairs_msg}`"
+ );
+ cfg.net.push(NetParameters {
+ mode: NetParametersMode::TapName {
+ tap_name,
+ mac: None,
+ },
+ vhost_net: cmd.vhost_net,
+ vq_pairs: cmd.net_vq_pairs,
+ });
+ }
+
+ for tap_fd in cmd.tap_fd {
+ log::warn!(
+ "`--tap-fd` is deprecated; please use \
+ `--net tap-fd={tap_fd}{vhost_net_msg}{vq_pairs_msg}`"
+ );
+ cfg.net.push(NetParameters {
+ mode: NetParametersMode::TapFd { tap_fd, mac: None },
+ vhost_net: cmd.vhost_net,
+ vq_pairs: cmd.net_vq_pairs,
+ });
+ }
+
+ if cmd.host_ip.is_some() || cmd.netmask.is_some() || cmd.mac_address.is_some() {
+ let host_ip = match cmd.host_ip {
+ Some(host_ip) => host_ip,
+ None => return Err("`host-ip` missing from network config".to_string()),
+ };
+ let netmask = match cmd.netmask {
+ Some(netmask) => netmask,
+ None => return Err("`netmask` missing from network config".to_string()),
+ };
+ let mac = match cmd.mac_address {
+ Some(mac) => mac,
+ None => return Err("`mac` missing from network config".to_string()),
+ };
+
+ if !cmd.vhost_user_net.is_empty() {
+ return Err(
+ "vhost-user-net cannot be used with any of --host-ip, --netmask or --mac"
+ .to_string(),
+ );
+ }
+
+ log::warn!(
+ "`--host-ip`, `--netmask`, and `--mac` are deprecated; please use \
+ `--net host-ip={host_ip},netmask={netmask},mac={mac}{vhost_net_msg}{vq_pairs_msg}`"
+ );
+
+ cfg.net.push(NetParameters {
+ mode: NetParametersMode::RawConfig {
+ host_ip,
+ netmask,
+ mac,
+ },
+ vhost_net: cmd.vhost_net,
+ vq_pairs: cmd.net_vq_pairs,
+ });
+ }
cfg.coiommu_param = cmd.coiommu;
@@ -2778,8 +2848,6 @@ impl TryFrom<RunCommand> for super::config::Config {
.get_or_insert_with(Default::default)
.pivot_root = p;
}
-
- cfg.net_vq_pairs = cmd.net_vq_pairs;
}
let protection_flags = [
diff --git a/src/crosvm/config.rs b/src/crosvm/config.rs
index 6fdbd9611..28472f100 100644
--- a/src/crosvm/config.rs
+++ b/src/crosvm/config.rs
@@ -7,7 +7,6 @@ use std::arch::x86_64::__cpuid;
#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
use std::arch::x86_64::__cpuid_count;
use std::collections::BTreeMap;
-use std::net;
use std::path::Path;
use std::path::PathBuf;
use std::str::FromStr;
@@ -74,7 +73,6 @@ pub(crate) use super::sys::HypervisorKind;
cfg_if::cfg_if! {
if #[cfg(unix)] {
- use base::RawDescriptor;
use devices::virtio::fs::passthrough;
#[cfg(feature = "gpu")]
use crate::crosvm::sys::GpuRenderServerParameters;
@@ -1055,7 +1053,6 @@ pub struct Config {
pub host_cpu_topology: bool,
#[cfg(windows)]
pub host_guid: Option<String>,
- pub host_ip: Option<net::Ipv4Addr>,
pub hugepages: bool,
pub hypervisor: Option<HypervisorKind>,
pub init_memory: Option<u64>,
@@ -1072,7 +1069,6 @@ pub struct Config {
pub log_file: Option<String>,
#[cfg(windows)]
pub logs_directory: Option<String>,
- pub mac_address: Option<net_util::MacAddress>,
pub memory: Option<u64>,
pub memory_file: Option<PathBuf>,
pub mmio_address_ranges: Vec<AddressRange>,
@@ -1081,8 +1077,6 @@ pub struct Config {
pub net: Vec<NetParameters>,
#[cfg(windows)]
pub net_vhost_user_tube: Option<Tube>,
- pub net_vq_pairs: Option<u16>,
- pub netmask: Option<net::Ipv4Addr>,
pub no_i8042: bool,
pub no_rtc: bool,
pub no_smt: bool,
@@ -1145,9 +1139,6 @@ pub struct Config {
pub swiotlb: Option<u64>,
#[cfg(windows)]
pub syslog_tag: Option<String>,
- #[cfg(unix)]
- pub tap_fd: Vec<RawDescriptor>,
- pub tap_name: Vec<String>,
#[cfg(target_os = "android")]
pub task_profiles: Vec<String>,
#[cfg(unix)]
@@ -1163,7 +1154,6 @@ pub struct Config {
pub vfio: Vec<super::sys::config::VfioOption>,
#[cfg(unix)]
pub vfio_isolate_hotplug: bool,
- pub vhost_net: bool,
#[cfg(unix)]
pub vhost_net_device_path: PathBuf,
pub vhost_user_blk: Vec<VhostUserOption>,
@@ -1274,7 +1264,6 @@ impl Default for Config {
host_cpu_topology: false,
#[cfg(windows)]
host_guid: None,
- host_ip: None,
#[cfg(windows)]
product_version: None,
#[cfg(windows)]
@@ -1299,7 +1288,6 @@ impl Default for Config {
log_file: None,
#[cfg(windows)]
logs_directory: None,
- mac_address: None,
memory: None,
memory_file: None,
mmio_address_ranges: Vec::new(),
@@ -1308,8 +1296,6 @@ impl Default for Config {
net: Vec::new(),
#[cfg(windows)]
net_vhost_user_tube: None,
- net_vq_pairs: None,
- netmask: None,
no_i8042: false,
no_rtc: false,
no_smt: false,
@@ -1365,9 +1351,6 @@ impl Default for Config {
swiotlb: None,
#[cfg(windows)]
syslog_tag: None,
- #[cfg(unix)]
- tap_fd: Vec::new(),
- tap_name: Vec::new(),
#[cfg(target_os = "android")]
task_profiles: Vec::new(),
#[cfg(unix)]
@@ -1383,7 +1366,6 @@ impl Default for Config {
vfio: Vec::new(),
#[cfg(unix)]
vfio_isolate_hotplug: false,
- vhost_net: false,
#[cfg(unix)]
vhost_net_device_path: PathBuf::from(VHOST_NET_PATH),
vhost_user_blk: Vec::new(),
diff --git a/src/crosvm/gpu_config.rs b/src/crosvm/gpu_config.rs
index 39fd387da..8f28e064c 100644
--- a/src/crosvm/gpu_config.rs
+++ b/src/crosvm/gpu_config.rs
@@ -412,7 +412,7 @@ mod tests {
let gpu_params = parse_gpu_options("context-types=virgl:cross-domain").unwrap();
assert_eq!(
- gpu_params.context_mask,
+ gpu_params.capset_mask,
(1 << RUTABAGA_CAPSET_VIRGL) | (1 << RUTABAGA_CAPSET_CROSS_DOMAIN)
);
}
diff --git a/src/crosvm/plugin/mod.rs b/src/crosvm/plugin/mod.rs
index 51d6ed405..96c980763 100644
--- a/src/crosvm/plugin/mod.rs
+++ b/src/crosvm/plugin/mod.rs
@@ -48,6 +48,7 @@ use base::Result as SysResult;
use base::SignalFd;
use base::WaitContext;
use base::SIGRTMIN;
+use devices::virtio::NetParametersMode;
use jail::create_sandbox_minijail;
use jail::mount_proc;
use jail::SandboxConfig;
@@ -548,31 +549,52 @@ pub fn run_config(cfg: Config) -> Result<()> {
};
let mut tap_interfaces: Vec<Tap> = Vec::new();
- if let Some(host_ip) = cfg.host_ip {
- if let Some(netmask) = cfg.netmask {
- if let Some(mac_address) = cfg.mac_address {
+ for net_params in cfg.net {
+ if net_params.vhost_net {
+ bail!("vhost-net not supported with plugin");
+ }
+
+ match net_params.mode {
+ NetParametersMode::RawConfig {
+ host_ip,
+ netmask,
+ mac,
+ } => {
let tap = Tap::new(false, false).context("error opening tap device")?;
tap.set_ip_addr(host_ip).context("error setting tap ip")?;
tap.set_netmask(netmask)
.context("error setting tap netmask")?;
- tap.set_mac_address(mac_address)
+ tap.set_mac_address(mac)
.context("error setting tap mac address")?;
tap.enable().context("error enabling tap device")?;
tap_interfaces.push(tap);
}
+ NetParametersMode::TapName { tap_name, mac } => {
+ let tap = Tap::new_with_name(tap_name.as_bytes(), true, false)
+ .context("failed to create tap device from name")?;
+ if let Some(mac) = mac {
+ tap.set_mac_address(mac)
+ .context("error setting tap mac addres")?;
+ }
+ tap_interfaces.push(tap);
+ }
+ NetParametersMode::TapFd { tap_fd, mac } => {
+ // Safe because we ensure that we get a unique handle to the fd.
+ let tap = unsafe {
+ Tap::from_raw_descriptor(
+ validate_raw_descriptor(tap_fd).context("failed to validate raw tap fd")?,
+ )
+ .context("failed to create tap device from raw fd")?
+ };
+ if let Some(mac) = mac {
+ tap.set_mac_address(mac)
+ .context("error setting tap mac addres")?;
+ }
+ tap_interfaces.push(tap);
+ }
}
}
- for tap_fd in cfg.tap_fd {
- // Safe because we ensure that we get a unique handle to the fd.
- let tap = unsafe {
- Tap::from_raw_descriptor(
- validate_raw_descriptor(tap_fd).context("failed to validate raw tap fd")?,
- )
- .context("failed to create tap device from raw fd")?
- };
- tap_interfaces.push(tap);
- }
let plugin_args: Vec<&str> = cfg.params.iter().map(|s| &s[..]).collect();
diff --git a/src/crosvm/sys/unix.rs b/src/crosvm/sys/unix.rs
index 4e8801e1c..c00427b48 100644
--- a/src/crosvm/sys/unix.rs
+++ b/src/crosvm/sys/unix.rs
@@ -77,8 +77,6 @@ use devices::virtio::BalloonFeatures;
use devices::virtio::BalloonMode;
#[cfg(feature = "gpu")]
use devices::virtio::EventDevice;
-use devices::virtio::NetParameters;
-use devices::virtio::NetParametersMode;
use devices::virtio::VirtioTransportType;
#[cfg(feature = "audio")]
use devices::Ac97Dev;
@@ -221,7 +219,7 @@ fn create_virtio_devices(
#[cfg(feature = "gpu")] render_server_fd: Option<SafeDescriptor>,
vvu_proxy_device_tubes: &mut Vec<Tube>,
vvu_proxy_max_sibling_mem_size: u64,
- registered_evt_q: &SendTube,
+ #[cfg_attr(not(feature = "balloon"), allow(unused_variables))] registered_evt_q: &SendTube,
) -> DeviceResult<Vec<VirtioDeviceStub>> {
let mut devs = Vec::new();
@@ -509,42 +507,8 @@ fn create_virtio_devices(
)?);
}
- let mut net_cfg_extra: Vec<_> = cfg
- .tap_fd
- .iter()
- .map(|fd| NetParameters {
- vhost_net: cfg.vhost_net,
- mode: NetParametersMode::TapFd {
- tap_fd: *fd,
- mac: None,
- },
- })
- .collect();
-
- if let (Some(host_ip), Some(netmask), Some(mac)) = (cfg.host_ip, cfg.netmask, cfg.mac_address) {
- if !cfg.vhost_user_net.is_empty() {
- bail!("vhost-user-net cannot be used with any of --host-ip, --netmask or --mac");
- }
- net_cfg_extra.push(NetParameters {
- vhost_net: cfg.vhost_net,
- mode: NetParametersMode::RawConfig {
- host_ip,
- netmask,
- mac,
- },
- });
- }
-
- net_cfg_extra.extend(cfg.tap_name.iter().map(|tap_name| NetParameters {
- vhost_net: cfg.vhost_net,
- mode: NetParametersMode::TapName {
- mac: None,
- tap_name: tap_name.to_owned(),
- },
- }));
-
- for opt in [&cfg.net, &net_cfg_extra].into_iter().flatten() {
- let vq_pairs = cfg.net_vq_pairs.unwrap_or(1);
+ for opt in &cfg.net {
+ let vq_pairs = opt.vq_pairs.unwrap_or(1);
let vcpu_count = cfg.vcpu_count.unwrap_or(1);
let multi_vq = vq_pairs > 1 && !opt.vhost_net;
let (tap, mac) = create_tap_for_net_device(&opt.mode, multi_vq)?;
@@ -844,6 +808,7 @@ fn create_devices(
vm_evt_wrtube,
#[cfg(feature = "balloon")]
balloon_device_tube,
+ #[cfg(feature = "balloon")]
balloon_wss_device_tube,
#[cfg(feature = "balloon")]
balloon_inflate_tube,
@@ -2912,6 +2877,7 @@ fn run_control<V: VmArch + 'static, Vcpu: VcpuArch + 'static>(
let mut pvpanic_code = PvPanicCode::Unknown;
#[cfg(feature = "balloon")]
let mut balloon_stats_id: u64 = 0;
+ #[cfg(feature = "balloon")]
let mut balloon_wss_id: u64 = 0;
let mut registered_evt_tubes: HashMap<RegisteredEvent, HashSet<AddressedTube>> = HashMap::new();
diff --git a/src/crosvm/sys/unix/config.rs b/src/crosvm/sys/unix/config.rs
index 09b626977..a5cfb4f71 100644
--- a/src/crosvm/sys/unix/config.rs
+++ b/src/crosvm/sys/unix/config.rs
@@ -54,19 +54,7 @@ pub fn check_serial_params(_serial_params: &SerialParameters) -> Result<(), Stri
Ok(())
}
-pub fn validate_config(cfg: &mut Config) -> std::result::Result<(), String> {
- if cfg.host_ip.is_some() || cfg.netmask.is_some() || cfg.mac_address.is_some() {
- if cfg.host_ip.is_none() {
- return Err("`host-ip` missing from network config".to_string());
- }
- if cfg.netmask.is_none() {
- return Err("`netmask` missing from network config".to_string());
- }
- if cfg.mac_address.is_none() {
- return Err("`mac` missing from network config".to_string());
- }
- }
-
+pub fn validate_config(_cfg: &mut Config) -> std::result::Result<(), String> {
Ok(())
}