Skip to content

Commit 5c7145d

Browse files
committed
Reset vcpu state
Signed-off-by: Ludvig Liljenberg <[email protected]>
1 parent 5c094b6 commit 5c7145d

File tree

10 files changed

+1260
-142
lines changed

10 files changed

+1260
-142
lines changed

src/hyperlight_host/src/hypervisor/hyperlight_vm.rs

Lines changed: 944 additions & 1 deletion
Large diffs are not rendered by default.

src/hyperlight_host/src/hypervisor/hyperv_linux.rs

Lines changed: 52 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ use std::sync::LazyLock;
2121
#[cfg(gdb)]
2222
use mshv_bindings::{DebugRegisters, hv_message_type_HVMSG_X64_EXCEPTION_INTERCEPT};
2323
use mshv_bindings::{
24-
FloatingPointUnit, SpecialRegisters, StandardRegisters, hv_message_type,
24+
FloatingPointUnit, SpecialRegisters, StandardRegisters, XSave, hv_message_type,
2525
hv_message_type_HVMSG_GPA_INTERCEPT, hv_message_type_HVMSG_UNMAPPED_GPA,
2626
hv_message_type_HVMSG_X64_HALT, hv_message_type_HVMSG_X64_IO_PORT_INTERCEPT,
2727
hv_partition_property_code_HV_PARTITION_PROPERTY_SYNTHETIC_PROC_FEATURES,
@@ -33,6 +33,7 @@ use tracing::{Span, instrument};
3333

3434
#[cfg(gdb)]
3535
use crate::hypervisor::gdb::DebuggableVm;
36+
use crate::hypervisor::regs::{CommonDebugRegs, FP_CONTROL_WORD_DEFAULT, MXCSR_DEFAULT};
3637
use crate::hypervisor::{HyperlightExit, Hypervisor};
3738
use crate::mem::memory_region::{MemoryRegion, MemoryRegionFlags};
3839
use crate::{Result, new_error};
@@ -208,11 +209,60 @@ impl Hypervisor for MshvVm {
208209
Ok(())
209210
}
210211

211-
#[cfg(crashdump)]
212+
fn debug_regs(&self) -> Result<CommonDebugRegs> {
213+
let debug_regs = self.vcpu_fd.get_debug_regs()?;
214+
Ok(debug_regs.into())
215+
}
216+
217+
fn set_debug_regs(&self, drs: &CommonDebugRegs) -> Result<()> {
218+
let mshv_debug_regs = drs.into();
219+
self.vcpu_fd.set_debug_regs(&mshv_debug_regs)?;
220+
Ok(())
221+
}
222+
212223
fn xsave(&self) -> Result<Vec<u8>> {
213224
let xsave = self.vcpu_fd.get_xsave()?;
214225
Ok(xsave.buffer.to_vec())
215226
}
227+
228+
fn reset_xsave(&self) -> Result<()> {
229+
let current_xsave = self.vcpu_fd.get_xsave()?;
230+
if current_xsave.buffer.len() < 576 {
231+
// Minimum: 512 legacy + 64 header
232+
return Err(new_error!(
233+
"Unexpected xsave length {}",
234+
current_xsave.buffer.len()
235+
));
236+
}
237+
238+
let mut buf = XSave::default(); // default is zeroed 4KB buffer
239+
240+
// Copy XCOMP_BV (offset 520-527) - preserves feature mask + compacted bit
241+
buf.buffer[520..528].copy_from_slice(&current_xsave.buffer[520..528]);
242+
243+
// XSAVE area layout from Intel SDM Vol. 1 Section 13.4.1:
244+
// - Bytes 0-1: FCW (x87 FPU Control Word)
245+
// - Bytes 24-27: MXCSR
246+
buf.buffer[0..2].copy_from_slice(&FP_CONTROL_WORD_DEFAULT.to_le_bytes());
247+
buf.buffer[24..28].copy_from_slice(&MXCSR_DEFAULT.to_le_bytes());
248+
249+
self.vcpu_fd.set_xsave(&buf)?;
250+
Ok(())
251+
}
252+
253+
#[cfg(test)]
254+
#[cfg(feature = "init-paging")]
255+
fn set_xsave(&self, xsave: &[u32; 1024]) -> Result<()> {
256+
let mut buf = XSave::default();
257+
// Safety: all valid u32 values are 4 valid u8 values
258+
let (prefix, bytes, suffix) = unsafe { xsave.align_to() };
259+
if !prefix.is_empty() || !suffix.is_empty() {
260+
return Err(new_error!("Invalid xsave buffer alignment"));
261+
}
262+
buf.buffer.copy_from_slice(bytes);
263+
self.vcpu_fd.set_xsave(&buf)?;
264+
Ok(())
265+
}
216266
}
217267

218268
#[cfg(gdb)]

0 commit comments

Comments
 (0)