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