diff options
author | Devin Moore <devinmoore@google.com> | 2023-04-10 23:51:43 +0000 |
---|---|---|
committer | Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com> | 2023-04-10 23:51:43 +0000 |
commit | cfcaf8cb174be1174ffca9e3ab5d5c63a62b86d1 (patch) | |
tree | 4f3348034ce8537d526fbafd31c9b83c3cb7251b | |
parent | 808bedf1e3d4324677c4d4bdd36e18c4bdad4d26 (diff) | |
parent | 305ce947f18364eaa808c3c8b7b51699f634227f (diff) | |
download | crosvm-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>
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(()) } |