+ mov rbx, [rsp + 0x8] ; rbx <- CpuIndex\r
+\r
+; enable CET if supported\r
+ mov al, strict byte 1 ; source operand may be patched\r
+ASM_PFX(mPatchCetSupported):\r
+ cmp al, 0\r
+ jz CetDone\r
+\r
+ mov ecx, MSR_IA32_S_CET\r
+ rdmsr\r
+ push rdx\r
+ push rax\r
+\r
+ mov ecx, MSR_IA32_PL0_SSP\r
+ rdmsr\r
+ push rdx\r
+ push rax\r
+\r
+ mov ecx, MSR_IA32_INTERRUPT_SSP_TABLE_ADDR\r
+ rdmsr\r
+ push rdx\r
+ push rax\r
+\r
+ mov ecx, MSR_IA32_S_CET\r
+ mov eax, MSR_IA32_CET_SH_STK_EN\r
+ xor edx, edx\r
+ wrmsr\r
+\r
+ mov ecx, MSR_IA32_PL0_SSP\r
+ mov eax, strict dword 0 ; source operand will be patched\r
+ASM_PFX(mPatchCetPl0Ssp):\r
+ xor edx, edx\r
+ wrmsr\r
+ mov rcx, cr0\r
+ btr ecx, 16 ; clear WP\r
+ mov cr0, rcx\r
+ mov [eax], eax ; reload SSP, and clear busyflag.\r
+ xor ecx, ecx\r
+ mov [eax + 4], ecx\r
+\r
+ mov ecx, MSR_IA32_INTERRUPT_SSP_TABLE_ADDR\r
+ mov eax, strict dword 0 ; source operand will be patched\r
+ASM_PFX(mPatchCetInterruptSspTable):\r
+ xor edx, edx\r
+ wrmsr\r
+\r
+ mov eax, strict dword 0 ; source operand will be patched\r
+ASM_PFX(mPatchCetInterruptSsp):\r
+ cmp eax, 0\r
+ jz CetInterruptDone\r
+ mov [eax], eax ; reload SSP, and clear busyflag.\r
+ xor ecx, ecx\r
+ mov [eax + 4], ecx\r
+CetInterruptDone:\r
+\r
+ mov rcx, cr0\r
+ bts ecx, 16 ; set WP\r
+ mov cr0, rcx\r
+\r
+ mov eax, 0x668 | CR4_CET\r
+ mov cr4, rax\r
+\r
+ SETSSBSY\r
+\r
+CetDone:\r