KeSaveExtendedAndSupervisorState

INT64 __stdcall KeSaveExtendedAndSupervisorState(UINT64 Mask, XSTATE_SAVE *XStateSave){
  unsigned __int8 CurrentIrql; 
  _ETHREAD *CurrentThread; 
  bool v5; 
  unsigned __int8 v6; 
  __int64 v7; 
  unsigned __int64 v8; 
  INT64 result; 
  struct _KPRCB *CurrentPrcb; 
  unsigned int v11; 
  CurrentIrql = KeGetCurrentIrql();
  CurrentThread = (_ETHREAD *)KeGetCurrentThread();
  if( CurrentIrql > 2u )
    KeBugCheckEx(0x131u, 1ui64, CurrentIrql, 0i64, 0i64);
  if( (KeFeatureBits & 0x800000) != 0 )
  {
    if( CurrentIrql == 2 && (KUSER_SHARED_DATA.XState.ControlFlags & 2) != 0 )
    {
      if( (~(KUSER_SHARED_DATA.XState.EnabledFeatures | KUSER_SHARED_DATA.XState.EnabledSupervisorFeatures) & Mask) != 0 )
LABEL_32:
        KeBugCheckEx(0x131u, 0i64, KeFeatureBits & 0x800000, (unsigned int)Mask, HIDWORD(Mask));
LABEL_25:
      v6 = CurrentIrql + 1;
      goto LABEL_9;
    }
    v5 = (~KUSER_SHARED_DATA.XState.EnabledFeatures & Mask) == 0;
  }
  else
  {
    v5 = (Mask & 0xFFFFFFFFFFFFFFFCui64) == 0;
  }
  if( !v5 )
    goto LABEL_32;
  if( CurrentIrql || (*((_BYTE *)CurrentThread + 192) & 1) != 0 )
    goto LABEL_25;
  v6 = 0;
LABEL_9:
  v7 = *((_QWORD *)CurrentThread + 51);
  v8 = (Mask | KUSER_SHARED_DATA.XState.EnabledFeatures) & 0xFFFFFFFFFFFFFFFCui64;
  if( v7 && *(_BYTE *)(v7 + 16) > v6 )
    KeBugCheckEx(0x131u, 2ui64, *(unsigned __int8 *)(v7 + 16), v6, 0i64);
  if( v8 )
  {
    if( CurrentIrql < 2u || v7 && *(_BYTE *)(v7 + 16) == v6 )
    {
      result = KeAllocateXStateContext(&XStateSave->XStateContext, Mask);
      if( (int)result < 0 )
        return result;
    }
    else
    {
      CurrentPrcb = KeGetCurrentPrcb();
      memset(*((_QWORD *)CurrentPrcb + 4282) + 512i64, 0i64);
      v11 = KeXStateLength;
      XStateSave->XStateContext.Buffer = 0i64;
      XStateSave->XStateContext.Length = v11;
      XStateSave->XStateContext.Area = (_XSAVE_AREA *)*((_QWORD *)CurrentPrcb + 4282);
    }
  }
  else
  {
    XStateSave->XStateContext.Length = 0;
    XStateSave->XStateContext.Buffer = 0i64;
    XStateSave->XStateContext.Area = 0i64;
  }
  XStateSave->Thread = CurrentThread;
  XStateSave->Level = v6;
  XStateSave->XStateContext.Mask = v8;
  if( !CurrentIrql )
    --*((_WORD *)CurrentThread + 243);
  XStateSave->Prev = (_XSTATE_SAVE *)*((_QWORD *)CurrentThread + 51);
  if( v8 && (KeFeatureBits & 0x800000) != 0 )
  {
    if( CurrentIrql == 2 && (KUSER_SHARED_DATA.XState.ControlFlags & 2) != 0 )
    {
      RtlXRestore(XStateSave->XStateContext.Area, 0i64);
      XStateSave->XStateContext.Area->Header.CompactionMask = v8;
      RtlXSaveS(&XStateSave->XStateContext.Area->LegacyState.ControlWord, v8);
    }
    else
    {
      RtlXSave(XStateSave->XStateContext.Area, v8);
    }
  }
  *((_QWORD *)CurrentThread + 51) = XStateSave;
  if( !CurrentIrql )
    KiLeaveGuardedRegionUnsafe((__int64)CurrentThread);
  return 0i64;
}

Referenced by:

KeSaveExtendedProcessorState
PnprQuiesceProcessorDpc
PopHandleNextState