在 Windows 驅動程式中使用擴充處理器功能

上次更新日期

  • 2016 年 7 月

使用擴充處理器功能的 x86 和 x64 系統的 Windows 驅動程式必須在呼叫 KeSaveExtendedProcessorStateKeRestoreExtendedProcessorState 之間包裝浮點計算,以避免使用緩存器的並行應用程式發生錯誤。

舊版MMX/x87緩存器

這些快取器會對應至XSTATE_MASK_LEGACY_FLOATING_POINT遮罩,而且無法供 x64 系統的驅動程式使用。 如需這些快取器的詳細資訊,請參閱 在WDM驅動程式中使用浮點

SSE 快取器

這些緩存器會對應至XSTATE_MASK_LEGACY_SSE旗標,並由 x64 編譯程式用於浮點運算。 使用這些緩存器的 x86 系統的驅動程式必須先儲存,才能使用,方法是傳遞 KeSaveExtendedProcessorState 呼叫中的 XSTATE_MASK_LEGACY 或 XSTATE_MASK_LEGACY_SSE 旗標,並在完成時使用 KeRestoreExtendedProcessorState 加以還原。 這在 x64 系統上是不必要的,但不有害。 如需這些快取器的詳細資訊,請參閱 在WDM驅動程式中使用浮點

AVX 快取器

這些緩存器會對應至XSTATE_MASK_GSSE或XSTATE_MASK_AVX遮罩。 新的 x86 處理器,例如 Intel Bridge (先前稱為 Gesher) 處理器,支援 AVX 指令和註冊集 (YMM0-YMM15) 。 在 Windows 7 的 Service Pack 1 (SP1) 、Windows Server 2008 R2 和較新版本的 Windows 中,x86 和 x64 版本的操作系統都會在線程 (和進程) 交換器之間保留 AVX 緩存器。 若要在內核模式中使用AVX緩存器,驅動程式 (x86和 x64) 必須明確儲存和還原 AVX 快取器。 AVX 快取器無法在中斷服務例程中使用,而且預設會關閉算術例外狀況。

include ksamd64.inc

        subttl "Set YMM State."
;++
;
; Routine Description:
;   
;   This routine loads the first four YMM registers with the state supplied.
;
; Arguments;
;
;   rcx - Supplies a pointer to the values we want to load.
;
; Return Value:
;
;   None
;
;--

LEAF_ENTRY SetYmmValues, _TEXT$00

        vmovdqa    ymm0,  ymmword ptr[rcx + 0]
        vmovdqa    ymm1,  ymmword ptr[rcx + 32]
        vmovdqa    ymm2,  ymmword ptr[rcx + 64]
        vmovdqa    ymm3,  ymmword ptr[rcx + 96]

        ret

LEAF_END SetYmmValues, _TEXT$00

        end
typedef DECLSPEC_ALIGN(32) struct _YMM_REGISTERS {
    ULONG64 Ymm4Registers[16];
} YMM_REGISTERS, *PYMM_REGISTERS;

VOID
FASTCALL
SetYmmValues(
    __in PYMM_REGISTERS YmmRegisterValues
    );

NTSTATUS
DriverEntry (
    __in PDRIVER_OBJECT DriverObject,
    __in PUNICODE_STRING RegistryPath
    )
{

    NTSTATUS Status;
    XSTATE_SAVE SaveState;
    ULONG64 EnabledFeatures;

    //
    // Load the first 4 YMM registers as 4 vectors of 4 64-bit integers.
    //

    YMM_REGISTERS RegisterValues = { 0, 1, 2, 3,        // YMM0
                                     4, 5, 6, 7,        // YMM1
                                     8, 9, 10, 11,      // YMM2
                                     12, 13, 14, 15 };  // YMM3

    //
    // Check to see if AVX is available. Bail if it is not.
    //

    EnabledFeatures = RtlGetEnabledExtendedFeatures(-1);
    if ((EnabledFeatures & XSTATE_MASK_GSSE) == 0) {
        Status = STATUS_FAILED_DRIVER_ENTRY;
        goto exit;
    }

    Status = KeSaveExtendedProcessorState(XSTATE_MASK_GSSE, &SaveState);

    if (!NT_SUCCESS(Status)) {
        goto exit;
    }

    __try {
        SetYmmValues(&RegisterValues);
    }
    __finally {
        KeRestoreExtendedProcessorState(&SaveState);
    }

exit:
    return Status;
}

KeSaveExtendedProcessorState
KeRestoreExtendedProcessorState
在 WDM 驅動程式中使用浮點