1 // Copyright 2017 The Chromium OS Authors. All rights reserved. 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, Ordering, PartialEq, PartialOrd}; 8 use std::collections::btree_map::BTreeMap; 9 use std::fmt::{self, Display}; 10 use std::result; 11 use std::sync::Arc; 12 13 use serde::{Deserialize, Serialize}; 14 use sync::Mutex; 15 16 /// Information about how a device was accessed. 17 #[derive(Copy, Clone, Eq, PartialEq, Debug, Serialize, Deserialize)] 18 pub struct BusAccessInfo { 19 /// Offset from base address that the device was accessed at. 20 pub offset: u64, 21 /// Absolute address of the device's access in its address space. 22 pub address: u64, 23 /// ID of the entity requesting a device access, usually the VCPU id. 24 pub id: usize, 25 } 26 27 // Implement `Display` for `MinMax`. 28 impl std::fmt::Display for BusAccessInfo { fmt(&self, f: &mut fmt::Formatter) -> fmt::Result29 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 30 write!(f, "{:?}", self) 31 } 32 } 33 34 /// Result of a write to a device's PCI configuration space. 35 /// This value represents the state change(s) that occurred due to the write. 36 /// Each member of this structure may be `None` if no change occurred, or `Some(new_value)` to 37 /// indicate a state change. 38 #[derive(Copy, Clone, Debug, Default, PartialEq)] 39 pub struct ConfigWriteResult { 40 /// New state of the memory bus for this PCI device: 41 /// - `None`: no change in state. 42 /// - `Some(true)`: memory decode enabled; device should respond to memory accesses. 43 /// - `Some(false)`: memory decode disabled; device should not respond to memory accesses. 44 pub mem_bus_new_state: Option<bool>, 45 46 /// New state of the I/O bus for this PCI device: 47 /// - `None`: no change in state. 48 /// - `Some(true)`: I/O decode enabled; device should respond to I/O accesses. 49 /// - `Some(false)`: I/O decode disabled; device should not respond to I/O accesses. 50 pub io_bus_new_state: Option<bool>, 51 } 52 53 /// Trait for devices that respond to reads or writes in an arbitrary address space. 54 /// 55 /// The device does not care where it exists in address space as each method is only given an offset 56 /// into its allocated portion of address space. 57 #[allow(unused_variables)] 58 pub trait BusDevice: Send { 59 /// Returns a label suitable for debug output. debug_label(&self) -> String60 fn debug_label(&self) -> String; 61 /// Reads at `offset` from this device read(&mut self, offset: BusAccessInfo, data: &mut [u8])62 fn read(&mut self, offset: BusAccessInfo, data: &mut [u8]) {} 63 /// Writes at `offset` into this device write(&mut self, offset: BusAccessInfo, data: &[u8])64 fn write(&mut self, offset: BusAccessInfo, data: &[u8]) {} 65 /// Sets a register in the configuration space. Only used by PCI. 66 /// * `reg_idx` - The index of the config register to modify. 67 /// * `offset` - Offset in to the register. config_register_write( &mut self, reg_idx: usize, offset: u64, data: &[u8], ) -> ConfigWriteResult68 fn config_register_write( 69 &mut self, 70 reg_idx: usize, 71 offset: u64, 72 data: &[u8], 73 ) -> ConfigWriteResult { 74 ConfigWriteResult { 75 ..Default::default() 76 } 77 } 78 /// Gets a register from the configuration space. Only used by PCI. 79 /// * `reg_idx` - The index of the config register to read. config_register_read(&self, reg_idx: usize) -> u3280 fn config_register_read(&self, reg_idx: usize) -> u32 { 81 0 82 } 83 /// Invoked when the device is sandboxed. on_sandboxed(&mut self)84 fn on_sandboxed(&mut self) {} 85 } 86 87 pub trait BusDeviceSync: BusDevice + Sync { read(&self, offset: BusAccessInfo, data: &mut [u8])88 fn read(&self, offset: BusAccessInfo, data: &mut [u8]); write(&self, offset: BusAccessInfo, data: &[u8])89 fn write(&self, offset: BusAccessInfo, data: &[u8]); 90 } 91 92 pub trait BusResumeDevice: Send { 93 /// notify the devices which are invoked 94 /// before the VM resumes form suspend. resume_imminent(&mut self)95 fn resume_imminent(&mut self) {} 96 } 97 98 #[derive(Debug)] 99 pub enum Error { 100 /// The insertion failed because the new device overlapped with an old device. 101 Overlap, 102 } 103 104 impl Display for Error { fmt(&self, f: &mut fmt::Formatter) -> fmt::Result105 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 106 use self::Error::*; 107 108 match self { 109 Overlap => write!(f, "new device overlaps with an old device"), 110 } 111 } 112 } 113 114 pub type Result<T> = result::Result<T, Error>; 115 116 /// Holds a base and length representing the address space occupied by a `BusDevice`. 117 /// 118 /// * base - The address at which the range start. 119 /// * len - The length of the range in bytes. 120 #[derive(Debug, Copy, Clone)] 121 pub struct BusRange { 122 pub base: u64, 123 pub len: u64, 124 } 125 126 impl BusRange { 127 /// Returns true if `addr` is within the range. contains(&self, addr: u64) -> bool128 pub fn contains(&self, addr: u64) -> bool { 129 self.base <= addr && addr < self.base + self.len 130 } 131 132 /// Returns true if there is overlap with the given range. overlaps(&self, base: u64, len: u64) -> bool133 pub fn overlaps(&self, base: u64, len: u64) -> bool { 134 self.base < (base + len) && base < self.base + self.len 135 } 136 } 137 138 impl Eq for BusRange {} 139 140 impl PartialEq for BusRange { eq(&self, other: &BusRange) -> bool141 fn eq(&self, other: &BusRange) -> bool { 142 self.base == other.base 143 } 144 } 145 146 impl Ord for BusRange { cmp(&self, other: &BusRange) -> Ordering147 fn cmp(&self, other: &BusRange) -> Ordering { 148 self.base.cmp(&other.base) 149 } 150 } 151 152 impl PartialOrd for BusRange { partial_cmp(&self, other: &BusRange) -> Option<Ordering>153 fn partial_cmp(&self, other: &BusRange) -> Option<Ordering> { 154 self.base.partial_cmp(&other.base) 155 } 156 } 157 158 #[derive(Clone)] 159 enum BusDeviceEntry { 160 OuterSync(Arc<Mutex<dyn BusDevice>>), 161 InnerSync(Arc<dyn BusDeviceSync>), 162 } 163 164 /// A device container for routing reads and writes over some address space. 165 /// 166 /// This doesn't have any restrictions on what kind of device or address space this applies to. The 167 /// only restriction is that no two devices can overlap in this address space. 168 /// 169 /// the 'resume_notify_devices' contains the devices which requires to be notified before the system 170 /// resume back from S3 suspended state. 171 #[derive(Clone)] 172 pub struct Bus { 173 devices: BTreeMap<BusRange, BusDeviceEntry>, 174 resume_notify_devices: Vec<Arc<Mutex<dyn BusResumeDevice>>>, 175 access_id: usize, 176 } 177 178 impl Bus { 179 /// Constructs an a bus with an empty address space. new() -> Bus180 pub fn new() -> Bus { 181 Bus { 182 devices: BTreeMap::new(), 183 resume_notify_devices: Vec::new(), 184 access_id: 0, 185 } 186 } 187 188 /// Sets the id that will be used for BusAccessInfo. set_access_id(&mut self, id: usize)189 pub fn set_access_id(&mut self, id: usize) { 190 self.access_id = id; 191 } 192 first_before(&self, addr: u64) -> Option<(BusRange, &BusDeviceEntry)>193 fn first_before(&self, addr: u64) -> Option<(BusRange, &BusDeviceEntry)> { 194 let (range, dev) = self 195 .devices 196 .range(..=BusRange { base: addr, len: 1 }) 197 .rev() 198 .next()?; 199 Some((*range, dev)) 200 } 201 get_device(&self, addr: u64) -> Option<(u64, u64, &BusDeviceEntry)>202 fn get_device(&self, addr: u64) -> Option<(u64, u64, &BusDeviceEntry)> { 203 if let Some((range, dev)) = self.first_before(addr) { 204 let offset = addr - range.base; 205 if offset < range.len { 206 return Some((offset, addr, dev)); 207 } 208 } 209 None 210 } 211 212 /// Puts the given device at the given address space. insert(&mut self, device: Arc<Mutex<dyn BusDevice>>, base: u64, len: u64) -> Result<()>213 pub fn insert(&mut self, device: Arc<Mutex<dyn BusDevice>>, base: u64, len: u64) -> Result<()> { 214 if len == 0 { 215 return Err(Error::Overlap); 216 } 217 218 // Reject all cases where the new device's range overlaps with an existing device. 219 if self 220 .devices 221 .iter() 222 .any(|(range, _dev)| range.overlaps(base, len)) 223 { 224 return Err(Error::Overlap); 225 } 226 227 if self 228 .devices 229 .insert(BusRange { base, len }, BusDeviceEntry::OuterSync(device)) 230 .is_some() 231 { 232 return Err(Error::Overlap); 233 } 234 235 Ok(()) 236 } 237 238 /// Puts the given device that implements BusDeviceSync at the given address space. Devices 239 /// that implement BusDeviceSync manage thread safety internally, and thus can be written to 240 /// by multiple threads simultaneously. insert_sync( &mut self, device: Arc<dyn BusDeviceSync>, base: u64, len: u64, ) -> Result<()>241 pub fn insert_sync( 242 &mut self, 243 device: Arc<dyn BusDeviceSync>, 244 base: u64, 245 len: u64, 246 ) -> Result<()> { 247 if len == 0 { 248 return Err(Error::Overlap); 249 } 250 251 // Reject all cases where the new device's range overlaps with an existing device. 252 if self 253 .devices 254 .iter() 255 .any(|(range, _dev)| range.overlaps(base, len)) 256 { 257 return Err(Error::Overlap); 258 } 259 260 if self 261 .devices 262 .insert(BusRange { base, len }, BusDeviceEntry::InnerSync(device)) 263 .is_some() 264 { 265 return Err(Error::Overlap); 266 } 267 268 Ok(()) 269 } 270 271 /// Reads data from the device that owns the range containing `addr` and puts it into `data`. 272 /// 273 /// Returns true on success, otherwise `data` is untouched. read(&self, addr: u64, data: &mut [u8]) -> bool274 pub fn read(&self, addr: u64, data: &mut [u8]) -> bool { 275 if let Some((offset, address, dev)) = self.get_device(addr) { 276 let io = BusAccessInfo { 277 address, 278 offset, 279 id: self.access_id, 280 }; 281 match dev { 282 BusDeviceEntry::OuterSync(dev) => dev.lock().read(io, data), 283 BusDeviceEntry::InnerSync(dev) => dev.read(io, data), 284 } 285 true 286 } else { 287 false 288 } 289 } 290 291 /// Writes `data` to the device that owns the range containing `addr`. 292 /// 293 /// Returns true on success, otherwise `data` is untouched. write(&self, addr: u64, data: &[u8]) -> bool294 pub fn write(&self, addr: u64, data: &[u8]) -> bool { 295 if let Some((offset, address, dev)) = self.get_device(addr) { 296 let io = BusAccessInfo { 297 address, 298 offset, 299 id: self.access_id, 300 }; 301 match dev { 302 BusDeviceEntry::OuterSync(dev) => dev.lock().write(io, data), 303 BusDeviceEntry::InnerSync(dev) => dev.write(io, data), 304 } 305 true 306 } else { 307 false 308 } 309 } 310 311 /// Register `device` for notifications of VM resume from suspend. notify_on_resume(&mut self, device: Arc<Mutex<dyn BusResumeDevice>>)312 pub fn notify_on_resume(&mut self, device: Arc<Mutex<dyn BusResumeDevice>>) { 313 self.resume_notify_devices.push(device); 314 } 315 316 /// Call `notify_resume` to notify the device that suspend resume is imminent. notify_resume(&mut self)317 pub fn notify_resume(&mut self) { 318 let devices = self.resume_notify_devices.clone(); 319 for dev in devices { 320 dev.lock().resume_imminent(); 321 } 322 } 323 } 324 325 #[cfg(test)] 326 mod tests { 327 use super::*; 328 329 struct DummyDevice; 330 impl BusDevice for DummyDevice { debug_label(&self) -> String331 fn debug_label(&self) -> String { 332 "dummy device".to_owned() 333 } 334 } 335 336 struct ConstantDevice { 337 uses_full_addr: bool, 338 } 339 340 impl BusDevice for ConstantDevice { debug_label(&self) -> String341 fn debug_label(&self) -> String { 342 "constant device".to_owned() 343 } 344 read(&mut self, info: BusAccessInfo, data: &mut [u8])345 fn read(&mut self, info: BusAccessInfo, data: &mut [u8]) { 346 let addr = if self.uses_full_addr { 347 info.address 348 } else { 349 info.offset 350 }; 351 for (i, v) in data.iter_mut().enumerate() { 352 *v = (addr as u8) + (i as u8); 353 } 354 } 355 write(&mut self, info: BusAccessInfo, data: &[u8])356 fn write(&mut self, info: BusAccessInfo, data: &[u8]) { 357 let addr = if self.uses_full_addr { 358 info.address 359 } else { 360 info.offset 361 }; 362 for (i, v) in data.iter().enumerate() { 363 assert_eq!(*v, (addr as u8) + (i as u8)) 364 } 365 } 366 } 367 368 #[test] bus_insert()369 fn bus_insert() { 370 let mut bus = Bus::new(); 371 let dummy = Arc::new(Mutex::new(DummyDevice)); 372 assert!(bus.insert(dummy.clone(), 0x10, 0).is_err()); 373 assert!(bus.insert(dummy.clone(), 0x10, 0x10).is_ok()); 374 assert!(bus.insert(dummy.clone(), 0x0f, 0x10).is_err()); 375 assert!(bus.insert(dummy.clone(), 0x10, 0x10).is_err()); 376 assert!(bus.insert(dummy.clone(), 0x10, 0x15).is_err()); 377 assert!(bus.insert(dummy.clone(), 0x12, 0x15).is_err()); 378 assert!(bus.insert(dummy.clone(), 0x12, 0x01).is_err()); 379 assert!(bus.insert(dummy.clone(), 0x0, 0x20).is_err()); 380 assert!(bus.insert(dummy.clone(), 0x20, 0x05).is_ok()); 381 assert!(bus.insert(dummy.clone(), 0x25, 0x05).is_ok()); 382 assert!(bus.insert(dummy.clone(), 0x0, 0x10).is_ok()); 383 } 384 385 #[test] bus_insert_full_addr()386 fn bus_insert_full_addr() { 387 let mut bus = Bus::new(); 388 let dummy = Arc::new(Mutex::new(DummyDevice)); 389 assert!(bus.insert(dummy.clone(), 0x10, 0).is_err()); 390 assert!(bus.insert(dummy.clone(), 0x10, 0x10).is_ok()); 391 assert!(bus.insert(dummy.clone(), 0x0f, 0x10).is_err()); 392 assert!(bus.insert(dummy.clone(), 0x10, 0x10).is_err()); 393 assert!(bus.insert(dummy.clone(), 0x10, 0x15).is_err()); 394 assert!(bus.insert(dummy.clone(), 0x12, 0x15).is_err()); 395 assert!(bus.insert(dummy.clone(), 0x12, 0x01).is_err()); 396 assert!(bus.insert(dummy.clone(), 0x0, 0x20).is_err()); 397 assert!(bus.insert(dummy.clone(), 0x20, 0x05).is_ok()); 398 assert!(bus.insert(dummy.clone(), 0x25, 0x05).is_ok()); 399 assert!(bus.insert(dummy.clone(), 0x0, 0x10).is_ok()); 400 } 401 402 #[test] bus_read_write()403 fn bus_read_write() { 404 let mut bus = Bus::new(); 405 let dummy = Arc::new(Mutex::new(DummyDevice)); 406 assert!(bus.insert(dummy.clone(), 0x10, 0x10).is_ok()); 407 assert!(bus.read(0x10, &mut [0, 0, 0, 0])); 408 assert!(bus.write(0x10, &[0, 0, 0, 0])); 409 assert!(bus.read(0x11, &mut [0, 0, 0, 0])); 410 assert!(bus.write(0x11, &[0, 0, 0, 0])); 411 assert!(bus.read(0x16, &mut [0, 0, 0, 0])); 412 assert!(bus.write(0x16, &[0, 0, 0, 0])); 413 assert!(!bus.read(0x20, &mut [0, 0, 0, 0])); 414 assert!(!bus.write(0x20, &mut [0, 0, 0, 0])); 415 assert!(!bus.read(0x06, &mut [0, 0, 0, 0])); 416 assert!(!bus.write(0x06, &mut [0, 0, 0, 0])); 417 } 418 419 #[test] bus_read_write_values()420 fn bus_read_write_values() { 421 let mut bus = Bus::new(); 422 let dummy = Arc::new(Mutex::new(ConstantDevice { 423 uses_full_addr: false, 424 })); 425 assert!(bus.insert(dummy.clone(), 0x10, 0x10).is_ok()); 426 427 let mut values = [0, 1, 2, 3]; 428 assert!(bus.read(0x10, &mut values)); 429 assert_eq!(values, [0, 1, 2, 3]); 430 assert!(bus.write(0x10, &values)); 431 assert!(bus.read(0x15, &mut values)); 432 assert_eq!(values, [5, 6, 7, 8]); 433 assert!(bus.write(0x15, &values)); 434 } 435 436 #[test] bus_read_write_full_addr_values()437 fn bus_read_write_full_addr_values() { 438 let mut bus = Bus::new(); 439 let dummy = Arc::new(Mutex::new(ConstantDevice { 440 uses_full_addr: true, 441 })); 442 assert!(bus.insert(dummy.clone(), 0x10, 0x10).is_ok()); 443 444 let mut values = [0u8; 4]; 445 assert!(bus.read(0x10, &mut values)); 446 assert_eq!(values, [0x10, 0x11, 0x12, 0x13]); 447 assert!(bus.write(0x10, &values)); 448 assert!(bus.read(0x15, &mut values)); 449 assert_eq!(values, [0x15, 0x16, 0x17, 0x18]); 450 assert!(bus.write(0x15, &values)); 451 } 452 453 #[test] bus_range_contains()454 fn bus_range_contains() { 455 let a = BusRange { 456 base: 0x1000, 457 len: 0x400, 458 }; 459 assert!(a.contains(0x1000)); 460 assert!(a.contains(0x13ff)); 461 assert!(!a.contains(0xfff)); 462 assert!(!a.contains(0x1400)); 463 assert!(a.contains(0x1200)); 464 } 465 466 #[test] bus_range_overlap()467 fn bus_range_overlap() { 468 let a = BusRange { 469 base: 0x1000, 470 len: 0x400, 471 }; 472 assert!(a.overlaps(0x1000, 0x400)); 473 assert!(a.overlaps(0xf00, 0x400)); 474 assert!(a.overlaps(0x1000, 0x01)); 475 assert!(a.overlaps(0xfff, 0x02)); 476 assert!(a.overlaps(0x1100, 0x100)); 477 assert!(a.overlaps(0x13ff, 0x100)); 478 assert!(!a.overlaps(0x1400, 0x100)); 479 assert!(!a.overlaps(0xf00, 0x100)); 480 } 481 } 482