summaryrefslogtreecommitdiffstats
path: root/UefiCpuPkg/Library/CpuExceptionHandlerLib
diff options
context:
space:
mode:
authorSheng, W <w.sheng@intel.com>2021-11-12 09:40:28 +0800
committermergify[bot] <37929162+mergify[bot]@users.noreply.github.com>2021-11-12 12:50:19 +0000
commit455b0347a7c55d3842e87b20259659a22f7e62a5 (patch)
tree6fdc4bbd12ba2f5943bd5a4ff27e9c91bfe5ead0 /UefiCpuPkg/Library/CpuExceptionHandlerLib
parent466ebdd2e0919c1538d03cd59833704bd5e1c028 (diff)
downloadedk2-455b0347a7c55d3842e87b20259659a22f7e62a5.tar.gz
edk2-455b0347a7c55d3842e87b20259659a22f7e62a5.tar.bz2
edk2-455b0347a7c55d3842e87b20259659a22f7e62a5.zip
UefiCpuPkg/PiSmmCpuDxeSmm: Use SMM Interrupt Shadow Stack
When CET shadow stack feature is enabled, it needs to use IST for the exceptions, and uses interrupt shadow stack for the stack switch. Shadow stack should be 32 bytes aligned. Check IST field, when clear shadow stack token busy bit when using retf. REF: https://bugzilla.tianocore.org/show_bug.cgi?id=3728 Signed-off-by: Sheng Wei <w.sheng@intel.com> Cc: Eric Dong <eric.dong@intel.com> Cc: Ray Ni <ray.ni@intel.com> Cc: Rahul Kumar <rahul1.kumar@intel.com> Reviewed-by: Ray Ni <ray.ni@intel.com>
Diffstat (limited to 'UefiCpuPkg/Library/CpuExceptionHandlerLib')
-rw-r--r--UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/Xcode5ExceptionHandlerAsm.nasm66
1 files changed, 46 insertions, 20 deletions
diff --git a/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/Xcode5ExceptionHandlerAsm.nasm b/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/Xcode5ExceptionHandlerAsm.nasm
index 4881a02848..84a12ddb88 100644
--- a/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/Xcode5ExceptionHandlerAsm.nasm
+++ b/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/Xcode5ExceptionHandlerAsm.nasm
@@ -16,16 +16,35 @@
%include "Nasm.inc"
;
+; Equivalent NASM structure of IA32_DESCRIPTOR
+;
+struc IA32_DESCRIPTOR
+ .Limit CTYPE_UINT16 1
+ .Base CTYPE_UINTN 1
+endstruc
+
+;
+; Equivalent NASM structure of IA32_IDT_GATE_DESCRIPTOR
+;
+struc IA32_IDT_GATE_DESCRIPTOR
+ .OffsetLow CTYPE_UINT16 1
+ .Selector CTYPE_UINT16 1
+ .Reserved_0 CTYPE_UINT8 1
+ .GateType CTYPE_UINT8 1
+ .OffsetHigh CTYPE_UINT16 1
+ .OffsetUpper CTYPE_UINT32 1
+ .Reserved_1 CTYPE_UINT32 1
+endstruc
+
+;
; CommonExceptionHandler()
;
%define VC_EXCEPTION 29
-%define PF_EXCEPTION 14
extern ASM_PFX(mErrorCodeFlag) ; Error code flags for exceptions
extern ASM_PFX(mDoFarReturnFlag) ; Do far return flag
extern ASM_PFX(CommonExceptionHandler)
-extern ASM_PFX(FeaturePcdGet (PcdCpuSmmStackGuard))
SECTION .data
@@ -282,42 +301,49 @@ DrFinish:
; The follow algorithm is used for clear shadow stack token busy bit.
; The comment is based on the sample shadow stack.
+ ; Shadow stack is 32 bytes aligned.
; The sample shadow stack layout :
; Address | Context
; +-------------------------+
- ; 0xFD0 | FREE | it is 0xFD8|0x02|(LMA & CS.L), after SAVEPREVSSP.
+ ; 0xFB8 | FREE | It is 0xFC0|0x02|(LMA & CS.L), after SAVEPREVSSP.
; +-------------------------+
- ; 0xFD8 | Prev SSP |
+ ; 0xFC0 | Prev SSP |
; +-------------------------+
- ; 0xFE0 | RIP |
+ ; 0xFC8 | RIP |
; +-------------------------+
- ; 0xFE8 | CS |
+ ; 0xFD0 | CS |
; +-------------------------+
- ; 0xFF0 | 0xFF0 | BUSY | BUSY flag cleared after CLRSSBSY
+ ; 0xFD8 | 0xFD8 | BUSY | BUSY flag cleared after CLRSSBSY
; +-------------------------+
- ; 0xFF8 | 0xFD8|0x02|(LMA & CS.L) |
+ ; 0xFE0 | 0xFC0|0x02|(LMA & CS.L) |
; +-------------------------+
; Instructions for Intel Control Flow Enforcement Technology (CET) are supported since NASM version 2.15.01.
cmp qword [ASM_PFX(mDoFarReturnFlag)], 0
jz CetDone
- cmp qword [rbp + 8], PF_EXCEPTION ; check if it is a Page Fault
- jnz CetDone
- cmp byte [dword ASM_PFX(FeaturePcdGet (PcdCpuSmmStackGuard))], 0
- jz CetDone
mov rax, cr4
- and rax, 0x800000 ; check if CET is enabled
+ and rax, 0x800000 ; Check if CET is enabled
+ jz CetDone
+ sub rsp, 0x10
+ sidt [rsp]
+ mov rcx, qword [rsp + IA32_DESCRIPTOR.Base]; Get IDT base address
+ add rsp, 0x10
+ mov rax, qword [rbp + 8]; Get exception number
+ sal rax, 0x04 ; Get IDT offset
+ add rax, rcx ; Get IDT gate descriptor address
+ mov al, byte [rax + IA32_IDT_GATE_DESCRIPTOR.Reserved_0]
+ and rax, 0x01 ; Check IST field
jz CetDone
- ; SSP should be 0xFD8 at this point
+ ; SSP should be 0xFC0 at this point
mov rax, 0x04 ; advance past cs:lip:prevssp;supervisor shadow stack token
- INCSSP_RAX ; After this SSP should be 0xFF8
- SAVEPREVSSP ; now the shadow stack restore token will be created at 0xFD0
- READSSP_RAX ; Read new SSP, SSP should be 0x1000
+ INCSSP_RAX ; After this SSP should be 0xFE0
+ SAVEPREVSSP ; now the shadow stack restore token will be created at 0xFB8
+ READSSP_RAX ; Read new SSP, SSP should be 0xFE8
sub rax, 0x10
- CLRSSBSY_RAX ; Clear token at 0xFF0, SSP should be 0 after this
+ CLRSSBSY_RAX ; Clear token at 0xFD8, SSP should be 0 after this
sub rax, 0x20
- RSTORSSP_RAX ; Restore to token at 0xFD0, new SSP will be 0xFD0
+ RSTORSSP_RAX ; Restore to token at 0xFB8, new SSP will be 0xFB8
mov rax, 0x01 ; Pop off the new save token created
- INCSSP_RAX ; SSP should be 0xFD8 now
+ INCSSP_RAX ; SSP should be 0xFC0 now
CetDone:
cli