devices/
bus.rs

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