KiUpdateSpeculationControl

VOID __stdcall KiUpdateSpeculationControl(PEPROCESS Process){
  struct _KPRCB *CurrentPrcb; 
  int v3; 
  unsigned __int8 BpbCurrentSpecCtrl; 
  bool v5; 
  int v6; 
  unsigned __int8 BpbRetpolineState; 
  char v8; 
  int v9; 
  unsigned __int64 SecurityDomain; 
  int v11; 
  int v12; 
  unsigned __int8 v13; 
  unsigned __int8 BpbState; 
  unsigned __int8 v15; 
  unsigned __int8 v16; 
  unsigned __int8 v17; 
  unsigned __int8 v18; 
  unsigned __int8 v19; 
  unsigned __int8 v20; 
  unsigned __int8 BpbUserSpecCtrl; 
  NTSTATUS updated; 
  char v23; 
  NTSTATUS v24; 
  bool v25; 
  char v26; 
  signed __int16 PairRegister; 
  signed __int16 v28; 
  int v29; 
  unsigned __int8 BpbRetpolineExitSpecCtrl; 
  unsigned __int8 BpbTrappedRetpolineExitSpecCtrl; 
  unsigned __int8 BpbKernelSpecCtrl; 
  unsigned int v33; 
  unsigned __int64 TrappedSecurityDomain; 
  __int128 v35; 
  char v36; 
  int v37; 
  _BOOL4 v38; 

  CurrentPrcb = KeGetCurrentPrcb();
  v35 = KiSpeculationFeatures;
  v3 = KiSpeculationFeatures;
  if( (KiSpeculationFeatures & 0x100000) == 0 )
    return;
  _disable();
  CurrentPrcb->BpbState &= 0x81u;
  if( (v3 & 1) != 0 )
  {
    KiUpdateSpecCtrlEnhancedIBRS((INT64)CurrentPrcb, (INT64)Process);
    _enable();
    return;
  }
  BpbCurrentSpecCtrl = CurrentPrcb->BpbCurrentSpecCtrl;
  v5 = 0;
  v36 = 0;
  v6 = v3 & 0x2000000;
  if( (v3 & 0x2000000) != 0 )
  {
    BpbRetpolineState = CurrentPrcb->BpbRetpolineState;
    if( (BpbRetpolineState & 2) == 0 && (BpbRetpolineState & 1) != 0 )
    {
      BpbCurrentSpecCtrl = CurrentPrcb->BpbTrappedRetpolineExitSpecCtrl;
      v5 = (CurrentPrcb->BpbTrappedBpbState & 0x10) != 0;
      v36 = 1;
    }
  }
  if( (v3 & 0x400000) != 0 && KiSsbdMsr == 72 )
  {
    BpbCurrentSpecCtrl |= 4u;
    v8 = 4;
  }
  else
  {
    v8 = 0;
  }
  CurrentPrcb->BpbKernelSpecCtrl = v8;
  CurrentPrcb->BpbUserSpecCtrl = v8;
  CurrentPrcb->BpbRetpolineExitSpecCtrl = v8;
  v37 = v3 & 0x2000;
  if( (v3 & 0x2000) != 0 )
  {
    CurrentPrcb->BpbKernelSpecCtrl |= 0x80u;
    CurrentPrcb->BpbRetpolineExitSpecCtrl |= 0x80u;
  }
  v9 = v3 & 0x8000000;
  if( v9 )
  {
    CurrentPrcb->BpbKernelSpecCtrl |= 2u;
    CurrentPrcb->BpbRetpolineExitSpecCtrl |= 2u;
  }
  TrappedSecurityDomain = CurrentPrcb->TrappedSecurityDomain;
  SecurityDomain = Process->SecurityDomain;
  v11 = v35;
  v38 = (Process->Flags3 & 0x400000) != 0;
  v33 = (Process->Flags3 >> 23) & 1;
  if( (Process->Flags3 & 0x400000) == 0 )
    SecurityDomain = 1i64;
  v12 = v35 & 0x200000;
  if( (v35 & 0x200000) == 0 )
  {
    if( !SecurityDomain )
    {
      if( (v35 & 2) != 0 )
      {
        if( (v35 & 0x40) != 0 )
        {
          CurrentPrcb->BpbRetpolineExitSpecCtrl |= 2u;
          if( !v6 )
            CurrentPrcb->BpbKernelSpecCtrl |= 2u;
        }
        else if( (v35 & 0x10) != 0 )
        {
          CurrentPrcb->BpbRetpolineExitSpecCtrl |= 1u;
          if( !v6 )
            CurrentPrcb->BpbKernelSpecCtrl |= 1u;
        }
      }
      goto LABEL_24;
    }
    if( KiIsBranchConfusionMitigationEnabled(&v35) )
    {
      v13 = CurrentPrcb->BpbState | 8;
      CurrentPrcb->BpbState = v13;
      if( (v11 & 8) == 0 )
        CurrentPrcb->BpbState = v13 | 2;
      if( (v11 & 2) != 0 )
      {
        if( (v11 & 0x40) != 0 )
        {
          CurrentPrcb->BpbRetpolineExitSpecCtrl |= 2u;
          if( !v6 )
            CurrentPrcb->BpbKernelSpecCtrl |= 2u;
        }
        else if( (v11 & 0x10) != 0 )
        {
          CurrentPrcb->BpbRetpolineExitSpecCtrl |= 1u;
          if( !v6 )
            CurrentPrcb->BpbKernelSpecCtrl |= 1u;
        }
      }
      goto LABEL_70;
    }
    if( (v11 & 0x10) != 0 )
    {
      CurrentPrcb->BpbRetpolineExitSpecCtrl |= 1u;
      if( !v6 )
        CurrentPrcb->BpbKernelSpecCtrl |= 1u;
      if( (v11 & 0x20) == 0 )
        CurrentPrcb->BpbState |= 2u;
      goto LABEL_70;
    }
    if( (v11 & 0x42) == 66 )
    {
      CurrentPrcb->BpbRetpolineExitSpecCtrl |= 2u;
      if( !v6 )
        CurrentPrcb->BpbKernelSpecCtrl |= 2u;
    }
    BpbState = CurrentPrcb->BpbState;
    if( v6 )
    {
      v15 = BpbState | 0x10;
      CurrentPrcb->BpbState = v15;
      if( (v11 & 0x20) != 0 )
      {
        if( (v11 & 8) != 0 )
          goto LABEL_70;
        v16 = v15 | 0x40;
LABEL_69:
        CurrentPrcb->BpbState = v16;
        goto LABEL_70;
      }
    }
    else
    {
      v15 = BpbState | 8;
      CurrentPrcb->BpbState = v15;
      if( (v11 & 8) != 0 )
        goto LABEL_70;
    }
    v16 = v15 | 2;
    goto LABEL_69;
  }
LABEL_70:
  if( !SecurityDomain || (v11 & 0x800000) == 0 )
  {
LABEL_24:
    CurrentPrcb->BpbTrappedRetpolineExitSpecCtrl &= ~4u;
    goto LABEL_25;
  }
  CurrentPrcb->BpbRetpolineExitSpecCtrl |= 4u;
  CurrentPrcb->BpbTrappedRetpolineExitSpecCtrl |= 4u;
  CurrentPrcb->BpbKernelSpecCtrl |= 4u;
  BpbCurrentSpecCtrl |= 4u;
LABEL_25:
  if( (v11 & 0x42) == 66 && ((v11 & 0x10000) != 0 || (Process->MitigationFlags & 0x40000000) != 0) )
  {
    CurrentPrcb->BpbUserSpecCtrl |= 2u;
    if( v6 )
    {
      if( Process != PsInitialSystemProcess )
        CurrentPrcb->BpbKernelSpecCtrl |= 2u;
    }
  }
  if( v9 )
    CurrentPrcb->BpbUserSpecCtrl |= 2u;
  if( (v11 & 0x800000) != 0 && (Process->MitigationFlags2 & 0x2000) != 0 )
    CurrentPrcb->BpbUserSpecCtrl |= 4u;
  if( !TrappedSecurityDomain
    || TrappedSecurityDomain == SecurityDomain
    || TrappedSecurityDomain == Process->ParentSecurityDomain )
  {
    goto LABEL_88;
  }
  if( (BpbCurrentSpecCtrl & 1) == 0 )
  {
    if( !v12 && (v11 & 0x10) == 0 && (!v6 || (CurrentPrcb->BpbRetpolineState & 2) != 0) )
      goto LABEL_88;
LABEL_86:
    v17 = CurrentPrcb->BpbState | 4;
    CurrentPrcb->BpbState = v17;
    if( (v11 & 8) == 0 )
      CurrentPrcb->BpbState = v17 | 0x20;
    goto LABEL_88;
  }
  if( (v11 & 2) == 0 )
  {
    BpbCurrentSpecCtrl &= 4u;
    goto LABEL_78;
  }
  if( (CurrentPrcb->PairRegister & 4) != 0 )
    goto LABEL_77;
  if( v6 && (CurrentPrcb->BpbRetpolineState & 1) == 0 )
  {
    BpbCurrentSpecCtrl &= 4u;
LABEL_77:
    LOBYTE(v11) = v35;
    goto LABEL_78;
  }
  LOBYTE(v11) = v35;
  if( (v35 & 0x40) != 0 )
    BpbCurrentSpecCtrl = BpbCurrentSpecCtrl & 4 | 2;
LABEL_78:
  if( (BpbCurrentSpecCtrl & 1) != 0 )
    goto LABEL_86;
  v5 = 1;
  v36 = 1;
LABEL_88:
  v18 = BpbCurrentSpecCtrl | 0x80;
  if( !v37 )
    v18 = BpbCurrentSpecCtrl;
  v19 = v18 | 2;
  if( !v9 )
    v19 = v18;
  if( v5 )
  {
    __writemsr(0x49u, 1ui64);
    if( (v11 & 8) == 0 )
      KiFlushCurrentRsb();
    CurrentPrcb->BpbState &= 0xDBu;
    CurrentPrcb->BpbTrappedBpbState &= 0xAFu;
    CurrentPrcb->TrappedSecurityDomain = 0i64;
    CurrentPrcb->BpbTrappedRetpolineExitSpecCtrl = v19;
  }
  v20 = v19;
  if( (CurrentPrcb->PairRegister & 4) == 0 )
    goto LABEL_127;
  if( TrappedSecurityDomain == SecurityDomain )
  {
    BpbUserSpecCtrl = CurrentPrcb->BpbUserSpecCtrl;
    if( (CurrentPrcb->PairPrcb->PairRegister & 1) != 0 )
    {
      CurrentPrcb->BpbUserSpecCtrl = BpbUserSpecCtrl & 0xFD;
      if( v6 )
        CurrentPrcb->BpbKernelSpecCtrl &= ~2u;
    }
    else
    {
      CurrentPrcb->BpbUserSpecCtrl = BpbUserSpecCtrl | 2;
      if( v6 )
        CurrentPrcb->BpbKernelSpecCtrl |= 2u;
    }
  }
  else
  {
    _InterlockedOr16(&CurrentPrcb->PairRegister, 2u);
  }
  if( !SecurityDomain )
  {
    updated = KiUpdateStibpPairing(&Process->Pcb);
    v23 = CurrentPrcb->BpbRetpolineExitSpecCtrl & 3;
    v24 = updated;
    CurrentPrcb->BpbTrappedRetpolineExitSpecCtrl = v23 | CurrentPrcb->BpbTrappedRetpolineExitSpecCtrl & 0xFC;
    if( v6 && (CurrentPrcb->BpbRetpolineState & 1) != 0 )
      v25 = v23 != 0;
    else
      v25 = (CurrentPrcb->BpbKernelSpecCtrl & 3) != 0;
    v26 = 1;
    v20 = (v25 ? 2 : 0) | v19 & 0xFC;
    if( !v38 )
      _InterlockedOr16(&CurrentPrcb->PairRegister, 2u);
    goto LABEL_129;
  }
  if( !v33 )
  {
LABEL_127:
    v24 = 0;
    goto LABEL_128;
  }
  _m_prefetchw((char *)&CurrentPrcb->2 + 14);
  PairRegister = CurrentPrcb->PairRegister;
  do
  {
    v28 = PairRegister;
    PairRegister = _InterlockedCompareExchange16(&CurrentPrcb->PairRegister, PairRegister | 0x100, PairRegister);
  }
  while( v28 != PairRegister );
  v29 = PairRegister & 1;
  if( (KiSpeculationFeatures & 0x2000000) != 0 )
  {
    BpbRetpolineExitSpecCtrl = CurrentPrcb->BpbRetpolineExitSpecCtrl;
    if( (BpbRetpolineExitSpecCtrl & 3) == 0 )
      CurrentPrcb->BpbRetpolineExitSpecCtrl = BpbRetpolineExitSpecCtrl | 2;
    BpbTrappedRetpolineExitSpecCtrl = CurrentPrcb->BpbTrappedRetpolineExitSpecCtrl;
    if( (BpbTrappedRetpolineExitSpecCtrl & 3) == 0 )
      CurrentPrcb->BpbTrappedRetpolineExitSpecCtrl = BpbTrappedRetpolineExitSpecCtrl | 2;
    v20 = v19;
    if( (CurrentPrcb->BpbRetpolineState & 1) == 0 )
      goto LABEL_126;
  }
  else
  {
    BpbKernelSpecCtrl = CurrentPrcb->BpbKernelSpecCtrl;
    if( (BpbKernelSpecCtrl & 3) == 0 )
      CurrentPrcb->BpbKernelSpecCtrl = BpbKernelSpecCtrl | 2;
    v20 = v19;
  }
  if( (v19 & 3) == 0 )
    v20 |= 2u;
LABEL_126:
  _InterlockedOr16(&CurrentPrcb->PairRegister, 2u);
  v24 = v29;
LABEL_128:
  v26 = v36;
LABEL_129:
  if( v20 != CurrentPrcb->BpbCurrentSpecCtrl )
  {
    CurrentPrcb->BpbCurrentSpecCtrl = v20;
    __writemsr(0x48u, v20);
  }
  if( v26 )
    CurrentPrcb->BpbRetpolineState |= 2u;
  _mm_lfence();
  _enable();
  if( v24 )
    KiSynchronizeStibpPairing((INT64)CurrentPrcb);
}

Referenced by:

SwapContext