Skip to content

Commit c18f0f1

Browse files
committed
Fix alignment issues
Signed-off-by: Ludvig Liljenberg <[email protected]>
1 parent afd8964 commit c18f0f1

File tree

2 files changed

+55
-21
lines changed

2 files changed

+55
-21
lines changed

src/hyperlight_host/src/hypervisor/regs/special_regs.rs

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@ extern crate mshv_ioctls3 as mshv_ioctls;
1010

1111
#[cfg(target_os = "windows")]
1212
use std::collections::HashSet;
13+
#[cfg(target_os = "windows")]
14+
use std::mem::offset_of;
1315

1416
#[cfg(kvm)]
1517
use kvm_bindings::{kvm_dtable, kvm_segment, kvm_sregs};
@@ -20,6 +22,8 @@ use windows::Win32::System::Hypervisor::*;
2022

2123
#[cfg(target_os = "windows")]
2224
use super::FromWhpRegisterError;
25+
#[cfg(target_os = "windows")]
26+
use crate::hypervisor::regs::{WHP_FPU_NAMES_LEN, WHP_REGS_NAMES_LEN};
2327

2428
#[derive(Debug, Default, Copy, Clone, PartialEq)]
2529
pub(crate) struct CommonSpecialRegisters {
@@ -147,6 +151,24 @@ impl From<&CommonSpecialRegisters> for kvm_sregs {
147151
}
148152
}
149153

154+
#[repr(C, align(16))]
155+
#[cfg(target_os = "windows")]
156+
pub(crate) struct AlignedRegisterValues<const N: usize>(pub(crate) [WHV_REGISTER_VALUE; N]);
157+
158+
#[cfg(target_os = "windows")]
159+
#[allow(clippy::disallowed_macros)] // this is at compile time
160+
const _: () = {
161+
// WHP_SREGS_NAMES_LEN
162+
assert!(std::mem::align_of::<AlignedRegisterValues<WHP_SREGS_NAMES_LEN>>() % 16 == 0);
163+
assert!(offset_of!(AlignedRegisterValues<WHP_SREGS_NAMES_LEN>, 0) % 16 == 0);
164+
// WHP_REGS_NAMES_LEN
165+
assert!(std::mem::align_of::<AlignedRegisterValues<WHP_REGS_NAMES_LEN>>() % 16 == 0,);
166+
assert!(offset_of!(AlignedRegisterValues<WHP_REGS_NAMES_LEN>, 0) % 16 == 0);
167+
// WHP_FPU_NAMES_LEN
168+
assert!(std::mem::align_of::<AlignedRegisterValues<WHP_FPU_NAMES_LEN>>() % 16 == 0,);
169+
assert!(offset_of!(AlignedRegisterValues<WHP_FPU_NAMES_LEN>, 0) % 16 == 0);
170+
};
171+
150172
#[cfg(target_os = "windows")]
151173
pub(crate) const WHP_SREGS_NAMES_LEN: usize = 17;
152174
#[cfg(target_os = "windows")]

src/hyperlight_host/src/hypervisor/whp.rs

Lines changed: 33 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,8 @@ use windows_result::HRESULT;
2626
#[cfg(gdb)]
2727
use super::handlers::DbgMemAccessHandlerWrapper;
2828
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,
3131
};
3232
use super::vm::HyperlightExit;
3333
use super::wrappers::HandleWrapper;
@@ -86,6 +86,16 @@ pub(crate) struct WhpVm {
8686
unsafe impl Send for WhpVm {}
8787
unsafe impl Sync for WhpVm {}
8888

89+
#[repr(C, align(16))]
90+
struct Align16<T>(T);
91+
#[allow(clippy::disallowed_macros)] // compile time
92+
const _: () = {
93+
assert!(
94+
std::mem::size_of::<Align16<WHV_REGISTER_VALUE>>()
95+
== std::mem::size_of::<WHV_REGISTER_VALUE>()
96+
);
97+
};
98+
8999
impl WhpVm {
90100
pub(crate) fn new(mmap_file_handle: HandleWrapper) -> Result<Self> {
91101
const NUM_CPU: u32 = 1;
@@ -112,12 +122,14 @@ impl WhpVm {
112122
/// Helper for setting arbitrary registers.
113123
fn set_registers(&self, registers: &[(WHV_REGISTER_NAME, WHV_REGISTER_VALUE)]) -> Result<()> {
114124
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![];
125+
126+
// Prepare register names (no special alignment needed)
127+
let mut register_names = Vec::with_capacity(register_count);
128+
let mut register_values = Vec::with_capacity(register_count);
117129

118130
for (key, value) in registers.iter() {
119131
register_names.push(*key);
120-
register_values.push(*value);
132+
register_values.push(Align16(*value));
121133
}
122134

123135
unsafe {
@@ -126,7 +138,7 @@ impl WhpVm {
126138
0,
127139
register_names.as_ptr(),
128140
register_count as u32,
129-
register_values.as_ptr(),
141+
register_values.as_ptr() as *const WHV_REGISTER_VALUE,
130142
)?;
131143
}
132144

@@ -136,22 +148,22 @@ impl WhpVm {
136148

137149
impl Vm for WhpVm {
138150
fn get_regs(&self) -> Result<CommonRegisters> {
139-
let mut whv_regs_values: [WHV_REGISTER_VALUE; WHP_REGS_NAMES_LEN] =
140-
unsafe { std::mem::zeroed() };
151+
let mut whv_regs_values =
152+
AlignedRegisterValues::<WHP_REGS_NAMES_LEN>(unsafe { std::mem::zeroed() });
141153

142154
unsafe {
143155
WHvGetVirtualProcessorRegisters(
144156
self.partition,
145157
0,
146158
WHP_REGS_NAMES.as_ptr(),
147-
WHP_REGS_NAMES_LEN as u32,
148-
whv_regs_values.as_mut_ptr(),
159+
whv_regs_values.0.len() as u32,
160+
whv_regs_values.0.as_mut_ptr(),
149161
)?;
150162
}
151163

152164
WHP_REGS_NAMES
153165
.into_iter()
154-
.zip(whv_regs_values)
166+
.zip(whv_regs_values.0)
155167
.collect::<Vec<(WHV_REGISTER_NAME, WHV_REGISTER_VALUE)>>()
156168
.as_slice()
157169
.try_into()
@@ -170,22 +182,22 @@ impl Vm for WhpVm {
170182
}
171183

172184
fn get_sregs(&self) -> Result<CommonSpecialRegisters> {
173-
let mut whp_sregs_values: [WHV_REGISTER_VALUE; WHP_SREGS_NAMES_LEN] =
174-
unsafe { std::mem::zeroed() };
185+
let mut whp_sregs_values =
186+
AlignedRegisterValues::<WHP_SREGS_NAMES_LEN>(unsafe { std::mem::zeroed() });
175187

176188
unsafe {
177189
WHvGetVirtualProcessorRegisters(
178190
self.partition,
179191
0,
180192
WHP_SREGS_NAMES.as_ptr(),
181-
whp_sregs_values.len() as u32,
182-
whp_sregs_values.as_mut_ptr(),
193+
whp_sregs_values.0.len() as u32,
194+
whp_sregs_values.0.as_mut_ptr(),
183195
)?;
184196
}
185197

186198
WHP_SREGS_NAMES
187199
.into_iter()
188-
.zip(whp_sregs_values)
200+
.zip(whp_sregs_values.0)
189201
.collect::<Vec<(WHV_REGISTER_NAME, WHV_REGISTER_VALUE)>>()
190202
.as_slice()
191203
.try_into()
@@ -204,22 +216,22 @@ impl Vm for WhpVm {
204216
}
205217

206218
fn get_fpu(&self) -> Result<CommonFpu> {
207-
let mut whp_fpu_values: [WHV_REGISTER_VALUE; WHP_FPU_NAMES_LEN] =
208-
unsafe { std::mem::zeroed() };
219+
let mut whp_fpu_values =
220+
AlignedRegisterValues::<WHP_FPU_NAMES_LEN>(unsafe { std::mem::zeroed() });
209221

210222
unsafe {
211223
WHvGetVirtualProcessorRegisters(
212224
self.partition,
213225
0,
214226
WHP_FPU_NAMES.as_ptr(),
215-
whp_fpu_values.len() as u32,
216-
whp_fpu_values.as_mut_ptr(),
227+
whp_fpu_values.0.len() as u32,
228+
whp_fpu_values.0.as_mut_ptr(),
217229
)?;
218230
}
219231

220232
WHP_FPU_NAMES
221233
.into_iter()
222-
.zip(whp_fpu_values)
234+
.zip(whp_fpu_values.0)
223235
.collect::<Vec<(WHV_REGISTER_NAME, WHV_REGISTER_VALUE)>>()
224236
.as_slice()
225237
.try_into()

0 commit comments

Comments
 (0)