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:
committed by
waddlesplash
parent
e0ff341bce
commit
27c16710b9
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user