Skip to content

Commit 7ac8334

Browse files
committed
Refactor VM data management and address space handling
- Introduced `VmData` and `VmDataWeak` structures to encapsulate VM state and configuration. - Removed the obsolete `data2.rs` file and migrated relevant functionality to `data.rs`. - Enhanced `VmAddrSpace` to manage memory regions more effectively, including methods for adding and initializing memory. - Updated `FdtBuilder` to streamline CPU and memory setup in the device tree. - Refactored `VCpuCommon` to utilize the new `HCpu` architecture. - Improved error handling and state management in VM lifecycle operations. - Added new traits for VM machine states to facilitate better state transitions and management.
1 parent 70bd7a6 commit 7ac8334

File tree

13 files changed

+740
-913
lines changed

13 files changed

+740
-913
lines changed

src/arch/aarch64/cpu.rs

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ use arm_vcpu::{Aarch64PerCpu, Aarch64VCpuCreateConfig};
66
use axvm_types::addr::*;
77

88
use crate::{
9-
data2::VmDataWeak,
9+
data::VmDataWeak,
1010
vcpu::VCpuCommon,
1111
vhal::{
1212
ArchCpuData,
@@ -19,6 +19,7 @@ pub struct HCpu {
1919
pub hard_id: CpuHardId,
2020
vpercpu: Aarch64PerCpu,
2121
max_guest_page_table_levels: usize,
22+
pub pa_range: core::ops::Range<usize>,
2223
}
2324

2425
impl HCpu {
@@ -33,12 +34,14 @@ impl HCpu {
3334
hard_id: CpuHardId::new(hard_id),
3435
vpercpu,
3536
max_guest_page_table_levels: 0,
37+
pa_range: 0..0,
3638
}
3739
}
3840

3941
pub fn init(&mut self) -> anyhow::Result<()> {
4042
self.vpercpu.hardware_enable();
4143
self.max_guest_page_table_levels = self.vpercpu.max_guest_page_table_levels();
44+
self.pa_range = self.vpercpu.pa_range();
4245
Ok(())
4346
}
4447

@@ -124,11 +127,15 @@ impl VCpu {
124127
}
125128

126129
pub fn run(&mut self) -> anyhow::Result<()> {
127-
info!("Starting vCPU {}", self.id());
130+
info!("Starting vCPU {}", self.bind_id());
128131

129132
while self.is_active() {
130133
let exit_reason = self.vcpu.run().map_err(|e| anyhow!("{e}"))?;
131-
debug!("vCPU {} exited with reason: {:?}", self.id(), exit_reason);
134+
debug!(
135+
"vCPU {} exited with reason: {:?}",
136+
self.bind_id(),
137+
exit_reason
138+
);
132139
match exit_reason {
133140
arm_vcpu::AxVCpuExitReason::Hypercall { nr, args } => todo!(),
134141
arm_vcpu::AxVCpuExitReason::MmioRead {
@@ -149,8 +156,8 @@ impl VCpu {
149156
} => todo!(),
150157
arm_vcpu::AxVCpuExitReason::CpuDown { _state } => todo!(),
151158
arm_vcpu::AxVCpuExitReason::SystemDown => {
152-
info!("vCPU {} requested system shutdown", self.common.bind_id);
153-
self.shutdown()?;
159+
info!("vCPU {} requested system shutdown", self.bind_id());
160+
self.vm()?.stop()?;
154161
}
155162
arm_vcpu::AxVCpuExitReason::Nothing => {}
156163
arm_vcpu::AxVCpuExitReason::SendIPI {

src/arch/aarch64/vm/init.rs

Lines changed: 13 additions & 164 deletions
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,11 @@ use std::{
88
use arm_vcpu::Aarch64VCpuSetupConfig;
99

1010
use crate::{
11-
GuestPhysAddr, TASK_STACK_SIZE, VmRunCommonData, VmStatusInitOps,
12-
arch::{VmStatusRunning, cpu::VCpu},
11+
GuestPhysAddr, TASK_STACK_SIZE, VmAddrSpace, VmMachineInitedOps,
12+
arch::{VmMachineRunning, cpu::VCpu},
1313
config::AxVMConfig,
14-
data2::VmDataWeak,
15-
vm::{MappingFlags, VmId},
14+
data::VmDataWeak,
15+
vm::VmId,
1616
};
1717

1818
const VM_ASPACE_BASE: GuestPhysAddr = GuestPhysAddr::from_usize(0);
@@ -23,128 +23,14 @@ const VM_ASPACE_END: GuestPhysAddr =
2323
pub struct VmMachineInited {
2424
pub id: VmId,
2525
pub name: String,
26-
// pt_levels: usize,
27-
// stop_requested: AtomicBool,
28-
pub run_data: VmStatusRunning,
26+
pub vcpus: Vec<VCpu>,
27+
pub vmspace: VmAddrSpace,
2928
}
3029

31-
impl VmMachineInited {
32-
/// Creates a new VM with the given configuration
33-
// pub fn new(config: &AxVMConfig) -> anyhow::Result<Self> {
34-
// let vm = Self {
35-
// id: config.id().into(),
36-
// name: config.name().into(),
37-
// pt_levels: 4,
38-
// stop_requested: AtomicBool::new(false),
39-
// run_data: None,
40-
// };
41-
// Ok(vm)
42-
// }
43-
30+
impl VmMachineInited {}
4431

45-
/// Initializes the VM, creating vCPUs and setting up memory
46-
pub fn init(&mut self, config: AxVMConfig) -> anyhow::Result<()> {
47-
debug!("Initializing VM {} ({})", self.id, self.name);
48-
49-
let vcpus = self.new_vcpus(&config)?;
50-
51-
let mut run_data = VmStatusRunning::new(
52-
VmRunCommonData::new(self.pt_levels, VM_ASPACE_BASE..VM_ASPACE_END)?,
53-
vcpus,
54-
);
55-
56-
debug!("Mapping memory regions for VM {} ({})", self.id, self.name);
57-
for memory_cfg in &config.memory_regions {
58-
use crate::vm::MappingFlags;
59-
let m = run_data.data.try_use()?.new_memory(
60-
memory_cfg,
61-
MappingFlags::READ
62-
| MappingFlags::WRITE
63-
| MappingFlags::EXECUTE
64-
| MappingFlags::USER,
65-
);
66-
run_data.data.add_memory(m);
67-
}
68-
69-
run_data.data.try_use()?.load_kernel_image(&config)?;
70-
run_data.make_dtb(&config)?;
71-
72-
run_data.data.try_use()?.map_passthrough_regions()?;
73-
74-
let kernel_entry = run_data.data.try_use()?.kernel_entry();
75-
let gpt_root = run_data.data.try_use()?.gpt_root();
76-
77-
// Setup vCPUs
78-
for vcpu in &mut run_data.vcpus {
79-
vcpu.vcpu.set_entry(kernel_entry).unwrap();
80-
vcpu.vcpu.set_dtb_addr(run_data.dtb_addr).unwrap();
81-
82-
let setup_config = Aarch64VCpuSetupConfig {
83-
passthrough_interrupt: config.interrupt_mode()
84-
== axvmconfig::VMInterruptMode::Passthrough,
85-
passthrough_timer: config.interrupt_mode()
86-
== axvmconfig::VMInterruptMode::Passthrough,
87-
};
88-
89-
vcpu.vcpu
90-
.setup(setup_config)
91-
.map_err(|e| anyhow::anyhow!("Failed to setup vCPU : {e:?}"))?;
92-
93-
// Set EPT root
94-
vcpu.vcpu
95-
.set_ept_root(gpt_root)
96-
.map_err(|e| anyhow::anyhow!("Failed to set EPT root for vCPU : {e:?}"))?;
97-
98-
run_data.vcpu_running_count.fetch_add(1, Ordering::SeqCst);
99-
}
100-
101-
self.run_data = Some(run_data);
102-
103-
Ok(())
104-
}
105-
106-
fn new_vcpus(&mut self, config: &AxVMConfig) -> anyhow::Result<Vec<VCpu>> {
107-
// Create vCPUs
108-
let mut vcpus = Vec::new();
109-
110-
let dtb_addr = GuestPhysAddr::from_usize(0);
111-
112-
match config.cpu_num {
113-
crate::config::CpuNumType::Alloc(num) => {
114-
for _ in 0..num {
115-
let vcpu = VCpu::new(None, dtb_addr)?;
116-
debug!("Created vCPU with {:?}", vcpu.id);
117-
vcpus.push(vcpu);
118-
}
119-
}
120-
crate::config::CpuNumType::Fixed(ref ids) => {
121-
for id in ids {
122-
let vcpu = VCpu::new(Some(*id), dtb_addr)?;
123-
debug!("Created vCPU with {:?}", vcpu.id);
124-
vcpus.push(vcpu);
125-
}
126-
}
127-
}
128-
129-
let vcpu_count = vcpus.len();
130-
131-
for vcpu in &vcpus {
132-
let max_levels = vcpu.with_hcpu(|cpu| cpu.max_guest_page_table_levels());
133-
if max_levels < self.pt_levels {
134-
self.pt_levels = max_levels;
135-
}
136-
}
137-
138-
debug!(
139-
"VM {} ({}) vCPU count: {}, Max Guest Page Table Levels: {}",
140-
self.id, self.name, vcpu_count, self.pt_levels
141-
);
142-
Ok(vcpus)
143-
}
144-
}
145-
146-
impl VmStatusInitOps for VmMachineInited {
147-
type Running = VmStatusRunning;
32+
impl VmMachineInitedOps for VmMachineInited {
33+
type Running = VmMachineRunning;
14834

14935
fn id(&self) -> VmId {
15036
self.id
@@ -155,51 +41,14 @@ impl VmStatusInitOps for VmMachineInited {
15541
}
15642

15743
fn start(self, vmdata: VmDataWeak) -> Result<Self::Running, (anyhow::Error, Self)> {
158-
let mut data = self.run_data.unwrap();
159-
160-
let mut vcpus = vec![];
161-
162-
vcpus.append(&mut data.vcpus);
163-
let mut vcpu_handles = vec![];
164-
let vm_id = self.id;
165-
166-
for mut vcpu in vcpus.into_iter() {
167-
let vcpu_id = vcpu.id;
168-
let vcpu_running_count = data.vcpu_running_count.clone();
169-
let bind_id = vcpu.binded_cpu_id();
170-
let handle = std::thread::Builder::new()
171-
.name(format!("{vm_id}-{vcpu_id}"))
172-
.stack_size(TASK_STACK_SIZE)
173-
.spawn(move || {
174-
assert!(
175-
set_current_affinity(AxCpuMask::one_shot(bind_id.raw())),
176-
"Initialize CPU affinity failed!"
177-
);
178-
match vcpu.run() {
179-
Ok(()) => {
180-
info!("vCPU {} of VM {} exited normally", vcpu_id, vm_id);
181-
}
182-
Err(e) => {
183-
error!(
184-
"vCPU {} of VM {} exited with error: {:?}",
185-
vcpu_id, vm_id, e
186-
);
187-
}
188-
}
189-
vcpu_running_count.fetch_sub(1, Ordering::SeqCst);
190-
vcpu
191-
})
192-
.unwrap();
193-
194-
vcpu_handles.push(handle);
195-
}
196-
44+
debug!("Starting VM {} ({})", self.id, self.name);
45+
let running = VmMachineRunning::new();
19746
info!(
19847
"VM {} ({}) with {} cpus booted successfully.",
19948
self.id,
20049
self.name,
201-
vcpu_handles.len()
50+
self.vcpus.len()
20251
);
203-
Ok(data)
52+
Ok(running)
20453
}
20554
}

0 commit comments

Comments
 (0)