1+ use crate :: fpuregs:: CommonFpu ;
2+ use crate :: sandbox:: hypervisor:: HypervisorType ;
3+ use crate :: sregs:: { CommonSegmentRegister , CommonSpecialRegisters } ;
14/*
25Copyright 2024 The Hyperlight Authors.
36
@@ -20,9 +23,6 @@ use std::sync::{Arc, Mutex};
2023#[ cfg( gdb) ]
2124use 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 } ;
2626use log:: LevelFilter ;
2727use tracing:: { instrument, Span } ;
2828
@@ -34,6 +34,7 @@ use super::handlers::DbgMemAccessHandlerWrapper;
3434use super :: handlers:: {
3535 MemAccessHandlerCaller , MemAccessHandlerWrapper , OutBHandlerCaller , OutBHandlerWrapper ,
3636} ;
37+ use super :: hyperv_linux:: MshvVm ;
3738use super :: kvm:: KvmVm ;
3839use 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;
4344use crate :: mem:: memory_region:: { MemoryRegion , MemoryRegionFlags } ;
4445use crate :: mem:: ptr:: { GuestPtr , RawPtr } ;
4546use crate :: metrics:: METRIC_GUEST_CANCELLATION ;
46- use crate :: regs:: Registers ;
47+ use crate :: regs:: CommonRegisters ;
4748use crate :: vm:: Vm ;
4849#[ cfg( gdb) ]
4950use crate :: HyperlightError ;
@@ -273,44 +274,35 @@ pub(super) struct HyperlightSandbox {
273274}
274275
275276impl 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