diff options
author | Alyssa Ross <hi@alyssa.is> | 2020-04-10 13:19:04 +0000 |
---|---|---|
committer | Alyssa Ross <hi@alyssa.is> | 2020-06-15 09:37:29 +0000 |
commit | eb90518961ca5f00bd832429be840600ce305fb4 (patch) | |
tree | 8415abc6314ac439b47d90305194cc88eca76146 /devices | |
parent | aa9ee49fdf908aef32d4363704099a0584834d4c (diff) | |
download | crosvm-eb90518961ca5f00bd832429be840600ce305fb4.tar crosvm-eb90518961ca5f00bd832429be840600ce305fb4.tar.gz crosvm-eb90518961ca5f00bd832429be840600ce305fb4.tar.bz2 crosvm-eb90518961ca5f00bd832429be840600ce305fb4.tar.lz crosvm-eb90518961ca5f00bd832429be840600ce305fb4.tar.xz crosvm-eb90518961ca5f00bd832429be840600ce305fb4.tar.zst crosvm-eb90518961ca5f00bd832429be840600ce305fb4.zip |
three parts
Diffstat (limited to 'devices')
-rw-r--r-- | devices/src/virtio/controller.rs | 534 | ||||
-rw-r--r-- | devices/src/virtio/mod.rs | 2 | ||||
-rw-r--r-- | devices/src/virtio/remote.rs | 536 | ||||
-rw-r--r-- | devices/src/virtio/virtualized.rs | 505 |
4 files changed, 1052 insertions, 525 deletions
diff --git a/devices/src/virtio/controller.rs b/devices/src/virtio/controller.rs index 7500164..dbb14e6 100644 --- a/devices/src/virtio/controller.rs +++ b/devices/src/virtio/controller.rs @@ -28,539 +28,23 @@ //! the virtio queue, and routing messages in and out of `WlState`. Possible events include the kill //! event, available descriptors on the `in` or `out` queue, and incoming data on any vfd's socket. -use std::fmt::{self, Formatter}; use std::os::unix::io::{AsRawFd, RawFd}; use std::sync::Arc; use std::thread; use msg_socket::{MsgReceiver, MsgSocket}; -use msg_socket2::de::{EnumAccessWithFds, SeqAccessWithFds, VariantAccessWithFds, VisitorWithFds}; -use msg_socket2::ser::{SerializeAdapter, SerializeStructVariantFds, SerializeTupleVariantFds}; -use msg_socket2::{DeserializeWithFds, DeserializerWithFds, FdSerializer, SerializeWithFds}; -use serde::ser::{SerializeStructVariant, SerializeTupleVariant, Serializer}; -use serde::{Deserialize, Serialize}; use sys_util::net::UnixSeqpacket; -use sys_util::{error, EventFd, GuestMemory, PollContext, PollToken, SharedMemory}; +use sys_util::{error, EventFd, GuestMemory, PollContext, PollToken}; +use vm_control::{MaybeOwnedFd, VmMemoryControlRequestSocket}; -use super::{Interrupt, InterruptProxyEvent, Params, Queue, VirtioDevice}; +use super::{ + remote::{Request, Response}, + Interrupt, InterruptProxyEvent, Queue, VirtioDevice, +}; use crate::{ - pci::{PciAddress, PciBarConfiguration, PciCapability, PciCapabilityID}, + pci::{PciAddress, PciBarConfiguration, PciCapability}, MemoryParams, }; -use vm_control::MaybeOwnedFd; - -// As far as I can tell, these never change on the other side, so it's -// fine to just copy them over. -#[derive(Clone, Debug, Deserialize, Serialize)] -pub struct RemotePciCapability { - bytes: Vec<u8>, - id: PciCapabilityID, -} - -impl RemotePciCapability { - pub fn from(capability: &dyn PciCapability) -> Self { - Self { - bytes: capability.bytes().to_vec(), - id: capability.id(), - } - } -} - -impl PciCapability for RemotePciCapability { - fn bytes(&self) -> &[u8] { - &self.bytes - } - - fn id(&self) -> PciCapabilityID { - self.id - } -} - -#[derive(Debug)] -pub enum Request { - Create { - device_params: Params, - memory_params: MemoryParams, - }, - - DebugLabel, - - DeviceType, - - QueueMaxSizes, - - Features, - AckFeatures(u64), - - ReadConfig { - offset: u64, - len: usize, - }, - WriteConfig { - offset: u64, - data: Vec<u8>, - }, - - Activate { - shm: MaybeOwnedFd<SharedMemory>, - interrupt: MaybeOwnedFd<UnixSeqpacket>, - interrupt_resample_evt: MaybeOwnedFd<EventFd>, - queues: Vec<Queue>, - queue_evts: Vec<MaybeOwnedFd<EventFd>>, - }, - - Reset, - - GetDeviceBars(PciAddress), - GetDeviceCaps, - - Kill, -} - -impl SerializeWithFds for Request { - fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> { - use Request::*; - - match self { - Create { - device_params, - memory_params, - } => { - let mut sv = serializer.serialize_struct_variant("Request", 0, "Create", 2)?; - sv.serialize_field("device_params", &SerializeAdapter::new(device_params))?; - sv.serialize_field("memory_params", memory_params)?; - sv.end() - } - - DebugLabel => serializer.serialize_unit_variant("Request", 1, "DebugLabel"), - - DeviceType => serializer.serialize_unit_variant("Request", 2, "DeviceType"), - QueueMaxSizes => serializer.serialize_unit_variant("Request", 3, "QueueMaxSizes"), - - Features => serializer.serialize_unit_variant("Request", 4, "Features"), - - AckFeatures(features) => { - let mut tv = serializer.serialize_tuple_variant("Request", 5, "AckFeatures", 1)?; - tv.serialize_field(features)?; - tv.end() - } - - ReadConfig { offset, len } => { - let mut sv = serializer.serialize_struct_variant("Request", 6, "ReadConfig", 2)?; - sv.serialize_field("offset", offset)?; - sv.serialize_field("len", len)?; - sv.end() - } - - WriteConfig { offset, data } => { - let mut sv = serializer.serialize_struct_variant("Request", 7, "WriteConfig", 2)?; - sv.serialize_field("offset", offset)?; - sv.serialize_field("data", data)?; - sv.end() - } - - Activate { - shm, - interrupt, - interrupt_resample_evt, - queues, - queue_evts, - } => { - let mut sv = serializer.serialize_struct_variant("Request", 8, "Activate", 7)?; - sv.serialize_field("shm", &SerializeAdapter::new(shm))?; - sv.serialize_field("interrupt", &SerializeAdapter::new(interrupt))?; - sv.serialize_field( - "interrupt_resample_evt", - &SerializeAdapter::new(interrupt_resample_evt), - )?; - sv.serialize_field("queues", queues)?; - sv.serialize_field("queue_evts", &SerializeAdapter::new(queue_evts))?; - sv.end() - } - - Reset => serializer.serialize_unit_variant("Request", 9, "Reset"), - - GetDeviceBars(address) => { - let mut sv = - serializer.serialize_struct_variant("Request", 10, "GetDeviceBars", 1)?; - sv.serialize_field("address", address)?; - sv.end() - } - - GetDeviceCaps => serializer.serialize_unit_variant("Request", 11, "GetDeviceCaps"), - - Kill => serializer.serialize_unit_variant("Request", 12, "Kill"), - } - } - - fn serialize_fds<'fds, S>(&'fds self, serializer: S) -> Result<S::Ok, S::Error> - where - S: FdSerializer<'fds>, - { - use Request::*; - - match self { - Create { - device_params, - memory_params, - } => { - let mut sv = serializer.serialize_struct_variant("Request", 0, "Create", 2)?; - sv.serialize_field("device_params", device_params)?; - sv.serialize_field("memory_params", memory_params)?; - sv.end() - } - - DebugLabel => serializer.serialize_unit_variant("Request", 1, "DebugLabel"), - DeviceType => serializer.serialize_unit_variant("Request", 2, "DeviceType"), - QueueMaxSizes => serializer.serialize_unit_variant("Request", 3, "QueueMaxSizes"), - Features => serializer.serialize_unit_variant("Request", 4, "Features"), - - AckFeatures(features) => { - let mut tv = serializer.serialize_tuple_variant("Request", 5, "AckFeatures", 1)?; - tv.serialize_field(features)?; - tv.end() - } - - ReadConfig { offset, len } => { - let mut sv = serializer.serialize_struct_variant("Request", 6, "ReadConfig", 2)?; - sv.serialize_field("offset", offset)?; - sv.serialize_field("len", len)?; - sv.end() - } - - WriteConfig { offset, data } => { - let mut sv = serializer.serialize_struct_variant("Request", 7, "WriteConfig", 2)?; - sv.serialize_field("offset", offset)?; - sv.serialize_field("data", data)?; - sv.end() - } - - Activate { - shm, - interrupt, - interrupt_resample_evt, - queues, - queue_evts, - } => { - let mut sv = serializer.serialize_struct_variant("Request", 8, "Activate", 2)?; - sv.serialize_field("shm", shm)?; - sv.serialize_field("interrupt", interrupt)?; - sv.serialize_field("interrupt_resample_evt", interrupt_resample_evt)?; - sv.serialize_field("queues", queues)?; - sv.serialize_field("queue_evts", queue_evts)?; - sv.end() - } - - Reset => serializer.serialize_unit_variant("Request", 9, "Reset"), - - GetDeviceBars(address) => { - let mut tv = - serializer.serialize_tuple_variant("Request", 10, "GetDeviceBars", 1)?; - tv.serialize_field(address)?; - tv.end() - } - - GetDeviceCaps => serializer.serialize_unit_variant("Request", 11, "GetDeviceCaps"), - - Kill => serializer.serialize_unit_variant("Request", 12, "Kill"), - } - } -} - -impl<'de> DeserializeWithFds<'de> for Request { - fn deserialize<D: DeserializerWithFds<'de>>(deserializer: D) -> Result<Self, D::Error> { - struct Visitor; - - impl<'de> VisitorWithFds<'de> for Visitor { - type Value = Request; - - fn expecting(&self, f: &mut Formatter) -> fmt::Result { - write!(f, "enum Request") - } - - fn visit_enum<A: EnumAccessWithFds<'de>>( - self, - data: A, - ) -> Result<Self::Value, A::Error> { - #[derive(Debug, Deserialize)] - enum Variant { - Create, - DebugLabel, - DeviceType, - QueueMaxSizes, - Features, - AckFeatures, - ReadConfig, - WriteConfig, - Activate, - Reset, - GetDeviceBars, - GetDeviceCaps, - Kill, - } - - match data.variant()? { - (Variant::Create, variant) => { - struct Visitor; - - impl<'de> VisitorWithFds<'de> for Visitor { - type Value = Request; - - fn expecting(&self, f: &mut Formatter) -> fmt::Result { - write!(f, "struct variant Request::Create") - } - - fn visit_seq<A: SeqAccessWithFds<'de>>( - self, - mut seq: A, - ) -> Result<Request, A::Error> { - use serde::de::Error; - - fn too_short<E: Error>(len: usize) -> E { - E::invalid_length( - len, - &"struct variant Request::Create with 2 elements", - ) - } - - Ok(Request::Create { - device_params: seq - .next_element()? - .ok_or_else(|| too_short(0))?, - memory_params: seq - .next_element()? - .ok_or_else(|| too_short(1))?, - }) - } - } - - variant.struct_variant(&["vm_socket", "memory_params"], Visitor) - } - - (Variant::DebugLabel, variant) => { - variant.unit_variant()?; - Ok(Request::DebugLabel) - } - - (Variant::DeviceType, variant) => { - variant.unit_variant()?; - Ok(Request::DeviceType) - } - - (Variant::QueueMaxSizes, variant) => { - variant.unit_variant()?; - Ok(Request::QueueMaxSizes) - } - - (Variant::Features, variant) => { - variant.unit_variant()?; - Ok(Request::Features) - } - - (Variant::AckFeatures, variant) => { - Ok(Request::AckFeatures(variant.newtype_variant()?)) - } - - (Variant::ReadConfig, variant) => { - struct Visitor; - - impl<'de> VisitorWithFds<'de> for Visitor { - type Value = Request; - - fn expecting(&self, f: &mut Formatter) -> fmt::Result { - write!(f, "struct variant Request::ReadConfig") - } - - fn visit_seq<A: SeqAccessWithFds<'de>>( - self, - mut seq: A, - ) -> Result<Request, A::Error> { - use serde::de::Error; - - fn too_short<E: Error>(len: usize) -> E { - E::invalid_length( - len, - &"struct variant Request::ReadConfig with 2 elements", - ) - } - - Ok(Request::ReadConfig { - offset: seq.next_element()?.ok_or_else(|| too_short(0))?, - len: seq.next_element()?.ok_or_else(|| too_short(1))?, - }) - } - } - - variant.struct_variant(&["offset", "len"], Visitor) - } - - (Variant::WriteConfig, variant) => { - struct Visitor; - - impl<'de> VisitorWithFds<'de> for Visitor { - type Value = Request; - - fn expecting(&self, f: &mut Formatter) -> fmt::Result { - write!(f, "struct variant Request::WriteConfig") - } - - fn visit_seq<A: SeqAccessWithFds<'de>>( - self, - mut seq: A, - ) -> Result<Request, A::Error> { - use serde::de::Error; - - fn too_short<E: Error>(len: usize) -> E { - E::invalid_length( - len, - &"struct variant Request::WriteConfig with 2 elements", - ) - } - - Ok(Request::WriteConfig { - offset: seq.next_element()?.ok_or_else(|| too_short(0))?, - data: seq.next_element()?.ok_or_else(|| too_short(1))?, - }) - } - } - - variant.struct_variant(&["offset", "data"], Visitor) - } - - (Variant::Activate, variant) => { - struct Visitor; - - impl<'de> VisitorWithFds<'de> for Visitor { - type Value = Request; - - fn expecting(&self, f: &mut Formatter) -> fmt::Result { - write!(f, "struct variant Request::Activate") - } - - fn visit_seq<A: SeqAccessWithFds<'de>>( - self, - mut seq: A, - ) -> Result<Request, A::Error> { - use serde::de::Error; - - fn too_short<E: Error>(len: usize) -> E { - E::invalid_length( - len, - &"struct variant Request::Activate with 7 elements", - ) - } - - Ok(Request::Activate { - shm: seq.next_element()?.ok_or_else(|| too_short(0))?, - interrupt: seq.next_element()?.ok_or_else(|| too_short(1))?, - interrupt_resample_evt: seq - .next_element()? - .ok_or_else(|| too_short(2))?, - queues: seq.next_element()?.ok_or_else(|| too_short(3))?, - queue_evts: seq.next_element()?.ok_or_else(|| too_short(4))?, - }) - } - } - - variant.struct_variant( - &[ - "shm", - "interrupt", - "interrupt_resample_evt", - "in_queue", - "out_queue", - "in_queue_evt", - "out_queue_evt", - ], - Visitor, - ) - } - - (Variant::Reset, variant) => { - variant.unit_variant()?; - Ok(Request::Reset) - } - - (Variant::GetDeviceBars, variant) => { - struct Visitor; - - impl<'de> VisitorWithFds<'de> for Visitor { - type Value = Request; - - fn expecting(&self, f: &mut Formatter) -> fmt::Result { - write!(f, "struct variant Request::GetDeviceBars") - } - - fn visit_seq<A: SeqAccessWithFds<'de>>( - self, - mut seq: A, - ) -> Result<Request, A::Error> { - use serde::de::Error; - - fn too_short<E: Error>(len: usize) -> E { - E::invalid_length( - len, - &"struct variant Request::GetDeviceBars with 2 elements", - ) - } - - Ok(Request::GetDeviceBars( - seq.next_element()?.ok_or_else(|| too_short(0))?, - )) - } - } - - variant.struct_variant(&["bus", "dev"], Visitor) - } - - (Variant::GetDeviceCaps, variant) => { - variant.unit_variant()?; - Ok(Request::GetDeviceCaps) - } - - (Variant::Kill, variant) => { - variant.unit_variant()?; - Ok(Request::Kill) - } - } - } - } - - deserializer.deserialize_enum( - "Request", - &[ - "Create", - "DebugLabel", - "DeviceType", - "QueueMaxSizes", - "Features", - "AckFeatures", - "ReadConfig", - "WriteConfig", - "Activate", - "Reset", - "GetDeviceBars", - "GetDeviceCaps", - "Kill", - ], - Visitor, - ) - } -} - -#[derive(Debug, Deserialize, DeserializeWithFds, Serialize, SerializeWithFds)] -#[msg_socket2(strategy = "serde")] -pub enum Response { - DebugLabel(String), - DeviceType(u32), - QueueMaxSizes(Vec<u16>), - Features(u64), - ReadConfig(Vec<u8>), - Reset(bool), - GetDeviceBars(Vec<PciBarConfiguration>), - GetDeviceCaps(Vec<RemotePciCapability>), - Kill, -} type Socket = msg_socket2::Socket<Request, Response>; @@ -671,13 +155,13 @@ impl Controller { /// Construct a controller, and initialize (but don't activate) /// the remote device. pub fn create( - device_params: Params, memory_params: MemoryParams, + vm_control_socket: VmMemoryControlRequestSocket, socket: Socket, ) -> Result<Controller, msg_socket2::Error> { socket.send(Request::Create { - device_params, memory_params, + vm_control_socket: MaybeOwnedFd::Borrowed(vm_control_socket.as_raw_fd()), })?; Ok(Controller { diff --git a/devices/src/virtio/mod.rs b/devices/src/virtio/mod.rs index acae318..9bc222e 100644 --- a/devices/src/virtio/mod.rs +++ b/devices/src/virtio/mod.rs @@ -32,8 +32,10 @@ use std::fmt::Debug; pub mod fs; #[cfg(feature = "gpu")] pub mod gpu; +pub mod remote; pub mod resource_bridge; pub mod vhost; +pub mod virtualized; pub use self::balloon::*; pub use self::block::*; diff --git a/devices/src/virtio/remote.rs b/devices/src/virtio/remote.rs new file mode 100644 index 0000000..e7f7967 --- /dev/null +++ b/devices/src/virtio/remote.rs @@ -0,0 +1,536 @@ +// Copyright 2017 The Chromium OS Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +use msg_socket2::de::{EnumAccessWithFds, SeqAccessWithFds, VariantAccessWithFds, VisitorWithFds}; +use msg_socket2::ser::{ + SerializeAdapter, SerializeStructVariant, SerializeStructVariantFds, SerializeTupleVariant, + SerializeTupleVariantFds, Serializer, +}; +use msg_socket2::{ + Deserialize, DeserializeWithFds, DeserializerWithFds, FdSerializer, Serialize, SerializeWithFds, +}; +use std::fmt::{self, Formatter}; +use sys_util::net::UnixSeqpacket; +use sys_util::{EventFd, SharedMemory}; +use vm_control::MaybeOwnedFd; + +use crate::pci::{PciAddress, PciBarConfiguration, PciCapability, PciCapabilityID}; +use crate::virtio::Queue; +use crate::MemoryParams; + +// As far as I can tell, these never change on the other side, so it's +// fine to just copy them over. +#[derive(Clone, Debug, Deserialize, Serialize)] +pub struct RemotePciCapability { + bytes: Vec<u8>, + id: PciCapabilityID, +} + +impl RemotePciCapability { + pub fn from(capability: &dyn PciCapability) -> Self { + Self { + bytes: capability.bytes().to_vec(), + id: capability.id(), + } + } +} + +impl PciCapability for RemotePciCapability { + fn bytes(&self) -> &[u8] { + &self.bytes + } + + fn id(&self) -> PciCapabilityID { + self.id + } +} + +#[derive(Debug)] +pub enum Request { + Create { + memory_params: MemoryParams, + vm_control_socket: MaybeOwnedFd<UnixSeqpacket>, + }, + + DebugLabel, + + DeviceType, + + QueueMaxSizes, + + Features, + AckFeatures(u64), + + ReadConfig { + offset: u64, + len: usize, + }, + WriteConfig { + offset: u64, + data: Vec<u8>, + }, + + Activate { + shm: MaybeOwnedFd<SharedMemory>, + interrupt: MaybeOwnedFd<UnixSeqpacket>, + interrupt_resample_evt: MaybeOwnedFd<EventFd>, + queues: Vec<Queue>, + queue_evts: Vec<MaybeOwnedFd<EventFd>>, + }, + + Reset, + + GetDeviceBars(PciAddress), + GetDeviceCaps, + + Kill, +} + +impl SerializeWithFds for Request { + fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> { + use Request::*; + + match self { + Create { + memory_params, + vm_control_socket, + } => { + let mut sv = serializer.serialize_struct_variant("Request", 0, "Create", 2)?; + sv.serialize_field("memory_params", memory_params)?; + sv.serialize_field( + "vm_control_socket", + &SerializeAdapter::new(vm_control_socket), + )?; + sv.end() + } + + DebugLabel => serializer.serialize_unit_variant("Request", 1, "DebugLabel"), + + DeviceType => serializer.serialize_unit_variant("Request", 2, "DeviceType"), + QueueMaxSizes => serializer.serialize_unit_variant("Request", 3, "QueueMaxSizes"), + + Features => serializer.serialize_unit_variant("Request", 4, "Features"), + + AckFeatures(features) => { + let mut tv = serializer.serialize_tuple_variant("Request", 5, "AckFeatures", 1)?; + tv.serialize_field(features)?; + tv.end() + } + + ReadConfig { offset, len } => { + let mut sv = serializer.serialize_struct_variant("Request", 6, "ReadConfig", 2)?; + sv.serialize_field("offset", offset)?; + sv.serialize_field("len", len)?; + sv.end() + } + + WriteConfig { offset, data } => { + let mut sv = serializer.serialize_struct_variant("Request", 7, "WriteConfig", 2)?; + sv.serialize_field("offset", offset)?; + sv.serialize_field("data", data)?; + sv.end() + } + + Activate { + shm, + interrupt, + interrupt_resample_evt, + queues, + queue_evts, + } => { + let mut sv = serializer.serialize_struct_variant("Request", 8, "Activate", 7)?; + sv.serialize_field("shm", &SerializeAdapter::new(shm))?; + sv.serialize_field("interrupt", &SerializeAdapter::new(interrupt))?; + sv.serialize_field( + "interrupt_resample_evt", + &SerializeAdapter::new(interrupt_resample_evt), + )?; + sv.serialize_field("queues", queues)?; + sv.serialize_field("queue_evts", &SerializeAdapter::new(queue_evts))?; + sv.end() + } + + Reset => serializer.serialize_unit_variant("Request", 9, "Reset"), + + GetDeviceBars(address) => { + let mut tv = + serializer.serialize_tuple_variant("Request", 10, "GetDeviceBars", 1)?; + tv.serialize_field(address)?; + tv.end() + } + + GetDeviceCaps => serializer.serialize_unit_variant("Request", 11, "GetDeviceCaps"), + + Kill => serializer.serialize_unit_variant("Request", 12, "Kill"), + } + } + + fn serialize_fds<'fds, S>(&'fds self, serializer: S) -> Result<S::Ok, S::Error> + where + S: FdSerializer<'fds>, + { + use Request::*; + + match self { + Create { + memory_params, + vm_control_socket, + } => { + let mut sv = serializer.serialize_struct_variant("Request", 0, "Create", 2)?; + sv.serialize_field("memory_params", memory_params)?; + sv.serialize_field("vm_control_socket", vm_control_socket)?; + sv.end() + } + + DebugLabel => serializer.serialize_unit_variant("Request", 1, "DebugLabel"), + DeviceType => serializer.serialize_unit_variant("Request", 2, "DeviceType"), + QueueMaxSizes => serializer.serialize_unit_variant("Request", 3, "QueueMaxSizes"), + Features => serializer.serialize_unit_variant("Request", 4, "Features"), + + AckFeatures(features) => { + let mut tv = serializer.serialize_tuple_variant("Request", 5, "AckFeatures", 1)?; + tv.serialize_field(features)?; + tv.end() + } + + ReadConfig { offset, len } => { + let mut sv = serializer.serialize_struct_variant("Request", 6, "ReadConfig", 2)?; + sv.serialize_field("offset", offset)?; + sv.serialize_field("len", len)?; + sv.end() + } + + WriteConfig { offset, data } => { + let mut sv = serializer.serialize_struct_variant("Request", 7, "WriteConfig", 2)?; + sv.serialize_field("offset", offset)?; + sv.serialize_field("data", data)?; + sv.end() + } + + Activate { + shm, + interrupt, + interrupt_resample_evt, + queues, + queue_evts, + } => { + let mut sv = serializer.serialize_struct_variant("Request", 8, "Activate", 2)?; + sv.serialize_field("shm", shm)?; + sv.serialize_field("interrupt", interrupt)?; + sv.serialize_field("interrupt_resample_evt", interrupt_resample_evt)?; + sv.serialize_field("queues", queues)?; + sv.serialize_field("queue_evts", queue_evts)?; + sv.end() + } + + Reset => serializer.serialize_unit_variant("Request", 9, "Reset"), + + GetDeviceBars(address) => { + let mut tv = + serializer.serialize_tuple_variant("Request", 10, "GetDeviceBars", 1)?; + tv.serialize_field(address)?; + tv.end() + } + + GetDeviceCaps => serializer.serialize_unit_variant("Request", 11, "GetDeviceCaps"), + + Kill => serializer.serialize_unit_variant("Request", 12, "Kill"), + } + } +} + +impl<'de> DeserializeWithFds<'de> for Request { + fn deserialize<D: DeserializerWithFds<'de>>(deserializer: D) -> Result<Self, D::Error> { + struct Visitor; + + impl<'de> VisitorWithFds<'de> for Visitor { + type Value = Request; + + fn expecting(&self, f: &mut Formatter) -> fmt::Result { + write!(f, "enum Request") + } + + fn visit_enum<A: EnumAccessWithFds<'de>>( + self, + data: A, + ) -> Result<Self::Value, A::Error> { + #[derive(Debug, Deserialize)] + enum Variant { + Create, + DebugLabel, + DeviceType, + QueueMaxSizes, + Features, + AckFeatures, + ReadConfig, + WriteConfig, + Activate, + Reset, + GetDeviceBars, + GetDeviceCaps, + Kill, + } + + match data.variant()? { + (Variant::Create, variant) => { + struct Visitor; + + impl<'de> VisitorWithFds<'de> for Visitor { + type Value = Request; + + fn expecting(&self, f: &mut Formatter) -> fmt::Result { + write!(f, "struct variant Request::Create") + } + + fn visit_seq<A: SeqAccessWithFds<'de>>( + self, + mut seq: A, + ) -> Result<Request, A::Error> { + use serde::de::Error; + + fn too_short<E: Error>(len: usize) -> E { + E::invalid_length( + len, + &"struct variant Request::Create with 2 elements", + ) + } + + Ok(Request::Create { + memory_params: seq + .next_element()? + .ok_or_else(|| too_short(0))?, + vm_control_socket: seq + .next_element()? + .ok_or_else(|| too_short(1))?, + }) + } + } + + variant.struct_variant(&["memory_params", "vm_control_socket"], Visitor) + } + + (Variant::DebugLabel, variant) => { + variant.unit_variant()?; + Ok(Request::DebugLabel) + } + + (Variant::DeviceType, variant) => { + variant.unit_variant()?; + Ok(Request::DeviceType) + } + + (Variant::QueueMaxSizes, variant) => { + variant.unit_variant()?; + Ok(Request::QueueMaxSizes) + } + + (Variant::Features, variant) => { + variant.unit_variant()?; + Ok(Request::Features) + } + + (Variant::AckFeatures, variant) => { + Ok(Request::AckFeatures(variant.newtype_variant()?)) + } + + (Variant::ReadConfig, variant) => { + struct Visitor; + + impl<'de> VisitorWithFds<'de> for Visitor { + type Value = Request; + + fn expecting(&self, f: &mut Formatter) -> fmt::Result { + write!(f, "struct variant Request::ReadConfig") + } + + fn visit_seq<A: SeqAccessWithFds<'de>>( + self, + mut seq: A, + ) -> Result<Request, A::Error> { + use serde::de::Error; + + fn too_short<E: Error>(len: usize) -> E { + E::invalid_length( + len, + &"struct variant Request::ReadConfig with 2 elements", + ) + } + + Ok(Request::ReadConfig { + offset: seq.next_element()?.ok_or_else(|| too_short(0))?, + len: seq.next_element()?.ok_or_else(|| too_short(1))?, + }) + } + } + + variant.struct_variant(&["offset", "len"], Visitor) + } + + (Variant::WriteConfig, variant) => { + struct Visitor; + + impl<'de> VisitorWithFds<'de> for Visitor { + type Value = Request; + + fn expecting(&self, f: &mut Formatter) -> fmt::Result { + write!(f, "struct variant Request::WriteConfig") + } + + fn visit_seq<A: SeqAccessWithFds<'de>>( + self, + mut seq: A, + ) -> Result<Request, A::Error> { + use serde::de::Error; + + fn too_short<E: Error>(len: usize) -> E { + E::invalid_length( + len, + &"struct variant Request::WriteConfig with 2 elements", + ) + } + + Ok(Request::WriteConfig { + offset: seq.next_element()?.ok_or_else(|| too_short(0))?, + data: seq.next_element()?.ok_or_else(|| too_short(1))?, + }) + } + } + + variant.struct_variant(&["offset", "data"], Visitor) + } + + (Variant::Activate, variant) => { + struct Visitor; + + impl<'de> VisitorWithFds<'de> for Visitor { + type Value = Request; + + fn expecting(&self, f: &mut Formatter) -> fmt::Result { + write!(f, "struct variant Request::Activate") + } + + fn visit_seq<A: SeqAccessWithFds<'de>>( + self, + mut seq: A, + ) -> Result<Request, A::Error> { + use serde::de::Error; + + fn too_short<E: Error>(len: usize) -> E { + E::invalid_length( + len, + &"struct variant Request::Activate with 7 elements", + ) + } + + Ok(Request::Activate { + shm: seq.next_element()?.ok_or_else(|| too_short(0))?, + interrupt: seq.next_element()?.ok_or_else(|| too_short(1))?, + interrupt_resample_evt: seq + .next_element()? + .ok_or_else(|| too_short(2))?, + queues: seq.next_element()?.ok_or_else(|| too_short(3))?, + queue_evts: seq.next_element()?.ok_or_else(|| too_short(4))?, + }) + } + } + + variant.struct_variant( + &[ + "shm", + "interrupt", + "interrupt_resample_evt", + "in_queue", + "out_queue", + "in_queue_evt", + "out_queue_evt", + ], + Visitor, + ) + } + + (Variant::Reset, variant) => { + variant.unit_variant()?; + Ok(Request::Reset) + } + + (Variant::GetDeviceBars, variant) => { + struct Visitor; + + impl<'de> VisitorWithFds<'de> for Visitor { + type Value = Request; + + fn expecting(&self, f: &mut Formatter) -> fmt::Result { + write!(f, "tuple variant Request::GetDeviceBars") + } + + fn visit_seq<A: SeqAccessWithFds<'de>>( + self, + mut seq: A, + ) -> Result<Request, A::Error> { + use serde::de::Error; + + fn too_short<E: Error>(len: usize) -> E { + E::invalid_length( + len, + &"tuple variant Request::GetDeviceBars with 1 elements", + ) + } + + Ok(Request::GetDeviceBars( + seq.next_element()?.ok_or_else(|| too_short(0))?, + )) + } + } + + variant.struct_variant(&["bus", "dev"], Visitor) + } + + (Variant::GetDeviceCaps, variant) => { + variant.unit_variant()?; + Ok(Request::GetDeviceCaps) + } + + (Variant::Kill, variant) => { + variant.unit_variant()?; + Ok(Request::Kill) + } + } + } + } + + deserializer.deserialize_enum( + "Request", + &[ + "Create", + "DebugLabel", + "DeviceType", + "QueueMaxSizes", + "Features", + "AckFeatures", + "ReadConfig", + "WriteConfig", + "Activate", + "Reset", + "GetDeviceBars", + "GetDeviceCaps", + "Kill", + ], + Visitor, + ) + } +} + +#[derive(Debug, Deserialize, DeserializeWithFds, Serialize, SerializeWithFds)] +#[msg_socket2(strategy = "serde")] +pub enum Response { + DebugLabel(String), + DeviceType(u32), + QueueMaxSizes(Vec<u16>), + Features(u64), + ReadConfig(Vec<u8>), + Reset(bool), + GetDeviceBars(Vec<PciBarConfiguration>), + GetDeviceCaps(Vec<RemotePciCapability>), + Kill, +} diff --git a/devices/src/virtio/virtualized.rs b/devices/src/virtio/virtualized.rs new file mode 100644 index 0000000..fd11f8a --- /dev/null +++ b/devices/src/virtio/virtualized.rs @@ -0,0 +1,505 @@ +// Copyright 2017 The Chromium OS Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +use msg_socket2::de::{EnumAccessWithFds, SeqAccessWithFds, VariantAccessWithFds, VisitorWithFds}; +use msg_socket2::ser::{ + SerializeAdapter, SerializeStructVariant, SerializeStructVariantFds, SerializeTupleVariant, + SerializeTupleVariantFds, Serializer, +}; +use msg_socket2::{ + Deserialize, DeserializeWithFds, DeserializerWithFds, FdSerializer, Serialize, SerializeWithFds, +}; +use std::fmt::{self, Formatter}; +use sys_util::net::UnixSeqpacket; +use sys_util::{EventFd, SharedMemory}; +use vm_control::MaybeOwnedFd; + +use crate::pci::{PciAddress, PciBarConfiguration}; +use crate::virtio::remote::RemotePciCapability; +use crate::virtio::Queue; +use crate::MemoryParams; + +#[derive(Debug)] +pub enum Request { + Create { + memory_params: MemoryParams, + ext_socket: UnixSeqpacket, + }, + + DebugLabel, + + DeviceType, + + QueueMaxSizes, + + Features, + AckFeatures(u64), + + ReadConfig { + offset: u64, + len: usize, + }, + WriteConfig { + offset: u64, + data: Vec<u8>, + }, + + Activate { + shm: MaybeOwnedFd<SharedMemory>, + interrupt: MaybeOwnedFd<UnixSeqpacket>, + interrupt_resample_evt: MaybeOwnedFd<EventFd>, + queues: Vec<Queue>, + queue_evts: Vec<MaybeOwnedFd<EventFd>>, + }, + + Reset, + + GetDeviceBars(PciAddress), + GetDeviceCaps, + + Kill, +} + +impl SerializeWithFds for Request { + fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> { + use Request::*; + + match self { + Create { + memory_params, + ext_socket, + } => { + let mut sv = serializer.serialize_struct_variant("Request", 0, "Create", 2)?; + sv.serialize_field("memory_params", memory_params)?; + sv.serialize_field("ext_socket", &SerializeAdapter::new(ext_socket))?; + sv.end() + } + + DebugLabel => serializer.serialize_unit_variant("Request", 1, "DebugLabel"), + + DeviceType => serializer.serialize_unit_variant("Request", 2, "DeviceType"), + QueueMaxSizes => serializer.serialize_unit_variant("Request", 3, "QueueMaxSizes"), + + Features => serializer.serialize_unit_variant("Request", 4, "Features"), + + AckFeatures(features) => { + let mut tv = serializer.serialize_tuple_variant("Request", 5, "AckFeatures", 1)?; + tv.serialize_field(features)?; + tv.end() + } + + ReadConfig { offset, len } => { + let mut sv = serializer.serialize_struct_variant("Request", 6, "ReadConfig", 2)?; + sv.serialize_field("offset", offset)?; + sv.serialize_field("len", len)?; + sv.end() + } + + WriteConfig { offset, data } => { + let mut sv = serializer.serialize_struct_variant("Request", 7, "WriteConfig", 2)?; + sv.serialize_field("offset", offset)?; + sv.serialize_field("data", data)?; + sv.end() + } + + Activate { + shm, + interrupt, + interrupt_resample_evt, + queues, + queue_evts, + } => { + let mut sv = serializer.serialize_struct_variant("Request", 8, "Activate", 7)?; + sv.serialize_field("shm", &SerializeAdapter::new(shm))?; + sv.serialize_field("interrupt", &SerializeAdapter::new(interrupt))?; + sv.serialize_field( + "interrupt_resample_evt", + &SerializeAdapter::new(interrupt_resample_evt), + )?; + sv.serialize_field("queues", queues)?; + sv.serialize_field("queue_evts", &SerializeAdapter::new(queue_evts))?; + sv.end() + } + + Reset => serializer.serialize_unit_variant("Request", 9, "Reset"), + + GetDeviceBars(address) => { + let mut tv = + serializer.serialize_tuple_variant("Request", 10, "GetDeviceBars", 1)?; + tv.serialize_field(address)?; + tv.end() + } + + GetDeviceCaps => serializer.serialize_unit_variant("Request", 11, "GetDeviceCaps"), + + Kill => serializer.serialize_unit_variant("Request", 12, "Kill"), + } + } + + fn serialize_fds<'fds, S>(&'fds self, serializer: S) -> Result<S::Ok, S::Error> + where + S: FdSerializer<'fds>, + { + use Request::*; + + match self { + Create { + memory_params, + ext_socket, + } => { + let mut sv = serializer.serialize_struct_variant("Request", 0, "Create", 2)?; + sv.serialize_field("memory_params", memory_params)?; + sv.serialize_field("ext_socket", ext_socket)?; + sv.end() + } + + DebugLabel => serializer.serialize_unit_variant("Request", 1, "DebugLabel"), + DeviceType => serializer.serialize_unit_variant("Request", 2, "DeviceType"), + QueueMaxSizes => serializer.serialize_unit_variant("Request", 3, "QueueMaxSizes"), + Features => serializer.serialize_unit_variant("Request", 4, "Features"), + + AckFeatures(features) => { + let mut tv = serializer.serialize_tuple_variant("Request", 5, "AckFeatures", 1)?; + tv.serialize_field(features)?; + tv.end() + } + + ReadConfig { offset, len } => { + let mut sv = serializer.serialize_struct_variant("Request", 6, "ReadConfig", 2)?; + sv.serialize_field("offset", offset)?; + sv.serialize_field("len", len)?; + sv.end() + } + + WriteConfig { offset, data } => { + let mut sv = serializer.serialize_struct_variant("Request", 7, "WriteConfig", 2)?; + sv.serialize_field("offset", offset)?; + sv.serialize_field("data", data)?; + sv.end() + } + + Activate { + shm, + interrupt, + interrupt_resample_evt, + queues, + queue_evts, + } => { + let mut sv = serializer.serialize_struct_variant("Request", 8, "Activate", 2)?; + sv.serialize_field("shm", shm)?; + sv.serialize_field("interrupt", interrupt)?; + sv.serialize_field("interrupt_resample_evt", interrupt_resample_evt)?; + sv.serialize_field("queues", queues)?; + sv.serialize_field("queue_evts", queue_evts)?; + sv.end() + } + + Reset => serializer.serialize_unit_variant("Request", 9, "Reset"), + + GetDeviceBars(address) => { + let mut tv = + serializer.serialize_tuple_variant("Request", 10, "GetDeviceBars", 1)?; + tv.serialize_field(address)?; + tv.end() + } + + GetDeviceCaps => serializer.serialize_unit_variant("Request", 11, "GetDeviceCaps"), + + Kill => serializer.serialize_unit_variant("Request", 12, "Kill"), + } + } +} + +impl<'de> DeserializeWithFds<'de> for Request { + fn deserialize<D: DeserializerWithFds<'de>>(deserializer: D) -> Result<Self, D::Error> { + struct Visitor; + + impl<'de> VisitorWithFds<'de> for Visitor { + type Value = Request; + + fn expecting(&self, f: &mut Formatter) -> fmt::Result { + write!(f, "enum Request") + } + + fn visit_enum<A: EnumAccessWithFds<'de>>( + self, + data: A, + ) -> Result<Self::Value, A::Error> { + #[derive(Debug, Deserialize)] + enum Variant { + Create, + DebugLabel, + DeviceType, + QueueMaxSizes, + Features, + AckFeatures, + ReadConfig, + WriteConfig, + Activate, + Reset, + GetDeviceBars, + GetDeviceCaps, + Kill, + } + + match data.variant()? { + (Variant::Create, variant) => { + struct Visitor; + + impl<'de> VisitorWithFds<'de> for Visitor { + type Value = Request; + + fn expecting(&self, f: &mut Formatter) -> fmt::Result { + write!(f, "struct variant Request::Create") + } + + fn visit_seq<A: SeqAccessWithFds<'de>>( + self, + mut seq: A, + ) -> Result<Request, A::Error> { + use serde::de::Error; + + fn too_short<E: Error>(len: usize) -> E { + E::invalid_length( + len, + &"struct variant Request::Create with 2 elements", + ) + } + + Ok(Request::Create { + memory_params: seq + .next_element()? + .ok_or_else(|| too_short(0))?, + ext_socket: seq.next_element()?.ok_or_else(|| too_short(1))?, + }) + } + } + + variant.struct_variant(&["memory_params", "ext_socket"], Visitor) + } + + (Variant::DebugLabel, variant) => { + variant.unit_variant()?; + Ok(Request::DebugLabel) + } + + (Variant::DeviceType, variant) => { + variant.unit_variant()?; + Ok(Request::DeviceType) + } + + (Variant::QueueMaxSizes, variant) => { + variant.unit_variant()?; + Ok(Request::QueueMaxSizes) + } + + (Variant::Features, variant) => { + variant.unit_variant()?; + Ok(Request::Features) + } + + (Variant::AckFeatures, variant) => { + Ok(Request::AckFeatures(variant.newtype_variant()?)) + } + + (Variant::ReadConfig, variant) => { + struct Visitor; + + impl<'de> VisitorWithFds<'de> for Visitor { + type Value = Request; + + fn expecting(&self, f: &mut Formatter) -> fmt::Result { + write!(f, "struct variant Request::ReadConfig") + } + + fn visit_seq<A: SeqAccessWithFds<'de>>( + self, + mut seq: A, + ) -> Result<Request, A::Error> { + use serde::de::Error; + + fn too_short<E: Error>(len: usize) -> E { + E::invalid_length( + len, + &"struct variant Request::ReadConfig with 2 elements", + ) + } + + Ok(Request::ReadConfig { + offset: seq.next_element()?.ok_or_else(|| too_short(0))?, + len: seq.next_element()?.ok_or_else(|| too_short(1))?, + }) + } + } + + variant.struct_variant(&["offset", "len"], Visitor) + } + + (Variant::WriteConfig, variant) => { + struct Visitor; + + impl<'de> VisitorWithFds<'de> for Visitor { + type Value = Request; + + fn expecting(&self, f: &mut Formatter) -> fmt::Result { + write!(f, "struct variant Request::WriteConfig") + } + + fn visit_seq<A: SeqAccessWithFds<'de>>( + self, + mut seq: A, + ) -> Result<Request, A::Error> { + use serde::de::Error; + + fn too_short<E: Error>(len: usize) -> E { + E::invalid_length( + len, + &"struct variant Request::WriteConfig with 2 elements", + ) + } + + Ok(Request::WriteConfig { + offset: seq.next_element()?.ok_or_else(|| too_short(0))?, + data: seq.next_element()?.ok_or_else(|| too_short(1))?, + }) + } + } + + variant.struct_variant(&["offset", "data"], Visitor) + } + + (Variant::Activate, variant) => { + struct Visitor; + + impl<'de> VisitorWithFds<'de> for Visitor { + type Value = Request; + + fn expecting(&self, f: &mut Formatter) -> fmt::Result { + write!(f, "struct variant Request::Activate") + } + + fn visit_seq<A: SeqAccessWithFds<'de>>( + self, + mut seq: A, + ) -> Result<Request, A::Error> { + use serde::de::Error; + + fn too_short<E: Error>(len: usize) -> E { + E::invalid_length( + len, + &"struct variant Request::Activate with 7 elements", + ) + } + + Ok(Request::Activate { + shm: seq.next_element()?.ok_or_else(|| too_short(0))?, + interrupt: seq.next_element()?.ok_or_else(|| too_short(1))?, + interrupt_resample_evt: seq + .next_element()? + .ok_or_else(|| too_short(2))?, + queues: seq.next_element()?.ok_or_else(|| too_short(3))?, + queue_evts: seq.next_element()?.ok_or_else(|| too_short(4))?, + }) + } + } + + variant.struct_variant( + &[ + "shm", + "interrupt", + "interrupt_resample_evt", + "in_queue", + "out_queue", + "in_queue_evt", + "out_queue_evt", + ], + Visitor, + ) + } + + (Variant::Reset, variant) => { + variant.unit_variant()?; + Ok(Request::Reset) + } + + (Variant::GetDeviceBars, variant) => { + struct Visitor; + + impl<'de> VisitorWithFds<'de> for Visitor { + type Value = Request; + + fn expecting(&self, f: &mut Formatter) -> fmt::Result { + write!(f, "tuple variant Request::GetDeviceBars") + } + + fn visit_seq<A: SeqAccessWithFds<'de>>( + self, + mut seq: A, + ) -> Result<Request, A::Error> { + use serde::de::Error; + + fn too_short<E: Error>(len: usize) -> E { + E::invalid_length( + len, + &"tuple variant Request::GetDeviceBars with 1 elements", + ) + } + + Ok(Request::GetDeviceBars( + seq.next_element()?.ok_or_else(|| too_short(0))?, + )) + } + } + + variant.struct_variant(&["bus", "dev"], Visitor) + } + + (Variant::GetDeviceCaps, variant) => { + variant.unit_variant()?; + Ok(Request::GetDeviceCaps) + } + + (Variant::Kill, variant) => { + variant.unit_variant()?; + Ok(Request::Kill) + } + } + } + } + + deserializer.deserialize_enum( + "Request", + &[ + "Create", + "DebugLabel", + "DeviceType", + "QueueMaxSizes", + "Features", + "AckFeatures", + "ReadConfig", + "WriteConfig", + "Activate", + "Reset", + "GetDeviceBars", + "GetDeviceCaps", + "Kill", + ], + Visitor, + ) + } +} + +#[derive(Debug, Deserialize, DeserializeWithFds, Serialize, SerializeWithFds)] +#[msg_socket2(strategy = "serde")] +pub enum Response { + DebugLabel(String), + DeviceType(u32), + QueueMaxSizes(Vec<u16>), + Features(u64), + ReadConfig(Vec<u8>), + Reset(bool), + GetDeviceBars(Vec<PciBarConfiguration>), + GetDeviceCaps(Vec<RemotePciCapability>), + Kill, +} |