mirror of
https://github.com/hermitcore/libhermit.git
synced 2025-03-09 00:00:03 +01:00
The sregs are now set properly for all cpus.
This commit is contained in:
parent
e7c08c271c
commit
bb5800abbe
4 changed files with 44 additions and 47 deletions
|
@ -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 {
|
||||
|
|
|
@ -58,6 +58,7 @@ pub enum Syscall {
|
|||
Other(*const kvm_run)
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum Return {
|
||||
Continue,
|
||||
Exit(i32)
|
||||
|
|
|
@ -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<c_int> {
|
||||
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<kvm_sregs> {
|
||||
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);
|
||||
|
|
|
@ -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<VirtualCPU>,
|
||||
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<bool> {
|
||||
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);
|
||||
|
|
Loading…
Add table
Reference in a new issue