;------------------------------------------------------------------------------\r
%include "Nasm.inc"\r
\r
+;\r
+; Equivalent NASM structure of IA32_DESCRIPTOR\r
+;\r
+struc IA32_DESCRIPTOR\r
+ .Limit CTYPE_UINT16 1\r
+ .Base CTYPE_UINTN 1\r
+endstruc\r
+\r
+;\r
+; Equivalent NASM structure of IA32_IDT_GATE_DESCRIPTOR\r
+;\r
+struc IA32_IDT_GATE_DESCRIPTOR\r
+ .OffsetLow CTYPE_UINT16 1\r
+ .Selector CTYPE_UINT16 1\r
+ .Reserved_0 CTYPE_UINT8 1\r
+ .GateType CTYPE_UINT8 1\r
+ .OffsetHigh CTYPE_UINT16 1\r
+ .OffsetUpper CTYPE_UINT32 1\r
+ .Reserved_1 CTYPE_UINT32 1\r
+endstruc\r
+\r
;\r
; CommonExceptionHandler()\r
;\r
\r
%define VC_EXCEPTION 29\r
-%define PF_EXCEPTION 14\r
\r
extern ASM_PFX(mErrorCodeFlag) ; Error code flags for exceptions\r
extern ASM_PFX(mDoFarReturnFlag) ; Do far return flag\r
extern ASM_PFX(CommonExceptionHandler)\r
-extern ASM_PFX(FeaturePcdGet (PcdCpuSmmStackGuard))\r
\r
SECTION .data\r
\r
\r
; The follow algorithm is used for clear shadow stack token busy bit.\r
; The comment is based on the sample shadow stack.\r
+ ; Shadow stack is 32 bytes aligned.\r
; The sample shadow stack layout :\r
; Address | Context\r
; +-------------------------+\r
- ; 0xFD0 | FREE | it is 0xFD8|0x02|(LMA & CS.L), after SAVEPREVSSP.\r
+ ; 0xFB8 | FREE | It is 0xFC0|0x02|(LMA & CS.L), after SAVEPREVSSP.\r
; +-------------------------+\r
- ; 0xFD8 | Prev SSP |\r
+ ; 0xFC0 | Prev SSP |\r
; +-------------------------+\r
- ; 0xFE0 | RIP |\r
+ ; 0xFC8 | RIP |\r
; +-------------------------+\r
- ; 0xFE8 | CS |\r
+ ; 0xFD0 | CS |\r
; +-------------------------+\r
- ; 0xFF0 | 0xFF0 | BUSY | BUSY flag cleared after CLRSSBSY\r
+ ; 0xFD8 | 0xFD8 | BUSY | BUSY flag cleared after CLRSSBSY\r
; +-------------------------+\r
- ; 0xFF8 | 0xFD8|0x02|(LMA & CS.L) |\r
+ ; 0xFE0 | 0xFC0|0x02|(LMA & CS.L) |\r
; +-------------------------+\r
; Instructions for Intel Control Flow Enforcement Technology (CET) are supported since NASM version 2.15.01.\r
cmp qword [ASM_PFX(mDoFarReturnFlag)], 0\r
jz CetDone\r
- cmp qword [rbp + 8], PF_EXCEPTION ; check if it is a Page Fault\r
- jnz CetDone\r
- cmp byte [dword ASM_PFX(FeaturePcdGet (PcdCpuSmmStackGuard))], 0\r
- jz CetDone\r
mov rax, cr4\r
- and rax, 0x800000 ; check if CET is enabled\r
+ and rax, 0x800000 ; Check if CET is enabled\r
+ jz CetDone\r
+ sub rsp, 0x10\r
+ sidt [rsp]\r
+ mov rcx, qword [rsp + IA32_DESCRIPTOR.Base]; Get IDT base address\r
+ add rsp, 0x10\r
+ mov rax, qword [rbp + 8]; Get exception number\r
+ sal rax, 0x04 ; Get IDT offset\r
+ add rax, rcx ; Get IDT gate descriptor address\r
+ mov al, byte [rax + IA32_IDT_GATE_DESCRIPTOR.Reserved_0]\r
+ and rax, 0x01 ; Check IST field\r
jz CetDone\r
- ; SSP should be 0xFD8 at this point\r
+ ; SSP should be 0xFC0 at this point\r
mov rax, 0x04 ; advance past cs:lip:prevssp;supervisor shadow stack token\r
- INCSSP_RAX ; After this SSP should be 0xFF8\r
- SAVEPREVSSP ; now the shadow stack restore token will be created at 0xFD0\r
- READSSP_RAX ; Read new SSP, SSP should be 0x1000\r
+ INCSSP_RAX ; After this SSP should be 0xFE0\r
+ SAVEPREVSSP ; now the shadow stack restore token will be created at 0xFB8\r
+ READSSP_RAX ; Read new SSP, SSP should be 0xFE8\r
sub rax, 0x10\r
- CLRSSBSY_RAX ; Clear token at 0xFF0, SSP should be 0 after this\r
+ CLRSSBSY_RAX ; Clear token at 0xFD8, SSP should be 0 after this\r
sub rax, 0x20\r
- RSTORSSP_RAX ; Restore to token at 0xFD0, new SSP will be 0xFD0\r
+ RSTORSSP_RAX ; Restore to token at 0xFB8, new SSP will be 0xFB8\r
mov rax, 0x01 ; Pop off the new save token created\r
- INCSSP_RAX ; SSP should be 0xFD8 now\r
+ INCSSP_RAX ; SSP should be 0xFC0 now\r
CetDone:\r
\r
cli\r