xref: /aosp_15_r20/external/crosvm/devices/src/bus.rs (revision bb4ee6a4ae7042d18b07a98463b9c8b875e44b39)
1 // Copyright 2017 The ChromiumOS Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 //! Handles routing to devices in an address space.
6 
7 use std::cmp::Ord;
8 use std::cmp::Ordering;
9 use std::cmp::PartialEq;
10 use std::cmp::PartialOrd;
11 use std::collections::BTreeMap;
12 use std::collections::BTreeSet;
13 use std::fmt;
14 use std::result;
15 use std::sync::Arc;
16 
17 use anyhow::anyhow;
18 use anyhow::Context;
19 use base::debug;
20 use base::error;
21 use base::Event;
22 use base::SharedMemory;
23 use remain::sorted;
24 use serde::Deserialize;
25 use serde::Serialize;
26 use sync::Mutex;
27 use thiserror::Error;
28 
29 #[cfg(feature = "stats")]
30 use crate::bus_stats::BusOperation;
31 #[cfg(feature = "stats")]
32 use crate::BusStatistics;
33 use crate::DeviceId;
34 use crate::PciAddress;
35 use crate::PciDevice;
36 use crate::Suspendable;
37 #[cfg(any(target_os = "android", target_os = "linux"))]
38 use crate::VfioPlatformDevice;
39 use crate::VirtioMmioDevice;
40 
41 /// Information about how a device was accessed.
42 #[derive(Copy, Clone, Eq, PartialEq, Debug, Serialize, Deserialize)]
43 pub struct BusAccessInfo {
44     /// Offset from base address that the device was accessed at.
45     pub offset: u64,
46     /// Absolute address of the device's access in its address space.
47     pub address: u64,
48     /// ID of the entity requesting a device access, usually the VCPU id.
49     pub id: usize,
50 }
51 
52 // Implement `Display` for `MinMax`.
53 impl std::fmt::Display for BusAccessInfo {
fmt(&self, f: &mut fmt::Formatter) -> fmt::Result54     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
55         write!(f, "{:?}", self)
56     }
57 }
58 
59 /// Result of a write to a device's PCI configuration space.
60 /// This value represents the state change(s) that occurred due to the write.
61 #[derive(Clone, Debug, Default, PartialEq, Eq)]
62 pub struct ConfigWriteResult {
63     /// The BusRange in the vector will be removed from mmio_bus
64     pub mmio_remove: Vec<BusRange>,
65 
66     /// The BusRange in the vector will be added into mmio_bus
67     pub mmio_add: Vec<BusRange>,
68 
69     /// The BusRange in the vector will be removed from io_bus
70     pub io_remove: Vec<BusRange>,
71 
72     /// The BusRange in the vector will be added into io_bus
73     pub io_add: Vec<BusRange>,
74 
75     /// Device specified at PciAddress will be removed after this config write
76     /// - `Vec<PciAddress>>`: specified device will be removed after this config write
77     pub removed_pci_devices: Vec<PciAddress>,
78 }
79 
80 #[derive(Copy, Clone, Debug, PartialEq, Eq, Serialize, Deserialize, PartialOrd, Ord)]
81 pub enum BusType {
82     Mmio,
83     Io,
84 }
85 
86 /// Trait for devices that respond to reads or writes in an arbitrary address space.
87 ///
88 /// The device does not care where it exists in address space as each method is only given an offset
89 /// into its allocated portion of address space.
90 #[allow(unused_variables)]
91 pub trait BusDevice: Send + Suspendable {
92     /// Returns a label suitable for debug output.
debug_label(&self) -> String93     fn debug_label(&self) -> String;
94     /// Returns a unique id per device type suitable for metrics gathering.
device_id(&self) -> DeviceId95     fn device_id(&self) -> DeviceId;
96     /// Reads at `offset` from this device
read(&mut self, offset: BusAccessInfo, data: &mut [u8])97     fn read(&mut self, offset: BusAccessInfo, data: &mut [u8]) {}
98     /// Writes at `offset` into this device
write(&mut self, offset: BusAccessInfo, data: &[u8])99     fn write(&mut self, offset: BusAccessInfo, data: &[u8]) {}
100     /// Sets a register in the configuration space. Only used by PCI.
101     /// * `reg_idx` - The index of the config register to modify.
102     /// * `offset` - Offset in to the register.
config_register_write( &mut self, reg_idx: usize, offset: u64, data: &[u8], ) -> ConfigWriteResult103     fn config_register_write(
104         &mut self,
105         reg_idx: usize,
106         offset: u64,
107         data: &[u8],
108     ) -> ConfigWriteResult {
109         ConfigWriteResult {
110             ..Default::default()
111         }
112     }
113     /// Gets a register from the configuration space. Only used by PCI.
114     /// * `reg_idx` - The index of the config register to read.
config_register_read(&self, reg_idx: usize) -> u32115     fn config_register_read(&self, reg_idx: usize) -> u32 {
116         0
117     }
118     /// Provides a memory region to back MMIO access to the configuration
119     /// space. If the device can keep the memory region up to date, then it
120     /// should return true, after which no more calls to config_register_read
121     /// will be made. Otherwise the device should return false.
122     ///
123     /// The device must set the header type register (0x0E) before returning
124     /// from this function, and must make no further modifications to it
125     /// after returning. This is to allow the caller to manage the multi-
126     /// function device bit without worrying about race conditions.
127     ///
128     /// * `shmem` - The shared memory to use for the configuration space.
129     /// * `base` - The base address of the memory region in shmem.
130     /// * `len` - The length of the memory region.
init_pci_config_mapping(&mut self, shmem: &SharedMemory, base: usize, len: usize) -> bool131     fn init_pci_config_mapping(&mut self, shmem: &SharedMemory, base: usize, len: usize) -> bool {
132         false
133     }
134     /// Sets a register in the virtual config space. Only used by PCI.
135     /// * `reg_idx` - The index of the config register to modify.
136     /// * `value` - The value to be written.
virtual_config_register_write(&mut self, reg_idx: usize, value: u32)137     fn virtual_config_register_write(&mut self, reg_idx: usize, value: u32) {}
138     /// Gets a register from the virtual config space. Only used by PCI.
139     /// * `reg_idx` - The index of the config register to read.
virtual_config_register_read(&self, reg_idx: usize) -> u32140     fn virtual_config_register_read(&self, reg_idx: usize) -> u32 {
141         0
142     }
143     /// Invoked when the device is sandboxed.
on_sandboxed(&mut self)144     fn on_sandboxed(&mut self) {}
145 
146     /// Gets a list of all ranges registered by this BusDevice.
get_ranges(&self) -> Vec<(BusRange, BusType)>147     fn get_ranges(&self) -> Vec<(BusRange, BusType)> {
148         Vec::new()
149     }
150 
151     /// Invoked when the device is destroyed
destroy_device(&mut self)152     fn destroy_device(&mut self) {}
153 
154     /// Returns the secondary bus number if this bus device is pci bridge
is_bridge(&self) -> Option<u8>155     fn is_bridge(&self) -> Option<u8> {
156         None
157     }
158 }
159 
160 pub trait BusDeviceSync: BusDevice + Sync {
read(&self, offset: BusAccessInfo, data: &mut [u8])161     fn read(&self, offset: BusAccessInfo, data: &mut [u8]);
write(&self, offset: BusAccessInfo, data: &[u8])162     fn write(&self, offset: BusAccessInfo, data: &[u8]);
snapshot_sync(&self) -> anyhow::Result<serde_json::Value>163     fn snapshot_sync(&self) -> anyhow::Result<serde_json::Value> {
164         Err(anyhow!(
165             "snapshot_sync not implemented for {}",
166             std::any::type_name::<Self>()
167         ))
168     }
169     /// Load a saved snapshot of an image.
restore_sync(&self, _data: serde_json::Value) -> anyhow::Result<()>170     fn restore_sync(&self, _data: serde_json::Value) -> anyhow::Result<()> {
171         Err(anyhow!(
172             "restore_sync not implemented for {}",
173             std::any::type_name::<Self>()
174         ))
175     }
176     /// Stop all threads related to the device.
177     /// Sleep should be idempotent.
sleep_sync(&self) -> anyhow::Result<()>178     fn sleep_sync(&self) -> anyhow::Result<()> {
179         Err(anyhow!(
180             "sleep_sync not implemented for {}",
181             std::any::type_name::<Self>()
182         ))
183     }
184     /// Create/Resume all threads related to the device.
185     /// Wake should be idempotent.
wake_sync(&self) -> anyhow::Result<()>186     fn wake_sync(&self) -> anyhow::Result<()> {
187         Err(anyhow!(
188             "wake_sync not implemented for {}",
189             std::any::type_name::<Self>()
190         ))
191     }
192 }
193 
194 pub trait BusResumeDevice: Send {
195     /// notify the devices which are invoked
196     /// before the VM resumes form suspend.
resume_imminent(&mut self)197     fn resume_imminent(&mut self) {}
198 }
199 
200 /// The key to identify hotplug device from host view.
201 /// like host sysfs path for vfio pci device, host disk file
202 /// path for virtio block device
203 #[derive(Copy, Clone, PartialEq, Eq, Debug, Hash)]
204 pub enum HotPlugKey {
205     HostUpstreamPort { host_addr: PciAddress },
206     HostDownstreamPort { host_addr: PciAddress },
207     HostVfio { host_addr: PciAddress },
208     GuestDevice { guest_addr: PciAddress },
209 }
210 
211 /// Trait for devices that notify hotplug event into guest
212 pub trait HotPlugBus: Send {
213     /// Request hot plug event. Returns error if the request is not sent. Upon success, optionally
214     /// returns an event, which is triggerred once when the guest OS completes the request (by
215     /// sending PCI_EXP_SLTCTL_CCIE). Returns None if no such mechanism is provided.
216     /// * 'addr' - the guest pci address for hotplug in device
hot_plug(&mut self, addr: PciAddress) -> anyhow::Result<Option<Event>>217     fn hot_plug(&mut self, addr: PciAddress) -> anyhow::Result<Option<Event>>;
218     /// Request hot unplug event. Returns error if the request is not sent. Upon success, optionally
219     /// returns an event, which is triggerred once when the guest OS completes the request (by
220     /// sending PCI_EXP_SLTCTL_CCIE). Returns None if no such mechanism is provided.
221     /// * 'addr' - the guest pci address for hotplug out device
hot_unplug(&mut self, addr: PciAddress) -> anyhow::Result<Option<Event>>222     fn hot_unplug(&mut self, addr: PciAddress) -> anyhow::Result<Option<Event>>;
223     /// Get a notification event when the HotPlugBus is ready for hot plug commands. If the port is
224     /// already ready, then the notification event is triggerred immediately.
get_ready_notification(&mut self) -> anyhow::Result<Event>225     fn get_ready_notification(&mut self) -> anyhow::Result<Event>;
226     /// Check whether the hotplug bus is available to add the new device
227     ///
228     /// - 'None': hotplug bus isn't match with host pci device
229     /// - 'Some(bus_num)': hotplug bus is match and put the device at bus_num
is_match(&self, host_addr: PciAddress) -> Option<u8>230     fn is_match(&self, host_addr: PciAddress) -> Option<u8>;
231     /// Gets the upstream PCI Address of the hotplug bus
get_address(&self) -> Option<PciAddress>232     fn get_address(&self) -> Option<PciAddress>;
233     /// Gets the secondary bus number of this bus
get_secondary_bus_number(&self) -> Option<u8>234     fn get_secondary_bus_number(&self) -> Option<u8>;
235     /// Add hotplug device into this bus
236     /// * 'hotplug_key' - the key to identify hotplug device from host view
237     /// * 'guest_addr' - the guest pci address for hotplug device
add_hotplug_device(&mut self, hotplug_key: HotPlugKey, guest_addr: PciAddress)238     fn add_hotplug_device(&mut self, hotplug_key: HotPlugKey, guest_addr: PciAddress);
239     /// get guest pci address from the specified hotplug_key
get_hotplug_device(&self, hotplug_key: HotPlugKey) -> Option<PciAddress>240     fn get_hotplug_device(&self, hotplug_key: HotPlugKey) -> Option<PciAddress>;
241     /// Check whether this hotplug bus is empty
is_empty(&self) -> bool242     fn is_empty(&self) -> bool;
243     /// Get hotplug key of this hotplug bus
get_hotplug_key(&self) -> Option<HotPlugKey>244     fn get_hotplug_key(&self) -> Option<HotPlugKey>;
245 }
246 
247 /// Trait for generic device abstraction, that is, all devices that reside on BusDevice and want
248 /// to be converted back to its original type. Each new foo device must provide
249 /// as_foo_device() + as_foo_device_mut() + into_foo_device(), default impl methods return None.
250 pub trait BusDeviceObj {
as_pci_device(&self) -> Option<&dyn PciDevice>251     fn as_pci_device(&self) -> Option<&dyn PciDevice> {
252         None
253     }
as_pci_device_mut(&mut self) -> Option<&mut dyn PciDevice>254     fn as_pci_device_mut(&mut self) -> Option<&mut dyn PciDevice> {
255         None
256     }
into_pci_device(self: Box<Self>) -> Option<Box<dyn PciDevice>>257     fn into_pci_device(self: Box<Self>) -> Option<Box<dyn PciDevice>> {
258         None
259     }
260     #[cfg(any(target_os = "android", target_os = "linux"))]
as_platform_device(&self) -> Option<&VfioPlatformDevice>261     fn as_platform_device(&self) -> Option<&VfioPlatformDevice> {
262         None
263     }
264     #[cfg(any(target_os = "android", target_os = "linux"))]
as_platform_device_mut(&mut self) -> Option<&mut VfioPlatformDevice>265     fn as_platform_device_mut(&mut self) -> Option<&mut VfioPlatformDevice> {
266         None
267     }
268     #[cfg(any(target_os = "android", target_os = "linux"))]
into_platform_device(self: Box<Self>) -> Option<Box<VfioPlatformDevice>>269     fn into_platform_device(self: Box<Self>) -> Option<Box<VfioPlatformDevice>> {
270         None
271     }
as_virtio_mmio_device(&self) -> Option<&VirtioMmioDevice>272     fn as_virtio_mmio_device(&self) -> Option<&VirtioMmioDevice> {
273         None
274     }
as_virtio_mmio_device_mut(&mut self) -> Option<&mut VirtioMmioDevice>275     fn as_virtio_mmio_device_mut(&mut self) -> Option<&mut VirtioMmioDevice> {
276         None
277     }
into_virtio_mmio_device(self: Box<Self>) -> Option<Box<VirtioMmioDevice>>278     fn into_virtio_mmio_device(self: Box<Self>) -> Option<Box<VirtioMmioDevice>> {
279         None
280     }
281 }
282 
283 #[sorted]
284 #[derive(Error, Debug)]
285 pub enum Error {
286     #[error("Bus Range not found")]
287     Empty,
288     /// The insertion failed because the new device overlapped with an old device.
289     #[error("new device {base},{len} overlaps with an old device {other_base},{other_len}")]
290     Overlap {
291         base: u64,
292         len: u64,
293         other_base: u64,
294         other_len: u64,
295     },
296 }
297 
298 pub type Result<T> = result::Result<T, Error>;
299 
300 /// Holds a base and length representing the address space occupied by a `BusDevice`.
301 ///
302 /// * base - The address at which the range start.
303 /// * len - The length of the range in bytes.
304 #[derive(Copy, Clone, Serialize, Deserialize)]
305 pub struct BusRange {
306     pub base: u64,
307     pub len: u64,
308 }
309 
310 impl BusRange {
311     /// Returns true if `addr` is within the range.
contains(&self, addr: u64) -> bool312     pub fn contains(&self, addr: u64) -> bool {
313         self.base <= addr && addr < self.base.saturating_add(self.len)
314     }
315 
316     /// Returns true if there is overlap with the given range.
overlaps(&self, base: u64, len: u64) -> bool317     pub fn overlaps(&self, base: u64, len: u64) -> bool {
318         self.base < base.saturating_add(len) && base < self.base.saturating_add(self.len)
319     }
320 }
321 
322 impl Eq for BusRange {}
323 
324 impl PartialEq for BusRange {
eq(&self, other: &BusRange) -> bool325     fn eq(&self, other: &BusRange) -> bool {
326         self.base == other.base
327     }
328 }
329 
330 impl Ord for BusRange {
cmp(&self, other: &BusRange) -> Ordering331     fn cmp(&self, other: &BusRange) -> Ordering {
332         self.base.cmp(&other.base)
333     }
334 }
335 
336 impl PartialOrd for BusRange {
partial_cmp(&self, other: &BusRange) -> Option<Ordering>337     fn partial_cmp(&self, other: &BusRange) -> Option<Ordering> {
338         Some(self.cmp(other))
339     }
340 }
341 
342 impl std::fmt::Debug for BusRange {
fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result343     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
344         write!(f, "{:#x}..+{:#x}", self.base, self.len)
345     }
346 }
347 
348 #[derive(Clone)]
349 struct BusEntry {
350     #[cfg(feature = "stats")]
351     index: usize,
352     device: BusDeviceEntry,
353 }
354 
355 #[derive(Clone)]
356 enum BusDeviceEntry {
357     OuterSync(Arc<Mutex<dyn BusDevice>>),
358     InnerSync(Arc<dyn BusDeviceSync>),
359 }
360 
361 /// A device container for routing reads and writes over some address space.
362 ///
363 /// This doesn't have any restrictions on what kind of device or address space this applies to. The
364 /// only restriction is that no two devices can overlap in this address space.
365 #[derive(Clone)]
366 pub struct Bus {
367     devices: Arc<Mutex<BTreeMap<BusRange, BusEntry>>>,
368     access_id: usize,
369     #[cfg(feature = "stats")]
370     pub stats: Arc<Mutex<BusStatistics>>,
371     bus_type: BusType,
372 }
373 
374 impl Bus {
375     /// Constructs an a bus with an empty address space.
new(bus_type: BusType) -> Bus376     pub fn new(bus_type: BusType) -> Bus {
377         Bus {
378             devices: Arc::new(Mutex::new(BTreeMap::new())),
379             access_id: 0,
380             #[cfg(feature = "stats")]
381             stats: Arc::new(Mutex::new(BusStatistics::new())),
382             bus_type,
383         }
384     }
385 
386     /// Gets the bus type
get_bus_type(&self) -> BusType387     pub fn get_bus_type(&self) -> BusType {
388         self.bus_type
389     }
390 
391     /// Sets the id that will be used for BusAccessInfo.
set_access_id(&mut self, id: usize)392     pub fn set_access_id(&mut self, id: usize) {
393         self.access_id = id;
394     }
395 
first_before(&self, addr: u64) -> Option<(BusRange, BusEntry)>396     fn first_before(&self, addr: u64) -> Option<(BusRange, BusEntry)> {
397         let devices = self.devices.lock();
398         let (range, entry) = devices
399             .range(..=BusRange { base: addr, len: 1 })
400             .next_back()?;
401         Some((*range, entry.clone()))
402     }
403 
get_device(&self, addr: u64) -> Option<(u64, u64, BusEntry)>404     fn get_device(&self, addr: u64) -> Option<(u64, u64, BusEntry)> {
405         if let Some((range, entry)) = self.first_before(addr) {
406             let offset = addr - range.base;
407             if offset < range.len {
408                 return Some((offset, addr, entry));
409             }
410         }
411         None
412     }
413 
414     /// There is no unique ID for device instances. For now we use the Arc pointers to dedup them.
415     ///
416     /// See virtio-gpu for an example of a single device instance with multiple bus entries.
417     ///
418     /// TODO: Add a unique ID to BusDevice and use that instead of pointers.
unique_devices(&self) -> Vec<BusDeviceEntry>419     fn unique_devices(&self) -> Vec<BusDeviceEntry> {
420         let mut seen_ptrs = BTreeSet::new();
421         self.devices
422             .lock()
423             .iter()
424             .map(|(_, bus_entry)| bus_entry.device.clone())
425             .filter(|dev| match dev {
426                 BusDeviceEntry::OuterSync(dev) => seen_ptrs.insert(Arc::as_ptr(dev) as *const u8),
427                 BusDeviceEntry::InnerSync(dev) => seen_ptrs.insert(Arc::as_ptr(dev) as *const u8),
428             })
429             .collect()
430     }
431 
432     /// Same as `unique_devices`, but also calculates the "snapshot key" for each device.
433     ///
434     /// The keys are used to associate a particular device with data in a serialized snapshot. The
435     /// keys need to be stable across multiple runs of the same crosvm binary.
436     ///
437     /// It is most convienent to calculate all the snapshot keys at once, because the keys are
438     /// dependant on the order of devices on the bus.
unique_devices_with_snapshot_key(&self) -> Vec<(String, BusDeviceEntry)>439     fn unique_devices_with_snapshot_key(&self) -> Vec<(String, BusDeviceEntry)> {
440         let mut next_ids = BTreeMap::<String, usize>::new();
441         let mut choose_key = |debug_label: String| -> String {
442             let label = debug_label.replace(char::is_whitespace, "-");
443             let id = next_ids.entry(label.clone()).or_default();
444             let key = format!("{}-{}", label, id);
445             *id += 1;
446             key
447         };
448 
449         let mut result = Vec::new();
450         for device_entry in self.unique_devices() {
451             let key = match &device_entry {
452                 BusDeviceEntry::OuterSync(d) => choose_key(d.lock().debug_label()),
453                 BusDeviceEntry::InnerSync(d) => choose_key(d.debug_label()),
454             };
455             result.push((key, device_entry));
456         }
457         result
458     }
459 
sleep_devices(&self) -> anyhow::Result<()>460     pub fn sleep_devices(&self) -> anyhow::Result<()> {
461         for device_entry in self.unique_devices() {
462             match device_entry {
463                 BusDeviceEntry::OuterSync(dev) => {
464                     let mut dev = (*dev).lock();
465                     debug!("Sleep on device: {}", dev.debug_label());
466                     dev.sleep()
467                         .with_context(|| format!("failed to sleep {}", dev.debug_label()))?;
468                 }
469                 BusDeviceEntry::InnerSync(dev) => {
470                     debug!("Sleep on device: {}", dev.debug_label());
471                     dev.sleep_sync()
472                         .with_context(|| format!("failed to sleep {}", dev.debug_label()))?;
473                 }
474             }
475         }
476         Ok(())
477     }
478 
wake_devices(&self) -> anyhow::Result<()>479     pub fn wake_devices(&self) -> anyhow::Result<()> {
480         for device_entry in self.unique_devices() {
481             match device_entry {
482                 BusDeviceEntry::OuterSync(dev) => {
483                     let mut dev = dev.lock();
484                     debug!("Wake on device: {}", dev.debug_label());
485                     dev.wake()
486                         .with_context(|| format!("failed to wake {}", dev.debug_label()))?;
487                 }
488                 BusDeviceEntry::InnerSync(dev) => {
489                     debug!("Wake on device: {}", dev.debug_label());
490                     dev.wake_sync()
491                         .with_context(|| format!("failed to wake {}", dev.debug_label()))?;
492                 }
493             }
494         }
495         Ok(())
496     }
497 
snapshot_devices( &self, snapshot_writer: &vm_control::SnapshotWriter, ) -> anyhow::Result<()>498     pub fn snapshot_devices(
499         &self,
500         snapshot_writer: &vm_control::SnapshotWriter,
501     ) -> anyhow::Result<()> {
502         for (snapshot_key, device_entry) in self.unique_devices_with_snapshot_key() {
503             match device_entry {
504                 BusDeviceEntry::OuterSync(dev) => {
505                     let mut dev = dev.lock();
506                     debug!("Snapshot on device: {}", dev.debug_label());
507                     snapshot_writer.write_fragment(
508                         &snapshot_key,
509                         &(*dev)
510                             .snapshot()
511                             .with_context(|| format!("failed to snapshot {}", dev.debug_label()))?,
512                     )?;
513                 }
514                 BusDeviceEntry::InnerSync(dev) => {
515                     debug!("Snapshot on device: {}", dev.debug_label());
516                     snapshot_writer.write_fragment(
517                         &snapshot_key,
518                         &dev.snapshot_sync()
519                             .with_context(|| format!("failed to snapshot {}", dev.debug_label()))?,
520                     )?;
521                 }
522             }
523         }
524         Ok(())
525     }
526 
restore_devices( &self, snapshot_reader: &vm_control::SnapshotReader, ) -> anyhow::Result<()>527     pub fn restore_devices(
528         &self,
529         snapshot_reader: &vm_control::SnapshotReader,
530     ) -> anyhow::Result<()> {
531         let mut unused_keys: BTreeSet<String> =
532             snapshot_reader.list_fragments()?.into_iter().collect();
533         for (snapshot_key, device_entry) in self.unique_devices_with_snapshot_key() {
534             unused_keys.remove(&snapshot_key);
535             match device_entry {
536                 BusDeviceEntry::OuterSync(dev) => {
537                     let mut dev = dev.lock();
538                     debug!("Restore on device: {}", dev.debug_label());
539                     dev.restore(snapshot_reader.read_fragment(&snapshot_key)?)
540                         .with_context(|| {
541                             format!("restore failed for device {}", dev.debug_label())
542                         })?;
543                 }
544                 BusDeviceEntry::InnerSync(dev) => {
545                     debug!("Restore on device: {}", dev.debug_label());
546                     dev.restore_sync(snapshot_reader.read_fragment(&snapshot_key)?)
547                         .with_context(|| {
548                             format!("restore failed for device {}", dev.debug_label())
549                         })?;
550                 }
551             }
552         }
553 
554         if !unused_keys.is_empty() {
555             error!(
556                 "unused restore data in bus, devices might be missing: {:?}",
557                 unused_keys
558             );
559         }
560 
561         Ok(())
562     }
563 
564     /// Puts the given device at the given address space.
insert(&self, device: Arc<Mutex<dyn BusDevice>>, base: u64, len: u64) -> Result<()>565     pub fn insert(&self, device: Arc<Mutex<dyn BusDevice>>, base: u64, len: u64) -> Result<()> {
566         if len == 0 {
567             return Err(Error::Overlap {
568                 base,
569                 len,
570                 other_base: 0,
571                 other_len: 0,
572             });
573         }
574 
575         // Reject all cases where the new device's range overlaps with an existing device.
576         let mut devices = self.devices.lock();
577         devices.iter().try_for_each(|(range, _dev)| {
578             if range.overlaps(base, len) {
579                 Err(Error::Overlap {
580                     base,
581                     len,
582                     other_base: range.base,
583                     other_len: range.len,
584                 })
585             } else {
586                 Ok(())
587             }
588         })?;
589 
590         #[cfg(feature = "stats")]
591         let name = device.lock().debug_label();
592         #[cfg(feature = "stats")]
593         let device_id = device.lock().device_id();
594         if devices
595             .insert(
596                 BusRange { base, len },
597                 BusEntry {
598                     #[cfg(feature = "stats")]
599                     index: self
600                         .stats
601                         .lock()
602                         .next_device_index(name, device_id.into(), base, len),
603                     device: BusDeviceEntry::OuterSync(device),
604                 },
605             )
606             .is_some()
607         {
608             return Err(Error::Overlap {
609                 base,
610                 len,
611                 other_base: base,
612                 other_len: len,
613             });
614         }
615 
616         Ok(())
617     }
618 
619     /// Puts the given device that implements BusDeviceSync at the given address space. Devices
620     /// that implement BusDeviceSync manage thread safety internally, and thus can be written to
621     /// by multiple threads simultaneously.
insert_sync(&self, device: Arc<dyn BusDeviceSync>, base: u64, len: u64) -> Result<()>622     pub fn insert_sync(&self, device: Arc<dyn BusDeviceSync>, base: u64, len: u64) -> Result<()> {
623         if len == 0 {
624             return Err(Error::Overlap {
625                 base,
626                 len,
627                 other_base: 0,
628                 other_len: 0,
629             });
630         }
631 
632         // Reject all cases where the new device's range overlaps with an existing device.
633         let mut devices = self.devices.lock();
634         devices.iter().try_for_each(|(range, _dev)| {
635             if range.overlaps(base, len) {
636                 Err(Error::Overlap {
637                     base,
638                     len,
639                     other_base: range.base,
640                     other_len: range.len,
641                 })
642             } else {
643                 Ok(())
644             }
645         })?;
646 
647         if devices
648             .insert(
649                 BusRange { base, len },
650                 BusEntry {
651                     #[cfg(feature = "stats")]
652                     index: self.stats.lock().next_device_index(
653                         device.debug_label(),
654                         device.device_id().into(),
655                         base,
656                         len,
657                     ),
658                     device: BusDeviceEntry::InnerSync(device),
659                 },
660             )
661             .is_some()
662         {
663             return Err(Error::Overlap {
664                 base,
665                 len,
666                 other_base: base,
667                 other_len: len,
668             });
669         }
670 
671         Ok(())
672     }
673 
674     /// Remove the given device at the given address space.
remove(&self, base: u64, len: u64) -> Result<()>675     pub fn remove(&self, base: u64, len: u64) -> Result<()> {
676         if len == 0 {
677             return Err(Error::Overlap {
678                 base,
679                 len,
680                 other_base: 0,
681                 other_len: 0,
682             });
683         }
684 
685         let mut devices = self.devices.lock();
686         if devices
687             .iter()
688             .any(|(range, _dev)| range.base == base && range.len == len)
689         {
690             let ret = devices.remove(&BusRange { base, len });
691             if ret.is_some() {
692                 Ok(())
693             } else {
694                 Err(Error::Empty)
695             }
696         } else {
697             Err(Error::Empty)
698         }
699     }
700 
701     /// Reads data from the device that owns the range containing `addr` and puts it into `data`.
702     ///
703     /// Returns true on success, otherwise `data` is filled with zeroes.
read(&self, addr: u64, data: &mut [u8]) -> bool704     pub fn read(&self, addr: u64, data: &mut [u8]) -> bool {
705         #[cfg(feature = "stats")]
706         let start = self.stats.lock().start_stat();
707 
708         // Initialize `data` with all zeroes to ensure consistent results even if device `read()`
709         // implementations don't always fill every byte.
710         data.fill(0);
711 
712         let device_index = if let Some((offset, address, entry)) = self.get_device(addr) {
713             let io = BusAccessInfo {
714                 address,
715                 offset,
716                 id: self.access_id,
717             };
718 
719             match &entry.device {
720                 BusDeviceEntry::OuterSync(dev) => dev.lock().read(io, data),
721                 BusDeviceEntry::InnerSync(dev) => dev.read(io, data),
722             }
723             #[cfg(feature = "stats")]
724             let index = Some(entry.index);
725             #[cfg(not(feature = "stats"))]
726             let index = Some(());
727             index
728         } else {
729             None
730         };
731 
732         #[cfg(feature = "stats")]
733         if let Some(device_index) = device_index {
734             self.stats
735                 .lock()
736                 .end_stat(BusOperation::Write, start, device_index);
737             return true;
738         }
739 
740         device_index.is_some()
741     }
742 
743     /// Writes `data` to the device that owns the range containing `addr`.
744     ///
745     /// Returns true on success, otherwise `data` is untouched.
write(&self, addr: u64, data: &[u8]) -> bool746     pub fn write(&self, addr: u64, data: &[u8]) -> bool {
747         #[cfg(feature = "stats")]
748         let start = self.stats.lock().start_stat();
749 
750         let device_index = if let Some((offset, address, entry)) = self.get_device(addr) {
751             let io = BusAccessInfo {
752                 address,
753                 offset,
754                 id: self.access_id,
755             };
756 
757             match &entry.device {
758                 BusDeviceEntry::OuterSync(dev) => dev.lock().write(io, data),
759                 BusDeviceEntry::InnerSync(dev) => dev.write(io, data),
760             }
761 
762             #[cfg(feature = "stats")]
763             let index = Some(entry.index);
764             #[cfg(not(feature = "stats"))]
765             let index = Some(());
766             index
767         } else {
768             None
769         };
770 
771         #[cfg(feature = "stats")]
772         if let Some(device_index) = device_index {
773             self.stats
774                 .lock()
775                 .end_stat(BusOperation::Write, start, device_index);
776         }
777         device_index.is_some()
778     }
779 }
780 
781 impl Default for Bus {
default() -> Self782     fn default() -> Self {
783         Self::new(BusType::Io)
784     }
785 }
786 
787 #[cfg(test)]
788 mod tests {
789     use anyhow::Result as AnyhowResult;
790 
791     use super::*;
792     use crate::pci::CrosvmDeviceId;
793     use crate::suspendable::Suspendable;
794     use crate::suspendable_tests;
795 
796     #[derive(Copy, Clone, Serialize, Deserialize, Eq, PartialEq, Debug)]
797     struct DummyDevice;
798 
799     impl BusDevice for DummyDevice {
device_id(&self) -> DeviceId800         fn device_id(&self) -> DeviceId {
801             CrosvmDeviceId::Cmos.into()
802         }
debug_label(&self) -> String803         fn debug_label(&self) -> String {
804             "dummy device".to_owned()
805         }
806     }
807 
808     impl Suspendable for DummyDevice {
snapshot(&mut self) -> AnyhowResult<serde_json::Value>809         fn snapshot(&mut self) -> AnyhowResult<serde_json::Value> {
810             serde_json::to_value(self).context("error serializing")
811         }
812 
restore(&mut self, data: serde_json::Value) -> AnyhowResult<()>813         fn restore(&mut self, data: serde_json::Value) -> AnyhowResult<()> {
814             *self = serde_json::from_value(data).context("error deserializing")?;
815             Ok(())
816         }
817 
sleep(&mut self) -> AnyhowResult<()>818         fn sleep(&mut self) -> AnyhowResult<()> {
819             Ok(())
820         }
821 
wake(&mut self) -> AnyhowResult<()>822         fn wake(&mut self) -> AnyhowResult<()> {
823             Ok(())
824         }
825     }
826 
827     #[derive(Copy, Clone, Serialize, Deserialize, Eq, PartialEq, Debug)]
828     struct ConstantDevice {
829         uses_full_addr: bool,
830     }
831 
832     impl BusDevice for ConstantDevice {
device_id(&self) -> DeviceId833         fn device_id(&self) -> DeviceId {
834             CrosvmDeviceId::Cmos.into()
835         }
836 
debug_label(&self) -> String837         fn debug_label(&self) -> String {
838             "constant device".to_owned()
839         }
840 
read(&mut self, info: BusAccessInfo, data: &mut [u8])841         fn read(&mut self, info: BusAccessInfo, data: &mut [u8]) {
842             let addr = if self.uses_full_addr {
843                 info.address
844             } else {
845                 info.offset
846             };
847             for (i, v) in data.iter_mut().enumerate() {
848                 *v = (addr as u8) + (i as u8);
849             }
850         }
851 
write(&mut self, info: BusAccessInfo, data: &[u8])852         fn write(&mut self, info: BusAccessInfo, data: &[u8]) {
853             let addr = if self.uses_full_addr {
854                 info.address
855             } else {
856                 info.offset
857             };
858             for (i, v) in data.iter().enumerate() {
859                 assert_eq!(*v, (addr as u8) + (i as u8))
860             }
861         }
862     }
863 
864     impl Suspendable for ConstantDevice {
snapshot(&mut self) -> AnyhowResult<serde_json::Value>865         fn snapshot(&mut self) -> AnyhowResult<serde_json::Value> {
866             serde_json::to_value(self).context("error serializing")
867         }
868 
restore(&mut self, data: serde_json::Value) -> AnyhowResult<()>869         fn restore(&mut self, data: serde_json::Value) -> AnyhowResult<()> {
870             *self = serde_json::from_value(data).context("error deserializing")?;
871             Ok(())
872         }
873 
sleep(&mut self) -> AnyhowResult<()>874         fn sleep(&mut self) -> AnyhowResult<()> {
875             Ok(())
876         }
877 
wake(&mut self) -> AnyhowResult<()>878         fn wake(&mut self) -> AnyhowResult<()> {
879             Ok(())
880         }
881     }
882 
modify_constant_device(constant: &mut ConstantDevice)883     fn modify_constant_device(constant: &mut ConstantDevice) {
884         constant.uses_full_addr = !constant.uses_full_addr;
885     }
886 
887     #[test]
bus_insert()888     fn bus_insert() {
889         let bus = Bus::new(BusType::Io);
890         let dummy = Arc::new(Mutex::new(DummyDevice));
891         assert!(bus.insert(dummy.clone(), 0x10, 0).is_err());
892         assert!(bus.insert(dummy.clone(), 0x10, 0x10).is_ok());
893         assert!(bus.insert(dummy.clone(), 0x0f, 0x10).is_err());
894         assert!(bus.insert(dummy.clone(), 0x10, 0x10).is_err());
895         assert!(bus.insert(dummy.clone(), 0x10, 0x15).is_err());
896         assert!(bus.insert(dummy.clone(), 0x12, 0x15).is_err());
897         assert!(bus.insert(dummy.clone(), 0x12, 0x01).is_err());
898         assert!(bus.insert(dummy.clone(), 0x0, 0x20).is_err());
899         assert!(bus.insert(dummy.clone(), 0x20, 0x05).is_ok());
900         assert!(bus.insert(dummy.clone(), 0x25, 0x05).is_ok());
901         assert!(bus.insert(dummy, 0x0, 0x10).is_ok());
902     }
903 
904     #[test]
bus_insert_full_addr()905     fn bus_insert_full_addr() {
906         let bus = Bus::new(BusType::Io);
907         let dummy = Arc::new(Mutex::new(DummyDevice));
908         assert!(bus.insert(dummy.clone(), 0x10, 0).is_err());
909         assert!(bus.insert(dummy.clone(), 0x10, 0x10).is_ok());
910         assert!(bus.insert(dummy.clone(), 0x0f, 0x10).is_err());
911         assert!(bus.insert(dummy.clone(), 0x10, 0x10).is_err());
912         assert!(bus.insert(dummy.clone(), 0x10, 0x15).is_err());
913         assert!(bus.insert(dummy.clone(), 0x12, 0x15).is_err());
914         assert!(bus.insert(dummy.clone(), 0x12, 0x01).is_err());
915         assert!(bus.insert(dummy.clone(), 0x0, 0x20).is_err());
916         assert!(bus.insert(dummy.clone(), 0x20, 0x05).is_ok());
917         assert!(bus.insert(dummy.clone(), 0x25, 0x05).is_ok());
918         assert!(bus.insert(dummy, 0x0, 0x10).is_ok());
919     }
920 
921     #[test]
bus_read_write()922     fn bus_read_write() {
923         let bus = Bus::new(BusType::Io);
924         let dummy = Arc::new(Mutex::new(DummyDevice));
925         assert!(bus.insert(dummy, 0x10, 0x10).is_ok());
926         assert!(bus.read(0x10, &mut [0, 0, 0, 0]));
927         assert!(bus.write(0x10, &[0, 0, 0, 0]));
928         assert!(bus.read(0x11, &mut [0, 0, 0, 0]));
929         assert!(bus.write(0x11, &[0, 0, 0, 0]));
930         assert!(bus.read(0x16, &mut [0, 0, 0, 0]));
931         assert!(bus.write(0x16, &[0, 0, 0, 0]));
932         assert!(!bus.read(0x20, &mut [0, 0, 0, 0]));
933         assert!(!bus.write(0x20, &[0, 0, 0, 0]));
934         assert!(!bus.read(0x06, &mut [0, 0, 0, 0]));
935         assert!(!bus.write(0x06, &[0, 0, 0, 0]));
936     }
937 
938     #[test]
bus_read_write_values()939     fn bus_read_write_values() {
940         let bus = Bus::new(BusType::Io);
941         let dummy = Arc::new(Mutex::new(ConstantDevice {
942             uses_full_addr: false,
943         }));
944         assert!(bus.insert(dummy, 0x10, 0x10).is_ok());
945 
946         let mut values = [0, 1, 2, 3];
947         assert!(bus.read(0x10, &mut values));
948         assert_eq!(values, [0, 1, 2, 3]);
949         assert!(bus.write(0x10, &values));
950         assert!(bus.read(0x15, &mut values));
951         assert_eq!(values, [5, 6, 7, 8]);
952         assert!(bus.write(0x15, &values));
953     }
954 
955     #[test]
bus_read_write_full_addr_values()956     fn bus_read_write_full_addr_values() {
957         let bus = Bus::new(BusType::Io);
958         let dummy = Arc::new(Mutex::new(ConstantDevice {
959             uses_full_addr: true,
960         }));
961         assert!(bus.insert(dummy, 0x10, 0x10).is_ok());
962 
963         let mut values = [0u8; 4];
964         assert!(bus.read(0x10, &mut values));
965         assert_eq!(values, [0x10, 0x11, 0x12, 0x13]);
966         assert!(bus.write(0x10, &values));
967         assert!(bus.read(0x15, &mut values));
968         assert_eq!(values, [0x15, 0x16, 0x17, 0x18]);
969         assert!(bus.write(0x15, &values));
970     }
971 
972     #[test]
bus_read_no_device()973     fn bus_read_no_device() {
974         let bus = Bus::new(BusType::Io);
975 
976         // read() should return false, since there is no device at address 0x10, but it should
977         // also fill the data with 0s.
978         let mut values = [1, 2, 3, 4];
979         assert!(!bus.read(0x10, &mut values));
980         assert_eq!(values, [0, 0, 0, 0]);
981     }
982 
983     suspendable_tests!(
984         constant_device_true,
985         ConstantDevice {
986             uses_full_addr: true,
987         },
988         modify_constant_device
989     );
990 
991     suspendable_tests!(
992         constant_device_false,
993         ConstantDevice {
994             uses_full_addr: false,
995         },
996         modify_constant_device
997     );
998 
999     #[test]
bus_range_contains()1000     fn bus_range_contains() {
1001         let a = BusRange {
1002             base: 0x1000,
1003             len: 0x400,
1004         };
1005         assert!(a.contains(0x1000));
1006         assert!(a.contains(0x13ff));
1007         assert!(!a.contains(0xfff));
1008         assert!(!a.contains(0x1400));
1009         assert!(a.contains(0x1200));
1010     }
1011 
1012     #[test]
bus_range_overlap()1013     fn bus_range_overlap() {
1014         let a = BusRange {
1015             base: 0x1000,
1016             len: 0x400,
1017         };
1018         assert!(a.overlaps(0x1000, 0x400));
1019         assert!(a.overlaps(0xf00, 0x400));
1020         assert!(a.overlaps(0x1000, 0x01));
1021         assert!(a.overlaps(0xfff, 0x02));
1022         assert!(a.overlaps(0x1100, 0x100));
1023         assert!(a.overlaps(0x13ff, 0x100));
1024         assert!(!a.overlaps(0x1400, 0x100));
1025         assert!(!a.overlaps(0xf00, 0x100));
1026     }
1027 }
1028