Skip to main content

axvisor_api/
vmm.rs

1// Copyright 2025 The Axvisor Team
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//     http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15//! Virtual machine management APIs for the AxVisor hypervisor.
16//!
17//! This module provides APIs for managing virtual machines (VMs) and virtual
18//! CPUs (vCPUs), including querying VM/vCPU information and interrupt
19//! injection.
20//!
21//! # Overview
22//!
23//! The VMM (Virtual Machine Monitor) APIs enable:
24//! - Querying the current VM and vCPU context
25//! - Getting information about VMs and their vCPUs
26//! - Injecting interrupts into virtual CPUs
27//! - Timer expiration notifications
28//!
29//! # Types
30//!
31//! - [`VMId`] - Virtual machine identifier.
32//! - [`VCpuId`] - Virtual CPU identifier.
33//! - [`InterruptVector`] - Interrupt vector number.
34//!
35//! # Helper Functions
36//!
37//! In addition to the core API trait, this module provides helper functions:
38//! - [`current_vm_vcpu_num`] - Get the vCPU count of the current VM.
39//! - [`current_vm_active_vcpus`] - Get the active vCPU mask of the current VM.
40//!
41//! # Implementation
42//!
43//! To implement these APIs, use the [`api_impl`](crate::api_impl) attribute
44//! macro on an impl block:
45//!
46//! ```rust,ignore
47//! struct VmmIfImpl;
48//!
49//! #[axvisor_api::api_impl]
50//! impl axvisor_api::vmm::VmmIf for VmmIfImpl {
51//!     fn current_vm_id() -> VMId {
52//!         // Return the current VM's ID
53//!     }
54//!     // ... implement other functions
55//! }
56//! ```
57
58/// Virtual machine identifier type.
59///
60/// Each virtual machine is assigned a unique identifier that can be used
61/// to reference it in API calls.
62pub type VMId = usize;
63
64/// Virtual CPU identifier type.
65///
66/// Each vCPU within a VM is assigned a unique identifier (0-indexed).
67pub type VCpuId = usize;
68
69/// Interrupt vector type.
70///
71/// Represents the interrupt vector number to be injected into a guest.
72pub type InterruptVector = u8;
73
74/// The maximum number of virtual CPUs supported in a virtual machine.
75pub const MAX_VCPU_NUM: usize = 64;
76
77/// A set of virtual CPUs.
78pub type VCpuSet = ax_cpumask::CpuMask<MAX_VCPU_NUM>;
79
80/// The API trait for virtual machine management functionalities.
81///
82/// This trait defines the core VM management interface required by the
83/// hypervisor components. Implementations should be provided by the VMM
84/// layer.
85#[crate::api_def]
86pub trait VmmIf {
87    /// Notify that a virtual CPU timer has expired.
88    /// Get the identifier of the current virtual machine.
89    ///
90    /// This function returns the VM ID of the VM that the calling context
91    /// belongs to.
92    ///
93    /// # Returns
94    ///
95    /// The current VM's identifier.
96    fn current_vm_id() -> VMId;
97
98    /// Get the identifier of the current virtual CPU.
99    ///
100    /// This function returns the vCPU ID within the current VM context.
101    ///
102    /// # Returns
103    ///
104    /// The current vCPU's identifier (0-indexed within the VM).
105    fn current_vcpu_id() -> VCpuId;
106
107    /// Get the number of virtual CPUs in a virtual machine.
108    ///
109    /// # Arguments
110    ///
111    /// * `vm_id` - The identifier of the virtual machine to query.
112    ///
113    /// # Returns
114    ///
115    /// - `Some(count)` - The number of vCPUs in the specified VM.
116    /// - `None` - If the VM ID is invalid.
117    fn vcpu_num(vm_id: VMId) -> Option<usize>;
118
119    /// Get the bitmask of active virtual CPUs in a virtual machine.
120    ///
121    /// Each bit in the returned value represents a vCPU, where bit N is set
122    /// if vCPU N is active (online and running).
123    ///
124    /// # Arguments
125    ///
126    /// * `vm_id` - The identifier of the virtual machine to query.
127    ///
128    /// # Returns
129    ///
130    /// - `Some(mask)` - The active vCPU bitmask for the specified VM.
131    /// - `None` - If the VM ID is invalid.
132    fn active_vcpus(vm_id: VMId) -> Option<usize>;
133
134    /// Inject an interrupt into a specific virtual CPU.
135    ///
136    /// This function queues an interrupt to be delivered to the specified
137    /// vCPU when it is next scheduled.
138    ///
139    /// # Arguments
140    ///
141    /// * `vm_id` - The identifier of the target virtual machine.
142    /// * `vcpu_id` - The identifier of the target virtual CPU.
143    /// * `vector` - The interrupt vector to inject.
144    ///
145    /// # Example
146    ///
147    /// ```rust,ignore
148    /// use axvisor_api::vmm::{inject_interrupt, current_vm_id};
149    ///
150    /// // Inject timer interrupt (vector 0x20) to vCPU 0 of the current VM
151    /// inject_interrupt(current_vm_id(), 0, 0x20);
152    /// ```
153    fn inject_interrupt(vm_id: VMId, vcpu_id: VCpuId, vector: InterruptVector);
154
155    /// Inject an interrupt to a set of virtual CPUs.
156    fn inject_interrupt_to_cpus(vm_id: VMId, vcpu_set: VCpuSet, vector: InterruptVector);
157
158    /// Notify that a virtual CPU's timer has expired.
159    ///
160    /// This function is called when a vCPU's virtual timer expires and needs
161    /// to be handled.
162    ///
163    /// # Arguments
164    ///
165    /// * `vm_id` - The identifier of the virtual machine.
166    /// * `vcpu_id` - The identifier of the virtual CPU whose timer expired.
167    ///
168    /// # Note
169    ///
170    /// This API may be revised in future versions as the timer virtualization
171    /// design evolves.
172    fn notify_vcpu_timer_expired(vm_id: VMId, vcpu_id: VCpuId);
173}
174
175/// Get the number of virtual CPUs in the current virtual machine executing on
176/// the current physical CPU.
177///
178/// This is a convenience function that combines [`current_vm_id`] and
179/// [`vcpu_num`].
180///
181/// # Returns
182///
183/// The number of vCPUs in the current VM.
184///
185/// # Panics
186///
187/// Panics if called outside of a valid VM context (when [`current_vm_id`]
188/// returns an invalid ID).
189pub fn current_vm_vcpu_num() -> usize {
190    vcpu_num(current_vm_id()).unwrap()
191}
192
193/// Get the bitmask of active virtual CPUs in the current virtual machine
194/// executing on the current physical CPU.
195///
196/// This is a convenience function that combines [`current_vm_id`] and
197/// [`active_vcpus`].
198///
199/// # Returns
200///
201/// The active vCPU bitmask for the current VM.
202///
203/// # Panics
204///
205/// Panics if called outside of a valid VM context (when [`current_vm_id`]
206/// returns an invalid ID).
207pub fn current_vm_active_vcpus() -> usize {
208    active_vcpus(current_vm_id()).unwrap()
209}