Skip to content

Commit 044cc53

Browse files
author
Jing Liu
committed
Add IO manager support
Based on resources definition, this adds device IO manager to manage all devices IO ranges. Signed-off-by: Jing Liu <[email protected]>
1 parent c2cafa6 commit 044cc53

File tree

2 files changed

+106
-0
lines changed

2 files changed

+106
-0
lines changed

src/device_manager.rs

Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
// Copyright © 2019 Intel Corporation. All Rights Reserved.
2+
// SPDX-License-Identifier: (Apache-2.0 AND BSD-3-Clause)
3+
4+
//! System level device management.
5+
//!
6+
//! [IoManager](struct.IoManager.html) responds to manage all devices
7+
//! of virtual machine, register IO resources callback,
8+
//! unregister devices and help VM IO exit handling.
9+
//!
10+
//!VMM would take responsible for getting device resource request, ask
11+
//! vm_allocator to allocate the resources, ask vm_device to register the
12+
//! devices IO windows, and finally set resources to virtual device.
13+
14+
use crate::resources::Resource;
15+
use crate::DeviceIo;
16+
17+
use std::collections::btree_map::BTreeMap;
18+
use std::result;
19+
use std::sync::Arc;
20+
21+
/// Error type for `IoManager` usage.
22+
#[derive(Debug)]
23+
pub enum Error {
24+
/// The inserting device overlaps with a current device.
25+
DeviceOverlap,
26+
}
27+
28+
/// Simplify the `Result` type.
29+
pub type Result<T> = result::Result<T, Error>;
30+
31+
/// System IO manager serving for all devices management and VM exit handling.
32+
#[derive(Default)]
33+
pub struct IoManager {
34+
/// Range mapping for VM exit pio operations.
35+
pio_bus: BTreeMap<(u16, u16), Arc<dyn DeviceIo>>,
36+
/// Range mapping for VM exit mmio operations.
37+
mmio_bus: BTreeMap<(u64, u64), Arc<dyn DeviceIo>>,
38+
}
39+
40+
impl IoManager {
41+
pub fn new() -> Self {
42+
IoManager::default()
43+
}
44+
/// Register a new device IO with its allocated resources.
45+
/// VMM is responsible for providing the allocated resources to virtual device.
46+
///
47+
/// # Arguements
48+
///
49+
/// * `device`: device instance object to be registered
50+
/// * `resources`: resources that this device owns, might include
51+
/// port I/O and memory-mapped I/O ranges, irq number, etc.
52+
pub fn register_device_io(
53+
&mut self,
54+
device: Arc<dyn DeviceIo>,
55+
resources: &[Resource],
56+
) -> Result<()> {
57+
// Register and mark device resources
58+
// The resources addresses being registered are sucessfully allocated before.
59+
for (idx, res) in resources.iter().enumerate() {
60+
match *res {
61+
Resource::PioAddressRange { base, size } => {
62+
if self.pio_bus.insert((base, size), device.clone()).is_some() {
63+
// Unregister registered resources.
64+
self.unregister_device_io(&resources[0..idx])?;
65+
66+
return Err(Error::DeviceOverlap);
67+
}
68+
}
69+
Resource::MmioAddressRange { base, size } => {
70+
if self.mmio_bus.insert((base, size), device.clone()).is_some() {
71+
// Unregister registered resources.
72+
self.unregister_device_io(&resources[0..idx])?;
73+
74+
return Err(Error::DeviceOverlap);
75+
}
76+
}
77+
_ => continue,
78+
}
79+
}
80+
Ok(())
81+
}
82+
83+
/// Unregister a device from `IoManager`, e.g. users specified removing.
84+
/// VMM pre-fetches the resources e.g. dev.get_assigned_resources()
85+
/// VMM is responsible for freeing the resources.
86+
///
87+
/// # Arguements
88+
///
89+
/// * `resources`: resources that this device owns, might include
90+
/// port I/O and memory-mapped I/O ranges, irq number, etc.
91+
pub fn unregister_device_io(&mut self, resources: &[Resource]) -> Result<()> {
92+
for res in resources.iter() {
93+
match *res {
94+
Resource::PioAddressRange { base, size } => {
95+
self.pio_bus.remove(&(base, size));
96+
}
97+
Resource::MmioAddressRange { base, size } => {
98+
self.mmio_bus.remove(&(base, size));
99+
}
100+
_ => continue,
101+
}
102+
}
103+
Ok(())
104+
}
105+
}

src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ extern crate vm_memory;
77

88
use vm_memory::GuestAddress;
99

10+
pub mod device_manager;
1011
pub mod resources;
1112

1213
/// IO Addresses.

0 commit comments

Comments
 (0)