@@ -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,18 @@ pub(crate) struct WhpVm {
86
86
unsafe impl Send for WhpVm { }
87
87
unsafe impl Sync for WhpVm { }
88
88
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 array 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
+
89
101
impl WhpVm {
90
102
pub ( crate ) fn new ( mmap_file_handle : HandleWrapper ) -> Result < Self > {
91
103
const NUM_CPU : u32 = 1 ;
@@ -112,12 +124,14 @@ impl WhpVm {
112
124
/// Helper for setting arbitrary registers.
113
125
fn set_registers ( & self , registers : & [ ( WHV_REGISTER_NAME , WHV_REGISTER_VALUE ) ] ) -> Result < ( ) > {
114
126
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) ;
117
131
118
132
for ( key, value) in registers. iter ( ) {
119
133
register_names. push ( * key) ;
120
- register_values. push ( * value) ;
134
+ register_values. push ( Align16 ( * value) ) ;
121
135
}
122
136
123
137
unsafe {
@@ -126,7 +140,7 @@ impl WhpVm {
126
140
0 ,
127
141
register_names. as_ptr ( ) ,
128
142
register_count as u32 ,
129
- register_values. as_ptr ( ) ,
143
+ register_values. as_ptr ( ) as * const WHV_REGISTER_VALUE ,
130
144
) ?;
131
145
}
132
146
@@ -136,22 +150,22 @@ impl WhpVm {
136
150
137
151
impl Vm for WhpVm {
138
152
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 ( ) } ) ;
141
155
142
156
unsafe {
143
157
WHvGetVirtualProcessorRegisters (
144
158
self . partition ,
145
159
0 ,
146
160
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 ( ) ,
149
163
) ?;
150
164
}
151
165
152
166
WHP_REGS_NAMES
153
167
. into_iter ( )
154
- . zip ( whv_regs_values)
168
+ . zip ( whv_regs_values. 0 )
155
169
. collect :: < Vec < ( WHV_REGISTER_NAME , WHV_REGISTER_VALUE ) > > ( )
156
170
. as_slice ( )
157
171
. try_into ( )
@@ -170,22 +184,22 @@ impl Vm for WhpVm {
170
184
}
171
185
172
186
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 ( ) } ) ;
175
189
176
190
unsafe {
177
191
WHvGetVirtualProcessorRegisters (
178
192
self . partition ,
179
193
0 ,
180
194
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 ( ) ,
183
197
) ?;
184
198
}
185
199
186
200
WHP_SREGS_NAMES
187
201
. into_iter ( )
188
- . zip ( whp_sregs_values)
202
+ . zip ( whp_sregs_values. 0 )
189
203
. collect :: < Vec < ( WHV_REGISTER_NAME , WHV_REGISTER_VALUE ) > > ( )
190
204
. as_slice ( )
191
205
. try_into ( )
@@ -204,22 +218,22 @@ impl Vm for WhpVm {
204
218
}
205
219
206
220
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 ( ) } ) ;
209
223
210
224
unsafe {
211
225
WHvGetVirtualProcessorRegisters (
212
226
self . partition ,
213
227
0 ,
214
228
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 ( ) ,
217
231
) ?;
218
232
}
219
233
220
234
WHP_FPU_NAMES
221
235
. into_iter ( )
222
- . zip ( whp_fpu_values)
236
+ . zip ( whp_fpu_values. 0 )
223
237
. collect :: < Vec < ( WHV_REGISTER_NAME , WHV_REGISTER_VALUE ) > > ( )
224
238
. as_slice ( )
225
239
. try_into ( )
0 commit comments