在 Windows 驅動程式中使用擴充處理器功能
上次更新日期
- 2016 年 7 月
使用擴充處理器功能的 x86 和 x64 系統的 Windows 驅動程式必須在呼叫 KeSaveExtendedProcessorState 和 KeRestoreExtendedProcessorState 之間包裝浮點計算,以避免使用緩存器的並行應用程式發生錯誤。
舊版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 驅動程式中使用浮點