axvcpu/arch_vcpu.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
15use axaddrspace::{GuestPhysAddr, HostPhysAddr};
16use axerrno::AxResult;
17use axvisor_api::vmm::{VCpuId, VMId};
18
19use crate::exit::AxVCpuExitReason;
20
21/// Architecture-specific virtual CPU trait definition.
22///
23/// This trait provides an abstraction layer for implementing virtual CPUs across
24/// different hardware architectures (x86_64, ARM64, RISC-V, etc.). Each architecture
25/// must implement this trait to provide the necessary low-level virtualization primitives.
26pub trait AxArchVCpu: Sized {
27 /// Architecture-specific configuration for VCpu creation.
28 ///
29 /// This associated type allows each architecture to define its own
30 /// configuration parameters needed during VCpu initialization.
31 type CreateConfig;
32
33 /// Architecture-specific configuration for VCpu setup.
34 ///
35 /// This associated type allows each architecture to specify additional
36 /// configuration parameters needed after basic VCpu creation but before execution.
37 type SetupConfig;
38
39 /// Creates a new architecture-specific VCpu instance.
40 fn new(vm_id: VMId, vcpu_id: VCpuId, config: Self::CreateConfig) -> AxResult<Self>;
41
42 /// Sets the guest entry point where VCpu execution will begin.
43 ///
44 /// It's guaranteed that this function is called only once, before [`AxArchVCpu::setup`] being called.
45 fn set_entry(&mut self, entry: GuestPhysAddr) -> AxResult;
46
47 /// Sets the Extended Page Table (EPT) root for memory translation.
48 ///
49 /// The EPT root defines the top-level page table used for guest-to-host
50 /// physical address translation in hardware virtualization.
51 fn set_ept_root(&mut self, ept_root: HostPhysAddr) -> AxResult;
52
53 /// Completes VCpu initialization and prepares it for execution.
54 ///
55 /// This method performs any final architecture-specific setup needed
56 /// before the VCpu can be bound and executed.
57 fn setup(&mut self, config: Self::SetupConfig) -> AxResult;
58
59 /// Executes the VCpu until a VM exit occurs.
60 ///
61 /// This is the core execution method that transfers control to the guest VCpu
62 /// and runs until the guest triggers a VM exit condition that requires
63 /// hypervisor intervention.
64 fn run(&mut self) -> AxResult<AxVCpuExitReason>;
65
66 /// Binds the VCpu to the current physical CPU for execution.
67 ///
68 /// This method performs any necessary architecture-specific initialization
69 /// to prepare the VCpu for execution on the current physical CPU.
70 fn bind(&mut self) -> AxResult;
71
72 /// Unbinds the VCpu from the current physical CPU.
73 ///
74 /// This method performs cleanup and state preservation when moving
75 /// the VCpu away from the current physical CPU.
76 fn unbind(&mut self) -> AxResult;
77
78 /// Sets the value of a general-purpose register.
79 fn set_gpr(&mut self, reg: usize, val: usize);
80
81 /// Inject an interrupt to the VCpu.
82 ///
83 /// It's guaranteed (for implementors, and required for callers) that this function is called
84 /// on the physical CPU where the VCpu is running or queueing.
85 ///
86 /// It's not guaranteed that the VCpu is running or bound to the current physical CPU when this
87 /// function is called. It means sometimes an irq queue is necessary to buffer the interrupts
88 /// until the VCpu is running.
89 fn inject_interrupt(&mut self, vector: usize) -> AxResult;
90
91 /// Sets the return value that will be delivered to the guest.
92 fn set_return_value(&mut self, val: usize);
93}