Skip to content

Commit

Permalink
Use long mode
Browse files Browse the repository at this point in the history
Signed-off-by: Dan Schatzberg <schatzberg.dan@gmail.com>
  • Loading branch information
dschatzberg committed Jul 19, 2016
1 parent 71313a2 commit 299d99c
Showing 1 changed file with 104 additions and 9 deletions.
113 changes: 104 additions & 9 deletions tests/kvm/bin.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,17 @@
#![feature(linkage, naked_functions, asm)]
// In this example we will construct a single CPU x86 VM which will execute
// "inb 0x01" at ring 0 with paging disabled
// "inb 0x01" at ring 0

extern crate kvm;
extern crate memmap;
extern crate x86;

use kvm::{Capability, Exit, IoDirection, System, Vcpu, VirtualMachine};
use memmap::{Mmap, Protection};
use std::fs::File;
use std::io::{BufRead, BufReader};
use x86::current::paging::*;
use x86::shared::paging::*;

#[naked]
unsafe extern "C" fn use_the_port() {
Expand All @@ -16,6 +20,29 @@ unsafe extern "C" fn use_the_port() {

#[test]
fn io_example() {
let vaddr = VAddr::from_usize(&use_the_port as *const _ as _);
println!("{} {}", pml4_index(vaddr), pdpt_index(vaddr));
// set up a page table that identity maps the lower half of the address space
let mut anon_mmap = Mmap::anonymous(2 * (1 << 20), Protection::ReadWrite).unwrap();
let slice = unsafe { anon_mmap.as_mut_slice() };
let pml4: &mut PML4 = unsafe { ::std::mem::transmute(&mut slice[0x1000]) };
for i in 0..256 {
let offset = 0x2000 + 0x1000 * i;
pml4[i] = PML4Entry::new(PAddr::from_u64(offset as _), PML4_P | PML4_RW);
let pdpt: &mut PDPT = unsafe { ::std::mem::transmute(&mut slice[offset]) };
for j in 0..512 {
pdpt[j] = PDPTEntry::new(PAddr::from_u64(((512 * i + j) as u64) << 30),
PDPT_P | PDPT_RW | PDPT_PS);
if i == pml4_index(vaddr) && j == pdpt_index(vaddr) {
println!("{:?}", pml4[i].get_address());
println!("{:?}", pdpt[j].get_address());
}
}
}

slice[0x1f0000] = 0xe4;
slice[0x1f0001] = 0x01;

// Initialize the KVM system
let sys = System::initialize().unwrap();

Expand All @@ -24,20 +51,22 @@ fn io_example() {

// Ensure that the VM supports memory backing with user memory
assert!(vm.check_capability(Capability::UserMemory) > 0);
// Set the 2 MB range to start at physical address 0

vm.set_user_memory_region(0, slice, 0).unwrap();

let f = File::open("/proc/self/maps").unwrap();
let reader = BufReader::new(f);

for line in reader.lines() {
let line = line.unwrap();
println!("{}", line);
//println!("{}", line);
let mut s = line.split(' ');
let mut s2 = s.next().unwrap().split('-');
let begin = usize::from_str_radix(s2.next().unwrap(), 16).unwrap();
let end = usize::from_str_radix(s2.next().unwrap(), 16).unwrap();
if end < 0x800000000000 {
let perm = s.next().unwrap();
println!("{:#X}-{:#X} {}", begin, end, perm);
//println!("{:#X}-{:#X} {}", begin, end, perm);
let slice = {
let begin_ptr: *mut u8 = begin as *const u8 as _;
unsafe { ::std::slice::from_raw_parts_mut(begin_ptr, end - begin) }
Expand Down Expand Up @@ -65,22 +94,88 @@ fn io_example() {
sregs.cs.dpl = 0;
sregs.cs.db = 0;
sregs.cs.s = 1;
sregs.cs.l = 0;
sregs.cs.l = 1;
sregs.cs.g = 1;
sregs.cs.avl = 0;

sregs.ss.base = 0x0;
sregs.ss.limit = 0xffffffff;
sregs.ss.selector = 0;
sregs.ss._type = 0;
sregs.ss.present = 0;
sregs.ss.dpl = 0;
sregs.ss.db = 1;
sregs.ss.s = 0;
sregs.ss.l = 0;
sregs.ss.g = 1;
sregs.ss.avl = 0;

sregs.ds.base = 0x0;
sregs.ds.limit = 0xffffffff;
sregs.ds.selector = 0;
sregs.ds._type = 0;
sregs.ds.present = 0;
sregs.ds.dpl = 0;
sregs.ds.db = 1;
sregs.ds.s = 0;
sregs.ds.l = 0;
sregs.ds.g = 1;
sregs.ds.avl = 0;

sregs.es.base = 0x0;
sregs.es.limit = 0xffffffff;
sregs.es.selector = 0;
sregs.es._type = 0;
sregs.es.present = 0;
sregs.es.dpl = 0;
sregs.es.db = 1;
sregs.es.s = 0;
sregs.es.l = 0;
sregs.es.g = 1;
sregs.es.avl = 0;

sregs.fs.base = 0x0;
sregs.fs.base = 0x0;
sregs.fs.limit = 0xffffffff;
sregs.fs.selector = 0;
sregs.fs._type = 0;
sregs.fs.present = 0;
sregs.fs.dpl = 0;
sregs.fs.db = 1;
sregs.fs.s = 0;
sregs.fs.l = 0;
sregs.fs.g = 1;
sregs.fs.avl = 0;

sregs.gs.base = 0x0;
sregs.gs.limit = 0xffffffff;
sregs.gs.selector = 0;
sregs.gs._type = 0;
sregs.gs.present = 0;
sregs.gs.dpl = 0;
sregs.gs.db = 1;
sregs.gs.s = 0;
sregs.gs.l = 0;
sregs.gs.g = 1;
sregs.gs.avl = 0;

// We don't need to populate the GDT if we have our segments setup
// cr0 - protected mode on, paging disabled
sregs.cr0 = 0x50033;
// cr0 - protected mode on, paging enabled
sregs.cr0 = 0x80050033;
sregs.cr3 = 0x1000;
sregs.cr4 = 0x1406b0;
sregs.efer = 0xd01;

// Set the special registers
vcpu.set_sregs(&sregs).unwrap();

let mut regs = vcpu.get_regs().unwrap();
// set the instruction pointer to 1 MB
regs.rip = &use_the_port as *const _ as _;
//regs.rip = &use_the_port as *const _ as _;
regs.rip = 0x1f0000;
println!("regs.rip = {:X}", regs.rip);
regs.rflags = 0x2;
// regs.rflags = 0x2;
regs.rflags = 0x246;
vcpu.set_regs(&regs).unwrap();

// Actually run the VCPU
Expand Down

0 comments on commit 299d99c

Please sign in to comment.