Skip to content

Commit 39a7d13

Browse files
committed
mshv 'working'
Signed-off-by: Ludvig Liljenberg <[email protected]>
1 parent 2692982 commit 39a7d13

File tree

10 files changed

+613
-504
lines changed

10 files changed

+613
-504
lines changed

src/hyperlight_host/src/fpuregs.rs

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
use kvm_bindings::kvm_fpu;
2+
use mshv_bindings2::FloatingPointUnit;
3+
4+
#[derive(Debug, Default, Clone, Copy, PartialEq)]
5+
pub struct CommonFpu {
6+
pub fpr: [[u8; 16]; 8],
7+
pub fcw: u16,
8+
pub fsw: u16,
9+
pub ftwx: u8,
10+
pub pad1: u8,
11+
pub last_opcode: u16,
12+
pub last_ip: u64,
13+
pub last_dp: u64,
14+
pub xmm: [[u8; 16]; 16],
15+
pub mxcsr: u32,
16+
pub pad2: u32,
17+
}
18+
19+
impl From<CommonFpu> for kvm_fpu {
20+
fn from(common_fpu: CommonFpu) -> Self {
21+
kvm_fpu {
22+
fpr: common_fpu.fpr,
23+
fcw: common_fpu.fcw,
24+
fsw: common_fpu.fsw,
25+
ftwx: common_fpu.ftwx,
26+
pad1: common_fpu.pad1,
27+
last_opcode: common_fpu.last_opcode,
28+
last_ip: common_fpu.last_ip,
29+
last_dp: common_fpu.last_dp,
30+
xmm: common_fpu.xmm,
31+
mxcsr: common_fpu.mxcsr,
32+
pad2: common_fpu.pad2,
33+
}
34+
}
35+
}
36+
impl From<CommonFpu> for FloatingPointUnit {
37+
fn from(common_fpu: CommonFpu) -> FloatingPointUnit {
38+
FloatingPointUnit {
39+
fpr: common_fpu.fpr,
40+
fcw: common_fpu.fcw,
41+
fsw: common_fpu.fsw,
42+
ftwx: common_fpu.ftwx,
43+
pad1: common_fpu.pad1,
44+
last_opcode: common_fpu.last_opcode,
45+
last_ip: common_fpu.last_ip,
46+
last_dp: common_fpu.last_dp,
47+
xmm: common_fpu.xmm,
48+
mxcsr: common_fpu.mxcsr,
49+
pad2: common_fpu.pad2,
50+
}
51+
}
52+
}
53+
54+
impl From<kvm_fpu> for CommonFpu {
55+
fn from(kvm_fpu: kvm_fpu) -> Self {
56+
Self {
57+
fpr: kvm_fpu.fpr,
58+
fcw: kvm_fpu.fcw,
59+
fsw: kvm_fpu.fsw,
60+
ftwx: kvm_fpu.ftwx,
61+
pad1: kvm_fpu.pad1,
62+
last_opcode: kvm_fpu.last_opcode,
63+
last_ip: kvm_fpu.last_ip,
64+
last_dp: kvm_fpu.last_dp,
65+
xmm: kvm_fpu.xmm,
66+
mxcsr: kvm_fpu.mxcsr,
67+
pad2: kvm_fpu.pad2,
68+
}
69+
}
70+
}
71+
72+
impl From<FloatingPointUnit> for CommonFpu {
73+
fn from(mshv_fpu: FloatingPointUnit) -> Self {
74+
Self {
75+
fpr: mshv_fpu.fpr,
76+
fcw: mshv_fpu.fcw,
77+
fsw: mshv_fpu.fsw,
78+
ftwx: mshv_fpu.ftwx,
79+
pad1: mshv_fpu.pad1,
80+
last_opcode: mshv_fpu.last_opcode,
81+
last_ip: mshv_fpu.last_ip,
82+
last_dp: mshv_fpu.last_dp,
83+
xmm: mshv_fpu.xmm,
84+
mxcsr: mshv_fpu.mxcsr,
85+
pad2: mshv_fpu.pad2,
86+
}
87+
}
88+
}

src/hyperlight_host/src/hypervisor/hyperlight_vm.rs

Lines changed: 28 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
use crate::fpuregs::CommonFpu;
2+
use crate::sandbox::hypervisor::HypervisorType;
3+
use crate::sregs::{CommonSegmentRegister, CommonSpecialRegisters};
14
/*
25
Copyright 2024 The Hyperlight Authors.
36
@@ -20,9 +23,6 @@ use std::sync::{Arc, Mutex};
2023
#[cfg(gdb)]
2124
use std::sync::{Arc, Mutex};
2225

23-
use kvm_bindings::{kvm_fpu, kvm_regs, kvm_userspace_memory_region, KVM_MEM_READONLY};
24-
use kvm_ioctls::Cap::UserMemory;
25-
use kvm_ioctls::{Kvm, VcpuExit, VcpuFd, VmFd};
2626
use log::LevelFilter;
2727
use tracing::{instrument, Span};
2828

@@ -34,6 +34,7 @@ use super::handlers::DbgMemAccessHandlerWrapper;
3434
use super::handlers::{
3535
MemAccessHandlerCaller, MemAccessHandlerWrapper, OutBHandlerCaller, OutBHandlerWrapper,
3636
};
37+
use super::hyperv_linux::MshvVm;
3738
use super::kvm::KvmVm;
3839
use super::{
3940
HyperlightExit, HyperlightVm, CR0_AM, CR0_ET, CR0_MP, CR0_NE, CR0_PE, CR0_PG, CR0_WP,
@@ -43,7 +44,7 @@ use crate::hypervisor::hypervisor_handler::HypervisorHandler;
4344
use crate::mem::memory_region::{MemoryRegion, MemoryRegionFlags};
4445
use crate::mem::ptr::{GuestPtr, RawPtr};
4546
use crate::metrics::METRIC_GUEST_CANCELLATION;
46-
use crate::regs::Registers;
47+
use crate::regs::CommonRegisters;
4748
use crate::vm::Vm;
4849
#[cfg(gdb)]
4950
use crate::HyperlightError;
@@ -273,44 +274,35 @@ pub(super) struct HyperlightSandbox {
273274
}
274275

275276
impl HyperlightSandbox {
276-
/// Create a new instance of a `KVMDriver`, with only control registers
277-
/// set. Standard registers will not be set, and `initialise` must
278-
/// be called to do so.
279277
#[instrument(err(Debug), skip_all, parent = Span::current(), level = "Trace")]
280278
pub(super) fn new(
279+
hv: &HypervisorType,
281280
mem_regions: Vec<MemoryRegion>,
282281
pml4_addr: u64,
283282
entrypoint: u64,
284283
rsp: u64,
285284
#[cfg(gdb)] gdb_conn: Option<DebugCommChannel<DebugResponse, DebugMsg>>,
286285
) -> Result<Self> {
287-
let kvm_vm = KvmVm::new()?;
288-
289-
let perm_flags =
290-
MemoryRegionFlags::READ | MemoryRegionFlags::WRITE | MemoryRegionFlags::EXECUTE;
291-
292-
mem_regions.iter().enumerate().try_for_each(|(i, region)| {
293-
let perm_flags = perm_flags.intersection(region.flags);
294-
let kvm_region = kvm_userspace_memory_region {
295-
slot: i as u32,
296-
guest_phys_addr: region.guest_region.start as u64,
297-
memory_size: (region.guest_region.end - region.guest_region.start) as u64,
298-
userspace_addr: region.host_region.start as u64,
299-
flags: match perm_flags {
300-
MemoryRegionFlags::READ => KVM_MEM_READONLY,
301-
_ => 0, // normal, RWX
302-
},
303-
};
304-
unsafe { kvm_vm.map_memory_kvm(kvm_region) }
305-
})?;
286+
let vm: Box<dyn Vm> = match hv {
287+
HypervisorType::Kvm => Box::new(KvmVm::new()?),
288+
HypervisorType::Mshv => Box::new(MshvVm::new()?),
289+
_ => {
290+
return Err(new_error!("Unsupported hypervisor type"));
291+
}
292+
};
306293

307-
let mut sregs = kvm_vm.sregs_kvm()?;
294+
// Safety: We haven't called this before and the regions are valid
295+
unsafe {
296+
vm.map_memory(&mem_regions)?;
297+
}
298+
299+
let mut sregs = vm.get_sregs()?;
308300
sregs.cr3 = pml4_addr;
309301
sregs.cr4 = CR4_PAE | CR4_OSFXSR | CR4_OSXMMEXCPT;
310302
sregs.cr0 = CR0_PE | CR0_MP | CR0_ET | CR0_NE | CR0_AM | CR0_PG | CR0_WP;
311303
sregs.efer = EFER_LME | EFER_LMA | EFER_SCE | EFER_NX;
312304
sregs.cs.l = 1; // required for 64-bit mode
313-
kvm_vm.set_sregs_kvm(&sregs)?;
305+
vm.set_sregs(&sregs)?;
314306

315307
#[cfg(gdb)]
316308
let (debug, gdb_conn) = if let Some(gdb_conn) = gdb_conn {
@@ -326,7 +318,7 @@ impl HyperlightSandbox {
326318
let rsp_gp = GuestPtr::try_from(RawPtr::from(rsp))?;
327319

328320
let ret = Self {
329-
vm: Box::new(kvm_vm),
321+
vm,
330322
entrypoint,
331323
orig_rsp: rsp_gp,
332324
mem_regions: mem_regions,
@@ -360,7 +352,7 @@ impl HyperlightVm for HyperlightSandbox {
360352
None => self.get_max_log_level().into(),
361353
};
362354

363-
let regs = Registers {
355+
let regs = CommonRegisters {
364356
rip: self.entrypoint,
365357
rsp: self.orig_rsp.absolute()?,
366358

@@ -395,21 +387,22 @@ impl HyperlightVm for HyperlightSandbox {
395387
#[cfg(gdb)] dbg_mem_access_fn: DbgMemAccessHandlerWrapper,
396388
) -> Result<()> {
397389
// Reset general purpose registers, then set RIP and RSP
398-
let regs = Registers {
390+
let regs = CommonRegisters {
399391
rip: dispatch_func_addr.into(),
400392
rsp: self.orig_rsp.absolute()?,
393+
rflags: 2,
401394
..Default::default()
402395
};
403396
self.vm.set_regs(&regs)?;
404397

405398
// reset fpu state
406-
let fpu = kvm_fpu {
399+
let fpu = CommonFpu {
407400
fcw: FP_CONTROL_WORD_DEFAULT,
408401
ftwx: FP_TAG_WORD_DEFAULT,
409402
mxcsr: MXCSR_DEFAULT,
410403
..Default::default() // zero out the rest
411404
};
412-
self.vm.set_fpu_regs(&fpu)?;
405+
self.vm.set_fpu(&fpu)?;
413406

414407
// run
415408
self.run(
@@ -428,8 +421,6 @@ impl HyperlightVm for HyperlightSandbox {
428421
&mut self,
429422
port: u16,
430423
data: Vec<u8>,
431-
_rip: u64,
432-
_instruction_length: u64,
433424
outb_handle_fn: OutBHandlerWrapper,
434425
) -> Result<()> {
435426
// KVM does not need RIP or instruction length, as it automatically sets the RIP
@@ -468,8 +459,8 @@ impl HyperlightVm for HyperlightSandbox {
468459
Ok(HyperlightExit::Halt()) => {
469460
break;
470461
}
471-
Ok(HyperlightExit::IoOut(port, data, rip, instruction_length)) => {
472-
self.handle_io(port, data, rip, instruction_length, outb_handle_fn.clone())?
462+
Ok(HyperlightExit::IoOut(port, data)) => {
463+
self.handle_io(port, data, outb_handle_fn.clone())?
473464
}
474465
Ok(HyperlightExit::MmioRead(addr)) => {
475466
match get_memory_access_violation(
@@ -574,11 +565,6 @@ impl HyperlightVm for HyperlightSandbox {
574565
Ok(())
575566
}
576567

577-
#[instrument(skip_all, parent = Span::current(), level = "Trace")]
578-
fn as_mut_hypervisor(&mut self) -> &mut dyn HyperlightVm {
579-
self as &mut dyn HyperlightVm
580-
}
581-
582568
#[cfg(crashdump)]
583569
fn get_memory_regions(&self) -> &[MemoryRegion] {
584570
&self.mem_regions

0 commit comments

Comments
 (0)