Skip to content

Commit bbe0834

Browse files
committed
Add docs for VM module
1 parent a1e9927 commit bbe0834

File tree

3 files changed

+74
-6
lines changed

3 files changed

+74
-6
lines changed

mythril/src/kmain.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -251,7 +251,7 @@ unsafe fn kmain(mut boot_info: BootInfo) -> ! {
251251
ioapic::map_gsi_vector(interrupt::gsi::UART, interrupt::vector::UART, 0)
252252
.expect("Failed to map com0 gsi");
253253

254-
let mut builder = vm::VirtualMachineBuilder::new();
254+
let mut builder = vm::VirtualMachineSetBuilder::new();
255255

256256
let raw_cfg = boot_info
257257
.find_module("mythril.cfg")

mythril/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ pub mod time;
4949
pub mod tsc;
5050
pub mod vcpu;
5151
pub mod virtdev;
52+
/// Top level virtual machine definition
5253
pub mod vm;
5354
pub mod vmcs;
5455
pub mod vmexit;

mythril/src/vm.rs

Lines changed: 72 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
#![deny(missing_docs)]
2+
13
use crate::apic;
24
use crate::boot_info::BootInfo;
35
use crate::error::{Error, Result};
@@ -39,29 +41,55 @@ pub const MAX_PER_VM_CORE_COUNT: usize = 32;
3941

4042
const MAX_PENDING_MSG: usize = 100;
4143

44+
/// Initialize the global VirtualMachineSet
45+
///
46+
/// This method must be called before calling 'virtual_machines'
4247
pub unsafe fn init_virtual_machines(machines: VirtualMachineSet) {
4348
RoAfterInit::init(&VIRTUAL_MACHINES, machines);
4449
}
4550

51+
/// Get the global VirtualMachineSet
4652
pub fn virtual_machines() -> &'static VirtualMachineSet {
4753
&*VIRTUAL_MACHINES
4854
}
4955

56+
/// A message for inter-core or inter-VM communication
57+
///
58+
/// These messages can be sent and received through the
59+
/// VirtualMachineSet type, accessible via the 'virtual_machines'
60+
/// method after startup
5061
pub enum VirtualMachineMsg {
62+
/// Transfer control of a physical serial console to another VM
5163
GrantConsole(physdev::com::Uart8250),
64+
65+
/// Cancel a the given timer
5266
CancelTimer(time::TimerId),
67+
68+
/// Start a core at the given physical address
5369
StartVcpu(GuestPhysAddr),
70+
71+
/// Inject a guest interrupt with the given vector
5472
GuestInterrupt {
73+
/// The type of the injected interrupt
5574
kind: vcpu::InjectedInterruptType,
75+
76+
/// The injected interrupt vector
5677
vector: u8,
5778
},
5879
}
5980

6081
struct VirtualMachineContext {
6182
vm: Arc<VirtualMachine>,
83+
84+
/// The per-core RX message queue
6285
msgqueue: RwLock<ArrayDeque<[VirtualMachineMsg; MAX_PENDING_MSG]>>,
6386
}
6487

88+
/// The set of configured virtual machines
89+
///
90+
/// This structure represents the set of all configured machines
91+
/// in the hypervisor and can be used to transmit and receive
92+
/// inter-vm or inter-core messages.
6593
pub struct VirtualMachineSet {
6694
machine_count: u32,
6795
map: BTreeMap<percore::CoreId, VirtualMachineContext>,
@@ -88,10 +116,12 @@ impl VirtualMachineSet {
88116
.next()
89117
}
90118

119+
/// Returns the number of VMs
91120
pub fn count(&self) -> u32 {
92121
self.machine_count
93122
}
94123

124+
/// Returns whether a given CoreId is associated with any VM
95125
pub fn is_assigned_core_id(&self, core_id: percore::CoreId) -> bool {
96126
self.map.contains_key(&core_id)
97127
}
@@ -108,10 +138,13 @@ impl VirtualMachineSet {
108138
.map(|context| context.vm.clone())
109139
}
110140

111-
pub fn get_by_vm_id(&self, id: u32) -> Option<Arc<VirtualMachine>> {
112-
self.context_by_vm_id(id).map(|context| context.vm.clone())
141+
/// Get a VirtualMachine by its vmid
142+
pub fn get_by_vm_id(&self, vmid: u32) -> Option<Arc<VirtualMachine>> {
143+
self.context_by_vm_id(vmid)
144+
.map(|context| context.vm.clone())
113145
}
114146

147+
/// Get the CoreId for the BSP core of a VM by its vmid
115148
pub fn bsp_core_id(&self, vmid: u32) -> Option<percore::CoreId> {
116149
self.get_by_vm_id(vmid).map(|vm| vm.config.bsp_id())
117150
}
@@ -195,22 +228,25 @@ impl VirtualMachineSet {
195228
}
196229
}
197230

198-
pub struct VirtualMachineBuilder {
231+
/// A structure to build up the set of VirtualMachines
232+
pub struct VirtualMachineSetBuilder {
199233
/// The number of virtual machines added to the builder
200234
machine_count: u32,
201235

202236
/// Mapping of core_id to VirtualMachine
203237
map: BTreeMap<percore::CoreId, Arc<VirtualMachine>>,
204238
}
205239

206-
impl VirtualMachineBuilder {
240+
impl VirtualMachineSetBuilder {
241+
/// Returns a new VirtualMachineSetBuilder
207242
pub fn new() -> Self {
208-
VirtualMachineBuilder {
243+
Self {
209244
machine_count: 0,
210245
map: BTreeMap::new(),
211246
}
212247
}
213248

249+
/// Add a VirtualMachine to the set
214250
pub fn insert_machine(&mut self, vm: Arc<VirtualMachine>) -> Result<()> {
215251
self.machine_count += 1;
216252
for cpu in vm.config.cpus() {
@@ -219,13 +255,15 @@ impl VirtualMachineBuilder {
219255
Ok(())
220256
}
221257

258+
/// Get the virtual machine that owns the core with the given core id
222259
pub fn get_by_core_id(
223260
&self,
224261
core_id: percore::CoreId,
225262
) -> Option<Arc<VirtualMachine>> {
226263
self.map.get(&core_id).map(|vm| vm.clone())
227264
}
228265

266+
/// Finish building the VirtualMachineSet
229267
pub fn finalize(self) -> VirtualMachineSet {
230268
VirtualMachineSet {
231269
machine_count: self.machine_count,
@@ -246,6 +284,7 @@ impl VirtualMachineBuilder {
246284
}
247285
}
248286

287+
/// A set of physical hardware that may be attached to a VM
249288
#[derive(Default)]
250289
pub struct PhysicalDeviceConfig {
251290
/// The physical serial connection for this VM (if any).
@@ -310,14 +349,17 @@ impl VirtualMachineConfig {
310349
&mut self.virtual_devices
311350
}
312351

352+
/// Access the configurations physical hardware
313353
pub fn physical_devices(&self) -> &PhysicalDeviceConfig {
314354
&self.physical_devices
315355
}
316356

357+
/// Get the list of CoreIds assicated with this VM
317358
pub fn cpus(&self) -> &ArrayVec<[percore::CoreId; MAX_PER_VM_CORE_COUNT]> {
318359
&self.cpus
319360
}
320361

362+
/// Get the CoreId of the BSP for this VM
321363
pub fn bsp_id(&self) -> percore::CoreId {
322364
self.cpus[0]
323365
}
@@ -391,16 +433,32 @@ impl VirtualMachine {
391433
Ok(vm)
392434
}
393435

436+
/// Notify this VirtualMachine that the current core is ready to start
437+
///
438+
/// Each core associated with this VirtualMachine must call this method
439+
/// in order for 'all_cores_ready' to return true. Cores must _not_
440+
/// invoke this method more than once.
394441
pub fn notify_ready(&self) {
395442
self.cpus_ready
396443
.fetch_add(1, core::sync::atomic::Ordering::SeqCst);
397444
}
398445

446+
/// Returns true when all VirtualMachine cores have called 'notify_ready'
399447
pub fn all_cores_ready(&self) -> bool {
400448
self.cpus_ready.load(core::sync::atomic::Ordering::SeqCst)
401449
== self.config.cpus.len() as u32
402450
}
403451

452+
/// Process the given DeviceEvent on the virtual hardware matching 'ident'
453+
///
454+
/// # Arguments
455+
///
456+
/// * `ident` - A DeviceInteraction like a Port I/O port or address used to
457+
/// find the relevant device.
458+
/// * `kind` - The DeviceEvent kind to dispatch
459+
/// * `vcpu` - A handle to the current vcpu
460+
/// * `responses` - A ResponseEventArray for any responses from the virtual
461+
/// hardware
404462
pub fn dispatch_event(
405463
&self,
406464
ident: impl DeviceInteraction + core::fmt::Debug,
@@ -426,6 +484,12 @@ impl VirtualMachine {
426484
dev.write().on_event(event)
427485
}
428486

487+
/// Returns an iterator of the CoreIds that are logically addressed by the given mask
488+
///
489+
/// # Arguments
490+
///
491+
/// * `mask` - The APIC ICR address contents (e.g., the upper 32 bits) for a
492+
/// logically addressed IPC
429493
pub fn logical_apic_destination(
430494
&self,
431495
mask: u32,
@@ -446,6 +510,8 @@ impl VirtualMachine {
446510
}))
447511
}
448512

513+
/// Notify the VirtualMachine of a change in the Logical Destination register
514+
/// for the current core
449515
pub fn update_core_logical_destination(&self, dest: u32) {
450516
let apic_state = self
451517
.logical_apic_state
@@ -456,6 +522,7 @@ impl VirtualMachine {
456522
.store(dest, core::sync::atomic::Ordering::SeqCst);
457523
}
458524

525+
/// Resolve a guest GSI to a specific CoreId, vector and interrupt type
459526
pub fn gsi_destination(
460527
&self,
461528
gsi: u32,

0 commit comments

Comments
 (0)