@@ -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,18 @@ pub(crate) struct WhpVm {
8686unsafe impl Send for WhpVm { }
8787unsafe impl Sync for WhpVm { }
8888
89+ /// WHV_REGISTER_VALUE must be 16-byte aligned, but the rust struct is incorrectly generated
90+ /// as 8-byte aligned. This is a workaround to ensure that the struct is 16-byte aligned.
91+ #[ repr( C , align( 16 ) ) ]
92+ struct Align16 < T > ( T ) ;
93+ #[ allow( clippy:: disallowed_macros) ] // compile time
94+ const _: ( ) = {
95+ assert ! (
96+ std:: mem:: size_of:: <Align16 <WHV_REGISTER_VALUE >>( )
97+ == std:: mem:: size_of:: <WHV_REGISTER_VALUE >( )
98+ ) ;
99+ } ;
100+
89101impl WhpVm {
90102 pub ( crate ) fn new ( mmap_file_handle : HandleWrapper ) -> Result < Self > {
91103 const NUM_CPU : u32 = 1 ;
@@ -112,12 +124,14 @@ impl WhpVm {
112124 /// Helper for setting arbitrary registers.
113125 fn set_registers ( & self , registers : & [ ( WHV_REGISTER_NAME , WHV_REGISTER_VALUE ) ] ) -> Result < ( ) > {
114126 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 ! [ ] ;
127+
128+ // Prepare register names (no special alignment needed)
129+ let mut register_names = Vec :: with_capacity ( register_count) ;
130+ let mut register_values = Vec :: with_capacity ( register_count) ;
117131
118132 for ( key, value) in registers. iter ( ) {
119133 register_names. push ( * key) ;
120- register_values. push ( * value) ;
134+ register_values. push ( Align16 ( * value) ) ;
121135 }
122136
123137 unsafe {
@@ -126,7 +140,7 @@ impl WhpVm {
126140 0 ,
127141 register_names. as_ptr ( ) ,
128142 register_count as u32 ,
129- register_values. as_ptr ( ) ,
143+ register_values. as_ptr ( ) as * const WHV_REGISTER_VALUE ,
130144 ) ?;
131145 }
132146
@@ -136,22 +150,22 @@ impl WhpVm {
136150
137151impl Vm for WhpVm {
138152 fn get_regs ( & self ) -> Result < CommonRegisters > {
139- let mut whv_regs_values: [ WHV_REGISTER_VALUE ; WHP_REGS_NAMES_LEN ] =
140- unsafe { std:: mem:: zeroed ( ) } ;
153+ let mut whv_regs_values =
154+ AlignedRegisterValues :: < WHP_REGS_NAMES_LEN > ( unsafe { std:: mem:: zeroed ( ) } ) ;
141155
142156 unsafe {
143157 WHvGetVirtualProcessorRegisters (
144158 self . partition ,
145159 0 ,
146160 WHP_REGS_NAMES . as_ptr ( ) ,
147- WHP_REGS_NAMES_LEN as u32 ,
148- whv_regs_values. as_mut_ptr ( ) ,
161+ whv_regs_values . 0 . len ( ) as u32 ,
162+ whv_regs_values. 0 . as_mut_ptr ( ) ,
149163 ) ?;
150164 }
151165
152166 WHP_REGS_NAMES
153167 . into_iter ( )
154- . zip ( whv_regs_values)
168+ . zip ( whv_regs_values. 0 )
155169 . collect :: < Vec < ( WHV_REGISTER_NAME , WHV_REGISTER_VALUE ) > > ( )
156170 . as_slice ( )
157171 . try_into ( )
@@ -170,22 +184,22 @@ impl Vm for WhpVm {
170184 }
171185
172186 fn get_sregs ( & self ) -> Result < CommonSpecialRegisters > {
173- let mut whp_sregs_values: [ WHV_REGISTER_VALUE ; WHP_SREGS_NAMES_LEN ] =
174- unsafe { std:: mem:: zeroed ( ) } ;
187+ let mut whp_sregs_values =
188+ AlignedRegisterValues :: < WHP_SREGS_NAMES_LEN > ( unsafe { std:: mem:: zeroed ( ) } ) ;
175189
176190 unsafe {
177191 WHvGetVirtualProcessorRegisters (
178192 self . partition ,
179193 0 ,
180194 WHP_SREGS_NAMES . as_ptr ( ) ,
181- whp_sregs_values. len ( ) as u32 ,
182- whp_sregs_values. as_mut_ptr ( ) ,
195+ whp_sregs_values. 0 . len ( ) as u32 ,
196+ whp_sregs_values. 0 . as_mut_ptr ( ) ,
183197 ) ?;
184198 }
185199
186200 WHP_SREGS_NAMES
187201 . into_iter ( )
188- . zip ( whp_sregs_values)
202+ . zip ( whp_sregs_values. 0 )
189203 . collect :: < Vec < ( WHV_REGISTER_NAME , WHV_REGISTER_VALUE ) > > ( )
190204 . as_slice ( )
191205 . try_into ( )
@@ -204,22 +218,22 @@ impl Vm for WhpVm {
204218 }
205219
206220 fn get_fpu ( & self ) -> Result < CommonFpu > {
207- let mut whp_fpu_values: [ WHV_REGISTER_VALUE ; WHP_FPU_NAMES_LEN ] =
208- unsafe { std:: mem:: zeroed ( ) } ;
221+ let mut whp_fpu_values =
222+ AlignedRegisterValues :: < WHP_FPU_NAMES_LEN > ( unsafe { std:: mem:: zeroed ( ) } ) ;
209223
210224 unsafe {
211225 WHvGetVirtualProcessorRegisters (
212226 self . partition ,
213227 0 ,
214228 WHP_FPU_NAMES . as_ptr ( ) ,
215- whp_fpu_values. len ( ) as u32 ,
216- whp_fpu_values. as_mut_ptr ( ) ,
229+ whp_fpu_values. 0 . len ( ) as u32 ,
230+ whp_fpu_values. 0 . as_mut_ptr ( ) ,
217231 ) ?;
218232 }
219233
220234 WHP_FPU_NAMES
221235 . into_iter ( )
222- . zip ( whp_fpu_values)
236+ . zip ( whp_fpu_values. 0 )
223237 . collect :: < Vec < ( WHV_REGISTER_NAME , WHV_REGISTER_VALUE ) > > ( )
224238 . as_slice ( )
225239 . try_into ( )
0 commit comments