Uso de características de procesador extendidas en controladores de Windows
Última actualización
- Julio de 2016
Los controladores de Windows para sistemas x86 y x64 que usan características de procesador extendidas deben encapsular cálculos de punto flotante entre llamadas a KeSaveExtendedProcessorState y KeRestoreExtendedProcessorState para evitar errores en aplicaciones simultáneas que podrían estar usando los registros.
Registros MMX/x87 heredados
Estos registros corresponden a la máscara de XSTATE_MASK_LEGACY_FLOATING_POINT y no están disponibles para los controladores de los sistemas x64. Para obtener más información sobre estos registros, vea Uso de punto flotante en un controlador WDM.
Registros de SSE
Estos registros corresponden a la marca XSTATE_MASK_LEGACY_SSE y los usa el compilador x64 para las operaciones de punto flotante. Los controladores de los sistemas x86 que usan estos registros deben guardarlos antes de usarlos pasando la marca XSTATE_MASK_LEGACY o XSTATE_MASK_LEGACY_SSE en la llamada KeSaveExtendedProcessorState y, cuando termine, restáurelos con KeRestoreExtendedProcessorState. Esto no es necesario en sistemas x64, pero no perjudiciales. Para obtener más información sobre estos registros, vea Uso de punto flotante en un controlador WDM.
Registros de AVX
Estos registros corresponden a las máscaras de XSTATE_MASK_GSSE o XSTATE_MASK_AVX. Nuevos procesadores x86, como el procesador Intel Sandy Bridge (anteriormente Gesher), admiten las instrucciones de AVX y el conjunto de registros (YMM0-YMM15). En Windows 7 con Service Pack 1 (SP1), Windows Server 2008 R2 y versiones más recientes de Windows, las versiones x86 y x64 del sistema operativo conservan los registros avX entre conmutadores de subproceso (y proceso). Para usar los registros avX en modo kernel, los controladores (x86 y x64) deben guardar y restaurar explícitamente los registros de AVX. Los registros AVX no se pueden usar en una rutina de servicio de interrupción y las excepciones aritméticas están desactivadas de forma predeterminada.
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;
}
Temas relacionados
KeSaveExtendedProcessorState
KeRestoreExtendedProcessorState
Uso de punto flotante en un controlador WDM