summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/Xcode5ExceptionHandlerAsm.nasm83
-rw-r--r--UefiCpuPkg/PiSmmCpuDxeSmm/X64/SmmFuncsArch.c2
2 files changed, 43 insertions, 42 deletions
diff --git a/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/Xcode5ExceptionHandlerAsm.nasm b/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/Xcode5ExceptionHandlerAsm.nasm
index ebe0eec874..4881a02848 100644
--- a/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/Xcode5ExceptionHandlerAsm.nasm
+++ b/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/Xcode5ExceptionHandlerAsm.nasm
@@ -20,6 +20,7 @@
;
%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
@@ -279,6 +280,46 @@ DrFinish:
call ASM_PFX(CommonExceptionHandler)
add rsp, 4 * 8 + 8
+ ; The follow algorithm is used for clear shadow stack token busy bit.
+ ; The comment is based on the sample shadow stack.
+ ; The sample shadow stack layout :
+ ; Address | Context
+ ; +-------------------------+
+ ; 0xFD0 | FREE | it is 0xFD8|0x02|(LMA & CS.L), after SAVEPREVSSP.
+ ; +-------------------------+
+ ; 0xFD8 | Prev SSP |
+ ; +-------------------------+
+ ; 0xFE0 | RIP |
+ ; +-------------------------+
+ ; 0xFE8 | CS |
+ ; +-------------------------+
+ ; 0xFF0 | 0xFF0 | BUSY | BUSY flag cleared after CLRSSBSY
+ ; +-------------------------+
+ ; 0xFF8 | 0xFD8|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
+ jz CetDone
+ ; SSP should be 0xFD8 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
+ sub rax, 0x10
+ CLRSSBSY_RAX ; Clear token at 0xFF0, SSP should be 0 after this
+ sub rax, 0x20
+ RSTORSSP_RAX ; Restore to token at 0xFD0, new SSP will be 0xFD0
+ mov rax, 0x01 ; Pop off the new save token created
+ INCSSP_RAX ; SSP should be 0xFD8 now
+CetDone:
+
cli
;; UINT64 ExceptionData;
add rsp, 8
@@ -373,47 +414,7 @@ DoReturn:
push qword [rax + 0x18] ; save EFLAGS in new location
mov rax, [rax] ; restore rax
popfq ; restore EFLAGS
-
- ; The follow algorithm is used for clear shadow stack token busy bit.
- ; The comment is based on the sample shadow stack.
- ; The sample shadow stack layout :
- ; Address | Context
- ; +-------------------------+
- ; 0xFD0 | FREE | it is 0xFD8|0x02|(LMA & CS.L), after SAVEPREVSSP.
- ; +-------------------------+
- ; 0xFD8 | Prev SSP |
- ; +-------------------------+
- ; 0xFE0 | RIP |
- ; +-------------------------+
- ; 0xFE8 | CS |
- ; +-------------------------+
- ; 0xFF0 | 0xFF0 | BUSY | BUSY flag cleared after CLRSSBSY
- ; +-------------------------+
- ; 0xFF8 | 0xFD8|0x02|(LMA & CS.L) |
- ; +-------------------------+
- ; Instructions for Intel Control Flow Enforcement Technology (CET) are supported since NASM version 2.15.01.
- push rax ; SSP should be 0xFD8 at this point
- cmp byte [dword ASM_PFX(FeaturePcdGet (PcdCpuSmmStackGuard))], 0
- jz CetDone
- mov rax, cr4
- and rax, 0x800000 ; check if CET is enabled
- jz CetDone
- 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
- push rax
- sub rax, 0x10
- CLRSSBSY_RAX ; Clear token at 0xFF0, SSP should be 0 after this
- sub rax, 0x20
- RSTORSSP_RAX ; Restore to token at 0xFD0, new SSP will be 0xFD0
- pop rax
- mov rax, 0x01 ; Pop off the new save token created
- INCSSP_RAX ; SSP should be 0xFD8 now
-CetDone:
- pop rax ; restore rax
-
- DB 0x48 ; prefix to composite "retq" with next "retf"
+ DB 0x48 ; prefix to composite "retq" with next "retf"
retf ; far return
DoIret:
iretq
diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/X64/SmmFuncsArch.c b/UefiCpuPkg/PiSmmCpuDxeSmm/X64/SmmFuncsArch.c
index 661c1ba294..ca3f5ff91a 100644
--- a/UefiCpuPkg/PiSmmCpuDxeSmm/X64/SmmFuncsArch.c
+++ b/UefiCpuPkg/PiSmmCpuDxeSmm/X64/SmmFuncsArch.c
@@ -202,7 +202,7 @@ InitShadowStack (
// Please refer to UefiCpuPkg/Library/CpuExceptionHandlerLib/X64 for the full stack frame at runtime.
//
InterruptSsp = (UINT32)((UINTN)ShadowStack + EFI_PAGES_TO_SIZE(1) - sizeof(UINT64));
- *(UINT32 *)(UINTN)InterruptSsp = (InterruptSsp - sizeof(UINT64) * 4) | 0x2;
+ *(UINT64 *)(UINTN)InterruptSsp = (InterruptSsp - sizeof(UINT64) * 4) | 0x2;
mCetInterruptSsp = InterruptSsp - sizeof(UINT64);
mCetInterruptSspTable = (UINT32)(UINTN)(mSmmInterruptSspTables + sizeof(UINT64) * 8 * CpuIndex);