Skip to content

Commit 01634a0

Browse files
ZR233songzhy
andauthored
fix flush dcache bug (#146)
* fix * fmt code * bug: when the kernel is in the filesystem, ​the kernel address cache is not flushed. --------- Co-authored-by: songzhy <[email protected]>
1 parent 3fa6e7b commit 01634a0

File tree

2 files changed

+90
-40
lines changed

2 files changed

+90
-40
lines changed

src/utils/mod.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
11
mod arch;
22

33
pub mod cache {
4+
#[allow(unused)]
45
/// Invalidate the data cache.
56
pub unsafe fn cache_invalidate_d(start: usize, len: usize) {
6-
super::arch::cache::cache_invalidate_d(start, len);
7+
unsafe { super::arch::cache::cache_invalidate_d(start, len) };
78
}
89
/// Clean and invalidate the data cache.
910
pub unsafe fn cache_clean_invalidate_d(start: usize, len: usize) {
10-
super::arch::cache::cache_clean_invalidate_d(start, len);
11+
unsafe { super::arch::cache::cache_clean_invalidate_d(start, len) };
1112
}
1213
}

src/vmm/images.rs

Lines changed: 87 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -1,68 +1,92 @@
1+
use alloc::vec::Vec;
2+
13
use axaddrspace::GuestPhysAddr;
24
use axerrno::AxResult;
35

46
use axvm::config::AxVMCrateConfig;
7+
use memory_addr::PhysAddr;
58

6-
#[cfg(target_arch = "aarch64")]
7-
use crate::utils::cache::cache_clean_invalidate_d;
89
use crate::vmm::VMRef;
910
use crate::vmm::config::config;
1011

1112
/// Loads the VM image files.
1213
pub fn load_vm_images(config: AxVMCrateConfig, vm: VMRef) -> AxResult {
13-
match config.kernel.image_location.as_deref() {
14-
Some("memory") => load_vm_images_from_memory(config, vm),
14+
let load_ranges = match config.kernel.image_location.as_deref() {
15+
Some("memory") => load_vm_images_from_memory(config, vm.clone()),
1516
#[cfg(feature = "fs")]
16-
Some("fs") => fs::load_vm_images_from_filesystem(config, vm),
17+
Some("fs") => fs::load_vm_images_from_filesystem(config, vm.clone()),
1718
_ => unimplemented!(
1819
"Check your \"image_location\" in config.toml, \"memory\" and \"fs\" are supported,\n NOTE: \"fs\" feature should be enabled if you want to load images from filesystem. (APP_FEATURES=fs)"
1920
),
21+
}?;
22+
flush_vm_images(&load_ranges);
23+
Ok(())
24+
}
25+
26+
fn flush_vm_images(ls: &[LoadRange]) {
27+
for l in ls {
28+
unsafe {
29+
crate::utils::cache::cache_clean_invalidate_d(l.start.as_usize(), l.size);
30+
}
2031
}
2132
}
2233

34+
struct LoadRange {
35+
start: PhysAddr,
36+
size: usize,
37+
}
38+
2339
/// Load VM images from memory
2440
/// into the guest VM's memory space based on the VM configuration.
25-
fn load_vm_images_from_memory(config: AxVMCrateConfig, vm: VMRef) -> AxResult {
41+
fn load_vm_images_from_memory(config: AxVMCrateConfig, vm: VMRef) -> AxResult<Vec<LoadRange>> {
2642
info!("Loading VM[{}] images from memory", config.base.id);
43+
let mut load_ranges = Vec::new();
2744

2845
let vm_imags = config::get_memory_images()
2946
.iter()
3047
.find(|&v| v.id == config.base.id)
3148
.expect("VM images is missed, Perhaps add `VM_CONFIGS=PATH/CONFIGS/FILE` command.");
3249

33-
load_vm_image_from_memory(vm_imags.kernel, config.kernel.kernel_load_addr, vm.clone())
34-
.expect("Failed to load VM images");
50+
load_ranges.append(
51+
&mut load_vm_image_from_memory(vm_imags.kernel, config.kernel.kernel_load_addr, vm.clone())
52+
.expect("Failed to load VM images"),
53+
);
3554

3655
// Load DTB image
3756
if let Some(buffer) = vm_imags.dtb {
38-
load_vm_image_from_memory(buffer, config.kernel.dtb_load_addr.unwrap(), vm.clone())
39-
.expect("Failed to load DTB images");
57+
load_ranges.append(
58+
&mut load_vm_image_from_memory(
59+
buffer,
60+
config.kernel.dtb_load_addr.unwrap(),
61+
vm.clone(),
62+
)
63+
.expect("Failed to load DTB images"),
64+
);
4065
}
4166

4267
// Load BIOS image
4368
if let Some(buffer) = vm_imags.bios {
44-
load_vm_image_from_memory(buffer, config.kernel.bios_load_addr.unwrap(), vm.clone())
45-
.expect("Failed to load BIOS images");
46-
}
47-
#[cfg(target_arch = "aarch64")]
48-
{
49-
for mem_region in &config.kernel.memory_regions {
50-
debug!(
51-
"flush all guest cache GPA: 0x{:x}, Size: 0x{:x}",
52-
mem_region.gpa, mem_region.size
53-
);
54-
unsafe {
55-
cache_clean_invalidate_d(mem_region.gpa, mem_region.size);
56-
}
57-
}
69+
load_ranges.append(
70+
&mut load_vm_image_from_memory(
71+
buffer,
72+
config.kernel.bios_load_addr.unwrap(),
73+
vm.clone(),
74+
)
75+
.expect("Failed to load BIOS images"),
76+
);
5877
}
5978

60-
Ok(())
79+
Ok(load_ranges)
6180
}
6281

63-
fn load_vm_image_from_memory(image_buffer: &[u8], load_addr: usize, vm: VMRef) -> AxResult {
82+
fn load_vm_image_from_memory(
83+
image_buffer: &[u8],
84+
load_addr: usize,
85+
vm: VMRef,
86+
) -> AxResult<Vec<LoadRange>> {
6487
let mut buffer_pos = 0;
6588
let image_load_gpa = GuestPhysAddr::from(load_addr);
89+
let mut load_ranges = alloc::vec![];
6690

6791
let image_size = image_buffer.len();
6892

@@ -86,7 +110,10 @@ fn load_vm_image_from_memory(image_buffer: &[u8], load_addr: usize, vm: VMRef) -
86110
bytes_to_write,
87111
);
88112
}
89-
113+
load_ranges.push(LoadRange {
114+
start: (region.as_ptr() as usize).into(),
115+
size: bytes_to_write,
116+
});
90117
// Update the position of the buffer.
91118
buffer_pos += bytes_to_write;
92119

@@ -97,7 +124,7 @@ fn load_vm_image_from_memory(image_buffer: &[u8], load_addr: usize, vm: VMRef) -
97124
}
98125
}
99126

100-
Ok(())
127+
Ok(load_ranges)
101128
}
102129

103130
#[cfg(feature = "fs")]
@@ -112,30 +139,38 @@ mod fs {
112139

113140
/// Loads the VM image files from the filesystem
114141
/// into the guest VM's memory space based on the VM configuration.
115-
pub(crate) fn load_vm_images_from_filesystem(config: AxVMCrateConfig, vm: VMRef) -> AxResult {
142+
pub(crate) fn load_vm_images_from_filesystem(
143+
config: AxVMCrateConfig,
144+
vm: VMRef,
145+
) -> AxResult<Vec<LoadRange>> {
116146
info!("Loading VM images from filesystem");
147+
let mut load_ranges = Vec::new();
117148
// Load kernel image.
118-
load_vm_image(
149+
load_ranges.append(&mut load_vm_image(
119150
config.kernel.kernel_path,
120151
GuestPhysAddr::from(config.kernel.kernel_load_addr),
121152
vm.clone(),
122-
)?;
153+
)?);
123154
// Load BIOS image if needed.
124155
if let Some(bios_path) = config.kernel.bios_path {
125156
if let Some(bios_load_addr) = config.kernel.bios_load_addr {
126-
load_vm_image(bios_path, GuestPhysAddr::from(bios_load_addr), vm.clone())?;
157+
load_ranges.append(&mut load_vm_image(
158+
bios_path,
159+
GuestPhysAddr::from(bios_load_addr),
160+
vm.clone(),
161+
)?);
127162
} else {
128163
return ax_err!(NotFound, "BIOS load addr is missed");
129164
}
130165
};
131166
// Load Ramdisk image if needed.
132167
if let Some(ramdisk_path) = config.kernel.ramdisk_path {
133168
if let Some(ramdisk_load_addr) = config.kernel.ramdisk_load_addr {
134-
load_vm_image(
169+
load_ranges.append(&mut load_vm_image(
135170
ramdisk_path,
136171
GuestPhysAddr::from(ramdisk_load_addr),
137172
vm.clone(),
138-
)?;
173+
)?);
139174
} else {
140175
return ax_err!(NotFound, "Ramdisk load addr is missed");
141176
}
@@ -144,22 +179,36 @@ mod fs {
144179
// Todo: generate DTB file for guest VM.
145180
if let Some(dtb_path) = config.kernel.dtb_path {
146181
if let Some(dtb_load_addr) = config.kernel.dtb_load_addr {
147-
load_vm_image(dtb_path, GuestPhysAddr::from(dtb_load_addr), vm.clone())?;
182+
load_ranges.append(&mut load_vm_image(
183+
dtb_path,
184+
GuestPhysAddr::from(dtb_load_addr),
185+
vm.clone(),
186+
)?);
148187
} else {
149188
return ax_err!(NotFound, "DTB load addr is missed");
150189
}
151190
};
152-
Ok(())
191+
Ok(load_ranges)
153192
}
154193

155-
fn load_vm_image(image_path: String, image_load_gpa: GuestPhysAddr, vm: VMRef) -> AxResult {
194+
fn load_vm_image(
195+
image_path: String,
196+
image_load_gpa: GuestPhysAddr,
197+
vm: VMRef,
198+
) -> AxResult<Vec<LoadRange>> {
156199
use std::io::{BufReader, Read};
157200
let (image_file, image_size) = open_image_file(image_path.as_str())?;
158201

159202
let image_load_regions = vm.get_image_load_region(image_load_gpa, image_size)?;
203+
let mut load_ranges = Vec::with_capacity(image_load_regions.len());
204+
160205
let mut file = BufReader::new(image_file);
161206

162207
for buffer in image_load_regions {
208+
load_ranges.push(LoadRange {
209+
start: (buffer.as_ptr() as usize).into(),
210+
size: buffer.len(),
211+
});
163212
file.read_exact(buffer).map_err(|err| {
164213
ax_err_type!(
165214
Io,
@@ -168,7 +217,7 @@ mod fs {
168217
})?
169218
}
170219

171-
Ok(())
220+
Ok(load_ranges)
172221
}
173222

174223
fn open_image_file(file_name: &str) -> AxResult<(File, usize)> {

0 commit comments

Comments
 (0)