diff --git a/tools/hermit_proxy/src/hermit/hermit_env.rs b/tools/hermit_proxy/src/hermit/hermit_env.rs index f4deb0bbe..d3b820449 100644 --- a/tools/hermit_proxy/src/hermit/hermit_env.rs +++ b/tools/hermit_proxy/src/hermit/hermit_env.rs @@ -22,7 +22,7 @@ pub fn mem_size() -> String { } pub fn mem_size_parsed() -> usize { - env::var("HERMIT_MEM").map(|x| utils::parse_mem(&x).unwrap_or(2*1000*1000)).unwrap_or(2*1000*1000) + env::var("HERMIT_MEM").map(|x| utils::parse_mem(&x).unwrap_or(512*1024*1024)).unwrap_or(512*1024*1024) } pub fn use_kvm() -> String { diff --git a/tools/hermit_proxy/src/hermit/uhyve/proto.rs b/tools/hermit_proxy/src/hermit/uhyve/proto.rs index e7e0c92b1..c2a72ca92 100644 --- a/tools/hermit_proxy/src/hermit/uhyve/proto.rs +++ b/tools/hermit_proxy/src/hermit/uhyve/proto.rs @@ -58,6 +58,7 @@ pub enum Syscall { Other(*const kvm_run) } +#[derive(Debug)] pub enum Return { Continue, Exit(i32) diff --git a/tools/hermit_proxy/src/hermit/uhyve/vcpu.rs b/tools/hermit_proxy/src/hermit/uhyve/vcpu.rs index ed857f49f..ad94b9519 100644 --- a/tools/hermit_proxy/src/hermit/uhyve/vcpu.rs +++ b/tools/hermit_proxy/src/hermit/uhyve/vcpu.rs @@ -75,38 +75,25 @@ impl VirtualCPU { kvm_fd: kvm_fd, vm_fd: vm_fd, vcpu_fd: fd, id: id, file: file, run_mem: run_mem, mboot: mboot, guest_mem: mem.mut_ptr() }; - cpu.set_mp_state(kvm_mp_state { mp_state: KVM_MP_STATE_RUNNABLE })?; - - if id == 0 { - debug!("Setup the first processor"); - - let mut mem = unsafe { - mem.as_mut_slice() - }; - - cpu.setup_first(&mut mem)?; - } - - - debug!("Initialize the register of {} with start address {:?}", id, entry); - - debug!("Set the CPUID"); cpu.setup_cpuid()?; + + debug!("Set MP state"); + + cpu.set_mp_state(kvm_mp_state { mp_state: KVM_MP_STATE_RUNNABLE })?; + + debug!("Initialize the register of {} with start address {:?}", id, entry); let mut regs = kvm_regs::empty(); regs.rip = entry; regs.rflags = 0x2; cpu.set_regs(regs)?; - Ok(cpu) } pub fn create_vcpu(fd: c_int, mut id: u32) -> Result { - let a = (&mut id) as *mut u32 as *mut u8; - unsafe { uhyve::ioctl::create_vcpu(fd, id as *mut u8) .map_err(|_| Error::IOCTL(NameIOCTL::CreateVcpu)) @@ -196,7 +183,10 @@ impl VirtualCPU { } unsafe { - proto::Syscall::from_mem(obj.run_mem.ptr(), obj.guest_mem).run(obj.guest_mem) + let a = proto::Syscall::from_mem(obj.run_mem.ptr(), obj.guest_mem).run(obj.guest_mem); + + debug!("{:?}", a); + a } } @@ -209,7 +199,7 @@ impl VirtualCPU { unsafe { while volatile_load(wrapped.mboot.offset(0x20)) < wrapped.id { thread::yield_now(); - debug!("{} - {}", wrapped.id, volatile_load(wrapped.mboot.offset(0x20))); + //debug!("{} - {}", wrapped.id, volatile_load(wrapped.mboot.offset(0x20))); } volatile_store(wrapped.mboot.offset(0x30), wrapped.id); @@ -226,28 +216,21 @@ impl VirtualCPU { child } - - pub fn setup_first(&self, mem: &mut [u8]) -> Result<()> { - // This is a fatal fault, so we will abort here - if self.id != 0 { - panic!("Shouldn't be called by any other processor than the first!"); - } - + + pub fn init_sregs(&self) -> Result { let mut sregs = self.get_sregs()?; debug!("Setup GDT"); - self.setup_system_gdt(&mut sregs, mem, 0)?; + self.setup_system_gdt(&mut sregs, 0)?; debug!("Setup the page table"); - self.setup_system_page_table(&mut sregs, mem)?; + self.setup_system_page_table(&mut sregs)?; debug!("Set the system to 64bit"); self.setup_system_64bit(&mut sregs)?; - self.set_sregs(sregs)?; - - Ok(()) + Ok(sregs) } - pub fn setup_system_gdt(&self, sregs: &mut kvm_sregs, mem: &mut [u8], offset: u64) -> Result<()> { + pub fn setup_system_gdt(&self, sregs: &mut kvm_sregs, offset: u64) -> Result<()> { let (mut data_seg, mut code_seg) = (kvm_segment::empty(), kvm_segment::empty()); // create the GDT entries @@ -256,8 +239,9 @@ impl VirtualCPU { let gdt_data = gdt::Entry::new(0xC093, 0, 0xFFFFF); // apply the new GDTs to our guest memory - let ptr = mem[offset as usize..].as_ptr() as *mut u64; unsafe { + let ptr = self.guest_mem.offset(offset as isize) as *mut u64; + *(ptr.offset(gdt::BOOT_NULL)) = gdt_null.as_u64(); *(ptr.offset(gdt::BOOT_CODE)) = gdt_code.as_u64(); *(ptr.offset(gdt::BOOT_DATA)) = gdt_data.as_u64(); @@ -277,16 +261,20 @@ impl VirtualCPU { Ok(()) } - pub fn setup_system_page_table(&self, sregs: &mut kvm_sregs, mem: &mut [u8]) -> Result<()> { - let pml4 = mem[BOOT_PML4..].as_ptr() as *mut u64; + pub fn setup_system_page_table(&self, sregs: &mut kvm_sregs) -> Result<()> { + /*let pml4 = mem[BOOT_PML4..].as_ptr() as *mut u64; let pdpte = mem[BOOT_PDPTE..].as_ptr() as *mut u64; - let pde = mem[BOOT_PDE..].as_ptr() as *mut u64; + let pde = mem[BOOT_PDE..].as_ptr() as *mut u64;*/ // TODO //assert!((guest_size & (GUEST_PAGE_SIZE - 1)) == 0); //assert!(guest_size <= (GUEST_PAGE_SIZE * 512)); unsafe { + let pml4 = self.guest_mem.offset(BOOT_PML4 as isize) as *mut u64; + let pdpte = self.guest_mem.offset(BOOT_PDPTE as isize) as *mut u64; + let pde = self.guest_mem.offset(BOOT_PDE as isize) as *mut u64; + libc::memset(pml4 as *mut c_void, 0x00, 4096); libc::memset(pdpte as *mut c_void, 0x00, 4096); libc::memset(pde as *mut c_void, 0x00, 4096); diff --git a/tools/hermit_proxy/src/hermit/uhyve/vm.rs b/tools/hermit_proxy/src/hermit/uhyve/vm.rs index c54c5d8db..0eb40edd7 100644 --- a/tools/hermit_proxy/src/hermit/uhyve/vm.rs +++ b/tools/hermit_proxy/src/hermit/uhyve/vm.rs @@ -13,7 +13,7 @@ use std::ffi::CStr; use hermit::hermit_env; use hermit::utils; use hermit::uhyve; -use super::kvm_header::{kvm_userspace_memory_region, KVM_CAP_SYNC_MMU, KVM_32BIT_GAP_START, KVM_32BIT_GAP_SIZE}; +use super::kvm_header::{kvm_userspace_memory_region, KVM_CAP_SYNC_MMU, KVM_32BIT_GAP_START, KVM_32BIT_GAP_SIZE, kvm_sregs}; use super::{Result, Error, NameIOCTL}; use super::vcpu::VirtualCPU; @@ -29,7 +29,8 @@ pub struct VirtualMachine { klog: Option<*const i8>, mboot: Option<*mut u8>, vcpus: Vec, - num_cpus: u32 + num_cpus: u32, + sregs: kvm_sregs } impl VirtualMachine { @@ -48,7 +49,7 @@ impl VirtualMachine { unsafe { libc::mprotect((mem.mut_ptr() as *mut libc::c_void).offset(KVM_32BIT_GAP_START as isize), KVM_32BIT_GAP_START, libc::PROT_NONE); } } - Ok(VirtualMachine { kvm_fd: kvm_fd, vm_fd: fd, mem: mem, elf_header: None, klog: None, vcpus: Vec::new(), mboot: None, num_cpus: num_cpus}) + Ok(VirtualMachine { kvm_fd: kvm_fd, vm_fd: fd, mem: mem, elf_header: None, klog: None, vcpus: Vec::new(), mboot: None, num_cpus: num_cpus, sregs: kvm_sregs::default()}) } /// Loads a kernel from path and initialite mem and elf_entry @@ -122,6 +123,7 @@ impl VirtualMachine { /// Initialize the virtual machine pub fn init(&mut self) -> Result<()> { let mut identity_base: u64 = 0xfffbc000; + if let Ok(true) = self.check_extension(KVM_CAP_SYNC_MMU) { identity_base = 0xfeffc000; @@ -155,7 +157,7 @@ impl VirtualMachine { Ok(()) } - + pub fn set_user_memory_region(&self, mut region: kvm_userspace_memory_region) -> Result<()> { unsafe { uhyve::ioctl::set_user_memory_region(self.vm_fd, (&mut region) as *mut kvm_userspace_memory_region) @@ -172,14 +174,14 @@ impl VirtualMachine { pub fn check_extension(&self, mut extension: u32) -> Result { unsafe { - uhyve::ioctl::check_extension(self.vm_fd, (&mut extension) as *mut u32 as *mut u8) - .map_err(|x| Error::IOCTL(NameIOCTL::CheckExtension)).map(|x| x == 1) + uhyve::ioctl::check_extension(self.vm_fd, extension as *mut u8) + .map_err(|x| Error::IOCTL(NameIOCTL::CheckExtension)).map(|x| x > 0) } } pub fn set_tss_identity(&self, identity_base: u64) -> Result<()> { unsafe { - uhyve::ioctl::set_identity_map_addr(self.kvm_fd, (&identity_base) as *const u64) + uhyve::ioctl::set_identity_map_addr(self.vm_fd, (&identity_base) as *const u64) .map_err(|x| Error::IOCTL(NameIOCTL::SetTssIdentity)).map(|_| ()) } } @@ -194,8 +196,14 @@ impl VirtualMachine { pub fn create_vcpu(&mut self, id: u8) -> Result<()> { let entry = self.elf_header.ok_or(Error::KernelNotLoaded)?.entry; - let cpu = VirtualCPU::new(self.kvm_fd, self.vm_fd, id, entry, &mut self.mem, self.mboot.unwrap())?; + let cpu = VirtualCPU::new(self.kvm_fd, self.vm_fd, id, entry, &mut self.mem,self.mboot.unwrap())?; + if id == 0 { + self.sregs = cpu.init_sregs()?; + } + + cpu.set_sregs(self.sregs)?; + let id = id as usize; self.vcpus.insert(id, cpu);