1*bb4ee6a4SAndroid Build Coastguard Worker // Copyright 2019 The ChromiumOS Authors 2*bb4ee6a4SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be 3*bb4ee6a4SAndroid Build Coastguard Worker // found in the LICENSE file. 4*bb4ee6a4SAndroid Build Coastguard Worker 5*bb4ee6a4SAndroid Build Coastguard Worker use std::collections::BTreeMap; 6*bb4ee6a4SAndroid Build Coastguard Worker use std::io; 7*bb4ee6a4SAndroid Build Coastguard Worker use std::sync::Arc; 8*bb4ee6a4SAndroid Build Coastguard Worker 9*bb4ee6a4SAndroid Build Coastguard Worker use anyhow::anyhow; 10*bb4ee6a4SAndroid Build Coastguard Worker use base::error; 11*bb4ee6a4SAndroid Build Coastguard Worker use base::warn; 12*bb4ee6a4SAndroid Build Coastguard Worker use base::AsRawDescriptor; 13*bb4ee6a4SAndroid Build Coastguard Worker use base::Error as SysError; 14*bb4ee6a4SAndroid Build Coastguard Worker use base::RawDescriptor; 15*bb4ee6a4SAndroid Build Coastguard Worker use base::Tube; 16*bb4ee6a4SAndroid Build Coastguard Worker use base::WorkerThread; 17*bb4ee6a4SAndroid Build Coastguard Worker use data_model::Le32; 18*bb4ee6a4SAndroid Build Coastguard Worker use remain::sorted; 19*bb4ee6a4SAndroid Build Coastguard Worker use resources::Alloc; 20*bb4ee6a4SAndroid Build Coastguard Worker use sync::Mutex; 21*bb4ee6a4SAndroid Build Coastguard Worker use thiserror::Error; 22*bb4ee6a4SAndroid Build Coastguard Worker use virtio_sys::virtio_fs::virtio_fs_config; 23*bb4ee6a4SAndroid Build Coastguard Worker use virtio_sys::virtio_fs::VIRTIO_FS_SHMCAP_ID_CACHE; 24*bb4ee6a4SAndroid Build Coastguard Worker use vm_control::FsMappingRequest; 25*bb4ee6a4SAndroid Build Coastguard Worker use vm_control::VmResponse; 26*bb4ee6a4SAndroid Build Coastguard Worker use vm_memory::GuestMemory; 27*bb4ee6a4SAndroid Build Coastguard Worker use zerocopy::AsBytes; 28*bb4ee6a4SAndroid Build Coastguard Worker 29*bb4ee6a4SAndroid Build Coastguard Worker use crate::pci::PciAddress; 30*bb4ee6a4SAndroid Build Coastguard Worker use crate::pci::PciBarConfiguration; 31*bb4ee6a4SAndroid Build Coastguard Worker use crate::pci::PciBarPrefetchable; 32*bb4ee6a4SAndroid Build Coastguard Worker use crate::pci::PciBarRegionType; 33*bb4ee6a4SAndroid Build Coastguard Worker use crate::pci::PciCapability; 34*bb4ee6a4SAndroid Build Coastguard Worker use crate::virtio::copy_config; 35*bb4ee6a4SAndroid Build Coastguard Worker use crate::virtio::device_constants::fs::FS_MAX_TAG_LEN; 36*bb4ee6a4SAndroid Build Coastguard Worker use crate::virtio::DeviceType; 37*bb4ee6a4SAndroid Build Coastguard Worker use crate::virtio::Interrupt; 38*bb4ee6a4SAndroid Build Coastguard Worker use crate::virtio::PciCapabilityType; 39*bb4ee6a4SAndroid Build Coastguard Worker use crate::virtio::Queue; 40*bb4ee6a4SAndroid Build Coastguard Worker use crate::virtio::VirtioDevice; 41*bb4ee6a4SAndroid Build Coastguard Worker use crate::virtio::VirtioPciShmCap; 42*bb4ee6a4SAndroid Build Coastguard Worker 43*bb4ee6a4SAndroid Build Coastguard Worker #[cfg(feature = "arc_quota")] 44*bb4ee6a4SAndroid Build Coastguard Worker mod arc_ioctl; 45*bb4ee6a4SAndroid Build Coastguard Worker mod caps; 46*bb4ee6a4SAndroid Build Coastguard Worker mod config; 47*bb4ee6a4SAndroid Build Coastguard Worker mod expiring_map; 48*bb4ee6a4SAndroid Build Coastguard Worker mod multikey; 49*bb4ee6a4SAndroid Build Coastguard Worker pub mod passthrough; 50*bb4ee6a4SAndroid Build Coastguard Worker mod read_dir; 51*bb4ee6a4SAndroid Build Coastguard Worker mod worker; 52*bb4ee6a4SAndroid Build Coastguard Worker 53*bb4ee6a4SAndroid Build Coastguard Worker pub use config::CachePolicy; 54*bb4ee6a4SAndroid Build Coastguard Worker pub use config::Config; 55*bb4ee6a4SAndroid Build Coastguard Worker use fuse::Server; 56*bb4ee6a4SAndroid Build Coastguard Worker use passthrough::PassthroughFs; 57*bb4ee6a4SAndroid Build Coastguard Worker pub use worker::Worker; 58*bb4ee6a4SAndroid Build Coastguard Worker 59*bb4ee6a4SAndroid Build Coastguard Worker const QUEUE_SIZE: u16 = 1024; 60*bb4ee6a4SAndroid Build Coastguard Worker 61*bb4ee6a4SAndroid Build Coastguard Worker const FS_BAR_NUM: u8 = 4; 62*bb4ee6a4SAndroid Build Coastguard Worker const FS_BAR_OFFSET: u64 = 0; 63*bb4ee6a4SAndroid Build Coastguard Worker const FS_BAR_SIZE: u64 = 1 << 33; 64*bb4ee6a4SAndroid Build Coastguard Worker 65*bb4ee6a4SAndroid Build Coastguard Worker /// Errors that may occur during the creation or operation of an Fs device. 66*bb4ee6a4SAndroid Build Coastguard Worker #[sorted] 67*bb4ee6a4SAndroid Build Coastguard Worker #[derive(Error, Debug)] 68*bb4ee6a4SAndroid Build Coastguard Worker pub enum Error { 69*bb4ee6a4SAndroid Build Coastguard Worker /// Failed to create the file system. 70*bb4ee6a4SAndroid Build Coastguard Worker #[error("failed to create file system: {0}")] 71*bb4ee6a4SAndroid Build Coastguard Worker CreateFs(io::Error), 72*bb4ee6a4SAndroid Build Coastguard Worker /// Creating WaitContext failed. 73*bb4ee6a4SAndroid Build Coastguard Worker #[error("failed to create WaitContext: {0}")] 74*bb4ee6a4SAndroid Build Coastguard Worker CreateWaitContext(SysError), 75*bb4ee6a4SAndroid Build Coastguard Worker /// Error happened in FUSE. 76*bb4ee6a4SAndroid Build Coastguard Worker #[error("fuse error: {0}")] 77*bb4ee6a4SAndroid Build Coastguard Worker FuseError(fuse::Error), 78*bb4ee6a4SAndroid Build Coastguard Worker /// Failed to get the uids for the worker thread. 79*bb4ee6a4SAndroid Build Coastguard Worker #[error("failed to get uids for the worker thread: {0}")] 80*bb4ee6a4SAndroid Build Coastguard Worker GetResuid(SysError), 81*bb4ee6a4SAndroid Build Coastguard Worker /// Failed to get the securebits for the worker thread. 82*bb4ee6a4SAndroid Build Coastguard Worker #[error("failed to get securebits for the worker thread: {0}")] 83*bb4ee6a4SAndroid Build Coastguard Worker GetSecurebits(SysError), 84*bb4ee6a4SAndroid Build Coastguard Worker /// A request is missing readable descriptors. 85*bb4ee6a4SAndroid Build Coastguard Worker #[error("request does not have any readable descriptors")] 86*bb4ee6a4SAndroid Build Coastguard Worker NoReadableDescriptors, 87*bb4ee6a4SAndroid Build Coastguard Worker /// A request is missing writable descriptors. 88*bb4ee6a4SAndroid Build Coastguard Worker #[error("request does not have any writable descriptors")] 89*bb4ee6a4SAndroid Build Coastguard Worker NoWritableDescriptors, 90*bb4ee6a4SAndroid Build Coastguard Worker /// Error while reading from the virtio queue's Event. 91*bb4ee6a4SAndroid Build Coastguard Worker #[error("failed to read from virtio queue Event: {0}")] 92*bb4ee6a4SAndroid Build Coastguard Worker ReadQueueEvent(SysError), 93*bb4ee6a4SAndroid Build Coastguard Worker /// Failed to set the securebits for the worker thread. 94*bb4ee6a4SAndroid Build Coastguard Worker #[error("failed to set securebits for the worker thread: {0}")] 95*bb4ee6a4SAndroid Build Coastguard Worker SetSecurebits(SysError), 96*bb4ee6a4SAndroid Build Coastguard Worker /// Failed to signal the virio used queue. 97*bb4ee6a4SAndroid Build Coastguard Worker #[error("failed to signal used queue: {0}")] 98*bb4ee6a4SAndroid Build Coastguard Worker SignalUsedQueue(SysError), 99*bb4ee6a4SAndroid Build Coastguard Worker /// The tag for the Fs device was too long to fit in the config space. 100*bb4ee6a4SAndroid Build Coastguard Worker #[error("Fs device tag is too long: len = {0}, max = {}", FS_MAX_TAG_LEN)] 101*bb4ee6a4SAndroid Build Coastguard Worker TagTooLong(usize), 102*bb4ee6a4SAndroid Build Coastguard Worker /// Calling unshare to disassociate FS attributes from parent failed. 103*bb4ee6a4SAndroid Build Coastguard Worker #[error("failed to unshare fs from parent: {0}")] 104*bb4ee6a4SAndroid Build Coastguard Worker UnshareFromParent(SysError), 105*bb4ee6a4SAndroid Build Coastguard Worker /// Error while polling for events. 106*bb4ee6a4SAndroid Build Coastguard Worker #[error("failed to wait for events: {0}")] 107*bb4ee6a4SAndroid Build Coastguard Worker WaitError(SysError), 108*bb4ee6a4SAndroid Build Coastguard Worker } 109*bb4ee6a4SAndroid Build Coastguard Worker 110*bb4ee6a4SAndroid Build Coastguard Worker impl From<fuse::Error> for Error { from(err: fuse::Error) -> Error111*bb4ee6a4SAndroid Build Coastguard Worker fn from(err: fuse::Error) -> Error { 112*bb4ee6a4SAndroid Build Coastguard Worker Error::FuseError(err) 113*bb4ee6a4SAndroid Build Coastguard Worker } 114*bb4ee6a4SAndroid Build Coastguard Worker } 115*bb4ee6a4SAndroid Build Coastguard Worker 116*bb4ee6a4SAndroid Build Coastguard Worker pub type Result<T> = ::std::result::Result<T, Error>; 117*bb4ee6a4SAndroid Build Coastguard Worker 118*bb4ee6a4SAndroid Build Coastguard Worker pub struct Fs { 119*bb4ee6a4SAndroid Build Coastguard Worker cfg: virtio_fs_config, 120*bb4ee6a4SAndroid Build Coastguard Worker tag: String, 121*bb4ee6a4SAndroid Build Coastguard Worker fs: Option<PassthroughFs>, 122*bb4ee6a4SAndroid Build Coastguard Worker queue_sizes: Box<[u16]>, 123*bb4ee6a4SAndroid Build Coastguard Worker avail_features: u64, 124*bb4ee6a4SAndroid Build Coastguard Worker acked_features: u64, 125*bb4ee6a4SAndroid Build Coastguard Worker pci_bar: Option<Alloc>, 126*bb4ee6a4SAndroid Build Coastguard Worker tube: Option<Tube>, 127*bb4ee6a4SAndroid Build Coastguard Worker workers: Vec<WorkerThread<Result<()>>>, 128*bb4ee6a4SAndroid Build Coastguard Worker } 129*bb4ee6a4SAndroid Build Coastguard Worker 130*bb4ee6a4SAndroid Build Coastguard Worker impl Fs { new( base_features: u64, tag: &str, num_workers: usize, fs_cfg: Config, tube: Tube, ) -> Result<Fs>131*bb4ee6a4SAndroid Build Coastguard Worker pub fn new( 132*bb4ee6a4SAndroid Build Coastguard Worker base_features: u64, 133*bb4ee6a4SAndroid Build Coastguard Worker tag: &str, 134*bb4ee6a4SAndroid Build Coastguard Worker num_workers: usize, 135*bb4ee6a4SAndroid Build Coastguard Worker fs_cfg: Config, 136*bb4ee6a4SAndroid Build Coastguard Worker tube: Tube, 137*bb4ee6a4SAndroid Build Coastguard Worker ) -> Result<Fs> { 138*bb4ee6a4SAndroid Build Coastguard Worker if tag.len() > FS_MAX_TAG_LEN { 139*bb4ee6a4SAndroid Build Coastguard Worker return Err(Error::TagTooLong(tag.len())); 140*bb4ee6a4SAndroid Build Coastguard Worker } 141*bb4ee6a4SAndroid Build Coastguard Worker 142*bb4ee6a4SAndroid Build Coastguard Worker let mut cfg_tag = [0u8; FS_MAX_TAG_LEN]; 143*bb4ee6a4SAndroid Build Coastguard Worker cfg_tag[..tag.len()].copy_from_slice(tag.as_bytes()); 144*bb4ee6a4SAndroid Build Coastguard Worker 145*bb4ee6a4SAndroid Build Coastguard Worker let cfg = virtio_fs_config { 146*bb4ee6a4SAndroid Build Coastguard Worker tag: cfg_tag, 147*bb4ee6a4SAndroid Build Coastguard Worker num_request_queues: Le32::from(num_workers as u32), 148*bb4ee6a4SAndroid Build Coastguard Worker }; 149*bb4ee6a4SAndroid Build Coastguard Worker 150*bb4ee6a4SAndroid Build Coastguard Worker let fs = PassthroughFs::new(tag, fs_cfg).map_err(Error::CreateFs)?; 151*bb4ee6a4SAndroid Build Coastguard Worker 152*bb4ee6a4SAndroid Build Coastguard Worker // There is always a high priority queue in addition to the request queues. 153*bb4ee6a4SAndroid Build Coastguard Worker let num_queues = num_workers + 1; 154*bb4ee6a4SAndroid Build Coastguard Worker 155*bb4ee6a4SAndroid Build Coastguard Worker Ok(Fs { 156*bb4ee6a4SAndroid Build Coastguard Worker cfg, 157*bb4ee6a4SAndroid Build Coastguard Worker tag: tag.to_string(), 158*bb4ee6a4SAndroid Build Coastguard Worker fs: Some(fs), 159*bb4ee6a4SAndroid Build Coastguard Worker queue_sizes: vec![QUEUE_SIZE; num_queues].into_boxed_slice(), 160*bb4ee6a4SAndroid Build Coastguard Worker avail_features: base_features, 161*bb4ee6a4SAndroid Build Coastguard Worker acked_features: 0, 162*bb4ee6a4SAndroid Build Coastguard Worker pci_bar: None, 163*bb4ee6a4SAndroid Build Coastguard Worker tube: Some(tube), 164*bb4ee6a4SAndroid Build Coastguard Worker workers: Vec::with_capacity(num_workers + 1), 165*bb4ee6a4SAndroid Build Coastguard Worker }) 166*bb4ee6a4SAndroid Build Coastguard Worker } 167*bb4ee6a4SAndroid Build Coastguard Worker } 168*bb4ee6a4SAndroid Build Coastguard Worker 169*bb4ee6a4SAndroid Build Coastguard Worker impl VirtioDevice for Fs { keep_rds(&self) -> Vec<RawDescriptor>170*bb4ee6a4SAndroid Build Coastguard Worker fn keep_rds(&self) -> Vec<RawDescriptor> { 171*bb4ee6a4SAndroid Build Coastguard Worker let mut fds = self 172*bb4ee6a4SAndroid Build Coastguard Worker .fs 173*bb4ee6a4SAndroid Build Coastguard Worker .as_ref() 174*bb4ee6a4SAndroid Build Coastguard Worker .map(PassthroughFs::keep_rds) 175*bb4ee6a4SAndroid Build Coastguard Worker .unwrap_or_default(); 176*bb4ee6a4SAndroid Build Coastguard Worker if let Some(rd) = self.tube.as_ref().map(|s| s.as_raw_descriptor()) { 177*bb4ee6a4SAndroid Build Coastguard Worker fds.push(rd); 178*bb4ee6a4SAndroid Build Coastguard Worker } 179*bb4ee6a4SAndroid Build Coastguard Worker 180*bb4ee6a4SAndroid Build Coastguard Worker fds 181*bb4ee6a4SAndroid Build Coastguard Worker } 182*bb4ee6a4SAndroid Build Coastguard Worker device_type(&self) -> DeviceType183*bb4ee6a4SAndroid Build Coastguard Worker fn device_type(&self) -> DeviceType { 184*bb4ee6a4SAndroid Build Coastguard Worker DeviceType::Fs 185*bb4ee6a4SAndroid Build Coastguard Worker } 186*bb4ee6a4SAndroid Build Coastguard Worker queue_max_sizes(&self) -> &[u16]187*bb4ee6a4SAndroid Build Coastguard Worker fn queue_max_sizes(&self) -> &[u16] { 188*bb4ee6a4SAndroid Build Coastguard Worker &self.queue_sizes 189*bb4ee6a4SAndroid Build Coastguard Worker } 190*bb4ee6a4SAndroid Build Coastguard Worker features(&self) -> u64191*bb4ee6a4SAndroid Build Coastguard Worker fn features(&self) -> u64 { 192*bb4ee6a4SAndroid Build Coastguard Worker self.avail_features 193*bb4ee6a4SAndroid Build Coastguard Worker } 194*bb4ee6a4SAndroid Build Coastguard Worker ack_features(&mut self, mut v: u64)195*bb4ee6a4SAndroid Build Coastguard Worker fn ack_features(&mut self, mut v: u64) { 196*bb4ee6a4SAndroid Build Coastguard Worker // Check if the guest is ACK'ing a feature that we didn't claim to have. 197*bb4ee6a4SAndroid Build Coastguard Worker let unrequested_features = v & !self.avail_features; 198*bb4ee6a4SAndroid Build Coastguard Worker if unrequested_features != 0 { 199*bb4ee6a4SAndroid Build Coastguard Worker warn!("virtio_fs got unknown feature ack: {:x}", v); 200*bb4ee6a4SAndroid Build Coastguard Worker 201*bb4ee6a4SAndroid Build Coastguard Worker // Don't count these features as acked. 202*bb4ee6a4SAndroid Build Coastguard Worker v &= !unrequested_features; 203*bb4ee6a4SAndroid Build Coastguard Worker } 204*bb4ee6a4SAndroid Build Coastguard Worker self.acked_features |= v; 205*bb4ee6a4SAndroid Build Coastguard Worker } 206*bb4ee6a4SAndroid Build Coastguard Worker read_config(&self, offset: u64, data: &mut [u8])207*bb4ee6a4SAndroid Build Coastguard Worker fn read_config(&self, offset: u64, data: &mut [u8]) { 208*bb4ee6a4SAndroid Build Coastguard Worker copy_config(data, 0, self.cfg.as_bytes(), offset) 209*bb4ee6a4SAndroid Build Coastguard Worker } 210*bb4ee6a4SAndroid Build Coastguard Worker activate( &mut self, _guest_mem: GuestMemory, interrupt: Interrupt, queues: BTreeMap<usize, Queue>, ) -> anyhow::Result<()>211*bb4ee6a4SAndroid Build Coastguard Worker fn activate( 212*bb4ee6a4SAndroid Build Coastguard Worker &mut self, 213*bb4ee6a4SAndroid Build Coastguard Worker _guest_mem: GuestMemory, 214*bb4ee6a4SAndroid Build Coastguard Worker interrupt: Interrupt, 215*bb4ee6a4SAndroid Build Coastguard Worker queues: BTreeMap<usize, Queue>, 216*bb4ee6a4SAndroid Build Coastguard Worker ) -> anyhow::Result<()> { 217*bb4ee6a4SAndroid Build Coastguard Worker if queues.len() != self.queue_sizes.len() { 218*bb4ee6a4SAndroid Build Coastguard Worker return Err(anyhow!( 219*bb4ee6a4SAndroid Build Coastguard Worker "expected {} queues, got {}", 220*bb4ee6a4SAndroid Build Coastguard Worker self.queue_sizes.len(), 221*bb4ee6a4SAndroid Build Coastguard Worker queues.len() 222*bb4ee6a4SAndroid Build Coastguard Worker )); 223*bb4ee6a4SAndroid Build Coastguard Worker } 224*bb4ee6a4SAndroid Build Coastguard Worker 225*bb4ee6a4SAndroid Build Coastguard Worker let fs = self.fs.take().expect("missing file system implementation"); 226*bb4ee6a4SAndroid Build Coastguard Worker let use_dax = fs.cfg().use_dax; 227*bb4ee6a4SAndroid Build Coastguard Worker 228*bb4ee6a4SAndroid Build Coastguard Worker let server = Arc::new(Server::new(fs)); 229*bb4ee6a4SAndroid Build Coastguard Worker let socket = self.tube.take().expect("missing mapping socket"); 230*bb4ee6a4SAndroid Build Coastguard Worker let mut slot = 0; 231*bb4ee6a4SAndroid Build Coastguard Worker 232*bb4ee6a4SAndroid Build Coastguard Worker // Set up shared memory for DAX. 233*bb4ee6a4SAndroid Build Coastguard Worker // TODO(b/176129399): Remove cfg! once DAX is supported on ARM. 234*bb4ee6a4SAndroid Build Coastguard Worker if cfg!(target_arch = "x86_64") && use_dax { 235*bb4ee6a4SAndroid Build Coastguard Worker // Create the shared memory region now before we start processing requests. 236*bb4ee6a4SAndroid Build Coastguard Worker let request = FsMappingRequest::AllocateSharedMemoryRegion( 237*bb4ee6a4SAndroid Build Coastguard Worker self.pci_bar.as_ref().cloned().expect("No pci_bar"), 238*bb4ee6a4SAndroid Build Coastguard Worker ); 239*bb4ee6a4SAndroid Build Coastguard Worker socket 240*bb4ee6a4SAndroid Build Coastguard Worker .send(&request) 241*bb4ee6a4SAndroid Build Coastguard Worker .expect("failed to send allocation message"); 242*bb4ee6a4SAndroid Build Coastguard Worker slot = match socket.recv() { 243*bb4ee6a4SAndroid Build Coastguard Worker Ok(VmResponse::RegisterMemory { slot }) => slot, 244*bb4ee6a4SAndroid Build Coastguard Worker Ok(VmResponse::Err(e)) => panic!("failed to allocate shared memory region: {}", e), 245*bb4ee6a4SAndroid Build Coastguard Worker r => panic!( 246*bb4ee6a4SAndroid Build Coastguard Worker "unexpected response to allocate shared memory region: {:?}", 247*bb4ee6a4SAndroid Build Coastguard Worker r 248*bb4ee6a4SAndroid Build Coastguard Worker ), 249*bb4ee6a4SAndroid Build Coastguard Worker }; 250*bb4ee6a4SAndroid Build Coastguard Worker } 251*bb4ee6a4SAndroid Build Coastguard Worker 252*bb4ee6a4SAndroid Build Coastguard Worker let socket = Arc::new(Mutex::new(socket)); 253*bb4ee6a4SAndroid Build Coastguard Worker let mut watch_resample_event = true; 254*bb4ee6a4SAndroid Build Coastguard Worker 255*bb4ee6a4SAndroid Build Coastguard Worker self.workers = queues 256*bb4ee6a4SAndroid Build Coastguard Worker .into_iter() 257*bb4ee6a4SAndroid Build Coastguard Worker .map(|(idx, queue)| { 258*bb4ee6a4SAndroid Build Coastguard Worker let server = server.clone(); 259*bb4ee6a4SAndroid Build Coastguard Worker let irq = interrupt.clone(); 260*bb4ee6a4SAndroid Build Coastguard Worker let socket = Arc::clone(&socket); 261*bb4ee6a4SAndroid Build Coastguard Worker 262*bb4ee6a4SAndroid Build Coastguard Worker let worker = 263*bb4ee6a4SAndroid Build Coastguard Worker WorkerThread::start(format!("v_fs:{}:{}", self.tag, idx), move |kill_evt| { 264*bb4ee6a4SAndroid Build Coastguard Worker let mut worker = Worker::new(queue, server, irq, socket, slot); 265*bb4ee6a4SAndroid Build Coastguard Worker worker.run(kill_evt, watch_resample_event) 266*bb4ee6a4SAndroid Build Coastguard Worker }); 267*bb4ee6a4SAndroid Build Coastguard Worker 268*bb4ee6a4SAndroid Build Coastguard Worker if watch_resample_event { 269*bb4ee6a4SAndroid Build Coastguard Worker watch_resample_event = false; 270*bb4ee6a4SAndroid Build Coastguard Worker } 271*bb4ee6a4SAndroid Build Coastguard Worker 272*bb4ee6a4SAndroid Build Coastguard Worker worker 273*bb4ee6a4SAndroid Build Coastguard Worker }) 274*bb4ee6a4SAndroid Build Coastguard Worker .collect(); 275*bb4ee6a4SAndroid Build Coastguard Worker Ok(()) 276*bb4ee6a4SAndroid Build Coastguard Worker } 277*bb4ee6a4SAndroid Build Coastguard Worker get_device_bars(&mut self, address: PciAddress) -> Vec<PciBarConfiguration>278*bb4ee6a4SAndroid Build Coastguard Worker fn get_device_bars(&mut self, address: PciAddress) -> Vec<PciBarConfiguration> { 279*bb4ee6a4SAndroid Build Coastguard Worker if self.fs.as_ref().map_or(false, |fs| !fs.cfg().use_dax) { 280*bb4ee6a4SAndroid Build Coastguard Worker return vec![]; 281*bb4ee6a4SAndroid Build Coastguard Worker } 282*bb4ee6a4SAndroid Build Coastguard Worker 283*bb4ee6a4SAndroid Build Coastguard Worker self.pci_bar = Some(Alloc::PciBar { 284*bb4ee6a4SAndroid Build Coastguard Worker bus: address.bus, 285*bb4ee6a4SAndroid Build Coastguard Worker dev: address.dev, 286*bb4ee6a4SAndroid Build Coastguard Worker func: address.func, 287*bb4ee6a4SAndroid Build Coastguard Worker bar: FS_BAR_NUM, 288*bb4ee6a4SAndroid Build Coastguard Worker }); 289*bb4ee6a4SAndroid Build Coastguard Worker 290*bb4ee6a4SAndroid Build Coastguard Worker vec![PciBarConfiguration::new( 291*bb4ee6a4SAndroid Build Coastguard Worker FS_BAR_NUM as usize, 292*bb4ee6a4SAndroid Build Coastguard Worker FS_BAR_SIZE, 293*bb4ee6a4SAndroid Build Coastguard Worker PciBarRegionType::Memory64BitRegion, 294*bb4ee6a4SAndroid Build Coastguard Worker PciBarPrefetchable::Prefetchable, 295*bb4ee6a4SAndroid Build Coastguard Worker )] 296*bb4ee6a4SAndroid Build Coastguard Worker } 297*bb4ee6a4SAndroid Build Coastguard Worker get_device_caps(&self) -> Vec<Box<dyn PciCapability>>298*bb4ee6a4SAndroid Build Coastguard Worker fn get_device_caps(&self) -> Vec<Box<dyn PciCapability>> { 299*bb4ee6a4SAndroid Build Coastguard Worker if self.fs.as_ref().map_or(false, |fs| !fs.cfg().use_dax) { 300*bb4ee6a4SAndroid Build Coastguard Worker return vec![]; 301*bb4ee6a4SAndroid Build Coastguard Worker } 302*bb4ee6a4SAndroid Build Coastguard Worker 303*bb4ee6a4SAndroid Build Coastguard Worker vec![Box::new(VirtioPciShmCap::new( 304*bb4ee6a4SAndroid Build Coastguard Worker PciCapabilityType::SharedMemoryConfig, 305*bb4ee6a4SAndroid Build Coastguard Worker FS_BAR_NUM, 306*bb4ee6a4SAndroid Build Coastguard Worker FS_BAR_OFFSET, 307*bb4ee6a4SAndroid Build Coastguard Worker FS_BAR_SIZE, 308*bb4ee6a4SAndroid Build Coastguard Worker VIRTIO_FS_SHMCAP_ID_CACHE as u8, 309*bb4ee6a4SAndroid Build Coastguard Worker ))] 310*bb4ee6a4SAndroid Build Coastguard Worker } 311*bb4ee6a4SAndroid Build Coastguard Worker } 312