@@ -26,8 +26,8 @@ use windows_result::HRESULT;
2626#[ cfg( gdb) ]
2727use super :: handlers:: DbgMemAccessHandlerWrapper ;
2828use super :: regs:: {
29- WHP_FPU_NAMES , WHP_FPU_NAMES_LEN , WHP_REGS_NAMES , WHP_REGS_NAMES_LEN , WHP_SREGS_NAMES ,
30- WHP_SREGS_NAMES_LEN ,
29+ AlignedRegisterValues , WHP_FPU_NAMES , WHP_FPU_NAMES_LEN , WHP_REGS_NAMES , WHP_REGS_NAMES_LEN ,
30+ WHP_SREGS_NAMES , WHP_SREGS_NAMES_LEN ,
3131} ;
3232use super :: vm:: HyperlightExit ;
3333use super :: wrappers:: HandleWrapper ;
@@ -86,6 +86,15 @@ pub(crate) struct WhpVm {
8686unsafe impl Send for WhpVm { }
8787unsafe impl Sync for WhpVm { }
8888
89+ #[ repr( C , align( 16 ) ) ]
90+ struct Align16 < T > ( T ) ;
91+ const _: ( ) = {
92+ assert ! (
93+ std:: mem:: size_of:: <Align16 <WHV_REGISTER_VALUE >>( )
94+ == std:: mem:: size_of:: <WHV_REGISTER_VALUE >( )
95+ ) ;
96+ } ;
97+
8998impl WhpVm {
9099 pub ( crate ) fn new ( mmap_file_handle : HandleWrapper ) -> Result < Self > {
91100 const NUM_CPU : u32 = 1 ;
@@ -112,21 +121,29 @@ impl WhpVm {
112121 /// Helper for setting arbitrary registers.
113122 fn set_registers ( & self , registers : & [ ( WHV_REGISTER_NAME , WHV_REGISTER_VALUE ) ] ) -> Result < ( ) > {
114123 let register_count = registers. len ( ) ;
115- let mut register_names: Vec < WHV_REGISTER_NAME > = vec ! [ ] ;
116- let mut register_values: Vec < WHV_REGISTER_VALUE > = vec ! [ ] ;
124+
125+ // Prepare register names (no special alignment needed)
126+ let mut register_names = Vec :: with_capacity ( register_count) ;
127+ let mut register_values = Vec :: with_capacity ( register_count) ;
117128
118129 for ( key, value) in registers. iter ( ) {
119130 register_names. push ( * key) ;
120- register_values. push ( * value) ;
131+ register_values. push ( Align16 ( * value) ) ;
121132 }
122133
134+ assert_eq ! (
135+ ( register_values. as_ptr( ) as usize ) % 16 ,
136+ 0 ,
137+ "register_values is not 16-byte aligned"
138+ ) ;
139+
123140 unsafe {
124141 WHvSetVirtualProcessorRegisters (
125142 self . partition ,
126143 0 ,
127144 register_names. as_ptr ( ) ,
128145 register_count as u32 ,
129- register_values. as_ptr ( ) ,
146+ register_values. as_ptr ( ) as * const WHV_REGISTER_VALUE ,
130147 ) ?;
131148 }
132149
@@ -136,22 +153,24 @@ impl WhpVm {
136153
137154impl Vm for WhpVm {
138155 fn get_regs ( & self ) -> Result < CommonRegisters > {
139- let mut whv_regs_values: [ WHV_REGISTER_VALUE ; WHP_REGS_NAMES_LEN ] =
140- unsafe { std:: mem:: zeroed ( ) } ;
156+ let mut whv_regs_values =
157+ AlignedRegisterValues :: < WHP_REGS_NAMES_LEN > ( unsafe { std:: mem:: zeroed ( ) } ) ;
158+
159+ assert_eq ! ( ( whv_regs_values. 0 . as_ptr( ) as usize ) % 16 , 0 ) ;
141160
142161 unsafe {
143162 WHvGetVirtualProcessorRegisters (
144163 self . partition ,
145164 0 ,
146165 WHP_REGS_NAMES . as_ptr ( ) ,
147- WHP_REGS_NAMES_LEN as u32 ,
148- whv_regs_values. as_mut_ptr ( ) ,
166+ whv_regs_values . 0 . len ( ) as u32 ,
167+ whv_regs_values. 0 . as_mut_ptr ( ) ,
149168 ) ?;
150169 }
151170
152171 WHP_REGS_NAMES
153172 . into_iter ( )
154- . zip ( whv_regs_values)
173+ . zip ( whv_regs_values. 0 )
155174 . collect :: < Vec < ( WHV_REGISTER_NAME , WHV_REGISTER_VALUE ) > > ( )
156175 . as_slice ( )
157176 . try_into ( )
@@ -170,22 +189,24 @@ impl Vm for WhpVm {
170189 }
171190
172191 fn get_sregs ( & self ) -> Result < CommonSpecialRegisters > {
173- let mut whp_sregs_values: [ WHV_REGISTER_VALUE ; WHP_SREGS_NAMES_LEN ] =
174- unsafe { std:: mem:: zeroed ( ) } ;
192+ let mut whp_sregs_values =
193+ AlignedRegisterValues :: < WHP_SREGS_NAMES_LEN > ( unsafe { std:: mem:: zeroed ( ) } ) ;
194+
195+ assert_eq ! ( ( whp_sregs_values. 0 . as_ptr( ) as usize ) % 16 , 0 ) ;
175196
176197 unsafe {
177198 WHvGetVirtualProcessorRegisters (
178199 self . partition ,
179200 0 ,
180201 WHP_SREGS_NAMES . as_ptr ( ) ,
181- whp_sregs_values. len ( ) as u32 ,
182- whp_sregs_values. as_mut_ptr ( ) ,
202+ whp_sregs_values. 0 . len ( ) as u32 ,
203+ whp_sregs_values. 0 . as_mut_ptr ( ) ,
183204 ) ?;
184205 }
185206
186207 WHP_SREGS_NAMES
187208 . into_iter ( )
188- . zip ( whp_sregs_values)
209+ . zip ( whp_sregs_values. 0 )
189210 . collect :: < Vec < ( WHV_REGISTER_NAME , WHV_REGISTER_VALUE ) > > ( )
190211 . as_slice ( )
191212 . try_into ( )
@@ -204,22 +225,24 @@ impl Vm for WhpVm {
204225 }
205226
206227 fn get_fpu ( & self ) -> Result < CommonFpu > {
207- let mut whp_fpu_values: [ WHV_REGISTER_VALUE ; WHP_FPU_NAMES_LEN ] =
208- unsafe { std:: mem:: zeroed ( ) } ;
228+ let mut whp_fpu_values =
229+ AlignedRegisterValues :: < WHP_FPU_NAMES_LEN > ( unsafe { std:: mem:: zeroed ( ) } ) ;
230+
231+ assert_eq ! ( ( whp_fpu_values. 0 . as_ptr( ) as usize ) % 16 , 0 ) ;
209232
210233 unsafe {
211234 WHvGetVirtualProcessorRegisters (
212235 self . partition ,
213236 0 ,
214237 WHP_FPU_NAMES . as_ptr ( ) ,
215- whp_fpu_values. len ( ) as u32 ,
216- whp_fpu_values. as_mut_ptr ( ) ,
238+ whp_fpu_values. 0 . len ( ) as u32 ,
239+ whp_fpu_values. 0 . as_mut_ptr ( ) ,
217240 ) ?;
218241 }
219242
220243 WHP_FPU_NAMES
221244 . into_iter ( )
222- . zip ( whp_fpu_values)
245+ . zip ( whp_fpu_values. 0 )
223246 . collect :: < Vec < ( WHV_REGISTER_NAME , WHV_REGISTER_VALUE ) > > ( )
224247 . as_slice ( )
225248 . try_into ( )
0 commit comments