@@ -36,6 +36,8 @@ pub enum Error {
36
36
WriteIDT ,
37
37
/// Writing PDPTE to RAM failed.
38
38
WritePDPTEAddress ,
39
+ /// Writing PDE to RAM failed.
40
+ WritePDEAddress ,
39
41
/// Writing PML4 to RAM failed.
40
42
WritePML4Address ,
41
43
}
@@ -193,11 +195,24 @@ fn setup_page_tables(mem: &GuestMemory, sregs: &mut kvm_sregs) -> Result<()> {
193
195
// Puts PML4 right after zero page but aligned to 4k.
194
196
let boot_pml4_addr = GuestAddress ( layout:: PML4_START ) ;
195
197
let boot_pdpte_addr = GuestAddress ( layout:: PDPTE_START ) ;
198
+ let boot_pde_addr = GuestAddress ( layout:: PDE_START ) ;
196
199
200
+ // Entry covering VA [0..512GB)
197
201
mem. write_obj_at_addr ( boot_pdpte_addr. offset ( ) as u64 | 0x03 , boot_pml4_addr)
198
202
. map_err ( |_| Error :: WritePML4Address ) ?;
199
- mem. write_obj_at_addr ( 0x83u64 , boot_pdpte_addr)
203
+
204
+ // Entry covering VA [0..1GB)
205
+ mem. write_obj_at_addr ( boot_pde_addr. offset ( ) as u64 | 0x03 , boot_pdpte_addr)
200
206
. map_err ( |_| Error :: WritePDPTEAddress ) ?;
207
+ // 512 2MB entries together covering VA [0..1GB). Note we are assuming
208
+ // CPU supports 2MB pages (/proc/cpuinfo has 'pse'). All modern CPUs do.
209
+ for i in 0 ..512 {
210
+ mem. write_obj_at_addr (
211
+ ( i << 21 ) + 0x83u64 ,
212
+ boot_pde_addr. unchecked_add ( ( i * 8 ) as usize ) ,
213
+ ) . map_err ( |_| Error :: WritePDEAddress ) ?;
214
+ }
215
+
201
216
sregs. cr3 = boot_pml4_addr. offset ( ) as u64 ;
202
217
sregs. cr4 |= X86_CR4_PAE ;
203
218
sregs. cr0 |= X86_CR0_PG ;
@@ -310,7 +325,13 @@ mod tests {
310
325
setup_page_tables ( & gm, & mut sregs) . unwrap ( ) ;
311
326
312
327
assert_eq ! ( 0xa003 , read_u64( & gm, layout:: PML4_START ) ) ;
313
- assert_eq ! ( 0x83 , read_u64( & gm, layout:: PDPTE_START ) ) ;
328
+ assert_eq ! ( 0xb003 , read_u64( & gm, layout:: PDPTE_START ) ) ;
329
+ for i in 0 ..512 {
330
+ assert_eq ! (
331
+ ( i << 21 ) + 0x83u64 ,
332
+ read_u64( & gm, layout:: PDE_START + ( i * 8 ) as usize )
333
+ ) ;
334
+ }
314
335
315
336
assert_eq ! ( layout:: PML4_START as u64 , sregs. cr3) ;
316
337
assert_eq ! ( X86_CR4_PAE , sregs. cr4) ;
0 commit comments