• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2018 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 use std::collections::HashMap;
6 use std::collections::HashSet;
7 use std::sync::Arc;
8 
9 #[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
10 use acpi_tables::sdt::SDT;
11 use anyhow::bail;
12 use anyhow::Context;
13 use base::error;
14 use base::Event;
15 use base::MemoryMapping;
16 use base::RawDescriptor;
17 use base::Tube;
18 use hypervisor::Datamatch;
19 use remain::sorted;
20 use resources::Error as SystemAllocatorFaliure;
21 use resources::SystemAllocator;
22 use sync::Mutex;
23 use thiserror::Error;
24 use vm_control::IoEventUpdateRequest;
25 use vm_control::VmMemoryRequest;
26 use vm_control::VmMemoryResponse;
27 
28 use super::PciId;
29 use crate::bus::BusDeviceObj;
30 use crate::bus::BusRange;
31 use crate::bus::BusType;
32 use crate::bus::ConfigWriteResult;
33 use crate::pci::pci_configuration;
34 use crate::pci::pci_configuration::PciBarConfiguration;
35 use crate::pci::pci_configuration::COMMAND_REG;
36 use crate::pci::pci_configuration::COMMAND_REG_IO_SPACE_MASK;
37 use crate::pci::pci_configuration::COMMAND_REG_MEMORY_SPACE_MASK;
38 use crate::pci::pci_configuration::NUM_BAR_REGS;
39 use crate::pci::pci_configuration::PCI_ID_REG;
40 use crate::pci::PciAddress;
41 use crate::pci::PciAddressError;
42 use crate::pci::PciInterruptPin;
43 use crate::virtio::ipc_memory_mapper::IpcMemoryMapper;
44 #[cfg(all(unix, feature = "audio"))]
45 use crate::virtio::snd::vios_backend::Error as VioSError;
46 use crate::BusAccessInfo;
47 use crate::BusDevice;
48 use crate::DeviceId;
49 use crate::IrqLevelEvent;
50 use crate::Suspendable;
51 
52 #[sorted]
53 #[derive(Error, Debug)]
54 pub enum Error {
55     /// Added pci device's parent bus does not belong to this bus
56     #[error("pci device {0}'s parent bus does not belong to bus {1}")]
57     AddedDeviceBusNotExist(PciAddress, u8),
58     /// Invalid alignment encountered.
59     #[error("Alignment must be a power of 2")]
60     BadAlignment,
61     /// The new bus has already been added to this bus
62     #[error("Added bus {0} already existed on bus {1}")]
63     BusAlreadyExist(u8, u8),
64     /// Target bus not exists on this bus
65     #[error("pci bus {0} does not exist on bus {1}")]
66     BusNotExist(u8, u8),
67     /// Setup of the device capabilities failed.
68     #[error("failed to add capability {0}")]
69     CapabilitiesSetup(pci_configuration::Error),
70     /// Create cras client failed.
71     #[cfg(all(unix, feature = "audio", feature = "audio_cras"))]
72     #[error("failed to create CRAS Client: {0}")]
73     CreateCrasClientFailed(libcras::Error),
74     /// Create VioS client failed.
75     #[cfg(all(unix, feature = "audio"))]
76     #[error("failed to create VioS Client: {0}")]
77     CreateViosClientFailed(VioSError),
78     /// Device is already on this bus
79     #[error("pci device {0} has already been added to bus {1}")]
80     DeviceAlreadyExist(PciAddress, u8),
81     /// Device not exist on this bus
82     #[error("pci device {0} does not located on bus {1}")]
83     DeviceNotExist(PciAddress, u8),
84     /// Allocating space for an IO BAR failed.
85     #[error("failed to allocate space for an IO BAR, size={0}: {1}")]
86     IoAllocationFailed(u64, SystemAllocatorFaliure),
87     /// ioevent registration failed.
88     #[error("IoEvent registration failed: {0}")]
89     IoEventRegisterFailed(IoEventError),
90     /// supports_iommu is false.
91     #[error("Iommu is not supported")]
92     IommuNotSupported,
93     /// Registering an IO BAR failed.
94     #[error("failed to register an IO BAR, addr={0} err={1}")]
95     IoRegistrationFailed(u64, pci_configuration::Error),
96     /// Out-of-space encountered
97     #[error("Out-of-space detected")]
98     OutOfSpace,
99     /// Overflow encountered
100     #[error("base={0} + size={1} overflows")]
101     Overflow(u64, u64),
102     /// The new added bus does not located on this bus
103     #[error("Added bus {0} does not located on bus {1}")]
104     ParentBusNotExist(u8, u8),
105     /// PCI Address is not allocated.
106     #[error("PCI address is not allocated")]
107     PciAddressMissing,
108     /// PCI Address parsing failure.
109     #[error("PCI address '{0}' could not be parsed: {1}")]
110     PciAddressParseFailure(String, PciAddressError),
111     /// PCI Address allocation failure.
112     #[error("failed to allocate PCI address")]
113     PciAllocationFailed,
114     /// PCI Bus window allocation failure.
115     #[error("failed to allocate window for PCI bus: {0}")]
116     PciBusWindowAllocationFailure(String),
117     /// Size of zero encountered
118     #[error("Size of zero detected")]
119     SizeZero,
120 }
121 
122 /// Errors when io event registration fails:
123 #[derive(Clone, Debug, Error)]
124 pub enum IoEventError {
125     /// Event clone failed.
126     #[error("Event clone failed: {0}")]
127     CloneFail(base::Error),
128     /// Failed due to system error.
129     #[error("System error: {0}")]
130     SystemError(base::Error),
131     /// Tube for ioevent register failed.
132     #[error("IoEvent register Tube failed")]
133     TubeFail,
134     /// ioevent_register_request not implemented for PciDevice emitting it.
135     #[error("ioevent register not implemented")]
136     Unsupported,
137 }
138 
139 pub type Result<T> = std::result::Result<T, Error>;
140 
141 /// Pci Bar Range information
142 #[derive(Clone, Debug)]
143 pub struct BarRange {
144     /// pci bar start address
145     pub addr: u64,
146     /// pci bar size
147     pub size: u64,
148     /// pci bar is prefetchable or not, it used to set parent's bridge window
149     pub prefetchable: bool,
150 }
151 
152 /// Pci Bus information
153 #[derive(Debug)]
154 pub struct PciBus {
155     // bus number
156     bus_num: u8,
157     // parent bus number
158     parent_bus_num: u8,
159     // devices located on this bus
160     child_devices: HashSet<PciAddress>,
161     // Hash map that stores all direct child buses of this bus.
162     // It maps from child bus number to its pci bus structure.
163     child_buses: HashMap<u8, Arc<Mutex<PciBus>>>,
164     // Is hotplug bus
165     hotplug_bus: bool,
166 }
167 
168 impl PciBus {
169     // Creates a new pci bus
new(bus_num: u8, parent_bus_num: u8, hotplug_bus: bool) -> Self170     pub fn new(bus_num: u8, parent_bus_num: u8, hotplug_bus: bool) -> Self {
171         PciBus {
172             bus_num,
173             parent_bus_num,
174             child_devices: HashSet::new(),
175             child_buses: HashMap::new(),
176             hotplug_bus,
177         }
178     }
179 
get_bus_num(&self) -> u8180     pub fn get_bus_num(&self) -> u8 {
181         self.bus_num
182     }
183 
184     // Find all PCI buses from this PCI bus to a given PCI bus
path_to(&self, bus_num: u8) -> Vec<u8>185     pub fn path_to(&self, bus_num: u8) -> Vec<u8> {
186         if self.bus_num == bus_num {
187             return vec![self.bus_num];
188         }
189 
190         for (_, child_bus) in self.child_buses.iter() {
191             let mut path = child_bus.lock().path_to(bus_num);
192             if !path.is_empty() {
193                 path.insert(0, self.bus_num);
194                 return path;
195             }
196         }
197         Vec::new()
198     }
199 
200     // Add a new child device to this pci bus tree.
add_child_device(&mut self, add_device: PciAddress) -> Result<()>201     pub fn add_child_device(&mut self, add_device: PciAddress) -> Result<()> {
202         if self.bus_num == add_device.bus {
203             if !self.child_devices.insert(add_device) {
204                 return Err(Error::DeviceAlreadyExist(add_device, self.bus_num));
205             }
206             return Ok(());
207         }
208 
209         for child_bus in self.child_buses.values() {
210             match child_bus.lock().add_child_device(add_device) {
211                 Ok(()) => return Ok(()),
212                 Err(e) => {
213                     if let Error::DeviceAlreadyExist(_, _) = e {
214                         return Err(e);
215                     }
216                 }
217             }
218         }
219         Err(Error::AddedDeviceBusNotExist(add_device, self.bus_num))
220     }
221 
222     // Remove one child device from this pci bus tree
remove_child_device(&mut self, device: PciAddress) -> Result<()>223     pub fn remove_child_device(&mut self, device: PciAddress) -> Result<()> {
224         if self.child_devices.remove(&device) {
225             return Ok(());
226         }
227         for child_bus in self.child_buses.values() {
228             if child_bus.lock().remove_child_device(device).is_ok() {
229                 return Ok(());
230             }
231         }
232         Err(Error::DeviceNotExist(device, self.bus_num))
233     }
234 
235     // Add a new child bus to this pci bus tree.
add_child_bus(&mut self, add_bus: Arc<Mutex<PciBus>>) -> Result<()>236     pub fn add_child_bus(&mut self, add_bus: Arc<Mutex<PciBus>>) -> Result<()> {
237         let add_bus_num = add_bus.lock().bus_num;
238         let add_bus_parent = add_bus.lock().parent_bus_num;
239         if self.bus_num == add_bus_parent {
240             if self.child_buses.contains_key(&add_bus_num) {
241                 return Err(Error::BusAlreadyExist(self.bus_num, add_bus_num));
242             }
243             self.child_buses.insert(add_bus_num, add_bus);
244             return Ok(());
245         }
246 
247         for child_bus in self.child_buses.values() {
248             match child_bus.lock().add_child_bus(add_bus.clone()) {
249                 Ok(_) => return Ok(()),
250                 Err(e) => {
251                     if let Error::BusAlreadyExist(_, _) = e {
252                         return Err(e);
253                     }
254                 }
255             }
256         }
257         Err(Error::ParentBusNotExist(add_bus_num, self.bus_num))
258     }
259 
260     // Remove one child bus from this pci bus tree.
remove_child_bus(&mut self, bus_no: u8) -> Result<()>261     pub fn remove_child_bus(&mut self, bus_no: u8) -> Result<()> {
262         if self.child_buses.remove(&bus_no).is_some() {
263             return Ok(());
264         }
265         for (_, child_bus) in self.child_buses.iter() {
266             if child_bus.lock().remove_child_bus(bus_no).is_ok() {
267                 return Ok(());
268             }
269         }
270         Err(Error::BusNotExist(bus_no, self.bus_num))
271     }
272 
273     // Find all downstream devices under the given bus
find_downstream_devices(&self, bus_no: u8) -> Vec<PciAddress>274     pub fn find_downstream_devices(&self, bus_no: u8) -> Vec<PciAddress> {
275         if self.bus_num == bus_no {
276             return self.get_downstream_devices();
277         }
278         for (_, child_bus) in self.child_buses.iter() {
279             let res = child_bus.lock().find_downstream_devices(bus_no);
280             if !res.is_empty() {
281                 return res;
282             }
283         }
284 
285         Vec::new()
286     }
287 
288     // Get all devices in this pci bus tree by level-order traversal (BFS)
get_downstream_devices(&self) -> Vec<PciAddress>289     pub fn get_downstream_devices(&self) -> Vec<PciAddress> {
290         let mut devices = Vec::new();
291         devices.extend(self.child_devices.clone());
292         for child_bus in self.child_buses.values() {
293             devices.extend(child_bus.lock().get_downstream_devices());
294         }
295         devices
296     }
297 
298     // Check if given device is located in the device tree
contains(&self, device: PciAddress) -> bool299     pub fn contains(&self, device: PciAddress) -> bool {
300         if self.child_devices.contains(&device) {
301             return true;
302         }
303 
304         for (_, child_bus) in self.child_buses.iter() {
305             if child_bus.lock().contains(device) {
306                 return true;
307             }
308         }
309 
310         false
311     }
312 
313     // Returns the hotplug bus that this device is on.
get_hotplug_bus(&self, device: PciAddress) -> Option<u8>314     pub fn get_hotplug_bus(&self, device: PciAddress) -> Option<u8> {
315         if self.hotplug_bus && self.contains(device) {
316             return Some(self.bus_num);
317         }
318         for (_, child_bus) in self.child_buses.iter() {
319             let hotplug_bus = child_bus.lock().get_hotplug_bus(device);
320             if hotplug_bus.is_some() {
321                 return hotplug_bus;
322             }
323         }
324         None
325     }
326 }
327 
328 pub enum PreferredIrq {
329     None,
330     Any,
331     Fixed { pin: PciInterruptPin, gsi: u32 },
332 }
333 
334 pub trait PciDevice: Send + Suspendable {
335     /// Returns a label suitable for debug output.
debug_label(&self) -> String336     fn debug_label(&self) -> String;
337 
338     /// Preferred PCI address for this device, if any.
preferred_address(&self) -> Option<PciAddress>339     fn preferred_address(&self) -> Option<PciAddress> {
340         None
341     }
342 
343     /// Allocate and return an unique bus, device and function number for this device.
344     /// May be called multiple times; on subsequent calls, the device should return the same
345     /// address it returned from the first call.
allocate_address(&mut self, resources: &mut SystemAllocator) -> Result<PciAddress>346     fn allocate_address(&mut self, resources: &mut SystemAllocator) -> Result<PciAddress>;
347 
348     /// A vector of device-specific file descriptors that must be kept open
349     /// after jailing. Must be called before the process is jailed.
keep_rds(&self) -> Vec<RawDescriptor>350     fn keep_rds(&self) -> Vec<RawDescriptor>;
351 
352     /// Preferred IRQ for this device.
353     /// The device may request a specific pin and IRQ number by returning a `Fixed` value.
354     /// If a device does not support INTx# interrupts at all, it should return `None`.
355     /// Otherwise, an appropriate IRQ will be allocated automatically.
356     /// The device's `assign_irq` function will be called with its assigned IRQ either way.
preferred_irq(&self) -> PreferredIrq357     fn preferred_irq(&self) -> PreferredIrq {
358         PreferredIrq::Any
359     }
360 
361     /// Assign a legacy PCI IRQ to this device.
362     /// The device may write to `irq_evt` to trigger an interrupt.
363     /// When `irq_resample_evt` is signaled, the device should re-assert `irq_evt` if necessary.
assign_irq(&mut self, _irq_evt: IrqLevelEvent, _pin: PciInterruptPin, _irq_num: u32)364     fn assign_irq(&mut self, _irq_evt: IrqLevelEvent, _pin: PciInterruptPin, _irq_num: u32) {}
365 
366     /// Allocates the needed IO BAR space using the `allocate` function which takes a size and
367     /// returns an address. Returns a Vec of BarRange{addr, size, prefetchable}.
allocate_io_bars(&mut self, _resources: &mut SystemAllocator) -> Result<Vec<BarRange>>368     fn allocate_io_bars(&mut self, _resources: &mut SystemAllocator) -> Result<Vec<BarRange>> {
369         Ok(Vec::new())
370     }
371 
372     /// Allocates the needed device BAR space. Returns a Vec of BarRange{addr, size, prefetchable}.
373     /// Unlike MMIO BARs (see allocate_io_bars), device BARs are not expected to incur VM exits
374     /// - these BARs represent normal memory.
allocate_device_bars(&mut self, _resources: &mut SystemAllocator) -> Result<Vec<BarRange>>375     fn allocate_device_bars(&mut self, _resources: &mut SystemAllocator) -> Result<Vec<BarRange>> {
376         Ok(Vec::new())
377     }
378 
379     /// Returns the configuration of a base address register, if present.
get_bar_configuration(&self, bar_num: usize) -> Option<PciBarConfiguration>380     fn get_bar_configuration(&self, bar_num: usize) -> Option<PciBarConfiguration>;
381 
382     /// Register any capabilties specified by the device.
register_device_capabilities(&mut self) -> Result<()>383     fn register_device_capabilities(&mut self) -> Result<()> {
384         Ok(())
385     }
386 
387     /// Gets a list of ioevents that should be registered with the running VM. The list is
388     /// returned as a Vec of (event, addr, datamatch) tuples.
ioevents(&self) -> Vec<(&Event, u64, Datamatch)>389     fn ioevents(&self) -> Vec<(&Event, u64, Datamatch)> {
390         Vec::new()
391     }
392 
393     /// Gets a reference to the Tube for sending VmMemoryRequest. Any devices that uses ioevents
394     /// shall provide Tube.
get_vm_memory_request_tube(&self) -> Option<&Tube>395     fn get_vm_memory_request_tube(&self) -> Option<&Tube> {
396         None
397     }
398 
399     /// Reads from a PCI configuration register.
400     /// * `reg_idx` - PCI register index (in units of 4 bytes).
read_config_register(&self, reg_idx: usize) -> u32401     fn read_config_register(&self, reg_idx: usize) -> u32;
402 
403     /// Writes to a PCI configuration register.
404     /// * `reg_idx` - PCI register index (in units of 4 bytes).
405     /// * `offset`  - byte offset within 4-byte register.
406     /// * `data`    - The data to write.
write_config_register(&mut self, reg_idx: usize, offset: u64, data: &[u8])407     fn write_config_register(&mut self, reg_idx: usize, offset: u64, data: &[u8]);
408 
409     /// Reads from a virtual config register.
410     /// * `reg_idx` - virtual config register index (in units of 4 bytes).
read_virtual_config_register(&self, _reg_idx: usize) -> u32411     fn read_virtual_config_register(&self, _reg_idx: usize) -> u32 {
412         0
413     }
414 
415     /// Writes to a virtual config register.
416     /// * `reg_idx` - virtual config register index (in units of 4 bytes).
417     /// * `value`   - the value to be written.
write_virtual_config_register(&mut self, _reg_idx: usize, _value: u32)418     fn write_virtual_config_register(&mut self, _reg_idx: usize, _value: u32) {}
419 
420     /// Reads from a BAR region mapped in to the device.
421     /// * `addr` - The guest address inside the BAR.
422     /// * `data` - Filled with the data from `addr`.
read_bar(&mut self, addr: u64, data: &mut [u8])423     fn read_bar(&mut self, addr: u64, data: &mut [u8]);
424     /// Writes to a BAR region mapped in to the device.
425     /// * `addr` - The guest address inside the BAR.
426     /// * `data` - The data to write.
write_bar(&mut self, addr: u64, data: &[u8])427     fn write_bar(&mut self, addr: u64, data: &[u8]);
428     /// Invoked when the device is sandboxed.
on_device_sandboxed(&mut self)429     fn on_device_sandboxed(&mut self) {}
430 
431     #[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
generate_acpi(&mut self, sdts: Vec<SDT>) -> Option<Vec<SDT>>432     fn generate_acpi(&mut self, sdts: Vec<SDT>) -> Option<Vec<SDT>> {
433         Some(sdts)
434     }
435 
436     /// Construct customized acpi method, and return the AML code and
437     /// shared memory
generate_acpi_methods(&mut self) -> (Vec<u8>, Option<(u32, MemoryMapping)>)438     fn generate_acpi_methods(&mut self) -> (Vec<u8>, Option<(u32, MemoryMapping)>) {
439         (Vec::new(), None)
440     }
441 
442     /// Invoked when the device is destroyed
destroy_device(&mut self)443     fn destroy_device(&mut self) {}
444 
445     /// Get the removed children devices under pci bridge
get_removed_children_devices(&self) -> Vec<PciAddress>446     fn get_removed_children_devices(&self) -> Vec<PciAddress> {
447         Vec::new()
448     }
449 
450     /// Get the pci bus generated by this pci device
get_new_pci_bus(&self) -> Option<Arc<Mutex<PciBus>>>451     fn get_new_pci_bus(&self) -> Option<Arc<Mutex<PciBus>>> {
452         None
453     }
454 
455     /// if device is a pci brdige, configure pci bridge window
configure_bridge_window( &mut self, _resources: &mut SystemAllocator, _bar_ranges: &[BarRange], ) -> Result<Vec<BarRange>>456     fn configure_bridge_window(
457         &mut self,
458         _resources: &mut SystemAllocator,
459         _bar_ranges: &[BarRange],
460     ) -> Result<Vec<BarRange>> {
461         Ok(Vec::new())
462     }
463 
464     /// if device is a pci bridge, configure subordinate bus number
set_subordinate_bus(&mut self, _bus_no: u8)465     fn set_subordinate_bus(&mut self, _bus_no: u8) {}
466 
467     /// Indicates whether the device supports IOMMU
supports_iommu(&self) -> bool468     fn supports_iommu(&self) -> bool {
469         false
470     }
471 
472     /// Sets the IOMMU for the device if `supports_iommu()`
set_iommu(&mut self, _iommu: IpcMemoryMapper) -> anyhow::Result<()>473     fn set_iommu(&mut self, _iommu: IpcMemoryMapper) -> anyhow::Result<()> {
474         bail!("Iommu not supported.");
475     }
476 }
477 
update_ranges( old_enabled: bool, new_enabled: bool, bus_type_filter: BusType, old_ranges: &[(BusRange, BusType)], new_ranges: &[(BusRange, BusType)], ) -> (Vec<BusRange>, Vec<BusRange>)478 fn update_ranges(
479     old_enabled: bool,
480     new_enabled: bool,
481     bus_type_filter: BusType,
482     old_ranges: &[(BusRange, BusType)],
483     new_ranges: &[(BusRange, BusType)],
484 ) -> (Vec<BusRange>, Vec<BusRange>) {
485     let mut remove_ranges = Vec::new();
486     let mut add_ranges = Vec::new();
487 
488     let old_ranges_filtered = old_ranges
489         .iter()
490         .filter(|(_range, bus_type)| *bus_type == bus_type_filter)
491         .map(|(range, _bus_type)| *range);
492     let new_ranges_filtered = new_ranges
493         .iter()
494         .filter(|(_range, bus_type)| *bus_type == bus_type_filter)
495         .map(|(range, _bus_type)| *range);
496 
497     if old_enabled && !new_enabled {
498         // Bus type was enabled and is now disabled; remove all old ranges.
499         remove_ranges.extend(old_ranges_filtered);
500     } else if !old_enabled && new_enabled {
501         // Bus type was disabled and is now enabled; add all new ranges.
502         add_ranges.extend(new_ranges_filtered);
503     } else if old_enabled && new_enabled {
504         // Bus type was enabled before and is still enabled; diff old and new ranges.
505         for (old_range, new_range) in old_ranges_filtered.zip(new_ranges_filtered) {
506             if old_range.base != new_range.base {
507                 remove_ranges.push(old_range);
508                 add_ranges.push(new_range);
509             }
510         }
511     }
512 
513     (remove_ranges, add_ranges)
514 }
515 
516 impl<T: PciDevice> BusDevice for T {
debug_label(&self) -> String517     fn debug_label(&self) -> String {
518         PciDevice::debug_label(self)
519     }
520 
device_id(&self) -> DeviceId521     fn device_id(&self) -> DeviceId {
522         // Use the PCI ID for PCI devices, which contains the PCI vendor ID and the PCI device ID
523         let pci_id: PciId = PciDevice::read_config_register(self, PCI_ID_REG).into();
524         pci_id.into()
525     }
526 
read(&mut self, info: BusAccessInfo, data: &mut [u8])527     fn read(&mut self, info: BusAccessInfo, data: &mut [u8]) {
528         self.read_bar(info.address, data)
529     }
530 
write(&mut self, info: BusAccessInfo, data: &[u8])531     fn write(&mut self, info: BusAccessInfo, data: &[u8]) {
532         self.write_bar(info.address, data)
533     }
534 
config_register_write( &mut self, reg_idx: usize, offset: u64, data: &[u8], ) -> ConfigWriteResult535     fn config_register_write(
536         &mut self,
537         reg_idx: usize,
538         offset: u64,
539         data: &[u8],
540     ) -> ConfigWriteResult {
541         if offset as usize + data.len() > 4 {
542             return Default::default();
543         }
544 
545         let old_command_reg = self.read_config_register(COMMAND_REG);
546         let old_ranges =
547             if old_command_reg & (COMMAND_REG_MEMORY_SPACE_MASK | COMMAND_REG_IO_SPACE_MASK) != 0 {
548                 self.get_ranges()
549             } else {
550                 Vec::new()
551             };
552 
553         self.write_config_register(reg_idx, offset, data);
554 
555         let new_command_reg = self.read_config_register(COMMAND_REG);
556         let new_ranges =
557             if new_command_reg & (COMMAND_REG_MEMORY_SPACE_MASK | COMMAND_REG_IO_SPACE_MASK) != 0 {
558                 self.get_ranges()
559             } else {
560                 Vec::new()
561             };
562 
563         let (mmio_remove, mmio_add) = update_ranges(
564             old_command_reg & COMMAND_REG_MEMORY_SPACE_MASK != 0,
565             new_command_reg & COMMAND_REG_MEMORY_SPACE_MASK != 0,
566             BusType::Mmio,
567             &old_ranges,
568             &new_ranges,
569         );
570 
571         let (io_remove, io_add) = update_ranges(
572             old_command_reg & COMMAND_REG_IO_SPACE_MASK != 0,
573             new_command_reg & COMMAND_REG_IO_SPACE_MASK != 0,
574             BusType::Io,
575             &old_ranges,
576             &new_ranges,
577         );
578 
579         let result = ConfigWriteResult {
580             mmio_remove,
581             mmio_add,
582             io_remove,
583             io_add,
584             removed_pci_devices: self.get_removed_children_devices(),
585         };
586 
587         // Handle ioevent changes
588         if !(result.io_add.is_empty()
589             && result.io_remove.is_empty()
590             && result.mmio_add.is_empty()
591             && result.mmio_remove.is_empty())
592         {
593             let ioevents = self.ioevents();
594             if !ioevents.is_empty() {
595                 if let Err(e) = send_ioevent_updates(
596                     self.get_vm_memory_request_tube(),
597                     ioevents,
598                     old_ranges,
599                     new_ranges,
600                 ) {
601                     error!(
602                         "send_ioevent_updates failed for {}: {:#}",
603                         self.debug_label(),
604                         e
605                     );
606                 }
607             }
608         }
609 
610         result
611     }
612 
config_register_read(&self, reg_idx: usize) -> u32613     fn config_register_read(&self, reg_idx: usize) -> u32 {
614         self.read_config_register(reg_idx)
615     }
616 
virtual_config_register_write(&mut self, reg_idx: usize, value: u32)617     fn virtual_config_register_write(&mut self, reg_idx: usize, value: u32) {
618         self.write_virtual_config_register(reg_idx, value);
619     }
620 
virtual_config_register_read(&self, reg_idx: usize) -> u32621     fn virtual_config_register_read(&self, reg_idx: usize) -> u32 {
622         self.read_virtual_config_register(reg_idx)
623     }
624 
on_sandboxed(&mut self)625     fn on_sandboxed(&mut self) {
626         self.on_device_sandboxed();
627     }
628 
get_ranges(&self) -> Vec<(BusRange, BusType)>629     fn get_ranges(&self) -> Vec<(BusRange, BusType)> {
630         let mut ranges = Vec::new();
631         for bar_num in 0..NUM_BAR_REGS {
632             if let Some(bar) = self.get_bar_configuration(bar_num) {
633                 let bus_type = if bar.is_memory() {
634                     BusType::Mmio
635                 } else {
636                     BusType::Io
637                 };
638                 ranges.push((
639                     BusRange {
640                         base: bar.address(),
641                         len: bar.size(),
642                     },
643                     bus_type,
644                 ));
645             }
646         }
647         ranges
648     }
649 
650     // Invoked when the device is destroyed
destroy_device(&mut self)651     fn destroy_device(&mut self) {
652         self.destroy_device()
653     }
654 
is_bridge(&self) -> Option<u8>655     fn is_bridge(&self) -> Option<u8> {
656         self.get_new_pci_bus().map(|bus| bus.lock().get_bus_num())
657     }
658 }
659 
660 impl<T: PciDevice + ?Sized> PciDevice for Box<T> {
661     /// Returns a label suitable for debug output.
debug_label(&self) -> String662     fn debug_label(&self) -> String {
663         (**self).debug_label()
664     }
preferred_address(&self) -> Option<PciAddress>665     fn preferred_address(&self) -> Option<PciAddress> {
666         (**self).preferred_address()
667     }
allocate_address(&mut self, resources: &mut SystemAllocator) -> Result<PciAddress>668     fn allocate_address(&mut self, resources: &mut SystemAllocator) -> Result<PciAddress> {
669         (**self).allocate_address(resources)
670     }
keep_rds(&self) -> Vec<RawDescriptor>671     fn keep_rds(&self) -> Vec<RawDescriptor> {
672         (**self).keep_rds()
673     }
preferred_irq(&self) -> PreferredIrq674     fn preferred_irq(&self) -> PreferredIrq {
675         (**self).preferred_irq()
676     }
assign_irq(&mut self, irq_evt: IrqLevelEvent, pin: PciInterruptPin, irq_num: u32)677     fn assign_irq(&mut self, irq_evt: IrqLevelEvent, pin: PciInterruptPin, irq_num: u32) {
678         (**self).assign_irq(irq_evt, pin, irq_num)
679     }
allocate_io_bars(&mut self, resources: &mut SystemAllocator) -> Result<Vec<BarRange>>680     fn allocate_io_bars(&mut self, resources: &mut SystemAllocator) -> Result<Vec<BarRange>> {
681         (**self).allocate_io_bars(resources)
682     }
allocate_device_bars(&mut self, resources: &mut SystemAllocator) -> Result<Vec<BarRange>>683     fn allocate_device_bars(&mut self, resources: &mut SystemAllocator) -> Result<Vec<BarRange>> {
684         (**self).allocate_device_bars(resources)
685     }
get_bar_configuration(&self, bar_num: usize) -> Option<PciBarConfiguration>686     fn get_bar_configuration(&self, bar_num: usize) -> Option<PciBarConfiguration> {
687         (**self).get_bar_configuration(bar_num)
688     }
register_device_capabilities(&mut self) -> Result<()>689     fn register_device_capabilities(&mut self) -> Result<()> {
690         (**self).register_device_capabilities()
691     }
ioevents(&self) -> Vec<(&Event, u64, Datamatch)>692     fn ioevents(&self) -> Vec<(&Event, u64, Datamatch)> {
693         (**self).ioevents()
694     }
read_virtual_config_register(&self, reg_idx: usize) -> u32695     fn read_virtual_config_register(&self, reg_idx: usize) -> u32 {
696         (**self).read_virtual_config_register(reg_idx)
697     }
write_virtual_config_register(&mut self, reg_idx: usize, value: u32)698     fn write_virtual_config_register(&mut self, reg_idx: usize, value: u32) {
699         (**self).write_virtual_config_register(reg_idx, value)
700     }
get_vm_memory_request_tube(&self) -> Option<&Tube>701     fn get_vm_memory_request_tube(&self) -> Option<&Tube> {
702         (**self).get_vm_memory_request_tube()
703     }
read_config_register(&self, reg_idx: usize) -> u32704     fn read_config_register(&self, reg_idx: usize) -> u32 {
705         (**self).read_config_register(reg_idx)
706     }
write_config_register(&mut self, reg_idx: usize, offset: u64, data: &[u8])707     fn write_config_register(&mut self, reg_idx: usize, offset: u64, data: &[u8]) {
708         (**self).write_config_register(reg_idx, offset, data)
709     }
read_bar(&mut self, addr: u64, data: &mut [u8])710     fn read_bar(&mut self, addr: u64, data: &mut [u8]) {
711         (**self).read_bar(addr, data)
712     }
write_bar(&mut self, addr: u64, data: &[u8])713     fn write_bar(&mut self, addr: u64, data: &[u8]) {
714         (**self).write_bar(addr, data)
715     }
716     /// Invoked when the device is sandboxed.
on_device_sandboxed(&mut self)717     fn on_device_sandboxed(&mut self) {
718         (**self).on_device_sandboxed()
719     }
720 
721     #[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
generate_acpi(&mut self, sdts: Vec<SDT>) -> Option<Vec<SDT>>722     fn generate_acpi(&mut self, sdts: Vec<SDT>) -> Option<Vec<SDT>> {
723         (**self).generate_acpi(sdts)
724     }
725 
generate_acpi_methods(&mut self) -> (Vec<u8>, Option<(u32, MemoryMapping)>)726     fn generate_acpi_methods(&mut self) -> (Vec<u8>, Option<(u32, MemoryMapping)>) {
727         (**self).generate_acpi_methods()
728     }
729 
destroy_device(&mut self)730     fn destroy_device(&mut self) {
731         (**self).destroy_device();
732     }
get_new_pci_bus(&self) -> Option<Arc<Mutex<PciBus>>>733     fn get_new_pci_bus(&self) -> Option<Arc<Mutex<PciBus>>> {
734         (**self).get_new_pci_bus()
735     }
get_removed_children_devices(&self) -> Vec<PciAddress>736     fn get_removed_children_devices(&self) -> Vec<PciAddress> {
737         (**self).get_removed_children_devices()
738     }
739 
configure_bridge_window( &mut self, resources: &mut SystemAllocator, bar_ranges: &[BarRange], ) -> Result<Vec<BarRange>>740     fn configure_bridge_window(
741         &mut self,
742         resources: &mut SystemAllocator,
743         bar_ranges: &[BarRange],
744     ) -> Result<Vec<BarRange>> {
745         (**self).configure_bridge_window(resources, bar_ranges)
746     }
747 }
748 
749 impl<T: PciDevice + ?Sized> Suspendable for Box<T> {
snapshot(&self) -> anyhow::Result<serde_json::Value>750     fn snapshot(&self) -> anyhow::Result<serde_json::Value> {
751         (**self).snapshot()
752     }
753 
restore(&mut self, data: serde_json::Value) -> anyhow::Result<()>754     fn restore(&mut self, data: serde_json::Value) -> anyhow::Result<()> {
755         (**self).restore(data)
756     }
757 
sleep(&mut self) -> anyhow::Result<()>758     fn sleep(&mut self) -> anyhow::Result<()> {
759         (**self).sleep()
760     }
761 
wake(&mut self) -> anyhow::Result<()>762     fn wake(&mut self) -> anyhow::Result<()> {
763         (**self).wake()
764     }
765 }
766 
767 impl<T: 'static + PciDevice> BusDeviceObj for T {
as_pci_device(&self) -> Option<&dyn PciDevice>768     fn as_pci_device(&self) -> Option<&dyn PciDevice> {
769         Some(self)
770     }
as_pci_device_mut(&mut self) -> Option<&mut dyn PciDevice>771     fn as_pci_device_mut(&mut self) -> Option<&mut dyn PciDevice> {
772         Some(self)
773     }
into_pci_device(self: Box<Self>) -> Option<Box<dyn PciDevice>>774     fn into_pci_device(self: Box<Self>) -> Option<Box<dyn PciDevice>> {
775         Some(self)
776     }
777 }
778 
779 /// Gets the ioevent requests based on new ioevents and changes to the BAR.
780 ///
781 /// Assumes the number of ioevents are unchanged after bar remapping, and corresponds to the same
782 /// BAR regions.
783 /// Returns pair (ioevent_unregister_requests, ioevent_register_requests) to be handled by device.
get_ioevent_requests( mut ioevents: Vec<(&Event, u64, Datamatch)>, old_range: Vec<(BusRange, BusType)>, new_range: Vec<(BusRange, BusType)>, ) -> Result<(Vec<IoEventUpdateRequest>, Vec<IoEventUpdateRequest>)>784 fn get_ioevent_requests(
785     mut ioevents: Vec<(&Event, u64, Datamatch)>,
786     old_range: Vec<(BusRange, BusType)>,
787     new_range: Vec<(BusRange, BusType)>,
788 ) -> Result<(Vec<IoEventUpdateRequest>, Vec<IoEventUpdateRequest>)> {
789     // Finds all ioevents with addr within new_range. Updates ioevents whose range are within the
790     // changed windows. Bus ranges are disjoint since they are memory addresses. sort both ioevents
791     // and range to get asymptotic optimal solution.
792     ioevents.sort_by_key(|ioevent| ioevent.1);
793     // Old and new ranges are paired to be sorted together to keep the correspondence.
794     let mut range_pair: Vec<((BusRange, BusType), (BusRange, BusType))> =
795         new_range.into_iter().zip(old_range.into_iter()).collect();
796     range_pair.sort_by_key(|(new, _old)| new.0.base);
797     let mut range_pair_iter = range_pair.iter();
798     let mut cur_range_pair = range_pair_iter.next();
799     let mut ioevent_iter = ioevents.into_iter();
800     let mut cur_ioevent = ioevent_iter.next();
801     let mut ioevent_unregister_requests = Vec::new();
802     let mut ioevent_register_requests = Vec::new();
803     while let Some((event, addr, datamatch)) = cur_ioevent {
804         if let Some(((new_bus_range, _), (old_bus_range, _))) = cur_range_pair {
805             if new_bus_range.contains(addr) {
806                 let offset = addr - new_bus_range.base;
807                 ioevent_unregister_requests.push(IoEventUpdateRequest {
808                     event: event
809                         .try_clone()
810                         .map_err(|e| Error::IoEventRegisterFailed(IoEventError::CloneFail(e)))?,
811                     addr: offset + old_bus_range.base,
812                     datamatch,
813                     register: false,
814                 });
815                 ioevent_register_requests.push(IoEventUpdateRequest {
816                     event: event
817                         .try_clone()
818                         .map_err(|e| Error::IoEventRegisterFailed(IoEventError::CloneFail(e)))?,
819                     addr,
820                     datamatch,
821                     register: true,
822                 });
823                 cur_ioevent = ioevent_iter.next();
824                 continue;
825             }
826             // Advance range if range upper bound is too small.
827             else if new_bus_range.base + new_bus_range.len <= addr {
828                 cur_range_pair = range_pair_iter.next();
829                 cur_ioevent = Some((event, addr, datamatch));
830                 continue;
831             }
832             // Advance ioevent if ioevent is lower than range lower bound.
833             else {
834                 cur_ioevent = ioevent_iter.next();
835                 continue;
836             }
837         }
838         // Stop if range is depleted.
839         break;
840     }
841     Ok((ioevent_unregister_requests, ioevent_register_requests))
842 }
843 
844 /// Sends ioevents through the tube, and returns result.
send_ioevent_update_request( tube: &Tube, request: IoEventUpdateRequest, ) -> std::result::Result<(), IoEventError>845 fn send_ioevent_update_request(
846     tube: &Tube,
847     request: IoEventUpdateRequest,
848 ) -> std::result::Result<(), IoEventError> {
849     tube.send(&VmMemoryRequest::IoEventRaw(request))
850         .map_err(|_| IoEventError::TubeFail)?;
851     if let VmMemoryResponse::Err(e) = tube
852         .recv::<VmMemoryResponse>()
853         .map_err(|_| IoEventError::TubeFail)?
854     {
855         return Err(IoEventError::SystemError(e));
856     }
857     Ok(())
858 }
859 
860 /// Sends register/unregister messages for ioevents based on the updated ranges.
send_ioevent_updates( vm_memory_request_tube: Option<&Tube>, ioevents: Vec<(&Event, u64, Datamatch)>, old_ranges: Vec<(BusRange, BusType)>, new_ranges: Vec<(BusRange, BusType)>, ) -> anyhow::Result<()>861 fn send_ioevent_updates(
862     vm_memory_request_tube: Option<&Tube>,
863     ioevents: Vec<(&Event, u64, Datamatch)>,
864     old_ranges: Vec<(BusRange, BusType)>,
865     new_ranges: Vec<(BusRange, BusType)>,
866 ) -> anyhow::Result<()> {
867     let tube = vm_memory_request_tube
868         .context("get_vm_memory_request_tube not implemented, device may malfunction")?;
869 
870     let (ioevent_unregister_requests, ioevent_register_requests) =
871         get_ioevent_requests(ioevents, old_ranges, new_ranges)
872             .context("Failed to get ioevent requests")?;
873 
874     for request in ioevent_unregister_requests {
875         match send_ioevent_update_request(tube, request) {
876             Err(IoEventError::SystemError(_)) => {
877                 // Do nothing, as unregister may fail due to placeholder value
878             }
879             Err(e) => return Err(e).context("IoEvent unregister failed"),
880             Ok(()) => {}
881         }
882     }
883 
884     for request in ioevent_register_requests {
885         send_ioevent_update_request(tube, request).context("IoEvent register failed")?;
886     }
887 
888     Ok(())
889 }
890 
891 #[cfg(test)]
892 mod tests {
893     use pci_configuration::PciBarPrefetchable;
894     use pci_configuration::PciBarRegionType;
895     use pci_configuration::PciClassCode;
896     use pci_configuration::PciConfiguration;
897     use pci_configuration::PciHeaderType;
898     use pci_configuration::PciMultimediaSubclass;
899 
900     use super::*;
901     use crate::pci::pci_configuration::BAR0_REG;
902 
903     const BAR0_SIZE: u64 = 0x1000;
904     const BAR2_SIZE: u64 = 0x20;
905     const BAR0_ADDR: u64 = 0xc0000000;
906     const BAR2_ADDR: u64 = 0x800;
907 
908     struct TestDev {
909         pub config_regs: PciConfiguration,
910     }
911 
912     impl PciDevice for TestDev {
debug_label(&self) -> String913         fn debug_label(&self) -> String {
914             "test".to_owned()
915         }
916 
keep_rds(&self) -> Vec<RawDescriptor>917         fn keep_rds(&self) -> Vec<RawDescriptor> {
918             Vec::new()
919         }
920 
read_config_register(&self, reg_idx: usize) -> u32921         fn read_config_register(&self, reg_idx: usize) -> u32 {
922             self.config_regs.read_reg(reg_idx)
923         }
924 
write_config_register(&mut self, reg_idx: usize, offset: u64, data: &[u8])925         fn write_config_register(&mut self, reg_idx: usize, offset: u64, data: &[u8]) {
926             self.config_regs.write_reg(reg_idx, offset, data)
927         }
928 
read_bar(&mut self, _addr: u64, _data: &mut [u8])929         fn read_bar(&mut self, _addr: u64, _data: &mut [u8]) {}
930 
write_bar(&mut self, _addr: u64, _data: &[u8])931         fn write_bar(&mut self, _addr: u64, _data: &[u8]) {}
932 
allocate_address(&mut self, _resources: &mut SystemAllocator) -> Result<PciAddress>933         fn allocate_address(&mut self, _resources: &mut SystemAllocator) -> Result<PciAddress> {
934             Err(Error::PciAllocationFailed)
935         }
936 
get_bar_configuration(&self, bar_num: usize) -> Option<PciBarConfiguration>937         fn get_bar_configuration(&self, bar_num: usize) -> Option<PciBarConfiguration> {
938             self.config_regs.get_bar_configuration(bar_num)
939         }
940     }
941 
942     impl Suspendable for TestDev {}
943 
944     #[test]
config_write_result()945     fn config_write_result() {
946         let mut test_dev = TestDev {
947             config_regs: PciConfiguration::new(
948                 0x1234,
949                 0xABCD,
950                 PciClassCode::MultimediaController,
951                 &PciMultimediaSubclass::AudioDevice,
952                 None,
953                 PciHeaderType::Device,
954                 0x5678,
955                 0xEF01,
956                 0,
957             ),
958         };
959 
960         let _ = test_dev.config_regs.add_pci_bar(
961             PciBarConfiguration::new(
962                 0,
963                 BAR0_SIZE,
964                 PciBarRegionType::Memory64BitRegion,
965                 PciBarPrefetchable::Prefetchable,
966             )
967             .set_address(BAR0_ADDR),
968         );
969         let _ = test_dev.config_regs.add_pci_bar(
970             PciBarConfiguration::new(
971                 2,
972                 BAR2_SIZE,
973                 PciBarRegionType::IoRegion,
974                 PciBarPrefetchable::NotPrefetchable,
975             )
976             .set_address(BAR2_ADDR),
977         );
978         let bar0_range = BusRange {
979             base: BAR0_ADDR,
980             len: BAR0_SIZE,
981         };
982         let bar2_range = BusRange {
983             base: BAR2_ADDR,
984             len: BAR2_SIZE,
985         };
986 
987         // Initialize command register to an all-zeroes value.
988         test_dev.config_register_write(COMMAND_REG, 0, &0u32.to_le_bytes());
989 
990         // Enable IO space access (bit 0 of command register).
991         assert_eq!(
992             test_dev.config_register_write(COMMAND_REG, 0, &1u32.to_le_bytes()),
993             ConfigWriteResult {
994                 mmio_remove: Vec::new(),
995                 mmio_add: Vec::new(),
996                 io_remove: Vec::new(),
997                 io_add: vec![bar2_range],
998                 removed_pci_devices: Vec::new(),
999             }
1000         );
1001 
1002         // Enable memory space access (bit 1 of command register).
1003         assert_eq!(
1004             test_dev.config_register_write(COMMAND_REG, 0, &3u32.to_le_bytes()),
1005             ConfigWriteResult {
1006                 mmio_remove: Vec::new(),
1007                 mmio_add: vec![bar0_range],
1008                 io_remove: Vec::new(),
1009                 io_add: Vec::new(),
1010                 removed_pci_devices: Vec::new(),
1011             }
1012         );
1013 
1014         // Rewrite the same IO + mem value again (result should be no change).
1015         assert_eq!(
1016             test_dev.config_register_write(COMMAND_REG, 0, &3u32.to_le_bytes()),
1017             ConfigWriteResult {
1018                 mmio_remove: Vec::new(),
1019                 mmio_add: Vec::new(),
1020                 io_remove: Vec::new(),
1021                 io_add: Vec::new(),
1022                 removed_pci_devices: Vec::new(),
1023             }
1024         );
1025 
1026         // Disable IO space access, leaving mem enabled.
1027         assert_eq!(
1028             test_dev.config_register_write(COMMAND_REG, 0, &2u32.to_le_bytes()),
1029             ConfigWriteResult {
1030                 mmio_remove: Vec::new(),
1031                 mmio_add: Vec::new(),
1032                 io_remove: vec![bar2_range],
1033                 io_add: Vec::new(),
1034                 removed_pci_devices: Vec::new(),
1035             }
1036         );
1037 
1038         // Disable mem space access.
1039         assert_eq!(
1040             test_dev.config_register_write(COMMAND_REG, 0, &0u32.to_le_bytes()),
1041             ConfigWriteResult {
1042                 mmio_remove: vec![bar0_range],
1043                 mmio_add: Vec::new(),
1044                 io_remove: Vec::new(),
1045                 io_add: Vec::new(),
1046                 removed_pci_devices: Vec::new(),
1047             }
1048         );
1049 
1050         assert_eq!(test_dev.get_ranges(), Vec::new());
1051 
1052         // Re-enable mem and IO space.
1053         assert_eq!(
1054             test_dev.config_register_write(COMMAND_REG, 0, &3u32.to_le_bytes()),
1055             ConfigWriteResult {
1056                 mmio_remove: Vec::new(),
1057                 mmio_add: vec![bar0_range],
1058                 io_remove: Vec::new(),
1059                 io_add: vec![bar2_range],
1060                 removed_pci_devices: Vec::new(),
1061             }
1062         );
1063 
1064         // Change Bar0's address
1065         assert_eq!(
1066             test_dev.config_register_write(BAR0_REG, 0, &0xD0000000u32.to_le_bytes()),
1067             ConfigWriteResult {
1068                 mmio_remove: vec!(bar0_range),
1069                 mmio_add: vec![BusRange {
1070                     base: 0xD0000000,
1071                     len: BAR0_SIZE
1072                 }],
1073                 io_remove: Vec::new(),
1074                 io_add: Vec::new(),
1075                 removed_pci_devices: Vec::new(),
1076             }
1077         );
1078     }
1079 
1080     #[test]
test_get_ioevent_request()1081     fn test_get_ioevent_request() {
1082         // Of the ioevents, only 108, 112, 116 are within the changed windows.
1083         // Corresponding old addresses are 208, 212, and 16.
1084         let events = vec![
1085             Event::new().unwrap(),
1086             Event::new().unwrap(),
1087             Event::new().unwrap(),
1088             Event::new().unwrap(),
1089             Event::new().unwrap(),
1090         ];
1091         let ioevents = vec![
1092             (&events[0], 100, Datamatch::AnyLength),
1093             (&events[1], 108, Datamatch::AnyLength),
1094             (&events[2], 112, Datamatch::AnyLength),
1095             (&events[3], 116, Datamatch::AnyLength),
1096             (&events[4], 120, Datamatch::AnyLength),
1097         ];
1098         let old_range = vec![
1099             (BusRange { base: 208, len: 8 }, BusType::Mmio),
1100             (BusRange { base: 16, len: 4 }, BusType::Mmio),
1101         ];
1102         let new_range = vec![
1103             (BusRange { base: 108, len: 8 }, BusType::Mmio),
1104             (BusRange { base: 116, len: 4 }, BusType::Mmio),
1105         ];
1106         let (mut unregister_requests, mut register_requests) =
1107             get_ioevent_requests(ioevents, old_range, new_range).unwrap();
1108         unregister_requests.sort_by_key(|request| request.addr);
1109         assert_eq!(unregister_requests.len(), 3);
1110         assert_eq!(unregister_requests[0].addr, 16);
1111         assert_eq!(unregister_requests[1].addr, 208);
1112         assert_eq!(unregister_requests[2].addr, 212);
1113         register_requests.sort_by_key(|request| request.addr);
1114         assert_eq!(register_requests.len(), 3);
1115         assert_eq!(register_requests[0].addr, 108);
1116         assert_eq!(register_requests[1].addr, 112);
1117         assert_eq!(register_requests[2].addr, 116);
1118     }
1119 }
1120