1 // Copyright 2018 The Chromium OS Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 use std::os::unix::io::RawFd; 6 use std::sync::atomic::AtomicUsize; 7 use std::sync::Arc; 8 9 use sys_util::{EventFd, GuestMemory}; 10 11 use super::*; 12 use crate::pci::{PciBarConfiguration, PciCapability}; 13 14 /// Trait for virtio devices to be driven by a virtio transport. 15 /// 16 /// The lifecycle of a virtio device is to be moved to a virtio transport, which will then query the 17 /// device. Once the guest driver has configured the device, `VirtioDevice::activate` will be called 18 /// and all the events, memory, and queues for device operation will be moved into the device. 19 /// Optionally, a virtio device can implement device reset in which it returns said resources and 20 /// resets its internal. 21 pub trait VirtioDevice: Send { 22 /// Returns a label suitable for debug output. debug_label(&self) -> String23 fn debug_label(&self) -> String { 24 match type_to_str(self.device_type()) { 25 Some(s) => format!("virtio-{}", s), 26 None => format!("virtio (type {})", self.device_type()), 27 } 28 } 29 30 /// A vector of device-specific file descriptors that must be kept open 31 /// after jailing. Must be called before the process is jailed. keep_fds(&self) -> Vec<RawFd>32 fn keep_fds(&self) -> Vec<RawFd>; 33 34 /// The virtio device type. device_type(&self) -> u3235 fn device_type(&self) -> u32; 36 37 /// The maximum size of each queue that this device supports. queue_max_sizes(&self) -> &[u16]38 fn queue_max_sizes(&self) -> &[u16]; 39 40 /// The set of feature bits that this device supports. features(&self) -> u6441 fn features(&self) -> u64 { 42 1 << VIRTIO_F_VERSION_1 43 } 44 45 /// Acknowledges that this set of features should be enabled. ack_features(&mut self, value: u64)46 fn ack_features(&mut self, value: u64) { 47 let _ = value; 48 } 49 50 /// Reads this device configuration space at `offset`. read_config(&self, offset: u64, data: &mut [u8])51 fn read_config(&self, offset: u64, data: &mut [u8]) { 52 let _ = offset; 53 let _ = data; 54 } 55 56 /// Writes to this device configuration space at `offset`. write_config(&mut self, offset: u64, data: &[u8])57 fn write_config(&mut self, offset: u64, data: &[u8]) { 58 let _ = offset; 59 let _ = data; 60 } 61 62 /// Activates this device for real usage. activate( &mut self, mem: GuestMemory, interrupt_evt: EventFd, interrupt_resample_evt: EventFd, status: Arc<AtomicUsize>, queues: Vec<Queue>, queue_evts: Vec<EventFd>, )63 fn activate( 64 &mut self, 65 mem: GuestMemory, 66 interrupt_evt: EventFd, 67 interrupt_resample_evt: EventFd, 68 status: Arc<AtomicUsize>, 69 queues: Vec<Queue>, 70 queue_evts: Vec<EventFd>, 71 ); 72 73 /// Optionally deactivates this device and returns ownership of the guest memory map, interrupt 74 /// event, and queue events. reset(&mut self) -> Option<(EventFd, Vec<EventFd>)>75 fn reset(&mut self) -> Option<(EventFd, Vec<EventFd>)> { 76 None 77 } 78 79 /// Returns any additional BAR configuration required by the device. get_device_bars(&self) -> Vec<PciBarConfiguration>80 fn get_device_bars(&self) -> Vec<PciBarConfiguration> { 81 Vec::new() 82 } 83 84 /// Returns any additional capabiltiies required by the device. get_device_caps(&self) -> Vec<Box<dyn PciCapability>>85 fn get_device_caps(&self) -> Vec<Box<dyn PciCapability>> { 86 Vec::new() 87 } 88 } 89