// 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, VmMemoryControlRequestSocket}; 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, 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, }, DebugLabel, DeviceType, QueueMaxSizes, Features, AckFeatures(u64), ReadConfig { offset: u64, len: usize, }, WriteConfig { offset: u64, data: Vec, }, Activate { shm: MaybeOwnedFd, interrupt: MaybeOwnedFd, interrupt_resample_evt: MaybeOwnedFd, queues: Vec, queue_evts: Vec>, }, Reset, GetDeviceBars(PciAddress), GetDeviceCaps, Kill, } impl SerializeWithFds for Request { fn serialize(&self, serializer: S) -> Result { 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 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>(deserializer: D) -> Result { 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>( self, data: A, ) -> Result { #[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>( self, mut seq: A, ) -> Result { use serde::de::Error; fn too_short(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>( self, mut seq: A, ) -> Result { use serde::de::Error; fn too_short(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>( self, mut seq: A, ) -> Result { use serde::de::Error; fn too_short(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>( self, mut seq: A, ) -> Result { use serde::de::Error; fn too_short(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>( self, mut seq: A, ) -> Result { use serde::de::Error; fn too_short(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), Features(u64), ReadConfig(Vec), Reset(bool), GetDeviceBars(Vec), GetDeviceCaps(Vec), Kill, }