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