Compare commits
4 Commits
edk2-stabl
...
edk2-stabl
Author | SHA1 | Date | |
---|---|---|---|
|
bb1bba3d77 | ||
|
4c7ce0d285 | ||
|
e1e7306b54 | ||
|
455b0347a7 |
@@ -885,6 +885,13 @@ AhciPrintStatusBlock (
|
||||
IN UINT32 DebugLevel
|
||||
)
|
||||
{
|
||||
//
|
||||
// Skip NULL pointer
|
||||
//
|
||||
if (AtaStatusBlock == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
// Only print status and error since we have all of the rest printed as
|
||||
// a part of command block print.
|
||||
|
@@ -1700,6 +1700,7 @@ ON_EXIT:
|
||||
}
|
||||
|
||||
FreePool (Dns4TokenEntry->Token->RspData.H2AData);
|
||||
Dns4TokenEntry->Token->RspData.H2AData = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1731,6 +1732,7 @@ ON_EXIT:
|
||||
}
|
||||
|
||||
FreePool (Dns6TokenEntry->Token->RspData.H2AData);
|
||||
Dns6TokenEntry->Token->RspData.H2AData = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -18,7 +18,7 @@
|
||||
|
||||
static UINTN MicrovmGedBase (VOID)
|
||||
{
|
||||
VOID *Address = (VOID*) MICROVM_GED_MMIO_BASE_REGS;
|
||||
VOID *Address = (VOID*)(UINTN) MICROVM_GED_MMIO_BASE_REGS;
|
||||
|
||||
if (EfiGoneVirtual ()) {
|
||||
EfiConvertPointer (0, &Address);
|
||||
|
@@ -15,17 +15,36 @@
|
||||
;------------------------------------------------------------------------------
|
||||
%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
|
||||
; SSP should be 0xFD8 at this point
|
||||
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 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
|
||||
|
@@ -861,35 +861,58 @@ PiCpuSmmEntry (
|
||||
mSmmStackSize = EFI_PAGES_TO_SIZE (EFI_SIZE_TO_PAGES (PcdGet32 (PcdCpuSmmStackSize)));
|
||||
if (FeaturePcdGet (PcdCpuSmmStackGuard)) {
|
||||
//
|
||||
// 2 more pages is allocated for each processor.
|
||||
// one is guard page and the other is known good stack.
|
||||
// SMM Stack Guard Enabled
|
||||
// 2 more pages is allocated for each processor, one is guard page and the other is known good stack.
|
||||
//
|
||||
// +-------------------------------------------+-----+-------------------------------------------+
|
||||
// +--------------------------------------------------+-----+--------------------------------------------------+
|
||||
// | Known Good Stack | Guard Page | SMM Stack | ... | Known Good Stack | Guard Page | SMM Stack |
|
||||
// +-------------------------------------------+-----+-------------------------------------------+
|
||||
// +--------------------------------------------------+-----+--------------------------------------------------+
|
||||
// | 4K | 4K PcdCpuSmmStackSize| | 4K | 4K PcdCpuSmmStackSize|
|
||||
// |<---------------- mSmmStackSize ----------------->| |<---------------- mSmmStackSize ----------------->|
|
||||
// | | | |
|
||||
// |<-------------- Processor 0 -------------->| |<-------------- Processor n -------------->|
|
||||
// |<------------------ Processor 0 ----------------->| |<------------------ Processor n ----------------->|
|
||||
//
|
||||
mSmmStackSize += EFI_PAGES_TO_SIZE (2);
|
||||
}
|
||||
|
||||
mSmmShadowStackSize = 0;
|
||||
if ((PcdGet32 (PcdControlFlowEnforcementPropertyMask) != 0) && mCetSupported) {
|
||||
mSmmShadowStackSize = EFI_PAGES_TO_SIZE (EFI_SIZE_TO_PAGES (PcdGet32 (PcdCpuSmmShadowStackSize)));
|
||||
|
||||
if (FeaturePcdGet (PcdCpuSmmStackGuard)) {
|
||||
//
|
||||
// SMM Stack Guard Enabled
|
||||
// Append Shadow Stack after normal stack
|
||||
// 2 more pages is allocated for each processor, one is guard page and the other is known good shadow stack.
|
||||
//
|
||||
// |= Stacks
|
||||
// +--------------------------------------------------+---------------------------------------------------------------+
|
||||
// | Known Good Stack | Guard Page | SMM Stack | Known Good Shadow Stack | Guard Page | SMM Shadow Stack |
|
||||
// +--------------------------------------------------+---------------------------------------------------------------+
|
||||
// | |PcdCpuSmmStackSize| |PcdCpuSmmShadowStackSize|
|
||||
// | 4K | 4K |PcdCpuSmmStackSize| 4K | 4K |PcdCpuSmmShadowStackSize|
|
||||
// |<---------------- mSmmStackSize ----------------->|<--------------------- mSmmShadowStackSize ------------------->|
|
||||
// | |
|
||||
// |<-------------------------------------------- Processor N ------------------------------------------------------->|
|
||||
//
|
||||
mSmmShadowStackSize = EFI_PAGES_TO_SIZE (EFI_SIZE_TO_PAGES (PcdGet32 (PcdCpuSmmShadowStackSize)));
|
||||
if (FeaturePcdGet (PcdCpuSmmStackGuard)) {
|
||||
mSmmShadowStackSize += EFI_PAGES_TO_SIZE (2);
|
||||
} else {
|
||||
//
|
||||
// SMM Stack Guard Disabled (Known Good Stack is still required for potential stack switch.)
|
||||
// Append Shadow Stack after normal stack with 1 more page as known good shadow stack.
|
||||
// 1 more pages is allocated for each processor, it is known good stack.
|
||||
//
|
||||
//
|
||||
// |= Stacks
|
||||
// +-------------------------------------+--------------------------------------------------+
|
||||
// | Known Good Stack | SMM Stack | Known Good Shadow Stack | SMM Shadow Stack |
|
||||
// +-------------------------------------+--------------------------------------------------+
|
||||
// | 4K |PcdCpuSmmStackSize| 4K |PcdCpuSmmShadowStackSize|
|
||||
// |<---------- mSmmStackSize ---------->|<--------------- mSmmShadowStackSize ------------>|
|
||||
// | |
|
||||
// |<-------------------------------- Processor N ----------------------------------------->|
|
||||
//
|
||||
mSmmShadowStackSize += EFI_PAGES_TO_SIZE (1);
|
||||
mSmmStackSize += EFI_PAGES_TO_SIZE (1);
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -557,6 +557,20 @@ InitializeIDTSmmStackGuard (
|
||||
VOID
|
||||
);
|
||||
|
||||
/**
|
||||
Initialize IDT IST Field.
|
||||
|
||||
@param[in] ExceptionType Exception type.
|
||||
@param[in] Ist IST value.
|
||||
|
||||
**/
|
||||
VOID
|
||||
EFIAPI
|
||||
InitializeIdtIst (
|
||||
IN EFI_EXCEPTION_TYPE ExceptionType,
|
||||
IN UINT8 Ist
|
||||
);
|
||||
|
||||
/**
|
||||
Initialize Gdt for all processors.
|
||||
|
||||
|
@@ -481,7 +481,17 @@ SmmInitPageTable (
|
||||
// Additional SMM IDT initialization for SMM stack guard
|
||||
//
|
||||
if (FeaturePcdGet (PcdCpuSmmStackGuard)) {
|
||||
InitializeIDTSmmStackGuard ();
|
||||
DEBUG ((DEBUG_INFO, "Initialize IDT IST field for SMM Stack Guard\n"));
|
||||
InitializeIdtIst (EXCEPT_IA32_PAGE_FAULT, 1);
|
||||
}
|
||||
|
||||
//
|
||||
// Additional SMM IDT initialization for SMM CET shadow stack
|
||||
//
|
||||
if ((PcdGet32 (PcdControlFlowEnforcementPropertyMask) != 0) && mCetSupported) {
|
||||
DEBUG ((DEBUG_INFO, "Initialize IDT IST field for SMM Shadow Stack\n"));
|
||||
InitializeIdtIst (EXCEPT_IA32_PAGE_FAULT, 1);
|
||||
InitializeIdtIst (EXCEPT_IA32_MACHINE_CHECK, 1);
|
||||
}
|
||||
|
||||
//
|
||||
|
@@ -24,24 +24,24 @@ UINT32 mCetInterruptSspTable;
|
||||
UINTN mSmmInterruptSspTables;
|
||||
|
||||
/**
|
||||
Initialize IDT for SMM Stack Guard.
|
||||
Initialize IDT IST Field.
|
||||
|
||||
@param[in] ExceptionType Exception type.
|
||||
@param[in] Ist IST value.
|
||||
|
||||
**/
|
||||
VOID
|
||||
EFIAPI
|
||||
InitializeIDTSmmStackGuard (
|
||||
VOID
|
||||
InitializeIdtIst (
|
||||
IN EFI_EXCEPTION_TYPE ExceptionType,
|
||||
IN UINT8 Ist
|
||||
)
|
||||
{
|
||||
IA32_IDT_GATE_DESCRIPTOR *IdtGate;
|
||||
|
||||
//
|
||||
// If SMM Stack Guard feature is enabled, set the IST field of
|
||||
// the interrupt gate for Page Fault Exception to be 1
|
||||
//
|
||||
IdtGate = (IA32_IDT_GATE_DESCRIPTOR *)gcSmiIdtr.Base;
|
||||
IdtGate += EXCEPT_IA32_PAGE_FAULT;
|
||||
IdtGate->Bits.Reserved_0 = 1;
|
||||
IdtGate += ExceptionType;
|
||||
IdtGate->Bits.Reserved_0 = Ist;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -89,7 +89,7 @@ InitGdt (
|
||||
GdtDescriptor->Bits.BaseMid = (UINT8)((UINTN)TssBase >> 16);
|
||||
GdtDescriptor->Bits.BaseHigh = (UINT8)((UINTN)TssBase >> 24);
|
||||
|
||||
if (FeaturePcdGet (PcdCpuSmmStackGuard)) {
|
||||
if ((FeaturePcdGet (PcdCpuSmmStackGuard)) || ((PcdGet32 (PcdControlFlowEnforcementPropertyMask) != 0) && mCetSupported)) {
|
||||
//
|
||||
// Setup top of known good stack as IST1 for each processor.
|
||||
//
|
||||
@@ -177,8 +177,16 @@ InitShadowStack (
|
||||
|
||||
if ((PcdGet32 (PcdControlFlowEnforcementPropertyMask) != 0) && mCetSupported) {
|
||||
SmmShadowStackSize = EFI_PAGES_TO_SIZE (EFI_SIZE_TO_PAGES (PcdGet32 (PcdCpuSmmShadowStackSize)));
|
||||
//
|
||||
// Add 1 page as known good shadow stack
|
||||
//
|
||||
SmmShadowStackSize += EFI_PAGES_TO_SIZE (1);
|
||||
|
||||
if (FeaturePcdGet (PcdCpuSmmStackGuard)) {
|
||||
SmmShadowStackSize += EFI_PAGES_TO_SIZE (2);
|
||||
//
|
||||
// Add one guard page between Known Good Shadow Stack and SMM Shadow Stack.
|
||||
//
|
||||
SmmShadowStackSize += EFI_PAGES_TO_SIZE (1);
|
||||
}
|
||||
mCetPl0Ssp = (UINT32)((UINTN)ShadowStack + SmmShadowStackSize - sizeof(UINT64));
|
||||
PatchInstructionX86 (mPatchCetPl0Ssp, mCetPl0Ssp, 4);
|
||||
@@ -186,7 +194,6 @@ InitShadowStack (
|
||||
DEBUG ((DEBUG_INFO, "ShadowStack - 0x%x\n", ShadowStack));
|
||||
DEBUG ((DEBUG_INFO, " SmmShadowStackSize - 0x%x\n", SmmShadowStackSize));
|
||||
|
||||
if (FeaturePcdGet (PcdCpuSmmStackGuard)) {
|
||||
if (mSmmInterruptSspTables == 0) {
|
||||
mSmmInterruptSspTables = (UINTN)AllocateZeroPool(sizeof(UINT64) * 8 * gSmmCpuPrivate->SmmCoreEntryContext.NumberOfCpus);
|
||||
ASSERT (mSmmInterruptSspTables != 0);
|
||||
@@ -194,14 +201,15 @@ InitShadowStack (
|
||||
}
|
||||
|
||||
//
|
||||
// The highest address on the stack (0xFF8) is a save-previous-ssp token pointing to a location that is 40 bytes away - 0xFD0.
|
||||
// The supervisor shadow stack token is just above it at address 0xFF0. This is where the interrupt SSP table points.
|
||||
// The highest address on the stack (0xFE0) is a save-previous-ssp token pointing to a location that is 40 bytes away - 0xFB8.
|
||||
// The supervisor shadow stack token is just above it at address 0xFD8. This is where the interrupt SSP table points.
|
||||
// So when an interrupt of exception occurs, we can use SAVESSP/RESTORESSP/CLEARSSBUSY for the supervisor shadow stack,
|
||||
// due to the reason the RETF in SMM exception handler cannot clear the BUSY flag with same CPL.
|
||||
// (only IRET or RETF with different CPL can clear BUSY flag)
|
||||
// Please refer to UefiCpuPkg/Library/CpuExceptionHandlerLib/X64 for the full stack frame at runtime.
|
||||
// According to SDM (ver. 075 June 2021), shadow stack should be 32 bytes aligned.
|
||||
//
|
||||
InterruptSsp = (UINT32)((UINTN)ShadowStack + EFI_PAGES_TO_SIZE(1) - sizeof(UINT64));
|
||||
InterruptSsp = (UINT32)(((UINTN)ShadowStack + EFI_PAGES_TO_SIZE(1) - (sizeof(UINT64) * 4)) & ~0x1f);
|
||||
*(UINT64 *)(UINTN)InterruptSsp = (InterruptSsp - sizeof(UINT64) * 4) | 0x2;
|
||||
mCetInterruptSsp = InterruptSsp - sizeof(UINT64);
|
||||
|
||||
@@ -214,5 +222,4 @@ InitShadowStack (
|
||||
DEBUG ((DEBUG_INFO, "mCetInterruptSspTable - 0x%x\n", mCetInterruptSspTable));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user