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