• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 snapshot::AnySnapshot;
27 use sync::Mutex;
28 use thiserror::Error;
29 
30 #[cfg(feature = "stats")]
31 use crate::bus_stats::BusOperation;
32 #[cfg(feature = "stats")]
33 use crate::BusStatistics;
34 use crate::DeviceId;
35 use crate::PciAddress;
36 use crate::PciDevice;
37 use crate::Suspendable;
38 #[cfg(any(target_os = "android", target_os = "linux"))]
39 use crate::VfioPlatformDevice;
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<AnySnapshot>163     fn snapshot_sync(&self) -> anyhow::Result<AnySnapshot> {
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: AnySnapshot) -> anyhow::Result<()>170     fn restore_sync(&self, _data: AnySnapshot) -> 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     }
272 }
273 
274 #[sorted]
275 #[derive(Error, Debug)]
276 pub enum Error {
277     #[error("Bus Range not found")]
278     Empty,
279     /// The insertion failed because the new device overlapped with an old device.
280     #[error("new device {base},{len} overlaps with an old device {other_base},{other_len}")]
281     Overlap {
282         base: u64,
283         len: u64,
284         other_base: u64,
285         other_len: u64,
286     },
287 }
288 
289 pub type Result<T> = result::Result<T, Error>;
290 
291 /// Holds a base and length representing the address space occupied by a `BusDevice`.
292 ///
293 /// * base - The address at which the range start.
294 /// * len - The length of the range in bytes.
295 #[derive(Copy, Clone, Serialize, Deserialize)]
296 pub struct BusRange {
297     pub base: u64,
298     pub len: u64,
299 }
300 
301 impl BusRange {
302     /// Returns true if `addr` is within the range.
contains(&self, addr: u64) -> bool303     pub fn contains(&self, addr: u64) -> bool {
304         self.base <= addr && addr < self.base.saturating_add(self.len)
305     }
306 
307     /// Returns true if there is overlap with the given range.
overlaps(&self, base: u64, len: u64) -> bool308     pub fn overlaps(&self, base: u64, len: u64) -> bool {
309         self.base < base.saturating_add(len) && base < self.base.saturating_add(self.len)
310     }
311 }
312 
313 impl Eq for BusRange {}
314 
315 impl PartialEq for BusRange {
eq(&self, other: &BusRange) -> bool316     fn eq(&self, other: &BusRange) -> bool {
317         self.base == other.base
318     }
319 }
320 
321 impl Ord for BusRange {
cmp(&self, other: &BusRange) -> Ordering322     fn cmp(&self, other: &BusRange) -> Ordering {
323         self.base.cmp(&other.base)
324     }
325 }
326 
327 impl PartialOrd for BusRange {
partial_cmp(&self, other: &BusRange) -> Option<Ordering>328     fn partial_cmp(&self, other: &BusRange) -> Option<Ordering> {
329         Some(self.cmp(other))
330     }
331 }
332 
333 impl std::fmt::Debug for BusRange {
fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result334     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
335         write!(f, "{:#x}..+{:#x}", self.base, self.len)
336     }
337 }
338 
339 #[derive(Clone)]
340 struct BusEntry {
341     #[cfg(feature = "stats")]
342     index: usize,
343     device: BusDeviceEntry,
344 }
345 
346 #[derive(Clone)]
347 enum BusDeviceEntry {
348     OuterSync(Arc<Mutex<dyn BusDevice>>),
349     InnerSync(Arc<dyn BusDeviceSync>),
350 }
351 
352 /// A device container for routing reads and writes over some address space.
353 ///
354 /// This doesn't have any restrictions on what kind of device or address space this applies to. The
355 /// only restriction is that no two devices can overlap in this address space.
356 #[derive(Clone)]
357 pub struct Bus {
358     devices: Arc<Mutex<BTreeMap<BusRange, BusEntry>>>,
359     access_id: usize,
360     #[cfg(feature = "stats")]
361     pub stats: Arc<Mutex<BusStatistics>>,
362     bus_type: BusType,
363 }
364 
365 impl Bus {
366     /// Constructs an a bus with an empty address space.
new(bus_type: BusType) -> Bus367     pub fn new(bus_type: BusType) -> Bus {
368         Bus {
369             devices: Arc::new(Mutex::new(BTreeMap::new())),
370             access_id: 0,
371             #[cfg(feature = "stats")]
372             stats: Arc::new(Mutex::new(BusStatistics::new())),
373             bus_type,
374         }
375     }
376 
377     /// Gets the bus type
get_bus_type(&self) -> BusType378     pub fn get_bus_type(&self) -> BusType {
379         self.bus_type
380     }
381 
382     /// Sets the id that will be used for BusAccessInfo.
set_access_id(&mut self, id: usize)383     pub fn set_access_id(&mut self, id: usize) {
384         self.access_id = id;
385     }
386 
first_before(&self, addr: u64) -> Option<(BusRange, BusEntry)>387     fn first_before(&self, addr: u64) -> Option<(BusRange, BusEntry)> {
388         let devices = self.devices.lock();
389         let (range, entry) = devices
390             .range(..=BusRange { base: addr, len: 1 })
391             .next_back()?;
392         Some((*range, entry.clone()))
393     }
394 
get_device(&self, addr: u64) -> Option<(u64, u64, BusEntry)>395     fn get_device(&self, addr: u64) -> Option<(u64, u64, BusEntry)> {
396         if let Some((range, entry)) = self.first_before(addr) {
397             let offset = addr - range.base;
398             if offset < range.len {
399                 return Some((offset, addr, entry));
400             }
401         }
402         None
403     }
404 
405     /// There is no unique ID for device instances. For now we use the Arc pointers to dedup them.
406     ///
407     /// See virtio-gpu for an example of a single device instance with multiple bus entries.
408     ///
409     /// TODO: Add a unique ID to BusDevice and use that instead of pointers.
unique_devices(&self) -> Vec<BusDeviceEntry>410     fn unique_devices(&self) -> Vec<BusDeviceEntry> {
411         let mut seen_ptrs = BTreeSet::new();
412         self.devices
413             .lock()
414             .iter()
415             .map(|(_, bus_entry)| bus_entry.device.clone())
416             .filter(|dev| match dev {
417                 BusDeviceEntry::OuterSync(dev) => seen_ptrs.insert(Arc::as_ptr(dev) as *const u8),
418                 BusDeviceEntry::InnerSync(dev) => seen_ptrs.insert(Arc::as_ptr(dev) as *const u8),
419             })
420             .collect()
421     }
422 
423     /// Same as `unique_devices`, but also calculates the "snapshot key" for each device.
424     ///
425     /// The keys are used to associate a particular device with data in a serialized snapshot. The
426     /// keys need to be stable across multiple runs of the same crosvm binary.
427     ///
428     /// It is most convienent to calculate all the snapshot keys at once, because the keys are
429     /// dependant on the order of devices on the bus.
unique_devices_with_snapshot_key(&self) -> Vec<(String, BusDeviceEntry)>430     fn unique_devices_with_snapshot_key(&self) -> Vec<(String, BusDeviceEntry)> {
431         let mut next_ids = BTreeMap::<String, usize>::new();
432         let mut choose_key = |debug_label: String| -> String {
433             let label = debug_label.replace(char::is_whitespace, "-");
434             let id = next_ids.entry(label.clone()).or_default();
435             let key = format!("{}-{}", label, id);
436             *id += 1;
437             key
438         };
439 
440         let mut result = Vec::new();
441         for device_entry in self.unique_devices() {
442             let key = match &device_entry {
443                 BusDeviceEntry::OuterSync(d) => choose_key(d.lock().debug_label()),
444                 BusDeviceEntry::InnerSync(d) => choose_key(d.debug_label()),
445             };
446             result.push((key, device_entry));
447         }
448         result
449     }
450 
sleep_devices(&self) -> anyhow::Result<()>451     pub fn sleep_devices(&self) -> anyhow::Result<()> {
452         for device_entry in self.unique_devices() {
453             match device_entry {
454                 BusDeviceEntry::OuterSync(dev) => {
455                     let mut dev = (*dev).lock();
456                     debug!("Sleep on device: {}", dev.debug_label());
457                     dev.sleep()
458                         .with_context(|| format!("failed to sleep {}", dev.debug_label()))?;
459                 }
460                 BusDeviceEntry::InnerSync(dev) => {
461                     debug!("Sleep on device: {}", dev.debug_label());
462                     dev.sleep_sync()
463                         .with_context(|| format!("failed to sleep {}", dev.debug_label()))?;
464                 }
465             }
466         }
467         Ok(())
468     }
469 
wake_devices(&self) -> anyhow::Result<()>470     pub fn wake_devices(&self) -> anyhow::Result<()> {
471         for device_entry in self.unique_devices() {
472             match device_entry {
473                 BusDeviceEntry::OuterSync(dev) => {
474                     let mut dev = dev.lock();
475                     debug!("Wake on device: {}", dev.debug_label());
476                     dev.wake()
477                         .with_context(|| format!("failed to wake {}", dev.debug_label()))?;
478                 }
479                 BusDeviceEntry::InnerSync(dev) => {
480                     debug!("Wake on device: {}", dev.debug_label());
481                     dev.wake_sync()
482                         .with_context(|| format!("failed to wake {}", dev.debug_label()))?;
483                 }
484             }
485         }
486         Ok(())
487     }
488 
snapshot_devices( &self, snapshot_writer: &snapshot::SnapshotWriter, ) -> anyhow::Result<()>489     pub fn snapshot_devices(
490         &self,
491         snapshot_writer: &snapshot::SnapshotWriter,
492     ) -> anyhow::Result<()> {
493         for (snapshot_key, device_entry) in self.unique_devices_with_snapshot_key() {
494             match device_entry {
495                 BusDeviceEntry::OuterSync(dev) => {
496                     let mut dev = dev.lock();
497                     debug!("Snapshot on device: {}", dev.debug_label());
498                     snapshot_writer.write_fragment(
499                         &snapshot_key,
500                         &(*dev)
501                             .snapshot()
502                             .with_context(|| format!("failed to snapshot {}", dev.debug_label()))?,
503                     )?;
504                 }
505                 BusDeviceEntry::InnerSync(dev) => {
506                     debug!("Snapshot on device: {}", dev.debug_label());
507                     snapshot_writer.write_fragment(
508                         &snapshot_key,
509                         &dev.snapshot_sync()
510                             .with_context(|| format!("failed to snapshot {}", dev.debug_label()))?,
511                     )?;
512                 }
513             }
514         }
515         Ok(())
516     }
517 
restore_devices( &self, snapshot_reader: &snapshot::SnapshotReader, ) -> anyhow::Result<()>518     pub fn restore_devices(
519         &self,
520         snapshot_reader: &snapshot::SnapshotReader,
521     ) -> anyhow::Result<()> {
522         let mut unused_keys: BTreeSet<String> =
523             snapshot_reader.list_fragments()?.into_iter().collect();
524         for (snapshot_key, device_entry) in self.unique_devices_with_snapshot_key() {
525             unused_keys.remove(&snapshot_key);
526             match device_entry {
527                 BusDeviceEntry::OuterSync(dev) => {
528                     let mut dev = dev.lock();
529                     debug!("Restore on device: {}", dev.debug_label());
530                     dev.restore(snapshot_reader.read_fragment(&snapshot_key)?)
531                         .with_context(|| {
532                             format!("restore failed for device {}", dev.debug_label())
533                         })?;
534                 }
535                 BusDeviceEntry::InnerSync(dev) => {
536                     debug!("Restore on device: {}", dev.debug_label());
537                     dev.restore_sync(snapshot_reader.read_fragment(&snapshot_key)?)
538                         .with_context(|| {
539                             format!("restore failed for device {}", dev.debug_label())
540                         })?;
541                 }
542             }
543         }
544 
545         if !unused_keys.is_empty() {
546             error!(
547                 "unused restore data in bus, devices might be missing: {:?}",
548                 unused_keys
549             );
550         }
551 
552         Ok(())
553     }
554 
555     /// Puts the given device at the given address space.
insert(&self, device: Arc<Mutex<dyn BusDevice>>, base: u64, len: u64) -> Result<()>556     pub fn insert(&self, device: Arc<Mutex<dyn BusDevice>>, base: u64, len: u64) -> Result<()> {
557         if len == 0 {
558             return Err(Error::Overlap {
559                 base,
560                 len,
561                 other_base: 0,
562                 other_len: 0,
563             });
564         }
565 
566         // Reject all cases where the new device's range overlaps with an existing device.
567         let mut devices = self.devices.lock();
568         devices.iter().try_for_each(|(range, _dev)| {
569             if range.overlaps(base, len) {
570                 Err(Error::Overlap {
571                     base,
572                     len,
573                     other_base: range.base,
574                     other_len: range.len,
575                 })
576             } else {
577                 Ok(())
578             }
579         })?;
580 
581         #[cfg(feature = "stats")]
582         let name = device.lock().debug_label();
583         #[cfg(feature = "stats")]
584         let device_id = device.lock().device_id();
585         if devices
586             .insert(
587                 BusRange { base, len },
588                 BusEntry {
589                     #[cfg(feature = "stats")]
590                     index: self
591                         .stats
592                         .lock()
593                         .next_device_index(name, device_id.into(), base, len),
594                     device: BusDeviceEntry::OuterSync(device),
595                 },
596             )
597             .is_some()
598         {
599             return Err(Error::Overlap {
600                 base,
601                 len,
602                 other_base: base,
603                 other_len: len,
604             });
605         }
606 
607         Ok(())
608     }
609 
610     /// Puts the given device that implements BusDeviceSync at the given address space. Devices
611     /// that implement BusDeviceSync manage thread safety internally, and thus can be written to
612     /// by multiple threads simultaneously.
insert_sync(&self, device: Arc<dyn BusDeviceSync>, base: u64, len: u64) -> Result<()>613     pub fn insert_sync(&self, device: Arc<dyn BusDeviceSync>, base: u64, len: u64) -> Result<()> {
614         if len == 0 {
615             return Err(Error::Overlap {
616                 base,
617                 len,
618                 other_base: 0,
619                 other_len: 0,
620             });
621         }
622 
623         // Reject all cases where the new device's range overlaps with an existing device.
624         let mut devices = self.devices.lock();
625         devices.iter().try_for_each(|(range, _dev)| {
626             if range.overlaps(base, len) {
627                 Err(Error::Overlap {
628                     base,
629                     len,
630                     other_base: range.base,
631                     other_len: range.len,
632                 })
633             } else {
634                 Ok(())
635             }
636         })?;
637 
638         if devices
639             .insert(
640                 BusRange { base, len },
641                 BusEntry {
642                     #[cfg(feature = "stats")]
643                     index: self.stats.lock().next_device_index(
644                         device.debug_label(),
645                         device.device_id().into(),
646                         base,
647                         len,
648                     ),
649                     device: BusDeviceEntry::InnerSync(device),
650                 },
651             )
652             .is_some()
653         {
654             return Err(Error::Overlap {
655                 base,
656                 len,
657                 other_base: base,
658                 other_len: len,
659             });
660         }
661 
662         Ok(())
663     }
664 
665     /// Remove the given device at the given address space.
remove(&self, base: u64, len: u64) -> Result<()>666     pub fn remove(&self, base: u64, len: u64) -> Result<()> {
667         if len == 0 {
668             return Err(Error::Overlap {
669                 base,
670                 len,
671                 other_base: 0,
672                 other_len: 0,
673             });
674         }
675 
676         let mut devices = self.devices.lock();
677         if devices
678             .iter()
679             .any(|(range, _dev)| range.base == base && range.len == len)
680         {
681             let ret = devices.remove(&BusRange { base, len });
682             if ret.is_some() {
683                 Ok(())
684             } else {
685                 Err(Error::Empty)
686             }
687         } else {
688             Err(Error::Empty)
689         }
690     }
691 
692     /// Reads data from the device that owns the range containing `addr` and puts it into `data`.
693     ///
694     /// Returns true on success, otherwise `data` is filled with zeroes.
read(&self, addr: u64, data: &mut [u8]) -> bool695     pub fn read(&self, addr: u64, data: &mut [u8]) -> bool {
696         #[cfg(feature = "stats")]
697         let start = self.stats.lock().start_stat();
698 
699         // Initialize `data` with all zeroes to ensure consistent results even if device `read()`
700         // implementations don't always fill every byte.
701         data.fill(0);
702 
703         let device_index = if let Some((offset, address, entry)) = self.get_device(addr) {
704             let io = BusAccessInfo {
705                 address,
706                 offset,
707                 id: self.access_id,
708             };
709 
710             match &entry.device {
711                 BusDeviceEntry::OuterSync(dev) => dev.lock().read(io, data),
712                 BusDeviceEntry::InnerSync(dev) => dev.read(io, data),
713             }
714             #[cfg(feature = "stats")]
715             let index = Some(entry.index);
716             #[cfg(not(feature = "stats"))]
717             let index = Some(());
718             index
719         } else {
720             None
721         };
722 
723         #[cfg(feature = "stats")]
724         if let Some(device_index) = device_index {
725             self.stats
726                 .lock()
727                 .end_stat(BusOperation::Write, start, device_index);
728             return true;
729         }
730 
731         device_index.is_some()
732     }
733 
734     /// Writes `data` to the device that owns the range containing `addr`.
735     ///
736     /// Returns true on success, otherwise `data` is untouched.
write(&self, addr: u64, data: &[u8]) -> bool737     pub fn write(&self, addr: u64, data: &[u8]) -> bool {
738         #[cfg(feature = "stats")]
739         let start = self.stats.lock().start_stat();
740 
741         let device_index = if let Some((offset, address, entry)) = self.get_device(addr) {
742             let io = BusAccessInfo {
743                 address,
744                 offset,
745                 id: self.access_id,
746             };
747 
748             match &entry.device {
749                 BusDeviceEntry::OuterSync(dev) => dev.lock().write(io, data),
750                 BusDeviceEntry::InnerSync(dev) => dev.write(io, data),
751             }
752 
753             #[cfg(feature = "stats")]
754             let index = Some(entry.index);
755             #[cfg(not(feature = "stats"))]
756             let index = Some(());
757             index
758         } else {
759             None
760         };
761 
762         #[cfg(feature = "stats")]
763         if let Some(device_index) = device_index {
764             self.stats
765                 .lock()
766                 .end_stat(BusOperation::Write, start, device_index);
767         }
768         device_index.is_some()
769     }
770 }
771 
772 impl Default for Bus {
default() -> Self773     fn default() -> Self {
774         Self::new(BusType::Io)
775     }
776 }
777 
778 #[cfg(test)]
779 mod tests {
780     use anyhow::Result as AnyhowResult;
781 
782     use super::*;
783     use crate::pci::CrosvmDeviceId;
784     use crate::suspendable::Suspendable;
785     use crate::suspendable_tests;
786 
787     #[derive(Copy, Clone, Serialize, Deserialize, Eq, PartialEq, Debug)]
788     struct DummyDevice;
789 
790     impl BusDevice for DummyDevice {
device_id(&self) -> DeviceId791         fn device_id(&self) -> DeviceId {
792             CrosvmDeviceId::Cmos.into()
793         }
debug_label(&self) -> String794         fn debug_label(&self) -> String {
795             "dummy device".to_owned()
796         }
797     }
798 
799     impl Suspendable for DummyDevice {
snapshot(&mut self) -> AnyhowResult<AnySnapshot>800         fn snapshot(&mut self) -> AnyhowResult<AnySnapshot> {
801             AnySnapshot::to_any(self).context("error serializing")
802         }
803 
restore(&mut self, data: AnySnapshot) -> AnyhowResult<()>804         fn restore(&mut self, data: AnySnapshot) -> AnyhowResult<()> {
805             *self = AnySnapshot::from_any(data).context("error deserializing")?;
806             Ok(())
807         }
808 
sleep(&mut self) -> AnyhowResult<()>809         fn sleep(&mut self) -> AnyhowResult<()> {
810             Ok(())
811         }
812 
wake(&mut self) -> AnyhowResult<()>813         fn wake(&mut self) -> AnyhowResult<()> {
814             Ok(())
815         }
816     }
817 
818     #[derive(Copy, Clone, Serialize, Deserialize, Eq, PartialEq, Debug)]
819     struct ConstantDevice {
820         uses_full_addr: bool,
821     }
822 
823     impl BusDevice for ConstantDevice {
device_id(&self) -> DeviceId824         fn device_id(&self) -> DeviceId {
825             CrosvmDeviceId::Cmos.into()
826         }
827 
debug_label(&self) -> String828         fn debug_label(&self) -> String {
829             "constant device".to_owned()
830         }
831 
read(&mut self, info: BusAccessInfo, data: &mut [u8])832         fn read(&mut self, info: BusAccessInfo, data: &mut [u8]) {
833             let addr = if self.uses_full_addr {
834                 info.address
835             } else {
836                 info.offset
837             };
838             for (i, v) in data.iter_mut().enumerate() {
839                 *v = (addr as u8) + (i as u8);
840             }
841         }
842 
write(&mut self, info: BusAccessInfo, data: &[u8])843         fn write(&mut self, info: BusAccessInfo, data: &[u8]) {
844             let addr = if self.uses_full_addr {
845                 info.address
846             } else {
847                 info.offset
848             };
849             for (i, v) in data.iter().enumerate() {
850                 assert_eq!(*v, (addr as u8) + (i as u8))
851             }
852         }
853     }
854 
855     impl Suspendable for ConstantDevice {
snapshot(&mut self) -> AnyhowResult<AnySnapshot>856         fn snapshot(&mut self) -> AnyhowResult<AnySnapshot> {
857             AnySnapshot::to_any(self).context("error serializing")
858         }
859 
restore(&mut self, data: AnySnapshot) -> AnyhowResult<()>860         fn restore(&mut self, data: AnySnapshot) -> AnyhowResult<()> {
861             *self = AnySnapshot::from_any(data).context("error deserializing")?;
862             Ok(())
863         }
864 
sleep(&mut self) -> AnyhowResult<()>865         fn sleep(&mut self) -> AnyhowResult<()> {
866             Ok(())
867         }
868 
wake(&mut self) -> AnyhowResult<()>869         fn wake(&mut self) -> AnyhowResult<()> {
870             Ok(())
871         }
872     }
873 
modify_constant_device(constant: &mut ConstantDevice)874     fn modify_constant_device(constant: &mut ConstantDevice) {
875         constant.uses_full_addr = !constant.uses_full_addr;
876     }
877 
878     #[test]
bus_insert()879     fn bus_insert() {
880         let bus = Bus::new(BusType::Io);
881         let dummy = Arc::new(Mutex::new(DummyDevice));
882         assert!(bus.insert(dummy.clone(), 0x10, 0).is_err());
883         assert!(bus.insert(dummy.clone(), 0x10, 0x10).is_ok());
884         assert!(bus.insert(dummy.clone(), 0x0f, 0x10).is_err());
885         assert!(bus.insert(dummy.clone(), 0x10, 0x10).is_err());
886         assert!(bus.insert(dummy.clone(), 0x10, 0x15).is_err());
887         assert!(bus.insert(dummy.clone(), 0x12, 0x15).is_err());
888         assert!(bus.insert(dummy.clone(), 0x12, 0x01).is_err());
889         assert!(bus.insert(dummy.clone(), 0x0, 0x20).is_err());
890         assert!(bus.insert(dummy.clone(), 0x20, 0x05).is_ok());
891         assert!(bus.insert(dummy.clone(), 0x25, 0x05).is_ok());
892         assert!(bus.insert(dummy, 0x0, 0x10).is_ok());
893     }
894 
895     #[test]
bus_insert_full_addr()896     fn bus_insert_full_addr() {
897         let bus = Bus::new(BusType::Io);
898         let dummy = Arc::new(Mutex::new(DummyDevice));
899         assert!(bus.insert(dummy.clone(), 0x10, 0).is_err());
900         assert!(bus.insert(dummy.clone(), 0x10, 0x10).is_ok());
901         assert!(bus.insert(dummy.clone(), 0x0f, 0x10).is_err());
902         assert!(bus.insert(dummy.clone(), 0x10, 0x10).is_err());
903         assert!(bus.insert(dummy.clone(), 0x10, 0x15).is_err());
904         assert!(bus.insert(dummy.clone(), 0x12, 0x15).is_err());
905         assert!(bus.insert(dummy.clone(), 0x12, 0x01).is_err());
906         assert!(bus.insert(dummy.clone(), 0x0, 0x20).is_err());
907         assert!(bus.insert(dummy.clone(), 0x20, 0x05).is_ok());
908         assert!(bus.insert(dummy.clone(), 0x25, 0x05).is_ok());
909         assert!(bus.insert(dummy, 0x0, 0x10).is_ok());
910     }
911 
912     #[test]
bus_read_write()913     fn bus_read_write() {
914         let bus = Bus::new(BusType::Io);
915         let dummy = Arc::new(Mutex::new(DummyDevice));
916         assert!(bus.insert(dummy, 0x10, 0x10).is_ok());
917         assert!(bus.read(0x10, &mut [0, 0, 0, 0]));
918         assert!(bus.write(0x10, &[0, 0, 0, 0]));
919         assert!(bus.read(0x11, &mut [0, 0, 0, 0]));
920         assert!(bus.write(0x11, &[0, 0, 0, 0]));
921         assert!(bus.read(0x16, &mut [0, 0, 0, 0]));
922         assert!(bus.write(0x16, &[0, 0, 0, 0]));
923         assert!(!bus.read(0x20, &mut [0, 0, 0, 0]));
924         assert!(!bus.write(0x20, &[0, 0, 0, 0]));
925         assert!(!bus.read(0x06, &mut [0, 0, 0, 0]));
926         assert!(!bus.write(0x06, &[0, 0, 0, 0]));
927     }
928 
929     #[test]
bus_read_write_values()930     fn bus_read_write_values() {
931         let bus = Bus::new(BusType::Io);
932         let dummy = Arc::new(Mutex::new(ConstantDevice {
933             uses_full_addr: false,
934         }));
935         assert!(bus.insert(dummy, 0x10, 0x10).is_ok());
936 
937         let mut values = [0, 1, 2, 3];
938         assert!(bus.read(0x10, &mut values));
939         assert_eq!(values, [0, 1, 2, 3]);
940         assert!(bus.write(0x10, &values));
941         assert!(bus.read(0x15, &mut values));
942         assert_eq!(values, [5, 6, 7, 8]);
943         assert!(bus.write(0x15, &values));
944     }
945 
946     #[test]
bus_read_write_full_addr_values()947     fn bus_read_write_full_addr_values() {
948         let bus = Bus::new(BusType::Io);
949         let dummy = Arc::new(Mutex::new(ConstantDevice {
950             uses_full_addr: true,
951         }));
952         assert!(bus.insert(dummy, 0x10, 0x10).is_ok());
953 
954         let mut values = [0u8; 4];
955         assert!(bus.read(0x10, &mut values));
956         assert_eq!(values, [0x10, 0x11, 0x12, 0x13]);
957         assert!(bus.write(0x10, &values));
958         assert!(bus.read(0x15, &mut values));
959         assert_eq!(values, [0x15, 0x16, 0x17, 0x18]);
960         assert!(bus.write(0x15, &values));
961     }
962 
963     #[test]
bus_read_no_device()964     fn bus_read_no_device() {
965         let bus = Bus::new(BusType::Io);
966 
967         // read() should return false, since there is no device at address 0x10, but it should
968         // also fill the data with 0s.
969         let mut values = [1, 2, 3, 4];
970         assert!(!bus.read(0x10, &mut values));
971         assert_eq!(values, [0, 0, 0, 0]);
972     }
973 
974     suspendable_tests!(
975         constant_device_true,
976         ConstantDevice {
977             uses_full_addr: true,
978         },
979         modify_constant_device
980     );
981 
982     suspendable_tests!(
983         constant_device_false,
984         ConstantDevice {
985             uses_full_addr: false,
986         },
987         modify_constant_device
988     );
989 
990     #[test]
bus_range_contains()991     fn bus_range_contains() {
992         let a = BusRange {
993             base: 0x1000,
994             len: 0x400,
995         };
996         assert!(a.contains(0x1000));
997         assert!(a.contains(0x13ff));
998         assert!(!a.contains(0xfff));
999         assert!(!a.contains(0x1400));
1000         assert!(a.contains(0x1200));
1001     }
1002 
1003     #[test]
bus_range_overlap()1004     fn bus_range_overlap() {
1005         let a = BusRange {
1006             base: 0x1000,
1007             len: 0x400,
1008         };
1009         assert!(a.overlaps(0x1000, 0x400));
1010         assert!(a.overlaps(0xf00, 0x400));
1011         assert!(a.overlaps(0x1000, 0x01));
1012         assert!(a.overlaps(0xfff, 0x02));
1013         assert!(a.overlaps(0x1100, 0x100));
1014         assert!(a.overlaps(0x13ff, 0x100));
1015         assert!(!a.overlaps(0x1400, 0x100));
1016         assert!(!a.overlaps(0xf00, 0x100));
1017     }
1018 }
1019