Skip to content

Commit db6bec4

Browse files
committed
Add support for reading the mxcsr registers
Signed-off-by: James Sturtevant <[email protected]>
1 parent fe1a687 commit db6bec4

File tree

7 files changed

+293
-4
lines changed

7 files changed

+293
-4
lines changed

src/hyperlight_host/src/hypervisor/gdb/hyperv_debug.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -218,6 +218,7 @@ impl GuestDebug for HypervDebug {
218218
fpu.xmm8, fpu.xmm9, fpu.xmm10, fpu.xmm11, fpu.xmm12, fpu.xmm13, fpu.xmm14,
219219
fpu.xmm15,
220220
];
221+
regs.mxcsr = fpu.mxcsr;
221222
} else {
222223
log::warn!("Failed to read FPU/XMM via WHVP for debug registers");
223224
}

src/hyperlight_host/src/hypervisor/gdb/kvm_debug.rs

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -193,17 +193,30 @@ impl GuestDebug for KvmDebug {
193193
regs.rip = vcpu_regs.rip;
194194
regs.rflags = vcpu_regs.rflags;
195195

196-
// Read XMM registers from FPU state
196+
// Read XMM registers from FPU state
197+
// note kvm get_fpu doesn't actually set or read the mxcsr value
198+
// https://elixir.bootlin.com/linux/v6.16/source/arch/x86/kvm/x86.c#L12229
197199
match vcpu_fd.get_fpu() {
198200
Ok(fpu) => {
199201
// Convert KVM XMM registers ([u8; 16] x 16) to [u128; 16]
200-
regs.xmm = fpu.xmm.map(u128::from_le_bytes);;
202+
regs.xmm = fpu.xmm.map(u128::from_le_bytes);
201203
},
202204
Err(e) => {
203205
log::warn!("Failed to read FPU state for XMM registers: {:?}", e);
204206
}
205207
}
206208

209+
// Read MXCSR from XSAVE (MXCSR is at byte offset 24 -> u32 index 6)
210+
// Todo maybe I could use xsave to read the registers too instead of a separate call to get_fpu
211+
match vcpu_fd.get_xsave() {
212+
Ok(xsave) => {
213+
regs.mxcsr = xsave.region[6];
214+
}
215+
Err(e) => {
216+
log::warn!("Failed to read XSAVE for MXCSR: {:?}", e);
217+
}
218+
}
219+
207220
Ok(())
208221
}
209222

src/hyperlight_host/src/hypervisor/gdb/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,7 @@ pub(crate) struct X86_64Regs {
110110
pub(crate) rip: u64,
111111
pub(crate) rflags: u64,
112112
pub(crate) xmm: [u128; 16],
113+
pub(crate) mxcsr: u32,
113114
}
114115

115116
/// Defines the possible reasons for which a vCPU can be stopped when debugging

src/hyperlight_host/src/hypervisor/gdb/mshv_debug.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -225,6 +225,7 @@ impl GuestDebug for MshvDebug {
225225
Ok(fpu) => {
226226
// MSHV exposes XMM as [[u8; 16]; 16]. Convert to [u128; 16]
227227
regs.xmm = fpu.xmm.map(u128::from_le_bytes);
228+
regs.mxcsr = fpu.mxcsr;
228229
}
229230
Err(e) => {
230231
log::warn!("Failed to read FPU state for XMM registers (MSHV): {:?}", e);
@@ -269,8 +270,6 @@ impl GuestDebug for MshvDebug {
269270

270271
rip: regs.rip,
271272
rflags: regs.rflags,
272-
273-
274273
};
275274

276275
vcpu_fd

src/hyperlight_host/src/hypervisor/gdb/x86_64_target.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -228,6 +228,7 @@ impl SingleThreadBase for HyperlightSandboxTarget {
228228
regs.rip = read_regs.rip;
229229
regs.eflags = read_regs.rflags as u32;
230230
regs.xmm = read_regs.xmm;
231+
regs.mxcsr = read_regs.mxcsr;
231232

232233
Ok(())
233234
}
@@ -269,6 +270,7 @@ impl SingleThreadBase for HyperlightSandboxTarget {
269270
rip: regs.rip,
270271
rflags: u64::from(regs.eflags),
271272
xmm: regs.xmm,
273+
mxcsr: regs.mxcsr,
272274
};
273275

274276
match self.send_command(DebugMsg::WriteRegisters(regs))? {

src/hyperlight_host/src/hypervisor/kvm.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -587,6 +587,9 @@ impl Hypervisor for KVMDriver {
587587
mxcsr: MXCSR_DEFAULT,
588588
..Default::default() // zero out the rest
589589
};
590+
591+
// note kvm set_fpu doesn't actually set or read the mxcsr value
592+
// https://elixir.bootlin.com/linux/v6.16/source/arch/x86/kvm/x86.c#L12229
590593
self.vcpu_fd.set_fpu(&fpu)?;
591594

592595
// run

src/tests/rust_guests/callbackguest/Cargo.lock

Lines changed: 270 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)