@@ -18,46 +18,46 @@ use alloc::sync::Arc;
1818use alloc:: vec:: Vec ;
1919use axaddrspace:: HostVirtAddr ;
2020use axerrno:: { AxError , AxResult , ax_err, ax_err_type} ;
21+ use axvisor_api:: vmm:: InterruptVector ;
2122use core:: alloc:: Layout ;
2223use core:: fmt;
2324use memory_addr:: { align_down_4k, align_up_4k} ;
2425use spin:: { Mutex , Once } ;
2526
2627use axaddrspace:: { AddrSpace , GuestPhysAddr , HostPhysAddr , MappingFlags , device:: AccessWidth } ;
2728use axdevice:: { AxVmDeviceConfig , AxVmDevices } ;
28- use axvcpu:: { AxVCpu , AxVCpuExitReason , AxVCpuHal } ;
29+ use axvcpu:: { AxVCpu , AxVCpuExitReason } ;
2930use cpumask:: CpuMask ;
3031
3132use crate :: config:: { AxVMConfig , PhysCpuList } ;
33+ use crate :: hal:: PagingHandlerImpl ;
34+ use crate :: has_hardware_support;
3235use crate :: vcpu:: AxArchVCpuImpl ;
33- use crate :: { AxVMHal , has_hardware_support} ;
3436
35- #[ cfg( target_arch = "riscv64" ) ]
37+ #[ cfg( not ( target_arch = "x86_64" ) ) ]
3638use crate :: vcpu:: AxVCpuCreateConfig ;
39+
3740#[ cfg( target_arch = "aarch64" ) ]
38- use crate :: vcpu:: { AxVCpuCreateConfig , get_sysreg_device} ;
41+ use crate :: vcpu:: get_sysreg_device;
3942
4043const VM_ASPACE_BASE : usize = 0x0 ;
4144const VM_ASPACE_SIZE : usize = 0x7fff_ffff_f000 ;
4245
4346/// A vCPU with architecture-independent interface.
44- #[ allow( type_alias_bounds) ]
45- type VCpu < U : AxVCpuHal > = AxVCpu < AxArchVCpuImpl < U > > ;
47+ type VCpu = AxVCpu < AxArchVCpuImpl > ;
4648/// A reference to a vCPU.
47- #[ allow( type_alias_bounds) ]
48- pub type AxVCpuRef < U : AxVCpuHal > = Arc < VCpu < U > > ;
49+ pub type AxVCpuRef = Arc < VCpu > ;
4950/// A reference to a VM.
50- #[ allow( type_alias_bounds) ]
51- pub type AxVMRef < H : AxVMHal , U : AxVCpuHal > = Arc < AxVM < H , U > > ; // we know the bound is not enforced here, we keep it for clarity
51+ pub type AxVMRef = Arc < AxVM > ;
5252
53- struct AxVMInnerConst < U : AxVCpuHal > {
53+ struct AxVMInnerConst {
5454 phys_cpu_ls : PhysCpuList ,
55- vcpu_list : Box < [ AxVCpuRef < U > ] > ,
55+ vcpu_list : Box < [ AxVCpuRef ] > ,
5656 devices : AxVmDevices ,
5757}
5858
59- unsafe impl < U : AxVCpuHal > Send for AxVMInnerConst < U > { }
60- unsafe impl < U : AxVCpuHal > Sync for AxVMInnerConst < U > { }
59+ unsafe impl Send for AxVMInnerConst { }
60+ unsafe impl Sync for AxVMInnerConst { }
6161
6262/// Represents a memory region in a virtual machine.
6363#[ derive( Debug , Clone ) ]
@@ -84,13 +84,12 @@ impl VMMemoryRegion {
8484 }
8585}
8686
87- struct AxVMInnerMut < H : AxVMHal > {
87+ struct AxVMInnerMut {
8888 // Todo: use more efficient lock.
89- address_space : AddrSpace < H :: PagingHandler > ,
89+ address_space : AddrSpace < PagingHandlerImpl > ,
9090 memory_regions : Vec < VMMemoryRegion > ,
9191 config : AxVMConfig ,
9292 vm_status : VMStatus ,
93- _marker : core:: marker:: PhantomData < H > ,
9493}
9594
9695/// VM status enumeration representing the lifecycle states of a virtual machine
@@ -145,19 +144,20 @@ impl fmt::Display for VMStatus {
145144const TEMP_MAX_VCPU_NUM : usize = 64 ;
146145
147146/// A Virtual Machine.
148- pub struct AxVM < H : AxVMHal , U : AxVCpuHal > {
147+ pub struct AxVM {
149148 id : usize ,
150- inner_const : Once < AxVMInnerConst < U > > ,
151- inner_mut : Mutex < AxVMInnerMut < H > > ,
149+ inner_const : Once < AxVMInnerConst > ,
150+ inner_mut : Mutex < AxVMInnerMut > ,
152151}
153152
154- impl < H : AxVMHal , U : AxVCpuHal > AxVM < H , U > {
153+ impl AxVM {
155154 /// Creates a new VM with the given configuration.
156155 /// Returns an error if the configuration is invalid.
157156 /// The VM is not started until `boot` is called.
158- pub fn new ( config : AxVMConfig ) -> AxResult < AxVMRef < H , U > > {
157+ pub fn new ( config : AxVMConfig ) -> AxResult < AxVMRef > {
159158 let address_space =
160- AddrSpace :: new_empty ( GuestPhysAddr :: from ( VM_ASPACE_BASE ) , VM_ASPACE_SIZE ) ?;
159+ // TODO: read level from config
160+ AddrSpace :: new_empty ( 4 , GuestPhysAddr :: from ( VM_ASPACE_BASE ) , VM_ASPACE_SIZE ) ?;
161161
162162 let result = Arc :: new ( Self {
163163 id : config. id ( ) ,
@@ -167,7 +167,6 @@ impl<H: AxVMHal, U: AxVCpuHal> AxVM<H, U> {
167167 config,
168168 memory_regions : Vec :: new ( ) ,
169169 vm_status : VMStatus :: Loading ,
170- _marker : core:: marker:: PhantomData ,
171170 } ) ,
172171 } ) ;
173172
@@ -189,7 +188,7 @@ impl<H: AxVMHal, U: AxVCpuHal> AxVM<H, U> {
189188 let dtb_addr = inner_mut. config . image_config ( ) . dtb_load_gpa ;
190189 let vcpu_id_pcpu_sets = inner_mut. config . phys_cpu_ls . get_vcpu_affinities_pcpu_ids ( ) ;
191190
192- info ! ( "dtb_load_gpa: {:?}" , dtb_addr ) ;
191+ info ! ( "dtb_load_gpa: {dtb_addr :?}" ) ;
193192 debug ! ( "id: {}, VCpuIdPCpuSets: {vcpu_id_pcpu_sets:#x?}" , self . id( ) ) ;
194193
195194 let mut vcpu_list = Vec :: with_capacity ( vcpu_id_pcpu_sets. len ( ) ) ;
@@ -205,6 +204,10 @@ impl<H: AxVMHal, U: AxVCpuHal> AxVM<H, U> {
205204 dtb_addr : dtb_addr. unwrap_or_default ( ) . as_usize ( ) ,
206205 } ;
207206
207+ // FIXME: VCpu is neither `Send` nor `Sync` by design, check whether
208+ // 1. we should make it `Send` and `Sync`, or
209+ // 2. we can guarantee that no cross-thread access is performed
210+ #[ allow( clippy:: arc_with_non_send_sync) ]
208211 vcpu_list. push ( Arc :: new ( VCpu :: new (
209212 self . id ( ) ,
210213 vcpu_id,
@@ -278,14 +281,10 @@ impl<H: AxVMHal, U: AxVCpuHal> AxVM<H, U> {
278281 ) ?;
279282 }
280283
281- #[ cfg ( target_arch = "aarch64" ) ]
284+ #[ cfg_attr ( not ( target_arch = "aarch64" ) , expect ( unused_mut ) ) ]
282285 let mut devices = axdevice:: AxVmDevices :: new ( AxVmDeviceConfig {
283286 emu_configs : inner_mut. config . emu_devices ( ) . to_vec ( ) ,
284287 } ) ;
285- #[ cfg( not( target_arch = "aarch64" ) ) ]
286- let devices = axdevice:: AxVmDevices :: new ( AxVmDeviceConfig {
287- emu_configs : inner_mut. config . emu_devices ( ) . to_vec ( ) ,
288- } ) ;
289288
290289 #[ cfg( target_arch = "aarch64" ) ]
291290 {
@@ -346,6 +345,9 @@ impl<H: AxVMHal, U: AxVCpuHal> AxVM<H, U> {
346345 passthrough_timer : passthrough,
347346 }
348347 } ;
348+ #[ cfg( not( target_arch = "aarch64" ) ) ]
349+ #[ allow( clippy:: let_unit_value) ]
350+ let setup_config = <AxArchVCpuImpl as axvcpu:: AxArchVCpu >:: SetupConfig :: default ( ) ;
349351
350352 let entry = if vcpu. id ( ) == 0 {
351353 inner_mut. config . bsp_entry ( )
@@ -358,10 +360,7 @@ impl<H: AxVMHal, U: AxVCpuHal> AxVM<H, U> {
358360 vcpu. setup (
359361 entry,
360362 inner_mut. address_space . page_table_root ( ) ,
361- #[ cfg( target_arch = "aarch64" ) ]
362363 setup_config,
363- #[ cfg( not( target_arch = "aarch64" ) ) ]
364- ( ) ,
365364 ) ?;
366365 }
367366 info ! ( "VM setup: id={}" , self . id( ) ) ;
@@ -383,7 +382,7 @@ impl<H: AxVMHal, U: AxVCpuHal> AxVM<H, U> {
383382 /// Retrieves the vCPU corresponding to the given vcpu_id for the VM.
384383 /// Returns None if the vCPU does not exist.
385384 #[ inline]
386- pub fn vcpu ( & self , vcpu_id : usize ) -> Option < AxVCpuRef < U > > {
385+ pub fn vcpu ( & self , vcpu_id : usize ) -> Option < AxVCpuRef > {
387386 self . vcpu_list ( ) . get ( vcpu_id) . cloned ( )
388387 }
389388
@@ -393,15 +392,15 @@ impl<H: AxVMHal, U: AxVCpuHal> AxVM<H, U> {
393392 self . inner_const ( ) . vcpu_list . len ( )
394393 }
395394
396- fn inner_const ( & self ) -> & AxVMInnerConst < U > {
395+ fn inner_const ( & self ) -> & AxVMInnerConst {
397396 self . inner_const
398397 . get ( )
399398 . expect ( "VM inner_const not initialized" )
400399 }
401400
402401 /// Returns a reference to the list of vCPUs corresponding to the VM.
403402 #[ inline]
404- pub fn vcpu_list ( & self ) -> & [ AxVCpuRef < U > ] {
403+ pub fn vcpu_list ( & self ) -> & [ AxVCpuRef ] {
405404 & self . inner_const ( ) . vcpu_list
406405 }
407406
@@ -594,13 +593,12 @@ impl<H: AxVMHal, U: AxVCpuHal> AxVM<H, U> {
594593 // It is not supported to inject interrupt to a vcpu in another VM yet.
595594 //
596595 // It may be supported in the future, as a essential feature for cross-VM communication.
597- if H :: current_vm_id ( ) != self . id ( ) {
596+ let current_running_vm = axvisor_api:: vmm:: current_vm_id ( ) ;
597+ if current_running_vm != vm_id {
598598 panic ! ( "Injecting interrupt to a vcpu in another VM is not supported" ) ;
599599 }
600600
601- for target_vcpu in & targets {
602- H :: inject_irq_to_vcpu ( vm_id, target_vcpu, irq) ?;
603- }
601+ axvisor_api:: vmm:: inject_interrupt_to_cpus ( vm_id, targets, irq as InterruptVector ) ;
604602
605603 Ok ( ( ) )
606604 }
@@ -757,7 +755,7 @@ impl<H: AxVMHal, U: AxVCpuHal> AxVM<H, U> {
757755 let s = unsafe { core:: slice:: from_raw_parts_mut ( hva, layout. size ( ) ) } ;
758756 let hva = HostVirtAddr :: from_mut_ptr_of ( hva) ;
759757
760- let hpa = H :: virt_to_phys ( hva) ;
758+ let hpa = axvisor_api :: memory :: virt_to_phys ( hva) ;
761759
762760 let gpa = gpa. unwrap_or_else ( || hpa. as_usize ( ) . into ( ) ) ;
763761
@@ -923,7 +921,7 @@ impl<H: AxVMHal, U: AxVCpuHal> AxVM<H, U> {
923921 }
924922}
925923
926- impl < H : AxVMHal , U : AxVCpuHal > Drop for AxVM < H , U > {
924+ impl Drop for AxVM {
927925 fn drop ( & mut self ) {
928926 info ! ( "Dropping VM[{}]" , self . id( ) ) ;
929927
0 commit comments