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