在 IRQL 中使用浮点运算high_level

using floating-point operations at high_level irql

提问人:daniel 提问时间:7/19/2023 更新时间:7/25/2023 访问量:114

问:

在HIGH_LEVEL IRQL 执行的内核例程中,我一直在尝试通过直接调用 FXSAVE 和 FXRSOR 来管理浮点状态。由于 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);

谁能确认这种方法对于管理 IRQL 的浮点状态是否正确和安全HIGH_LEVEL?我将不胜感激任何改进的见解或建议。

Windows 内核 MASM 浮动 IRQL

评论


答:

0赞 daniel 7/24/2023 #1

我一直在研究内核编程,需要执行浮点运算。在内核模式下执行此操作的挑战之一是在高级 irql 中保留浮点和 SIMD 状态。我想分享一种我发现使用_fxsave64和_fxrstor64内部函数有效的方法。

先决条件: 确保您有充分的理由在内核中使用浮点,因为它可能会引入难以调试的问题。

溶液: 首先,声明一个缓冲区来保存 FPU 状态。此缓冲区应为 16 字节

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

接下来,将浮点代码包装在 _fxsave64 和 _fxrstor64 之间:

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

警告:

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

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