• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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