]> git.proxmox.com Git - mirror_edk2.git/blobdiff - UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/Xcode5ExceptionHandlerAsm.nasm
UefiCpuPkg/PiSmmCpuDxeSmm: Use SMM Interrupt Shadow Stack
[mirror_edk2.git] / UefiCpuPkg / Library / CpuExceptionHandlerLib / X64 / Xcode5ExceptionHandlerAsm.nasm
index 4881a02848f3d8efc1e272f74bb07b98ba21de99..84a12ddb88d7dafd02c833c6d81c806b3ff90124 100644 (file)
 ;------------------------------------------------------------------------------\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
@@ -282,42 +301,49 @@ DrFinish:
 \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