1
+ use alloc:: vec:: Vec ;
2
+
1
3
use axaddrspace:: GuestPhysAddr ;
2
4
use axerrno:: AxResult ;
3
5
4
6
use axvm:: config:: AxVMCrateConfig ;
7
+ use memory_addr:: PhysAddr ;
5
8
6
- #[ cfg( target_arch = "aarch64" ) ]
7
- use crate :: utils:: cache:: cache_clean_invalidate_d;
8
9
use crate :: vmm:: VMRef ;
9
10
use crate :: vmm:: config:: config;
10
11
11
12
/// Loads the VM image files.
12
13
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 ( ) ) ,
15
16
#[ 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 ( ) ) ,
17
18
_ => unimplemented ! (
18
19
"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)"
19
20
) ,
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
+ }
20
31
}
21
32
}
22
33
34
+ struct LoadRange {
35
+ start : PhysAddr ,
36
+ size : usize ,
37
+ }
38
+
23
39
/// Load VM images from memory
24
40
/// 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 > > {
26
42
info ! ( "Loading VM[{}] images from memory" , config. base. id) ;
43
+ let mut load_ranges = Vec :: new ( ) ;
27
44
28
45
let vm_imags = config:: get_memory_images ( )
29
46
. iter ( )
30
47
. find ( |& v| v. id == config. base . id )
31
48
. expect ( "VM images is missed, Perhaps add `VM_CONFIGS=PATH/CONFIGS/FILE` command." ) ;
32
49
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
+ ) ;
35
54
36
55
// Load DTB image
37
56
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
+ ) ;
40
65
}
41
66
42
67
// Load BIOS image
43
68
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
+ ) ;
58
77
}
59
78
60
- Ok ( ( ) )
79
+ Ok ( load_ranges )
61
80
}
62
81
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 > > {
64
87
let mut buffer_pos = 0 ;
65
88
let image_load_gpa = GuestPhysAddr :: from ( load_addr) ;
89
+ let mut load_ranges = alloc:: vec![ ] ;
66
90
67
91
let image_size = image_buffer. len ( ) ;
68
92
@@ -86,7 +110,10 @@ fn load_vm_image_from_memory(image_buffer: &[u8], load_addr: usize, vm: VMRef) -
86
110
bytes_to_write,
87
111
) ;
88
112
}
89
-
113
+ load_ranges. push ( LoadRange {
114
+ start : ( region. as_ptr ( ) as usize ) . into ( ) ,
115
+ size : bytes_to_write,
116
+ } ) ;
90
117
// Update the position of the buffer.
91
118
buffer_pos += bytes_to_write;
92
119
@@ -97,7 +124,7 @@ fn load_vm_image_from_memory(image_buffer: &[u8], load_addr: usize, vm: VMRef) -
97
124
}
98
125
}
99
126
100
- Ok ( ( ) )
127
+ Ok ( load_ranges )
101
128
}
102
129
103
130
#[ cfg( feature = "fs" ) ]
@@ -112,30 +139,38 @@ mod fs {
112
139
113
140
/// Loads the VM image files from the filesystem
114
141
/// 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 > > {
116
146
info ! ( "Loading VM images from filesystem" ) ;
147
+ let mut load_ranges = Vec :: new ( ) ;
117
148
// Load kernel image.
118
- load_vm_image (
149
+ load_ranges . append ( & mut load_vm_image (
119
150
config. kernel . kernel_path ,
120
151
GuestPhysAddr :: from ( config. kernel . kernel_load_addr ) ,
121
152
vm. clone ( ) ,
122
- ) ?;
153
+ ) ?) ;
123
154
// Load BIOS image if needed.
124
155
if let Some ( bios_path) = config. kernel . bios_path {
125
156
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
+ ) ?) ;
127
162
} else {
128
163
return ax_err ! ( NotFound , "BIOS load addr is missed" ) ;
129
164
}
130
165
} ;
131
166
// Load Ramdisk image if needed.
132
167
if let Some ( ramdisk_path) = config. kernel . ramdisk_path {
133
168
if let Some ( ramdisk_load_addr) = config. kernel . ramdisk_load_addr {
134
- load_vm_image (
169
+ load_ranges . append ( & mut load_vm_image (
135
170
ramdisk_path,
136
171
GuestPhysAddr :: from ( ramdisk_load_addr) ,
137
172
vm. clone ( ) ,
138
- ) ?;
173
+ ) ?) ;
139
174
} else {
140
175
return ax_err ! ( NotFound , "Ramdisk load addr is missed" ) ;
141
176
}
@@ -144,22 +179,36 @@ mod fs {
144
179
// Todo: generate DTB file for guest VM.
145
180
if let Some ( dtb_path) = config. kernel . dtb_path {
146
181
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
+ ) ?) ;
148
187
} else {
149
188
return ax_err ! ( NotFound , "DTB load addr is missed" ) ;
150
189
}
151
190
} ;
152
- Ok ( ( ) )
191
+ Ok ( load_ranges )
153
192
}
154
193
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 > > {
156
199
use std:: io:: { BufReader , Read } ;
157
200
let ( image_file, image_size) = open_image_file ( image_path. as_str ( ) ) ?;
158
201
159
202
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
+
160
205
let mut file = BufReader :: new ( image_file) ;
161
206
162
207
for buffer in image_load_regions {
208
+ load_ranges. push ( LoadRange {
209
+ start : ( buffer. as_ptr ( ) as usize ) . into ( ) ,
210
+ size : buffer. len ( ) ,
211
+ } ) ;
163
212
file. read_exact ( buffer) . map_err ( |err| {
164
213
ax_err_type ! (
165
214
Io ,
@@ -168,7 +217,7 @@ mod fs {
168
217
} ) ?
169
218
}
170
219
171
- Ok ( ( ) )
220
+ Ok ( load_ranges )
172
221
}
173
222
174
223
fn open_image_file ( file_name : & str ) -> AxResult < ( File , usize ) > {
0 commit comments