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