• 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::btree_map::BTreeMap;
12 use std::collections::hash_map::HashMap;
13 use std::collections::VecDeque;
14 use std::fmt;
15 use std::result;
16 use std::sync::Arc;
17 
18 use anyhow::anyhow;
19 use anyhow::Context;
20 use base::error;
21 use remain::sorted;
22 use serde::Deserialize;
23 use serde::Serialize;
24 use sync::Mutex;
25 use thiserror::Error;
26 
27 #[cfg(feature = "stats")]
28 use crate::bus_stats::BusOperation;
29 #[cfg(feature = "stats")]
30 use crate::BusStatistics;
31 use crate::DeviceId;
32 use crate::PciAddress;
33 use crate::PciDevice;
34 use crate::Suspendable;
35 #[cfg(unix)]
36 use crate::VfioPlatformDevice;
37 use crate::VirtioMmioDevice;
38 
39 /// Information about how a device was accessed.
40 #[derive(Copy, Clone, Eq, PartialEq, Debug, Serialize, Deserialize)]
41 pub struct BusAccessInfo {
42     /// Offset from base address that the device was accessed at.
43     pub offset: u64,
44     /// Absolute address of the device's access in its address space.
45     pub address: u64,
46     /// ID of the entity requesting a device access, usually the VCPU id.
47     pub id: usize,
48 }
49 
50 // Implement `Display` for `MinMax`.
51 impl std::fmt::Display for BusAccessInfo {
fmt(&self, f: &mut fmt::Formatter) -> fmt::Result52     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
53         write!(f, "{:?}", self)
54     }
55 }
56 
57 /// Result of a write to a device's PCI configuration space.
58 /// This value represents the state change(s) that occurred due to the write.
59 #[derive(Clone, Debug, Default, PartialEq, Eq)]
60 pub struct ConfigWriteResult {
61     /// The BusRange in the vector will be removed from mmio_bus
62     pub mmio_remove: Vec<BusRange>,
63 
64     /// The BusRange in the vector will be added into mmio_bus
65     pub mmio_add: Vec<BusRange>,
66 
67     /// The BusRange in the vector will be removed from io_bus
68     pub io_remove: Vec<BusRange>,
69 
70     /// The BusRange in the vector will be added into io_bus
71     pub io_add: Vec<BusRange>,
72 
73     /// Device specified at PciAddress will be removed after this config write
74     /// - 'Vec<PciAddress>>': specified device will be removed after this config write
75     pub removed_pci_devices: Vec<PciAddress>,
76 }
77 
78 #[derive(Copy, Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
79 pub enum BusType {
80     Mmio,
81     Io,
82 }
83 
84 /// Trait for devices that respond to reads or writes in an arbitrary address space.
85 ///
86 /// The device does not care where it exists in address space as each method is only given an offset
87 /// into its allocated portion of address space.
88 #[allow(unused_variables)]
89 pub trait BusDevice: Send + Suspendable {
90     /// Returns a label suitable for debug output.
debug_label(&self) -> String91     fn debug_label(&self) -> String;
92     /// Returns a unique id per device type suitable for metrics gathering.
device_id(&self) -> DeviceId93     fn device_id(&self) -> DeviceId;
94     /// Reads at `offset` from this device
read(&mut self, offset: BusAccessInfo, data: &mut [u8])95     fn read(&mut self, offset: BusAccessInfo, data: &mut [u8]) {}
96     /// Writes at `offset` into this device
write(&mut self, offset: BusAccessInfo, data: &[u8])97     fn write(&mut self, offset: BusAccessInfo, data: &[u8]) {}
98     /// Sets a register in the configuration space. Only used by PCI.
99     /// * `reg_idx` - The index of the config register to modify.
100     /// * `offset` - Offset in to the register.
config_register_write( &mut self, reg_idx: usize, offset: u64, data: &[u8], ) -> ConfigWriteResult101     fn config_register_write(
102         &mut self,
103         reg_idx: usize,
104         offset: u64,
105         data: &[u8],
106     ) -> ConfigWriteResult {
107         ConfigWriteResult {
108             ..Default::default()
109         }
110     }
111     /// Gets a register from the configuration space. Only used by PCI.
112     /// * `reg_idx` - The index of the config register to read.
config_register_read(&self, reg_idx: usize) -> u32113     fn config_register_read(&self, reg_idx: usize) -> u32 {
114         0
115     }
116     /// Sets a register in the virtual config space. Only used by PCI.
117     /// * `reg_idx` - The index of the config register to modify.
118     /// * `value` - The value to be written.
virtual_config_register_write(&mut self, reg_idx: usize, value: u32)119     fn virtual_config_register_write(&mut self, reg_idx: usize, value: u32) {}
120     /// Gets a register from the virtual config space. Only used by PCI.
121     /// * `reg_idx` - The index of the config register to read.
virtual_config_register_read(&self, reg_idx: usize) -> u32122     fn virtual_config_register_read(&self, reg_idx: usize) -> u32 {
123         0
124     }
125     /// Invoked when the device is sandboxed.
on_sandboxed(&mut self)126     fn on_sandboxed(&mut self) {}
127 
128     /// Gets a list of all ranges registered by this BusDevice.
get_ranges(&self) -> Vec<(BusRange, BusType)>129     fn get_ranges(&self) -> Vec<(BusRange, BusType)> {
130         Vec::new()
131     }
132 
133     /// Invoked when the device is destroyed
destroy_device(&mut self)134     fn destroy_device(&mut self) {}
135 
136     /// Returns the secondary bus number if this bus device is pci bridge
is_bridge(&self) -> Option<u8>137     fn is_bridge(&self) -> Option<u8> {
138         None
139     }
140 }
141 
142 pub trait BusDeviceSync: BusDevice + Sync {
read(&self, offset: BusAccessInfo, data: &mut [u8])143     fn read(&self, offset: BusAccessInfo, data: &mut [u8]);
write(&self, offset: BusAccessInfo, data: &[u8])144     fn write(&self, offset: BusAccessInfo, data: &[u8]);
snapshot_sync(&self) -> anyhow::Result<serde_json::Value>145     fn snapshot_sync(&self) -> anyhow::Result<serde_json::Value> {
146         Err(anyhow!(
147             "snapshot_sync not implemented for {}",
148             std::any::type_name::<Self>()
149         ))
150     }
151     /// Load a saved snapshot of an image.
restore_sync(&self, _data: serde_json::Value) -> anyhow::Result<()>152     fn restore_sync(&self, _data: serde_json::Value) -> anyhow::Result<()> {
153         Err(anyhow!(
154             "restore_sync not implemented for {}",
155             std::any::type_name::<Self>()
156         ))
157     }
158     /// Stop all threads related to the device.
159     /// Sleep should be idempotent.
sleep_sync(&self) -> anyhow::Result<()>160     fn sleep_sync(&self) -> anyhow::Result<()> {
161         Err(anyhow!(
162             "sleep_sync not implemented for {}",
163             std::any::type_name::<Self>()
164         ))
165     }
166     /// Create/Resume all threads related to the device.
167     /// Wake should be idempotent.
wake_sync(&self) -> anyhow::Result<()>168     fn wake_sync(&self) -> anyhow::Result<()> {
169         Err(anyhow!(
170             "wake_sync not implemented for {}",
171             std::any::type_name::<Self>()
172         ))
173     }
174 }
175 
176 pub trait BusResumeDevice: Send {
177     /// notify the devices which are invoked
178     /// before the VM resumes form suspend.
resume_imminent(&mut self)179     fn resume_imminent(&mut self) {}
180 }
181 
182 /// The key to identify hotplug device from host view.
183 /// like host sysfs path for vfio pci device, host disk file
184 /// path for virtio block device
185 #[derive(Copy, Clone, PartialEq, Eq, Debug)]
186 pub enum HostHotPlugKey {
187     UpstreamPort { host_addr: PciAddress },
188     DownstreamPort { host_addr: PciAddress },
189     Vfio { host_addr: PciAddress },
190 }
191 
192 /// Trait for devices that notify hotplug event into guest
193 pub trait HotPlugBus {
194     /// Notify hotplug in event into guest
195     /// * 'addr' - the guest pci address for hotplug in device
hot_plug(&mut self, addr: PciAddress)196     fn hot_plug(&mut self, addr: PciAddress);
197     /// Notify hotplug out event into guest
198     /// * 'addr' - the guest pci address for hotplug out device
hot_unplug(&mut self, addr: PciAddress)199     fn hot_unplug(&mut self, addr: PciAddress);
200     /// Check whether the hotplug bus is available to add the new device
201     ///
202     /// - 'None': hotplug bus isn't match with host pci device
203     /// - 'Some(bus_num)': hotplug bus is match and put the device at bus_num
is_match(&self, host_addr: PciAddress) -> Option<u8>204     fn is_match(&self, host_addr: PciAddress) -> Option<u8>;
205     /// Add hotplug device into this bus
206     /// * 'host_key' - the key to identify hotplug device from host view
207     /// * 'guest_addr' - the guest pci address for hotplug device
add_hotplug_device(&mut self, host_key: HostHotPlugKey, guest_addr: PciAddress)208     fn add_hotplug_device(&mut self, host_key: HostHotPlugKey, guest_addr: PciAddress);
209     /// get guest pci address from the specified host_key
get_hotplug_device(&self, host_key: HostHotPlugKey) -> Option<PciAddress>210     fn get_hotplug_device(&self, host_key: HostHotPlugKey) -> Option<PciAddress>;
211     /// Check whether this hotplug bus is empty
is_empty(&self) -> bool212     fn is_empty(&self) -> bool;
213     /// Get hotplug key of this hotplug bus
get_hotplug_key(&self) -> Option<HostHotPlugKey>214     fn get_hotplug_key(&self) -> Option<HostHotPlugKey>;
215 }
216 
217 /// Trait for generic device abstraction, that is, all devices that reside on BusDevice and want
218 /// to be converted back to its original type. Each new foo device must provide
219 /// as_foo_device() + as_foo_device_mut() + into_foo_device(), default impl methods return None.
220 pub trait BusDeviceObj {
as_pci_device(&self) -> Option<&dyn PciDevice>221     fn as_pci_device(&self) -> Option<&dyn PciDevice> {
222         None
223     }
as_pci_device_mut(&mut self) -> Option<&mut dyn PciDevice>224     fn as_pci_device_mut(&mut self) -> Option<&mut dyn PciDevice> {
225         None
226     }
into_pci_device(self: Box<Self>) -> Option<Box<dyn PciDevice>>227     fn into_pci_device(self: Box<Self>) -> Option<Box<dyn PciDevice>> {
228         None
229     }
230     #[cfg(unix)]
as_platform_device(&self) -> Option<&VfioPlatformDevice>231     fn as_platform_device(&self) -> Option<&VfioPlatformDevice> {
232         None
233     }
234     #[cfg(unix)]
as_platform_device_mut(&mut self) -> Option<&mut VfioPlatformDevice>235     fn as_platform_device_mut(&mut self) -> Option<&mut VfioPlatformDevice> {
236         None
237     }
238     #[cfg(unix)]
into_platform_device(self: Box<Self>) -> Option<Box<VfioPlatformDevice>>239     fn into_platform_device(self: Box<Self>) -> Option<Box<VfioPlatformDevice>> {
240         None
241     }
as_virtio_mmio_device(&self) -> Option<&VirtioMmioDevice>242     fn as_virtio_mmio_device(&self) -> Option<&VirtioMmioDevice> {
243         None
244     }
as_virtio_mmio_device_mut(&mut self) -> Option<&mut VirtioMmioDevice>245     fn as_virtio_mmio_device_mut(&mut self) -> Option<&mut VirtioMmioDevice> {
246         None
247     }
into_virtio_mmio_device(self: Box<Self>) -> Option<Box<VirtioMmioDevice>>248     fn into_virtio_mmio_device(self: Box<Self>) -> Option<Box<VirtioMmioDevice>> {
249         None
250     }
251 }
252 
253 #[sorted]
254 #[derive(Error, Debug)]
255 pub enum Error {
256     #[error("Bus Range not found")]
257     Empty,
258     /// The insertion failed because the new device overlapped with an old device.
259     #[error("new device {base},{len} overlaps with an old device {other_base},{other_len}")]
260     Overlap {
261         base: u64,
262         len: u64,
263         other_base: u64,
264         other_len: u64,
265     },
266 }
267 
268 pub type Result<T> = result::Result<T, Error>;
269 
270 /// Holds a base and length representing the address space occupied by a `BusDevice`.
271 ///
272 /// * base - The address at which the range start.
273 /// * len - The length of the range in bytes.
274 #[derive(Debug, Copy, Clone, Serialize, Deserialize)]
275 pub struct BusRange {
276     pub base: u64,
277     pub len: u64,
278 }
279 
280 impl BusRange {
281     /// Returns true if `addr` is within the range.
contains(&self, addr: u64) -> bool282     pub fn contains(&self, addr: u64) -> bool {
283         self.base <= addr && addr < self.base + self.len
284     }
285 
286     /// Returns true if there is overlap with the given range.
overlaps(&self, base: u64, len: u64) -> bool287     pub fn overlaps(&self, base: u64, len: u64) -> bool {
288         self.base < (base + len) && base < self.base + self.len
289     }
290 }
291 
292 impl Eq for BusRange {}
293 
294 impl PartialEq for BusRange {
eq(&self, other: &BusRange) -> bool295     fn eq(&self, other: &BusRange) -> bool {
296         self.base == other.base
297     }
298 }
299 
300 impl Ord for BusRange {
cmp(&self, other: &BusRange) -> Ordering301     fn cmp(&self, other: &BusRange) -> Ordering {
302         self.base.cmp(&other.base)
303     }
304 }
305 
306 impl PartialOrd for BusRange {
partial_cmp(&self, other: &BusRange) -> Option<Ordering>307     fn partial_cmp(&self, other: &BusRange) -> Option<Ordering> {
308         self.base.partial_cmp(&other.base)
309     }
310 }
311 
312 #[derive(Clone)]
313 struct BusEntry {
314     #[cfg(feature = "stats")]
315     index: usize,
316     device: BusDeviceEntry,
317 }
318 
319 #[derive(Clone)]
320 enum BusDeviceEntry {
321     OuterSync(Arc<Mutex<dyn BusDevice>>),
322     InnerSync(Arc<dyn BusDeviceSync>),
323 }
324 
325 /// A device container for routing reads and writes over some address space.
326 ///
327 /// This doesn't have any restrictions on what kind of device or address space this applies to. The
328 /// only restriction is that no two devices can overlap in this address space.
329 #[derive(Clone)]
330 pub struct Bus {
331     devices: Arc<Mutex<BTreeMap<BusRange, BusEntry>>>,
332     access_id: usize,
333     #[cfg(feature = "stats")]
334     pub stats: Arc<Mutex<BusStatistics>>,
335 }
336 
337 impl Bus {
338     /// Constructs an a bus with an empty address space.
new() -> Bus339     pub fn new() -> Bus {
340         Bus {
341             devices: Arc::new(Mutex::new(BTreeMap::new())),
342             access_id: 0,
343             #[cfg(feature = "stats")]
344             stats: Arc::new(Mutex::new(BusStatistics::new())),
345         }
346     }
347 
348     /// Sets the id that will be used for BusAccessInfo.
set_access_id(&mut self, id: usize)349     pub fn set_access_id(&mut self, id: usize) {
350         self.access_id = id;
351     }
352 
first_before(&self, addr: u64) -> Option<(BusRange, BusEntry)>353     fn first_before(&self, addr: u64) -> Option<(BusRange, BusEntry)> {
354         let devices = self.devices.lock();
355         let (range, entry) = devices
356             .range(..=BusRange { base: addr, len: 1 })
357             .rev()
358             .next()?;
359         Some((*range, entry.clone()))
360     }
361 
get_device(&self, addr: u64) -> Option<(u64, u64, BusEntry)>362     fn get_device(&self, addr: u64) -> Option<(u64, u64, BusEntry)> {
363         if let Some((range, entry)) = self.first_before(addr) {
364             let offset = addr - range.base;
365             if offset < range.len {
366                 return Some((offset, addr, entry));
367             }
368         }
369         None
370     }
371 
sleep_devices(&self) -> anyhow::Result<()>372     pub fn sleep_devices(&self) -> anyhow::Result<()> {
373         let devices_lock = &(self.devices).lock();
374         for (_, device_entry) in devices_lock.iter() {
375             match &(device_entry.device) {
376                 BusDeviceEntry::OuterSync(dev) => {
377                     let mut device_lock = (*dev).lock();
378                     if let Err(e) = device_lock.sleep() {
379                         //TODO: Enable this line when b/232437513 is done
380                         // return Err(anyhow!("Failed to sleep {}.", (*device_lock).debug_label()));
381                         error!("Failed to sleep {}: {}", (*device_lock).debug_label(), e);
382                     }
383                 }
384                 BusDeviceEntry::InnerSync(dev) => {
385                     (**dev).sleep_sync().context("failed to sleep device")?;
386                 }
387             }
388         }
389         Ok(())
390     }
391 
wake_devices(&self) -> anyhow::Result<()>392     pub fn wake_devices(&self) -> anyhow::Result<()> {
393         let devices_lock = &(self.devices).lock();
394         for (_, device_entry) in devices_lock.iter() {
395             match &(device_entry.device) {
396                 BusDeviceEntry::OuterSync(dev) => {
397                     let mut device_lock = (*dev).lock();
398                     if let Err(e) = device_lock.wake() {
399                         //TODO: Enable this line when b/232437513 is done
400                         // return Err(anyhow!("Failed to wake {}.", (*device_lock).debug_label()));
401                         error!("Failed to wake {}: {}", (*device_lock).debug_label(), e);
402                     };
403                 }
404                 BusDeviceEntry::InnerSync(dev) => {
405                     (**dev).wake_sync().context("failed to wake device")?;
406                 }
407             }
408         }
409         Ok(())
410     }
411 
snapshot_devices( &self, mut add_snapshot: impl FnMut(u32, serde_json::Value), ) -> anyhow::Result<()>412     pub fn snapshot_devices(
413         &self,
414         mut add_snapshot: impl FnMut(u32, serde_json::Value),
415     ) -> anyhow::Result<()> {
416         let devices_lock = &(self.devices).lock();
417         for (_, device_entry) in devices_lock.iter() {
418             let (device_id, serialized_device, device_label) = match &(device_entry.device) {
419                 BusDeviceEntry::OuterSync(dev) => {
420                     let device_lock = (*dev).lock();
421                     (
422                         u32::from(device_lock.device_id()),
423                         (*device_lock).snapshot(),
424                         (*device_lock).debug_label(),
425                     )
426                 }
427                 BusDeviceEntry::InnerSync(dev) => (
428                     u32::from((dev).device_id()),
429                     (**dev).snapshot_sync(),
430                     (**dev).debug_label(),
431                 ),
432             };
433             match serialized_device {
434                 Ok(snapshot) => {
435                     add_snapshot(device_id, snapshot);
436                 }
437                 Err(e) => {
438                     //TODO: Enable this line when b/232437513 is done
439                     // return Err(anyhow!("Failed to snapshot {}.", (*device_lock).debug_label()));
440                     error!("Failed to snapshot {}: {}.", device_label, e);
441                 }
442             }
443         }
444         Ok(())
445     }
446 
restore_devices( &self, devices_map: &mut HashMap<u32, VecDeque<serde_json::Value>>, ) -> anyhow::Result<()>447     pub fn restore_devices(
448         &self,
449         devices_map: &mut HashMap<u32, VecDeque<serde_json::Value>>,
450     ) -> anyhow::Result<()> {
451         let devices_lock = &(self.devices).lock();
452         for (_, device_entry) in devices_lock.iter() {
453             match &(device_entry.device) {
454                 BusDeviceEntry::OuterSync(dev) => {
455                     let mut device_lock = (*dev).lock();
456                     let device_id = u32::from(device_lock.device_id());
457                     let device_data = devices_map.get_mut(&device_id);
458                     match device_data {
459                         Some(dev_dq) => {
460                             match dev_dq.pop_front() {
461                                 Some(dev_data) => {
462                                     (*device_lock).restore(dev_data).context("device failed to restore snapshot")?;
463                                 }
464                                 None => base::info!("no data found in snapshot for {}", device_lock.debug_label()),
465                             }
466                         },
467                         None => base::info!("device {} does not have stored data in the snapshot. Device data will not change.", (*device_lock).debug_label()),
468                     }
469                 }
470                 BusDeviceEntry::InnerSync(dev) => {
471                     let device_id = u32::from(dev.device_id());
472                     let device_data = devices_map.get_mut(&device_id);
473                     match device_data {
474                         Some(dev_dq) => {
475                             match dev_dq.pop_front() {
476                                 Some(dev_data) => {
477                                     (**dev).restore_sync(dev_data).context("device failed to restore snapshot")?;
478                                 }
479                                 None => base::info!("no data found in snapshot for {}", (**dev).debug_label()),
480                             }
481                         },
482                         None => base::info!("device {} does not have stored data in the snapshot. Device data will not change.", dev.debug_label()),
483                     }
484                 }
485             }
486         }
487         Ok(())
488     }
489 
490     /// Puts the given device at the given address space.
insert(&self, device: Arc<Mutex<dyn BusDevice>>, base: u64, len: u64) -> Result<()>491     pub fn insert(&self, device: Arc<Mutex<dyn BusDevice>>, base: u64, len: u64) -> Result<()> {
492         if len == 0 {
493             return Err(Error::Overlap {
494                 base,
495                 len,
496                 other_base: 0,
497                 other_len: 0,
498             });
499         }
500 
501         // Reject all cases where the new device's range overlaps with an existing device.
502         let mut devices = self.devices.lock();
503         devices.iter().try_for_each(|(range, _dev)| {
504             if range.overlaps(base, len) {
505                 Err(Error::Overlap {
506                     base,
507                     len,
508                     other_base: range.base,
509                     other_len: range.len,
510                 })
511             } else {
512                 Ok(())
513             }
514         })?;
515 
516         #[cfg(feature = "stats")]
517         let name = device.lock().debug_label();
518         #[cfg(feature = "stats")]
519         let device_id = device.lock().device_id();
520         if devices
521             .insert(
522                 BusRange { base, len },
523                 BusEntry {
524                     #[cfg(feature = "stats")]
525                     index: self
526                         .stats
527                         .lock()
528                         .next_device_index(name, device_id.into(), base, len),
529                     device: BusDeviceEntry::OuterSync(device),
530                 },
531             )
532             .is_some()
533         {
534             return Err(Error::Overlap {
535                 base,
536                 len,
537                 other_base: base,
538                 other_len: len,
539             });
540         }
541 
542         Ok(())
543     }
544 
545     /// Puts the given device that implements BusDeviceSync at the given address space. Devices
546     /// that implement BusDeviceSync manage thread safety internally, and thus can be written to
547     /// by multiple threads simultaneously.
insert_sync(&self, device: Arc<dyn BusDeviceSync>, base: u64, len: u64) -> Result<()>548     pub fn insert_sync(&self, device: Arc<dyn BusDeviceSync>, base: u64, len: u64) -> Result<()> {
549         if len == 0 {
550             return Err(Error::Overlap {
551                 base,
552                 len,
553                 other_base: 0,
554                 other_len: 0,
555             });
556         }
557 
558         // Reject all cases where the new device's range overlaps with an existing device.
559         let mut devices = self.devices.lock();
560         devices.iter().try_for_each(|(range, _dev)| {
561             if range.overlaps(base, len) {
562                 Err(Error::Overlap {
563                     base,
564                     len,
565                     other_base: range.base,
566                     other_len: range.len,
567                 })
568             } else {
569                 Ok(())
570             }
571         })?;
572 
573         if devices
574             .insert(
575                 BusRange { base, len },
576                 BusEntry {
577                     #[cfg(feature = "stats")]
578                     index: self.stats.lock().next_device_index(
579                         device.debug_label(),
580                         device.device_id().into(),
581                         base,
582                         len,
583                     ),
584                     device: BusDeviceEntry::InnerSync(device),
585                 },
586             )
587             .is_some()
588         {
589             return Err(Error::Overlap {
590                 base,
591                 len,
592                 other_base: base,
593                 other_len: len,
594             });
595         }
596 
597         Ok(())
598     }
599 
600     /// Remove the given device at the given address space.
remove(&self, base: u64, len: u64) -> Result<()>601     pub fn remove(&self, base: u64, len: u64) -> Result<()> {
602         if len == 0 {
603             return Err(Error::Overlap {
604                 base,
605                 len,
606                 other_base: 0,
607                 other_len: 0,
608             });
609         }
610 
611         let mut devices = self.devices.lock();
612         if devices
613             .iter()
614             .any(|(range, _dev)| range.base == base && range.len == len)
615         {
616             let ret = devices.remove(&BusRange { base, len });
617             if ret.is_some() {
618                 Ok(())
619             } else {
620                 Err(Error::Empty)
621             }
622         } else {
623             Err(Error::Empty)
624         }
625     }
626 
627     /// Reads data from the device that owns the range containing `addr` and puts it into `data`.
628     ///
629     /// Returns true on success, otherwise `data` is untouched.
read(&self, addr: u64, data: &mut [u8]) -> bool630     pub fn read(&self, addr: u64, data: &mut [u8]) -> bool {
631         #[cfg(feature = "stats")]
632         let start = self.stats.lock().start_stat();
633 
634         let device_index = if let Some((offset, address, entry)) = self.get_device(addr) {
635             let io = BusAccessInfo {
636                 address,
637                 offset,
638                 id: self.access_id,
639             };
640 
641             match &entry.device {
642                 BusDeviceEntry::OuterSync(dev) => dev.lock().read(io, data),
643                 BusDeviceEntry::InnerSync(dev) => dev.read(io, data),
644             }
645             #[cfg(feature = "stats")]
646             let index = Some(entry.index);
647             #[cfg(not(feature = "stats"))]
648             let index = Some(());
649             index
650         } else {
651             None
652         };
653 
654         #[cfg(feature = "stats")]
655         if let Some(device_index) = device_index {
656             self.stats
657                 .lock()
658                 .end_stat(BusOperation::Write, start, device_index);
659             return true;
660         }
661 
662         device_index.is_some()
663     }
664 
665     /// Writes `data` to the device that owns the range containing `addr`.
666     ///
667     /// Returns true on success, otherwise `data` is untouched.
write(&self, addr: u64, data: &[u8]) -> bool668     pub fn write(&self, addr: u64, data: &[u8]) -> bool {
669         #[cfg(feature = "stats")]
670         let start = self.stats.lock().start_stat();
671 
672         let device_index = if let Some((offset, address, entry)) = self.get_device(addr) {
673             let io = BusAccessInfo {
674                 address,
675                 offset,
676                 id: self.access_id,
677             };
678 
679             match &entry.device {
680                 BusDeviceEntry::OuterSync(dev) => dev.lock().write(io, data),
681                 BusDeviceEntry::InnerSync(dev) => dev.write(io, data),
682             }
683 
684             #[cfg(feature = "stats")]
685             let index = Some(entry.index);
686             #[cfg(not(feature = "stats"))]
687             let index = Some(());
688             index
689         } else {
690             None
691         };
692 
693         #[cfg(feature = "stats")]
694         if let Some(device_index) = device_index {
695             self.stats
696                 .lock()
697                 .end_stat(BusOperation::Write, start, device_index);
698         }
699         device_index.is_some()
700     }
701 }
702 
703 #[cfg(test)]
704 mod tests {
705     use anyhow::Result as AnyhowResult;
706 
707     use super::*;
708     use crate::pci::CrosvmDeviceId;
709     use crate::suspendable::Suspendable;
710     use crate::suspendable_tests;
711 
712     #[derive(Copy, Clone, Serialize, Deserialize, Eq, PartialEq, Debug)]
713     struct DummyDevice;
714 
715     impl BusDevice for DummyDevice {
device_id(&self) -> DeviceId716         fn device_id(&self) -> DeviceId {
717             CrosvmDeviceId::Cmos.into()
718         }
debug_label(&self) -> String719         fn debug_label(&self) -> String {
720             "dummy device".to_owned()
721         }
722     }
723 
724     impl Suspendable for DummyDevice {
snapshot(&self) -> AnyhowResult<serde_json::Value>725         fn snapshot(&self) -> AnyhowResult<serde_json::Value> {
726             serde_json::to_value(self).context("error serializing")
727         }
728 
restore(&mut self, data: serde_json::Value) -> AnyhowResult<()>729         fn restore(&mut self, data: serde_json::Value) -> AnyhowResult<()> {
730             *self = serde_json::from_value(data).context("error deserializing")?;
731             Ok(())
732         }
733 
sleep(&mut self) -> AnyhowResult<()>734         fn sleep(&mut self) -> AnyhowResult<()> {
735             Ok(())
736         }
737 
wake(&mut self) -> AnyhowResult<()>738         fn wake(&mut self) -> AnyhowResult<()> {
739             Ok(())
740         }
741     }
742 
743     #[derive(Copy, Clone, Serialize, Deserialize, Eq, PartialEq, Debug)]
744     struct ConstantDevice {
745         uses_full_addr: bool,
746     }
747 
748     impl BusDevice for ConstantDevice {
device_id(&self) -> DeviceId749         fn device_id(&self) -> DeviceId {
750             CrosvmDeviceId::Cmos.into()
751         }
752 
debug_label(&self) -> String753         fn debug_label(&self) -> String {
754             "constant device".to_owned()
755         }
756 
read(&mut self, info: BusAccessInfo, data: &mut [u8])757         fn read(&mut self, info: BusAccessInfo, data: &mut [u8]) {
758             let addr = if self.uses_full_addr {
759                 info.address
760             } else {
761                 info.offset
762             };
763             for (i, v) in data.iter_mut().enumerate() {
764                 *v = (addr as u8) + (i as u8);
765             }
766         }
767 
write(&mut self, info: BusAccessInfo, data: &[u8])768         fn write(&mut self, info: BusAccessInfo, data: &[u8]) {
769             let addr = if self.uses_full_addr {
770                 info.address
771             } else {
772                 info.offset
773             };
774             for (i, v) in data.iter().enumerate() {
775                 assert_eq!(*v, (addr as u8) + (i as u8))
776             }
777         }
778     }
779 
780     impl Suspendable for ConstantDevice {
snapshot(&self) -> AnyhowResult<serde_json::Value>781         fn snapshot(&self) -> AnyhowResult<serde_json::Value> {
782             serde_json::to_value(self).context("error serializing")
783         }
784 
restore(&mut self, data: serde_json::Value) -> AnyhowResult<()>785         fn restore(&mut self, data: serde_json::Value) -> AnyhowResult<()> {
786             *self = serde_json::from_value(data).context("error deserializing")?;
787             Ok(())
788         }
789 
sleep(&mut self) -> AnyhowResult<()>790         fn sleep(&mut self) -> AnyhowResult<()> {
791             Ok(())
792         }
793 
wake(&mut self) -> AnyhowResult<()>794         fn wake(&mut self) -> AnyhowResult<()> {
795             Ok(())
796         }
797     }
798 
modify_constant_device(constant: &mut ConstantDevice)799     fn modify_constant_device(constant: &mut ConstantDevice) {
800         constant.uses_full_addr = !constant.uses_full_addr;
801     }
802 
803     #[test]
bus_insert()804     fn bus_insert() {
805         let bus = Bus::new();
806         let dummy = Arc::new(Mutex::new(DummyDevice));
807         assert!(bus.insert(dummy.clone(), 0x10, 0).is_err());
808         assert!(bus.insert(dummy.clone(), 0x10, 0x10).is_ok());
809         assert!(bus.insert(dummy.clone(), 0x0f, 0x10).is_err());
810         assert!(bus.insert(dummy.clone(), 0x10, 0x10).is_err());
811         assert!(bus.insert(dummy.clone(), 0x10, 0x15).is_err());
812         assert!(bus.insert(dummy.clone(), 0x12, 0x15).is_err());
813         assert!(bus.insert(dummy.clone(), 0x12, 0x01).is_err());
814         assert!(bus.insert(dummy.clone(), 0x0, 0x20).is_err());
815         assert!(bus.insert(dummy.clone(), 0x20, 0x05).is_ok());
816         assert!(bus.insert(dummy.clone(), 0x25, 0x05).is_ok());
817         assert!(bus.insert(dummy, 0x0, 0x10).is_ok());
818     }
819 
820     #[test]
bus_insert_full_addr()821     fn bus_insert_full_addr() {
822         let bus = Bus::new();
823         let dummy = Arc::new(Mutex::new(DummyDevice));
824         assert!(bus.insert(dummy.clone(), 0x10, 0).is_err());
825         assert!(bus.insert(dummy.clone(), 0x10, 0x10).is_ok());
826         assert!(bus.insert(dummy.clone(), 0x0f, 0x10).is_err());
827         assert!(bus.insert(dummy.clone(), 0x10, 0x10).is_err());
828         assert!(bus.insert(dummy.clone(), 0x10, 0x15).is_err());
829         assert!(bus.insert(dummy.clone(), 0x12, 0x15).is_err());
830         assert!(bus.insert(dummy.clone(), 0x12, 0x01).is_err());
831         assert!(bus.insert(dummy.clone(), 0x0, 0x20).is_err());
832         assert!(bus.insert(dummy.clone(), 0x20, 0x05).is_ok());
833         assert!(bus.insert(dummy.clone(), 0x25, 0x05).is_ok());
834         assert!(bus.insert(dummy, 0x0, 0x10).is_ok());
835     }
836 
837     #[test]
bus_read_write()838     fn bus_read_write() {
839         let bus = Bus::new();
840         let dummy = Arc::new(Mutex::new(DummyDevice));
841         assert!(bus.insert(dummy, 0x10, 0x10).is_ok());
842         assert!(bus.read(0x10, &mut [0, 0, 0, 0]));
843         assert!(bus.write(0x10, &[0, 0, 0, 0]));
844         assert!(bus.read(0x11, &mut [0, 0, 0, 0]));
845         assert!(bus.write(0x11, &[0, 0, 0, 0]));
846         assert!(bus.read(0x16, &mut [0, 0, 0, 0]));
847         assert!(bus.write(0x16, &[0, 0, 0, 0]));
848         assert!(!bus.read(0x20, &mut [0, 0, 0, 0]));
849         assert!(!bus.write(0x20, &[0, 0, 0, 0]));
850         assert!(!bus.read(0x06, &mut [0, 0, 0, 0]));
851         assert!(!bus.write(0x06, &[0, 0, 0, 0]));
852     }
853 
854     #[test]
bus_read_write_values()855     fn bus_read_write_values() {
856         let bus = Bus::new();
857         let dummy = Arc::new(Mutex::new(ConstantDevice {
858             uses_full_addr: false,
859         }));
860         assert!(bus.insert(dummy, 0x10, 0x10).is_ok());
861 
862         let mut values = [0, 1, 2, 3];
863         assert!(bus.read(0x10, &mut values));
864         assert_eq!(values, [0, 1, 2, 3]);
865         assert!(bus.write(0x10, &values));
866         assert!(bus.read(0x15, &mut values));
867         assert_eq!(values, [5, 6, 7, 8]);
868         assert!(bus.write(0x15, &values));
869     }
870 
871     #[test]
bus_read_write_full_addr_values()872     fn bus_read_write_full_addr_values() {
873         let bus = Bus::new();
874         let dummy = Arc::new(Mutex::new(ConstantDevice {
875             uses_full_addr: true,
876         }));
877         assert!(bus.insert(dummy, 0x10, 0x10).is_ok());
878 
879         let mut values = [0u8; 4];
880         assert!(bus.read(0x10, &mut values));
881         assert_eq!(values, [0x10, 0x11, 0x12, 0x13]);
882         assert!(bus.write(0x10, &values));
883         assert!(bus.read(0x15, &mut values));
884         assert_eq!(values, [0x15, 0x16, 0x17, 0x18]);
885         assert!(bus.write(0x15, &values));
886     }
887 
888     suspendable_tests!(
889         constant_device_true,
890         ConstantDevice {
891             uses_full_addr: true,
892         },
893         modify_constant_device
894     );
895 
896     suspendable_tests!(
897         constant_device_false,
898         ConstantDevice {
899             uses_full_addr: false,
900         },
901         modify_constant_device
902     );
903 
904     #[test]
bus_range_contains()905     fn bus_range_contains() {
906         let a = BusRange {
907             base: 0x1000,
908             len: 0x400,
909         };
910         assert!(a.contains(0x1000));
911         assert!(a.contains(0x13ff));
912         assert!(!a.contains(0xfff));
913         assert!(!a.contains(0x1400));
914         assert!(a.contains(0x1200));
915     }
916 
917     #[test]
bus_range_overlap()918     fn bus_range_overlap() {
919         let a = BusRange {
920             base: 0x1000,
921             len: 0x400,
922         };
923         assert!(a.overlaps(0x1000, 0x400));
924         assert!(a.overlaps(0xf00, 0x400));
925         assert!(a.overlaps(0x1000, 0x01));
926         assert!(a.overlaps(0xfff, 0x02));
927         assert!(a.overlaps(0x1100, 0x100));
928         assert!(a.overlaps(0x13ff, 0x100));
929         assert!(!a.overlaps(0x1400, 0x100));
930         assert!(!a.overlaps(0xf00, 0x100));
931     }
932 }
933