windows 在高级irql使用浮点运算

dfuffjeb  于 2023-08-07  发布在  Windows
关注(0)|答案(1)|浏览(132)

在HIGH_LEVEL IRQL上执行的内核例程中,我一直试图通过直接调用FXSAVE和FXRSTOR来管理浮点状态。由于KeSaveExtendedProcessorState和KeRestoreExtendedProcessorState在这个级别上不可用,我不得不求助于这个方法。
以下是我当前的实现:
在汇编代码中,我定义了两个过程SaveFxState和RestoreFxState:

SaveFxState PROC
    ; Save the floating point state
    mov rax, rcx
    fxsave [rax]
    ret
SaveFxState ENDP

RestoreFxState PROC
    ; Restore the floating point state
    mov rax, rcx
    fxrstor [rax]
    ret
RestoreFxState ENDP

字符集
这些过程通过外部“C”链接公开到我的C++代码:

extern "C" {
    void SaveFxState(void* saveArea);
    void RestoreFxState(void* saveArea);
}


我使用这些程序如下:

FXSAVE_FORMAT g_FxSaveArea;

SaveFxState(&g_FxSaveArea);

// Floating-point operations are here

RestoreFxState(&g_FxSaveArea);


有人可以确认这种方法在HIGH_LEVEL IRQL上管理浮点状态是否正确和安全吗?我将感谢任何改进的见解或建议。

jjjwad0x

jjjwad0x1#

我一直在进行内核编程,需要执行浮点运算。在内核模式下这样做的挑战之一是在高级irql中保留浮点和SIMD状态。我想分享一个我发现使用_fxsave64和_fxrstor64 intrinsic有效的方法。
必要条件:确保您有充分的理由在内核中使用浮点,因为它可能会引入难以调试的问题。
解决方案:首先,声明一个缓冲区来保存FPU状态。此缓冲区应为16字节

aligned:
__declspec(align(16)) BYTE FpuState[512];  // Ensure the memory area is 16-byte aligned

字符集
接下来,在_fxsave64和_fxrstor64之间 Package 浮点代码:

void KernelFunctionWithFPUOperations()
{
    _fxsave64(FpuState);
    __try {
        DoFloatingPointCalculation();
    }
    __finally {
        _fxrstor64(FpuState);
    }
}


注意事项:

  • 始终确保缓冲器对齐。
  • 在内核模式下谨慎使用结构化异常处理。有一些特殊的注意事项需要注意。
  • 除非绝对必要,否则通常不鼓励在内核中使用浮点运算。确保你已经采取了必要的预防措施。

我希望这对任何面临类似挑战的人都有帮助!欢迎反馈或进一步的见解!

相关问题