xref: /aosp_15_r20/external/crosvm/devices/src/virtio/fs/mod.rs (revision bb4ee6a4ae7042d18b07a98463b9c8b875e44b39)
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