Skip to content

Commit ef21cf1

Browse files
Jing Liujiangliu
Jing Liu
authored andcommitted
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 6aae202 commit ef21cf1

File tree

2 files changed

+109
-0
lines changed

2 files changed

+109
-0
lines changed

src/device_manager.rs

+108
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
// Copyright © 2019 Intel Corporation. All Rights Reserved.
2+
// SPDX-License-Identifier: (Apache-2.0 OR BSD-3-Clause)
3+
4+
//! System level device management.
5+
//!
6+
//! [IoManager](struct.IoManager.html) is respondsible for managing
7+
//! all devices of virtual machine, registering IO resources callback,
8+
//! unregistering devices and helping VM IO exit handling.
9+
//!
10+
//!VMM would be responsible for getting device resource request, ask
11+
//! vm_allocator to allocate the resources, ask vm_device to register the
12+
//! devices IO ranges, 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+
/// Create an default IoManager with empty IO member.
42+
pub fn new() -> Self {
43+
IoManager::default()
44+
}
45+
/// Register a new device IO with its allocated resources.
46+
/// VMM is responsible for providing the allocated resources to virtual device.
47+
///
48+
/// # Arguments
49+
///
50+
/// * `device`: device instance object to be registered
51+
/// * `resources`: resources that this device owns, might include
52+
/// port I/O and memory-mapped I/O ranges, irq number, etc.
53+
pub fn register_device_io(
54+
&mut self,
55+
device: Arc<dyn DeviceIo>,
56+
resources: &[Resource],
57+
) -> Result<()> {
58+
// Register and mark device resources
59+
// The resources addresses being registered are sucessfully allocated before.
60+
for (idx, res) in resources.iter().enumerate() {
61+
match *res {
62+
Resource::PioAddressRange { base, size } => {
63+
if self.pio_bus.insert((base, size), device.clone()).is_some() {
64+
// Unregister registered resources.
65+
self.unregister_device_io(&resources[0..idx])
66+
.expect("failed to unregister devices");
67+
68+
return Err(Error::DeviceOverlap);
69+
}
70+
}
71+
Resource::MmioAddressRange { base, size } => {
72+
if self.mmio_bus.insert((base, size), device.clone()).is_some() {
73+
// Unregister registered resources.
74+
self.unregister_device_io(&resources[0..idx])
75+
.expect("failed to unregister devices");
76+
77+
return Err(Error::DeviceOverlap);
78+
}
79+
}
80+
_ => continue,
81+
}
82+
}
83+
Ok(())
84+
}
85+
86+
/// Unregister a device from `IoManager`, e.g. users specified removing.
87+
/// VMM pre-fetches the resources e.g. dev.get_assigned_resources()
88+
/// VMM is responsible for freeing the resources.
89+
///
90+
/// # Arguments
91+
///
92+
/// * `resources`: resources that this device owns, might include
93+
/// port I/O and memory-mapped I/O ranges, irq number, etc.
94+
pub fn unregister_device_io(&mut self, resources: &[Resource]) -> Result<()> {
95+
for res in resources.iter() {
96+
match *res {
97+
Resource::PioAddressRange { base, size } => {
98+
self.pio_bus.remove(&(base, size));
99+
}
100+
Resource::MmioAddressRange { base, size } => {
101+
self.mmio_bus.remove(&(base, size));
102+
}
103+
_ => continue,
104+
}
105+
}
106+
Ok(())
107+
}
108+
}

src/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33

44
//! rust-vmm device model.
55
6+
pub mod device_manager;
67
pub mod resources;
78

89
/// IO Addresses.

0 commit comments

Comments
 (0)