44
55extern crate kvm;
66extern crate memmap;
7+ extern crate x86;
78
89use kvm:: { Capability , Exit , IoDirection , System , Vcpu , VirtualMachine } ;
10+ use std:: mem;
11+ use memmap:: { Mmap , Protection } ;
912use std:: fs:: File ;
1013use std:: io:: { BufRead , BufReader } ;
1114
15+ use x86:: shared:: control_regs;
16+ use x86:: bits64:: paging;
17+
1218#[ naked]
1319unsafe extern "C" fn use_the_port ( ) {
1420 asm ! ( "inb $0, %al" :: "i" ( 0x01 ) :: "volatile" ) ;
@@ -71,13 +77,34 @@ fn io_example() {
7177
7278 // We don't need to populate the GDT if we have our segments setup
7379 // cr0 - protected mode on, paging disabled
74- sregs. cr0 = 0x50033 ;
80+
81+ let cr0 = control_regs:: CR0_ENABLE_PAGING | control_regs:: CR0_ALIGNMENT_MASK | control_regs:: CR0_WRITE_PROTECT | control_regs:: CR0_NUMERIC_ERROR | control_regs:: CR0_EXTENSION_TYPE | control_regs:: CR0_MONITOR_COPROCESSOR | control_regs:: CR0_PROTECTED_MODE ;
82+ sregs. cr0 = cr0. bits ( ) as u64 ;
83+
84+ let cr4 = control_regs:: CR4_ENABLE_GLOBAL_PAGES | control_regs:: CR4_ENABLE_PAE | control_regs:: CR4_ENABLE_PSE ;
85+ sregs. cr4 = cr4. bits ( ) as u64 ;
86+
87+ // Construct identity map
88+ let mut allocations = Vec :: with_capacity ( 512 +1 ) ;
89+ let mut pml4_mem = Mmap :: anonymous ( 4096 , Protection :: ReadWrite ) . unwrap ( ) ;
90+ let pml4 = unsafe { mem:: transmute :: < * mut u8 , & mut paging:: PML4 > ( pml4_mem. mut_ptr ( ) ) } ;
91+ allocations. push ( pml4_mem) ;
92+ for i in 0 ..512 {
93+ let mut pdpt_mem = Mmap :: anonymous ( 4096 , Protection :: ReadWrite ) . unwrap ( ) ;
94+ let pdpt = unsafe { mem:: transmute :: < * mut u8 , & mut paging:: PDPT > ( pdpt_mem. mut_ptr ( ) ) } ;
95+ for j in 0 ..512 {
96+ let offset = j * ( 1024 * 1024 * 1024 ) + i * 512 * ( 1024 * 1024 * 1024 ) ;
97+ pdpt[ j] = paging:: PDPTEntry :: new ( paging:: PAddr :: from_u64 ( offset as u64 ) , paging:: PDPT_P | paging:: PDPT_RW | paging:: PDPT_PS ) ;
98+ }
99+ pml4[ i] = paging:: PML4Entry :: new ( paging:: PAddr :: from_u64 ( pdpt as * const _ as u64 ) , paging:: PML4_P | paging:: PML4_RW ) ;
100+ allocations. push ( pdpt_mem) ;
101+ }
102+ sregs. cr3 = & pml4 as * const _ as _ ;
75103
76104 // Set the special registers
77105 vcpu. set_sregs ( & sregs) . unwrap ( ) ;
78106
79107 let mut regs = vcpu. get_regs ( ) . unwrap ( ) ;
80- // set the instruction pointer to 1 MB
81108 regs. rip = & use_the_port as * const _ as _ ;
82109 println ! ( "regs.rip = {:X}" , regs. rip) ;
83110 regs. rflags = 0x2 ;
@@ -88,6 +115,7 @@ fn io_example() {
88115
89116 // Ensure that the exit reason we get back indicates that the I/O
90117 // instruction was executed
118+ println ! ( "{:?}" , run) ;
91119 assert ! ( run. exit_reason == Exit :: Io ) ;
92120 let io = unsafe { * run. io ( ) } ;
93121 assert ! ( io. direction == IoDirection :: In ) ;
0 commit comments