@@ -22,8 +22,11 @@ use std::sync::LazyLock;
2222use mshv_bindings:: DebugRegisters ;
2323#[ cfg( gdb) ]
2424use mshv_bindings:: hv_message_type_HVMSG_X64_EXCEPTION_INTERCEPT;
25+ use mshv_bindings:: hv_message_type_HVMSG_X64_MSR_INTERCEPT;
26+ use mshv_bindings:: { XSave , mshv_install_intercept} ;
2527use mshv_bindings:: {
26- hv_message_type, hv_message_type_HVMSG_GPA_INTERCEPT, hv_message_type_HVMSG_UNMAPPED_GPA,
28+ hv_intercept_parameters, hv_intercept_type_HV_INTERCEPT_TYPE_X64_MSR_INDEX, hv_message_type,
29+ hv_message_type_HVMSG_GPA_INTERCEPT, hv_message_type_HVMSG_UNMAPPED_GPA,
2730 hv_message_type_HVMSG_X64_HALT, hv_message_type_HVMSG_X64_IO_PORT_INTERCEPT,
2831 hv_partition_property_code_HV_PARTITION_PROPERTY_SYNTHETIC_PROC_FEATURES,
2932 hv_partition_synthetic_processor_features, hv_register_assoc,
@@ -32,7 +35,9 @@ use mshv_bindings::{
3235use mshv_ioctls:: { Mshv , VcpuFd , VmFd } ;
3336use tracing:: { Span , instrument} ;
3437
35- use crate :: hypervisor:: regs:: { CommonFpu , CommonRegisters , CommonSpecialRegisters } ;
38+ use crate :: hypervisor:: regs:: {
39+ CommonDebugRegs , CommonFpu , CommonRegisters , CommonSpecialRegisters ,
40+ } ;
3641use crate :: hypervisor:: vm:: { Vm , VmExit } ;
3742use crate :: mem:: memory_region:: { MemoryRegion , MemoryRegionFlags } ;
3843use crate :: { Result , new_error} ;
@@ -83,8 +88,21 @@ impl MshvVm {
8388 vm_fd
8489 } ;
8590
86- let vcpu_fd = vm_fd. create_vcpu ( 0 ) ?;
91+ let intercept = mshv_install_intercept {
92+ access_type_mask : mshv_bindings:: HV_INTERCEPT_ACCESS_MASK_WRITE , // | mshv_bindings::HV_INTERCEPT_ACCESS_MASK_READ to work
93+ intercept_type : mshv_bindings:: hv_intercept_type_HV_INTERCEPT_TYPE_X64_MSR,
94+ intercept_parameter : Default :: default ( ) ,
95+ } ;
96+ vm_fd. install_intercept ( intercept) ?;
97+
98+ // let intercept = mshv_install_intercept {
99+ // access_type_mask: mshv_bindings::HV_INTERCEPT_ACCESS_MASK_NONE,
100+ // intercept_type: mshv_bindings::hv_intercept_type_HV_INTERCEPT_TYPE_X64_MSR,
101+ // intercept_parameter: Default::default(),
102+ // };
103+ // vm_fd.install_intercept(intercept)?;
87104
105+ let vcpu_fd = vm_fd. create_vcpu ( 0 ) ?;
88106 Ok ( Self { vm_fd, vcpu_fd } )
89107 }
90108}
@@ -116,12 +134,32 @@ impl Vm for MshvVm {
116134 Ok ( ( ) )
117135 }
118136
119- #[ cfg( crashdump) ]
120137 fn xsave ( & self ) -> Result < Vec < u8 > > {
121138 let xsave = self . vcpu_fd . get_xsave ( ) ?;
122139 Ok ( xsave. buffer . to_vec ( ) )
123140 }
124141
142+ fn set_xsave ( & self , xsave : & [ u32 ; 1024 ] ) -> Result < ( ) > {
143+ let mut buf = XSave :: default ( ) ;
144+ let ( prefix, bytes, suffix) = unsafe { xsave. align_to ( ) } ;
145+ assert ! ( prefix. is_empty( ) ) ;
146+ assert ! ( suffix. is_empty( ) ) ;
147+ buf. buffer . copy_from_slice ( bytes) ;
148+ self . vcpu_fd . set_xsave ( & buf) ?;
149+ Ok ( ( ) )
150+ }
151+
152+ fn debug_regs ( & self ) -> Result < CommonDebugRegs > {
153+ let debug_regs = self . vcpu_fd . get_debug_regs ( ) ?;
154+ Ok ( debug_regs. into ( ) )
155+ }
156+
157+ fn set_debug_regs ( & self , drs : & CommonDebugRegs ) -> Result < ( ) > {
158+ let mshv_debug_regs = drs. into ( ) ;
159+ self . vcpu_fd . set_debug_regs ( & mshv_debug_regs) ?;
160+ Ok ( ( ) )
161+ }
162+
125163 /// # Safety
126164 /// The caller must ensure that the memory region is valid and points to valid memory,
127165 /// and lives long enough for the VM to use it.
@@ -142,6 +180,7 @@ impl Vm for MshvVm {
142180 const IO_PORT : hv_message_type = hv_message_type_HVMSG_X64_IO_PORT_INTERCEPT;
143181 const UNMAPPED_GPA : hv_message_type = hv_message_type_HVMSG_UNMAPPED_GPA;
144182 const INVALID_GPA : hv_message_type = hv_message_type_HVMSG_GPA_INTERCEPT;
183+ const MSR : hv_message_type = hv_message_type_HVMSG_X64_MSR_INTERCEPT;
145184 #[ cfg( gdb) ]
146185 const EXCEPTION_INTERCEPT : hv_message_type = hv_message_type_HVMSG_X64_EXCEPTION_INTERCEPT;
147186
@@ -183,6 +222,17 @@ impl Vm for MshvVm {
183222 _ => VmExit :: Unknown ( "Unknown MMIO access" . to_string ( ) ) ,
184223 }
185224 }
225+ MSR => {
226+ let msr_message = m. to_msr_info ( ) . map_err ( mshv_ioctls:: MshvError :: from) ?;
227+ let read = msr_message. header . intercept_access_type ;
228+ let msr_number = msr_message. msr_number ;
229+ let rdx = msr_message. rdx ;
230+ let rax = msr_message. rax ;
231+ panic ! (
232+ "MSR access: msr_number=0x{:X}, read={}, rdx=0x{:X}, rax=0x{:X}" ,
233+ msr_number, read, rdx, rax
234+ ) ;
235+ }
186236 #[ cfg( gdb) ]
187237 EXCEPTION_INTERCEPT => {
188238 let exception_message = m
0 commit comments