@@ -31,9 +31,8 @@ use log::error;
3131use mshv_bindings:: hv_message;
3232use mshv_bindings:: {
3333 hv_message_type, hv_message_type_HVMSG_GPA_INTERCEPT, hv_message_type_HVMSG_UNMAPPED_GPA,
34- hv_message_type_HVMSG_X64_HALT, hv_message_type_HVMSG_X64_IO_PORT_INTERCEPT, hv_register_assoc,
35- hv_register_name_HV_X64_REGISTER_RIP, hv_register_value, mshv_user_mem_region,
36- FloatingPointUnit , SegmentRegister , SpecialRegisters , StandardRegisters ,
34+ hv_message_type_HVMSG_X64_HALT, hv_message_type_HVMSG_X64_IO_PORT_INTERCEPT, mshv_user_mem_region,
35+ SegmentRegister , SpecialRegisters , StandardRegisters ,
3736} ;
3837#[ cfg( mshv3) ]
3938use mshv_bindings:: {
@@ -43,19 +42,18 @@ use mshv_bindings::{
4342use mshv_ioctls:: { Mshv , VcpuFd , VmFd } ;
4443use tracing:: { instrument, Span } ;
4544
46- use super :: fpu:: { FP_CONTROL_WORD_DEFAULT , FP_TAG_WORD_DEFAULT , MXCSR_DEFAULT } ;
4745#[ cfg( gdb) ]
4846use super :: handlers:: DbgMemAccessHandlerWrapper ;
49- use super :: handlers:: { MemAccessHandlerWrapper , OutBHandlerWrapper } ;
47+ use super :: handlers:: MemAccessHandlerWrapper ;
5048use super :: {
5149 Hypervisor , VirtualCPU , CR0_AM , CR0_ET , CR0_MP , CR0_NE , CR0_PE , CR0_PG , CR0_WP , CR4_OSFXSR ,
5250 CR4_OSXMMEXCPT , CR4_PAE , EFER_LMA , EFER_LME , EFER_NX , EFER_SCE ,
5351} ;
5452use crate :: hypervisor:: hypervisor_handler:: HypervisorHandler ;
5553use crate :: hypervisor:: HyperlightExit ;
5654use crate :: mem:: memory_region:: { MemoryRegion , MemoryRegionFlags } ;
57- use crate :: mem:: ptr:: { GuestPtr , RawPtr } ;
58- use crate :: { log_then_return, new_error , Result } ;
55+ use crate :: mem:: ptr:: GuestPtr ;
56+ use crate :: { log_then_return, Result } ;
5957
6058/// Determine whether the HyperV for Linux hypervisor API is present
6159/// and functional.
@@ -199,10 +197,9 @@ impl Hypervisor for HypervLinuxDriver {
199197 #[ instrument( err( Debug ) , skip_all, parent = Span :: current( ) , level = "Trace" ) ]
200198 fn initialise (
201199 & mut self ,
202- peb_addr : RawPtr ,
203- seed : u64 ,
200+ custom_guest_memory_region_addr : u64 ,
201+ custom_guest_memory_region_size : u64 ,
204202 page_size : u32 ,
205- outb_hdl : OutBHandlerWrapper ,
206203 mem_access_hdl : MemAccessHandlerWrapper ,
207204 hv_handler : Option < HypervisorHandler > ,
208205 #[ cfg( gdb) ] dbg_mem_access_fn : DbgMemAccessHandlerWrapper ,
@@ -213,8 +210,8 @@ impl Hypervisor for HypervLinuxDriver {
213210 rflags : 2 , //bit 1 of rlags is required to be set
214211
215212 // function args
216- rcx : peb_addr . into ( ) ,
217- rdx : seed ,
213+ rcx : custom_guest_memory_region_addr . into ( ) ,
214+ rdx : custom_guest_memory_region_size . into ( ) ,
218215 r8 : page_size. into ( ) ,
219216 r9 : self . get_max_log_level ( ) . into ( ) ,
220217
@@ -225,7 +222,6 @@ impl Hypervisor for HypervLinuxDriver {
225222 VirtualCPU :: run (
226223 self . as_mut_hypervisor ( ) ,
227224 hv_handler,
228- outb_hdl,
229225 mem_access_hdl,
230226 #[ cfg( gdb) ]
231227 dbg_mem_access_fn,
@@ -240,78 +236,79 @@ impl Hypervisor for HypervLinuxDriver {
240236 Ok ( ( ) )
241237 }
242238
243- #[ instrument( err( Debug ) , skip_all, parent = Span :: current( ) , level = "Trace" ) ]
244- fn dispatch_call_from_host (
245- & mut self ,
246- dispatch_func_addr : RawPtr ,
247- outb_handle_fn : OutBHandlerWrapper ,
248- mem_access_fn : MemAccessHandlerWrapper ,
249- hv_handler : Option < HypervisorHandler > ,
250- #[ cfg( gdb) ] dbg_mem_access_fn : DbgMemAccessHandlerWrapper ,
251- ) -> Result < ( ) > {
252- // Reset general purpose registers except RSP, then set RIP
253- let rsp_before = self . vcpu_fd . get_regs ( ) ?. rsp ;
254- let regs = StandardRegisters {
255- rip : dispatch_func_addr. into ( ) ,
256- rsp : rsp_before,
257- rflags : 2 , //bit 1 of rlags is required to be set
258- ..Default :: default ( )
259- } ;
260- self . vcpu_fd . set_regs ( & regs) ?;
261-
262- // reset fpu state
263- let fpu = FloatingPointUnit {
264- fcw : FP_CONTROL_WORD_DEFAULT ,
265- ftwx : FP_TAG_WORD_DEFAULT ,
266- mxcsr : MXCSR_DEFAULT ,
267- ..Default :: default ( ) // zero out the rest
268- } ;
269- self . vcpu_fd . set_fpu ( & fpu) ?;
270-
271- // run
272- VirtualCPU :: run (
273- self . as_mut_hypervisor ( ) ,
274- hv_handler,
275- outb_handle_fn,
276- mem_access_fn,
277- #[ cfg( gdb) ]
278- dbg_mem_access_fn,
279- ) ?;
280-
281- // reset RSP to what it was before function call
282- self . vcpu_fd . set_regs ( & StandardRegisters {
283- rsp : rsp_before,
284- rflags : 2 , //bit 1 of rlags is required to be set
285- ..Default :: default ( )
286- } ) ?;
287- Ok ( ( ) )
288- }
289-
290- #[ instrument( err( Debug ) , skip_all, parent = Span :: current( ) , level = "Trace" ) ]
291- fn handle_io (
292- & mut self ,
293- port : u16 ,
294- data : Vec < u8 > ,
295- rip : u64 ,
296- instruction_length : u64 ,
297- outb_handle_fn : OutBHandlerWrapper ,
298- ) -> Result < ( ) > {
299- let payload = data[ ..8 ] . try_into ( ) ?;
300- outb_handle_fn
301- . try_lock ( )
302- . map_err ( |e| new_error ! ( "Error locking at {}:{}: {}" , file!( ) , line!( ) , e) ) ?
303- . call ( port, u64:: from_le_bytes ( payload) ) ?;
304-
305- // update rip
306- self . vcpu_fd . set_reg ( & [ hv_register_assoc {
307- name : hv_register_name_HV_X64_REGISTER_RIP,
308- value : hv_register_value {
309- reg64 : rip + instruction_length,
310- } ,
311- ..Default :: default ( )
312- } ] ) ?;
313- Ok ( ( ) )
314- }
239+ // TODO(danbugs:297): bring back
240+ // #[instrument(err(Debug), skip_all, parent = Span::current(), level = "Trace")]
241+ // fn dispatch_call_from_host(
242+ // &mut self,
243+ // dispatch_func_addr: RawPtr,
244+ // outb_handle_fn: OutBHandlerWrapper,
245+ // mem_access_fn: MemAccessHandlerWrapper,
246+ // hv_handler: Option<HypervisorHandler>,
247+ // #[cfg(gdb)] dbg_mem_access_fn: DbgMemAccessHandlerWrapper,
248+ // ) -> Result<()> {
249+ // // Reset general purpose registers except RSP, then set RIP
250+ // let rsp_before = self.vcpu_fd.get_regs()?.rsp;
251+ // let regs = StandardRegisters {
252+ // rip: dispatch_func_addr.into(),
253+ // rsp: rsp_before,
254+ // rflags: 2, //bit 1 of rlags is required to be set
255+ // ..Default::default()
256+ // };
257+ // self.vcpu_fd.set_regs(®s)?;
258+ //
259+ // // reset fpu state
260+ // let fpu = FloatingPointUnit {
261+ // fcw: FP_CONTROL_WORD_DEFAULT,
262+ // ftwx: FP_TAG_WORD_DEFAULT,
263+ // mxcsr: MXCSR_DEFAULT,
264+ // ..Default::default() // zero out the rest
265+ // };
266+ // self.vcpu_fd.set_fpu(&fpu)?;
267+ //
268+ // // run
269+ // VirtualCPU::run(
270+ // self.as_mut_hypervisor(),
271+ // hv_handler,
272+ // outb_handle_fn,
273+ // mem_access_fn,
274+ // #[cfg(gdb)]
275+ // dbg_mem_access_fn,
276+ // )?;
277+ //
278+ // // reset RSP to what it was before function call
279+ // self.vcpu_fd.set_regs(&StandardRegisters {
280+ // rsp: rsp_before,
281+ // rflags: 2, //bit 1 of rlags is required to be set
282+ // ..Default::default()
283+ // })?;
284+ // Ok(())
285+ // }
286+ //
287+ // #[instrument(err(Debug), skip_all, parent = Span::current(), level = "Trace")]
288+ // fn handle_io(
289+ // &mut self,
290+ // port: u16,
291+ // data: Vec<u8>,
292+ // rip: u64,
293+ // instruction_length: u64,
294+ // outb_handle_fn: OutBHandlerWrapper,
295+ // ) -> Result<()> {
296+ // let payload = data[..8].try_into()?;
297+ // outb_handle_fn
298+ // .try_lock()
299+ // .map_err(|e| new_error!("Error locking at {}:{}: {}", file!(), line!(), e))?
300+ // .call(port, u64::from_le_bytes(payload))?;
301+ //
302+ // // update rip
303+ // self.vcpu_fd.set_reg(&[hv_register_assoc {
304+ // name: hv_register_name_HV_X64_REGISTER_RIP,
305+ // value: hv_register_value {
306+ // reg64: rip + instruction_length,
307+ // },
308+ // ..Default::default()
309+ // }])?;
310+ // Ok(())
311+ // }
315312
316313 #[ instrument( err( Debug ) , skip_all, parent = Span :: current( ) , level = "Trace" ) ]
317314 fn run ( & mut self ) -> Result < super :: HyperlightExit > {
@@ -419,57 +416,58 @@ impl Drop for HypervLinuxDriver {
419416 }
420417}
421418
422- #[ cfg( test) ]
423- mod tests {
424- use super :: * ;
425- use crate :: mem:: memory_region:: MemoryRegionVecBuilder ;
426- use crate :: mem:: shared_mem:: { ExclusiveSharedMemory , SharedMemory } ;
427-
428- #[ rustfmt:: skip]
429- const CODE : [ u8 ; 12 ] = [
430- 0xba , 0xf8 , 0x03 , /* mov $0x3f8, %dx */
431- 0x00 , 0xd8 , /* add %bl, %al */
432- 0x04 , b'0' , /* add $'0', %al */
433- 0xee , /* out %al, (%dx) */
434- /* send a 0 to indicate we're done */
435- 0xb0 , b'\0' , /* mov $'\0', %al */
436- 0xee , /* out %al, (%dx) */
437- 0xf4 , /* HLT */
438- ] ;
439-
440- fn shared_mem_with_code (
441- code : & [ u8 ] ,
442- mem_size : usize ,
443- load_offset : usize ,
444- ) -> Result < Box < ExclusiveSharedMemory > > {
445- if load_offset > mem_size {
446- log_then_return ! (
447- "code load offset ({}) > memory size ({})" ,
448- load_offset,
449- mem_size
450- ) ;
451- }
452- let mut shared_mem = ExclusiveSharedMemory :: new ( mem_size) ?;
453- shared_mem. copy_from_slice ( code, load_offset) ?;
454- Ok ( Box :: new ( shared_mem) )
455- }
456-
457- #[ test]
458- fn create_driver ( ) {
459- if !super :: is_hypervisor_present ( ) {
460- return ;
461- }
462- const MEM_SIZE : usize = 0x3000 ;
463- let gm = shared_mem_with_code ( CODE . as_slice ( ) , MEM_SIZE , 0 ) . unwrap ( ) ;
464- let rsp_ptr = GuestPtr :: try_from ( 0 ) . unwrap ( ) ;
465- let pml4_ptr = GuestPtr :: try_from ( 0 ) . unwrap ( ) ;
466- let entrypoint_ptr = GuestPtr :: try_from ( 0 ) . unwrap ( ) ;
467- let mut regions = MemoryRegionVecBuilder :: new ( 0 , gm. base_addr ( ) ) ;
468- regions. push_page_aligned (
469- MEM_SIZE ,
470- MemoryRegionFlags :: READ | MemoryRegionFlags :: WRITE | MemoryRegionFlags :: EXECUTE ,
471- crate :: mem:: memory_region:: MemoryRegionType :: Code ,
472- ) ;
473- super :: HypervLinuxDriver :: new ( regions. build ( ) , entrypoint_ptr, rsp_ptr, pml4_ptr) . unwrap ( ) ;
474- }
475- }
419+ // TODO(danbugs:297): bring back
420+ // #[cfg(test)]
421+ // mod tests {
422+ // use super::*;
423+ // use crate::mem::memory_region::MemoryRegionVecBuilder;
424+ // use crate::mem::shared_mem::{ExclusiveSharedMemory, SharedMemory};
425+ //
426+ // #[rustfmt::skip]
427+ // const CODE: [u8; 12] = [
428+ // 0xba, 0xf8, 0x03, /* mov $0x3f8, %dx */
429+ // 0x00, 0xd8, /* add %bl, %al */
430+ // 0x04, b'0', /* add $'0', %al */
431+ // 0xee, /* out %al, (%dx) */
432+ // /* send a 0 to indicate we're done */
433+ // 0xb0, b'\0', /* mov $'\0', %al */
434+ // 0xee, /* out %al, (%dx) */
435+ // 0xf4, /* HLT */
436+ // ];
437+ //
438+ // fn shared_mem_with_code(
439+ // code: &[u8],
440+ // mem_size: usize,
441+ // load_offset: usize,
442+ // ) -> Result<Box<ExclusiveSharedMemory>> {
443+ // if load_offset > mem_size {
444+ // log_then_return!(
445+ // "code load offset ({}) > memory size ({})",
446+ // load_offset,
447+ // mem_size
448+ // );
449+ // }
450+ // let mut shared_mem = ExclusiveSharedMemory::new(mem_size)?;
451+ // shared_mem.copy_from_slice(code, load_offset)?;
452+ // Ok(Box::new(shared_mem))
453+ // }
454+ //
455+ // #[test]
456+ // fn create_driver() {
457+ // if !super::is_hypervisor_present() {
458+ // return;
459+ // }
460+ // const MEM_SIZE: usize = 0x3000;
461+ // let gm = shared_mem_with_code(CODE.as_slice(), MEM_SIZE, 0).unwrap();
462+ // let rsp_ptr = GuestPtr::try_from(0).unwrap();
463+ // let pml4_ptr = GuestPtr::try_from(0).unwrap();
464+ // let entrypoint_ptr = GuestPtr::try_from(0).unwrap();
465+ // let mut regions = MemoryRegionVecBuilder::new(0, gm.base_addr());
466+ // regions.push_page_aligned(
467+ // MEM_SIZE,
468+ // MemoryRegionFlags::READ | MemoryRegionFlags::WRITE | MemoryRegionFlags::EXECUTE,
469+ // crate::mem::memory_region::MemoryRegionType::Code,
470+ // );
471+ // super::HypervLinuxDriver::new(regions.build(), entrypoint_ptr, rsp_ptr, pml4_ptr).unwrap();
472+ // }
473+ // }
0 commit comments