nvmm: Implement curthread_save/restore_fpu.

It actually is needed to reset MXCSR.

Doesn't seem to affect behavior, though.
This commit is contained in:
Augustin Cavalier
2026-07-22 03:14:57 +00:00
committed by waddlesplash
parent e0ff341bce
commit 27c16710b9
4 changed files with 34 additions and 12 deletions
@@ -68,6 +68,32 @@ haiku_get_xsave_mask()
}
extern "C" void
haiku_curthread_save_fpu()
{
#if KDEBUG
uint32 sseControl;
asm volatile("stmxcsr %0" : "=m" (sseControl));
if ((sseControl & ~0x3F) != 0x1F80) {
cpu_status status = disable_interrupts();
dprintf("nvmm: curthread_save_fpu: non-default MXCSR\n");
restore_interrupts(status);
}
#endif
}
extern "C" void
haiku_curthread_restore_fpu()
{
// Haiku allows FPU usage in the kernel, so saving/restoring the overall
// FPU state isn't needed. However, on x86, MXCSR is callee-saved, so we
// have to reset it when "restoring" state.
uint32 sseControl = 0x1F80;
asm volatile("ldmxcsr %0" : : "m" (sseControl));
}
extern "C" void
haiku_save_fpu(void* area, uint64_t xsave_features)
{
@@ -908,8 +908,10 @@ void x86_curthread_restore_dbregs(uint64_t *drs);
fpurstor((union savefpu *)(a), m); \
})
#elif defined(__HAIKU__)
#define x86_curthread_save_fpu() // Haiku allows FPU usage in the kernel, thus
#define x86_curthread_restore_fpu() // save/restore of thread FPU state not needed.
void haiku_curthread_save_fpu();
void haiku_curthread_restore_fpu();
#define x86_curthread_save_fpu haiku_curthread_save_fpu
#define x86_curthread_restore_fpu haiku_curthread_restore_fpu
void haiku_save_fpu(void* area, uint64_t xsave_features);
void haiku_restore_fpu(const void* area, uint64_t xsave_features);
@@ -1387,7 +1387,7 @@ svm_vcpu_guest_fpu_enter(struct nvmm_cpu *vcpu)
{
struct svm_cpudata *cpudata = vcpu->cpudata;
#if defined(__NetBSD__)
#if defined(__NetBSD__) || defined(__HAIKU__)
x86_curthread_save_fpu();
#elif defined(__DragonFly__)
/*
@@ -1413,7 +1413,7 @@ svm_vcpu_guest_fpu_leave(struct nvmm_cpu *vcpu)
}
x86_save_fpu(&cpudata->gxsave, svm_xcr0_mask);
#if defined(__NetBSD__)
#if defined(__NetBSD__) || defined(__HAIKU__)
x86_curthread_restore_fpu();
#elif defined(__DragonFly__)
npxpop(&cpudata->hstate.hmctx);
@@ -2057,7 +2057,7 @@ vmx_vcpu_guest_fpu_enter(struct nvmm_cpu *vcpu)
{
struct vmx_cpudata *cpudata = vcpu->cpudata;
#if defined(__NetBSD__)
#if defined(__NetBSD__) || defined(__HAIKU__)
x86_curthread_save_fpu();
#elif defined(__DragonFly__)
/*
@@ -2065,12 +2065,6 @@ vmx_vcpu_guest_fpu_enter(struct nvmm_cpu *vcpu)
* FPU or not. Need to use npxpush()/npxpop() to handle this.
*/
npxpush(&cpudata->hstate.hmctx);
#elif defined(__HAIKU__)
/*
* Haiku allows floating point on kernel and it handles save and restore
* FPU state on context switches (see commit 396b742). The only thing
* we need to save and restore manually is the XCR0 register.
*/
#endif
x86_restore_fpu(&cpudata->gxsave, vmx_xcr0_mask);
@@ -2089,7 +2083,7 @@ vmx_vcpu_guest_fpu_leave(struct nvmm_cpu *vcpu)
}
x86_save_fpu(&cpudata->gxsave, vmx_xcr0_mask);
#if defined(__NetBSD__)
#if defined(__NetBSD__) || defined(__HAIKU__)
x86_curthread_restore_fpu();
#elif defined(__DragonFly__)
npxpop(&cpudata->hstate.hmctx);