@@ -26,8 +26,8 @@ use windows_result::HRESULT;
26
26
#[ cfg( gdb) ]
27
27
use super :: handlers:: DbgMemAccessHandlerWrapper ;
28
28
use 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 ,
31
31
} ;
32
32
use super :: vm:: HyperlightExit ;
33
33
use super :: wrappers:: HandleWrapper ;
@@ -86,6 +86,15 @@ pub(crate) struct WhpVm {
86
86
unsafe impl Send for WhpVm { }
87
87
unsafe impl Sync for WhpVm { }
88
88
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
+
89
98
impl WhpVm {
90
99
pub ( crate ) fn new ( mmap_file_handle : HandleWrapper ) -> Result < Self > {
91
100
const NUM_CPU : u32 = 1 ;
@@ -112,21 +121,29 @@ impl WhpVm {
112
121
/// Helper for setting arbitrary registers.
113
122
fn set_registers ( & self , registers : & [ ( WHV_REGISTER_NAME , WHV_REGISTER_VALUE ) ] ) -> Result < ( ) > {
114
123
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) ;
117
128
118
129
for ( key, value) in registers. iter ( ) {
119
130
register_names. push ( * key) ;
120
- register_values. push ( * value) ;
131
+ register_values. push ( Align16 ( * value) ) ;
121
132
}
122
133
134
+ assert_eq ! (
135
+ ( register_values. as_ptr( ) as usize ) % 16 ,
136
+ 0 ,
137
+ "register_values is not 16-byte aligned"
138
+ ) ;
139
+
123
140
unsafe {
124
141
WHvSetVirtualProcessorRegisters (
125
142
self . partition ,
126
143
0 ,
127
144
register_names. as_ptr ( ) ,
128
145
register_count as u32 ,
129
- register_values. as_ptr ( ) ,
146
+ register_values. as_ptr ( ) as * const WHV_REGISTER_VALUE ,
130
147
) ?;
131
148
}
132
149
@@ -136,22 +153,24 @@ impl WhpVm {
136
153
137
154
impl Vm for WhpVm {
138
155
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 ) ;
141
160
142
161
unsafe {
143
162
WHvGetVirtualProcessorRegisters (
144
163
self . partition ,
145
164
0 ,
146
165
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 ( ) ,
149
168
) ?;
150
169
}
151
170
152
171
WHP_REGS_NAMES
153
172
. into_iter ( )
154
- . zip ( whv_regs_values)
173
+ . zip ( whv_regs_values. 0 )
155
174
. collect :: < Vec < ( WHV_REGISTER_NAME , WHV_REGISTER_VALUE ) > > ( )
156
175
. as_slice ( )
157
176
. try_into ( )
@@ -170,22 +189,24 @@ impl Vm for WhpVm {
170
189
}
171
190
172
191
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 ) ;
175
196
176
197
unsafe {
177
198
WHvGetVirtualProcessorRegisters (
178
199
self . partition ,
179
200
0 ,
180
201
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 ( ) ,
183
204
) ?;
184
205
}
185
206
186
207
WHP_SREGS_NAMES
187
208
. into_iter ( )
188
- . zip ( whp_sregs_values)
209
+ . zip ( whp_sregs_values. 0 )
189
210
. collect :: < Vec < ( WHV_REGISTER_NAME , WHV_REGISTER_VALUE ) > > ( )
190
211
. as_slice ( )
191
212
. try_into ( )
@@ -204,22 +225,24 @@ impl Vm for WhpVm {
204
225
}
205
226
206
227
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 ) ;
209
232
210
233
unsafe {
211
234
WHvGetVirtualProcessorRegisters (
212
235
self . partition ,
213
236
0 ,
214
237
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 ( ) ,
217
240
) ?;
218
241
}
219
242
220
243
WHP_FPU_NAMES
221
244
. into_iter ( )
222
- . zip ( whp_fpu_values)
245
+ . zip ( whp_fpu_values. 0 )
223
246
. collect :: < Vec < ( WHV_REGISTER_NAME , WHV_REGISTER_VALUE ) > > ( )
224
247
. as_slice ( )
225
248
. try_into ( )
0 commit comments