Skip to content

Commit db7db82

Browse files
committed
feat: add cache flush
1 parent c43052a commit db7db82

File tree

9 files changed

+121
-95
lines changed

9 files changed

+121
-95
lines changed

Cargo.toml

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -36,10 +36,9 @@ axaddrspace = "0.2"
3636
# axdevice_base = "0.1"
3737
# axvcpu = "0.1"
3838
axvmconfig = {version = "0.1", default-features = false}
39-
axconfig = {workspace = true}
40-
axhal.workspace = true
4139
axruntime.workspace = true
42-
axtask.workspace = true
40+
axhal.workspace = true
41+
axstd.workspace = true
4342
axvm-types.workspace = true
4443

4544
[target.'cfg(target_arch = "x86_64")'.dependencies]

src/arch/aarch64/cpu.rs

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,12 @@ use arm_vcpu::{Aarch64PerCpu, Aarch64VCpuCreateConfig};
66
use axhal::percpu::this_cpu_id;
77
use axvm_types::addr::*;
88

9-
use crate::vhal::{
10-
ArchCpuData,
11-
cpu::{CpuHardId, CpuId, HCpuExclusive},
9+
use crate::{
10+
TASK_STACK_SIZE, VmId,
11+
vhal::{
12+
ArchCpuData,
13+
cpu::{CpuHardId, CpuId, HCpuExclusive},
14+
},
1215
};
1316

1417
pub struct HCpu {
@@ -106,4 +109,14 @@ impl VCpu {
106109
{
107110
self.hcpu.with_cpu(f)
108111
}
112+
113+
pub fn binded_cpu_id(&self) -> CpuId {
114+
self.hcpu.cpu_id()
115+
}
116+
117+
pub fn run(&mut self) -> anyhow::Result<()> {
118+
info!("Starting vCPU {}", self.id);
119+
120+
Ok(())
121+
}
109122
}

src/arch/aarch64/mod.rs

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ impl ArchHal for Hal {
4242

4343
fn init() -> anyhow::Result<()> {
4444
arm_vcpu::init_hal(&cpu::VCpuHal);
45+
4546
Ok(())
4647
}
4748

@@ -62,10 +63,3 @@ impl ArchHal for Hal {
6263
dcache_range(CacheOp::CleanAndInvalidate, vaddr.as_usize(), size);
6364
}
6465
}
65-
66-
// Implement Display for VmId
67-
impl fmt::Display for VmId {
68-
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
69-
write!(f, "VmId({:?})", self)
70-
}
71-
}

src/arch/aarch64/vm.rs

Lines changed: 62 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,15 @@
11
use core::sync::atomic::{AtomicBool, AtomicUsize, Ordering};
2+
use std::os::arceos::{api::task::AxCpuMask, modules::axtask::set_current_affinity};
23

34
use super::AddrSpace;
45
use alloc::{collections::BTreeMap, string::String, vec::Vec};
6+
use arm_vcpu::Aarch64VCpuSetupConfig;
57

68
use crate::{
7-
GuestPhysAddr, HostPhysAddr, HostVirtAddr,
9+
GuestPhysAddr, HostPhysAddr, HostVirtAddr, TASK_STACK_SIZE,
810
arch::cpu::VCpu,
911
config::{AxVMConfig, MemoryKind},
10-
region::Region,
12+
region::GuestRegion,
1113
vhal::{ArchHal, cpu::CpuId, phys_to_virt, virt_to_phys},
1214
vm::{Status, VmId, VmOps},
1315
};
@@ -115,12 +117,8 @@ impl ArchVm {
115117
);
116118

117119
run_data.load_images(&config)?;
118-
for vcpu in &mut run_data.vcpus {
119-
vcpu.vcpu.set_entry(run_data.kernel_entry).unwrap();
120-
vcpu.vcpu.set_dtb_addr(run_data.dtb_addr).unwrap();
121-
}
122120

123-
// // Add emulated devices
121+
// Add emulated devices
124122
// for emu_device in config.emu_devices() {
125123
// let device_info = DeviceInfo {
126124
// device_type: DeviceType::Emulated,
@@ -176,36 +174,27 @@ impl ArchVm {
176174
// })?;
177175
// }
178176

179-
// // Setup vCPUs
180-
// for (vcpu_id, vcpu) in &vcpus {
181-
// let entry = if *vcpu_id == 0 {
182-
// config.bsp_entry()
183-
// } else {
184-
// config.ap_entry()
185-
// };
186-
187-
// let setup_config = AxVCpuSetupConfig {
188-
// passthrough_interrupt: config.interrupt_mode()
189-
// == axvmconfig::VMInterruptMode::Passthrough,
190-
// passthrough_timer: config.interrupt_mode()
191-
// == axvmconfig::VMInterruptMode::Passthrough,
192-
// };
177+
// Setup vCPUs
178+
for vcpu in &mut run_data.vcpus {
179+
vcpu.vcpu.set_entry(run_data.kernel_entry).unwrap();
180+
vcpu.vcpu.set_dtb_addr(run_data.dtb_addr).unwrap();
193181

194-
// // Set entry point first
195-
// vcpu.set_entry(entry).map_err(|e| {
196-
// anyhow::anyhow!("Failed to set entry for vCPU {}: {:?}", vcpu_id, e)
197-
// })?;
182+
let setup_config = Aarch64VCpuSetupConfig {
183+
passthrough_interrupt: config.interrupt_mode()
184+
== axvmconfig::VMInterruptMode::Passthrough,
185+
passthrough_timer: config.interrupt_mode()
186+
== axvmconfig::VMInterruptMode::Passthrough,
187+
};
198188

199-
// // Set EPT root
200-
// vcpu.set_ept_root(address_space.page_table_root())
201-
// .map_err(|e| {
202-
// anyhow::anyhow!("Failed to set EPT root for vCPU {}: {:?}", vcpu_id, e)
203-
// })?;
189+
vcpu.vcpu
190+
.setup(setup_config)
191+
.map_err(|e| anyhow::anyhow!("Failed to setup vCPU : {e:?}"))?;
204192

205-
// // Setup vCPU with configuration
206-
// vcpu.setup(setup_config)
207-
// .map_err(|e| anyhow::anyhow!("Failed to setup vCPU {}: {:?}", vcpu_id, e))?;
208-
// }
193+
// Set EPT root
194+
vcpu.vcpu
195+
.set_ept_root(run_data.address_space.page_table_root())
196+
.map_err(|e| anyhow::anyhow!("Failed to set EPT root for vCPU : {e:?}"))?;
197+
}
209198

210199
self.state = StateMachine::Inited(run_data);
211200

@@ -318,29 +307,44 @@ impl VmOps for ArchVm {
318307
_ => return Err(anyhow::anyhow!("VM is not in Inited state")),
319308
};
320309

321-
// Transition to Running state
322-
// let new_data = RunData {
323-
// // vcpus: BTreeMap::new(),
324-
// // address_space: AddrSpace::new_empty(4, GuestPhysAddr::from(0), 0).unwrap(),
325-
// devices: BTreeMap::new(),
326-
// };
327-
// let old_data = core::mem::replace(data, new_data);
328-
// self.transition_state(StateMachine::Running(old_data))?;
329-
330-
// // Start all vCPUs
331-
// let vcpus = self.get_vcpus();
332-
// for (vcpu_id, vcpu) in vcpus.iter().enumerate() {
333-
// debug!("Starting vCPU {} for VM {}", vcpu_id, self.id);
334-
// vcpu.bind()
335-
// .map_err(|e| anyhow::anyhow!("Failed to bind vCPU {}: {:?}", vcpu_id, e))?;
336-
// }
310+
let mut vcpus = vec![];
311+
vcpus.append(&mut data.vcpus);
312+
let mut vcpu_handles = vec![];
313+
let vm_id = self.id;
314+
for mut vcpu in vcpus.into_iter() {
315+
let vcpu_id = vcpu.id;
316+
let bind_id = vcpu.binded_cpu_id();
317+
let handle = std::thread::Builder::new()
318+
.name(format!("{}-{vcpu_id}", self.id,))
319+
.stack_size(TASK_STACK_SIZE)
320+
.spawn(move || {
321+
assert!(
322+
set_current_affinity(AxCpuMask::one_shot(bind_id.raw())),
323+
"Initialize CPU affinity failed!"
324+
);
325+
match vcpu.run() {
326+
Ok(()) => {
327+
info!("vCPU {} of VM {} exited normally", vcpu_id, vm_id);
328+
}
329+
Err(e) => {
330+
error!(
331+
"vCPU {} of VM {} exited with error: {:?}",
332+
vcpu_id, vm_id, e
333+
);
334+
}
335+
}
336+
})
337+
.map_err(|e| anyhow!("{e}"))?;
338+
339+
vcpu_handles.push(handle);
340+
}
337341

338-
// info!(
339-
// "VM {} ({}) booted successfully with {} vCPUs",
340-
// self.id,
341-
// self.name,
342-
// vcpus.len()
343-
// );
342+
info!(
343+
"VM {} ({}) with {} cpus booted successfully.",
344+
self.id,
345+
self.name,
346+
vcpu_handles.len()
347+
);
344348

345349
Ok(())
346350
}
@@ -523,7 +527,7 @@ enum StateMachine {
523527
pub struct RunData {
524528
vcpus: Vec<VCpu>,
525529
address_space: AddrSpace,
526-
regions: Vec<Region>,
530+
regions: Vec<GuestRegion>,
527531
devices: BTreeMap<String, DeviceInfo>,
528532
kernel_entry: GuestPhysAddr,
529533
dtb_addr: GuestPhysAddr,
@@ -534,7 +538,7 @@ pub struct RunData {
534538

535539
impl RunData {
536540
fn add_memory_region(&mut self, config: &MemoryKind) -> anyhow::Result<()> {
537-
let region = Region::new(config);
541+
let region = GuestRegion::new(config);
538542
self.address_space
539543
.map_linear(
540544
region.gpa.as_usize().into(),

src/lib.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,9 @@ extern crate log;
1616
#[macro_use]
1717
extern crate anyhow;
1818

19-
const TASK_STACK_SIZE: usize = 0x40000; // 16KB
19+
extern crate axstd as std;
20+
21+
const TASK_STACK_SIZE: usize = 0x40000; // 256 KB
2022

2123
#[cfg_attr(target_arch = "aarch64", path = "arch/aarch64/mod.rs")]
2224
#[cfg_attr(target_arch = "x86_64", path = "arch/x86_64/mod.rs")]

src/region.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -11,22 +11,22 @@ use crate::{
1111
const ALIGN: usize = 1024 * 1024 * 2;
1212

1313
#[derive(Debug, Clone)]
14-
pub struct Region {
14+
pub struct GuestRegion {
1515
pub gpa: GuestPhysAddr,
1616
pub hva: HostVirtAddr,
1717
pub size: usize,
1818
pub own: bool,
1919
}
2020

21-
impl Region {
21+
impl GuestRegion {
2222
pub fn new(kind: &MemoryKind) -> Self {
2323
match kind {
2424
MemoryKind::Identical { size } => {
2525
let hva = HostVirtAddr::from(unsafe {
2626
alloc::alloc::alloc(Layout::from_size_align_unchecked(*size, ALIGN))
2727
} as usize);
2828
let gpa = GuestPhysAddr::from_usize(virt_to_phys(hva).as_usize());
29-
Region {
29+
GuestRegion {
3030
gpa,
3131
hva,
3232
size: *size,
@@ -36,7 +36,7 @@ impl Region {
3636
MemoryKind::Passthrough { hpa, size } => {
3737
let hva = phys_to_virt(*hpa);
3838
let gpa = GuestPhysAddr::from_usize(hva.as_usize());
39-
Region {
39+
GuestRegion {
4040
gpa,
4141
hva,
4242
size: *size,
@@ -47,7 +47,7 @@ impl Region {
4747
let hva = HostVirtAddr::from(unsafe {
4848
alloc::alloc::alloc(Layout::from_size_align_unchecked(*size, ALIGN))
4949
} as usize);
50-
Region {
50+
GuestRegion {
5151
gpa: *gpa,
5252
hva,
5353
size: *size,
@@ -62,7 +62,7 @@ impl Region {
6262
}
6363
}
6464

65-
impl Drop for Region {
65+
impl Drop for GuestRegion {
6666
fn drop(&mut self) {
6767
if self.own {
6868
unsafe {

src/vhal/cpu.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,10 @@ pub(super) static HCPU_ALLOC: Mutex<BitAlloc4K> = Mutex::new(BitAlloc4K::DEFAULT
1414
pub struct HCpuExclusive(CpuId);
1515

1616
impl HCpuExclusive {
17+
pub fn id(&self) -> CpuId {
18+
self.0
19+
}
20+
1721
pub fn try_new(id: Option<CpuId>) -> Option<Self> {
1822
let mut a = HCPU_ALLOC.lock();
1923
match id {

src/vhal/mod.rs

Lines changed: 19 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,8 @@
11
use alloc::{collections::BTreeMap, vec::Vec};
2+
use axstd::{
3+
os::arceos::{api::task::AxCpuMask, modules::axtask::set_current_affinity},
4+
thread::yield_now,
5+
};
26
use bitmap_allocator::{BitAlloc, BitAlloc4K};
37
use core::{
48
fmt::Display,
@@ -7,15 +11,13 @@ use core::{
711
use spin::Mutex;
812

913
use crate::{
14+
HostPhysAddr, HostVirtAddr, TASK_STACK_SIZE,
1015
arch::{HCpu, Hal},
1116
vhal::{
1217
cpu::{CpuHardId, CpuId},
1318
precpu::PreCpuSet,
1419
},
15-
{HostPhysAddr, HostVirtAddr},
1620
};
17-
use axconfig::TASK_STACK_SIZE;
18-
use axtask::AxCpuMask;
1921

2022
pub(crate) mod cpu;
2123
pub(crate) mod precpu;
@@ -30,42 +32,42 @@ pub fn init() -> anyhow::Result<()> {
3032

3133
info!("Initializing VHal for {cpu_count} CPUs...");
3234
cpu::PRE_CPU.init();
35+
3336
for cpu_id in 0..cpu_count {
3437
let id = CpuId::new(cpu_id);
35-
let _handle = axtask::spawn_raw(
36-
move || {
38+
axstd::thread::Builder::new()
39+
.name(format!("init-cpu-{}", cpu_id))
40+
.stack_size(TASK_STACK_SIZE)
41+
.spawn(move || {
3742
info!("Core {cpu_id} is initializing hardware virtualization support...");
3843
// Initialize cpu affinity here.
3944
assert!(
40-
axtask::set_current_affinity(AxCpuMask::one_shot(cpu_id)),
45+
set_current_affinity(AxCpuMask::one_shot(cpu_id)),
4146
"Initialize CPU affinity failed!"
4247
);
4348
info!("Enabling hardware virtualization support on core {id}");
4449
timer::init_percpu();
4550

46-
let cpu_data = Hal::current_cpu_init(id).expect("Enable virtualization failed!");
47-
unsafe { cpu::PRE_CPU.set(cpu_data.hard_id(), cpu_data) };
51+
// let cpu_data = Hal::current_cpu_init(id).expect("Enable virtualization failed!");
52+
// unsafe { cpu::PRE_CPU.set(cpu_data.hard_id(), cpu_data) };
4853
let _ = CORES.fetch_add(1, Ordering::Release);
49-
},
50-
format!("init-cpu-{}", cpu_id),
51-
TASK_STACK_SIZE,
52-
);
53-
// handles.push(_handle);
54+
})
55+
.map_err(|e| anyhow!("{e:?}"))?;
5456
}
5557
info!("Waiting for all cores to enable hardware virtualization...");
5658

5759
// Wait for all cores to enable virtualization.
5860
while CORES.load(Ordering::Acquire) != cpu_count {
5961
// Use `yield_now` instead of `core::hint::spin_loop` to avoid deadlock.
60-
axtask::yield_now();
62+
yield_now();
6163
}
62-
// for handle in handles {
63-
// handle.join();
64-
// }
6564

6665
cpu::HCPU_ALLOC.lock().insert(0..cpu_count);
6766

6867
info!("All cores have enabled hardware virtualization support.");
68+
69+
70+
6971
Ok(())
7072
}
7173

0 commit comments

Comments
 (0)