0

In my kernel routine that executes at HIGH_LEVEL IRQL, I've been trying to manage the floating-point state by directly invoking FXSAVE and FXRSTOR. As KeSaveExtendedProcessorState and KeRestoreExtendedProcessorState are not usable at this level, I had to resort to this method.

Here's my current implementation:

In the assembly code, I've defined two procedures SaveFxState and 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

These procedures are exposed with extern "C" linkage to my C++ code:

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

I use these procedures as follows:

FXSAVE_FORMAT g_FxSaveArea;

SaveFxState(&g_FxSaveArea);

// Floating-point operations are here

RestoreFxState(&g_FxSaveArea);

Can anyone confirm whether this approach is correct and safe for managing floating-point state at HIGH_LEVEL IRQL? I would appreciate any insights or suggestions for improvement.

daniel
  • 25
  • 3

1 Answers1

0

I've been working on kernel programming and needed to perform floating-point operations. One of the challenges with doing this in kernel mode is preserving the floating-point and SIMD state in high level irql . I wanted to share a method I've found to be effective using the _fxsave64 and _fxrstor64 intrinsics.

Prerequisites: Ensure you have a good reason to use floating-point in the kernel, as it can introduce hard-to-debug issues.

Solution: Firstly, declare a buffer to save the FPU state. This buffer should be 16-byte

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

Next, wrap your floating-point code between _fxsave64 and _fxrstor64:

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

Caveats:

  • Always ensure the alignment for the buffer.
  • Use Structured Exception Handling cautiously in kernel mode. There are some special considerations to be aware of.
  • Using floating-point operations in the kernel is typically discouraged unless absolutely necessary. Ensure you've implemented the necessary precautions.

I hope this helps anyone facing similar challenges! Feedback or further insights are welcome!

Tsyvarev
  • 60,011
  • 17
  • 110
  • 153
daniel
  • 25
  • 3