mirror of
https://github.com/tianocore/edk2
synced 2026-08-27 00:23:19 -04:00
UefiCpuPkg: Set up 256 IDT Descs in SEC/PEI/SMM
Currently, SEC, PEI, and SMM only set up 32 - 34 IDT descs. This means that any exceptions received above that number will cause a #GP fault. This commit updates these environments to follow DXE and set up the IDT with the architecturally defined 256 entries, each of which point to the common exception handler. This does two things: - Has well defined behavior for receiving exceptions in these environments instead of relying on a #GP fault to occur. - Allows the stack cookie interrupt (0x42) to be routed correctly instead of appearing as a #GP fault. Signed-off-by: Oliver Smith-Denny <osde@microsoft.com>
This commit is contained in:
parent
3ed9aceeb8
commit
3454d7ab41
17 changed files with 38 additions and 46 deletions
|
|
@ -10,8 +10,6 @@
|
|||
#include "CpuMp.h"
|
||||
#include "CpuPageTable.h"
|
||||
|
||||
#define CPU_INTERRUPT_NUM 256
|
||||
|
||||
//
|
||||
// Global Variables
|
||||
//
|
||||
|
|
@ -720,11 +718,11 @@ InitInterruptDescriptorTable (
|
|||
|
||||
AsmReadIdtr (&IdtDescriptor);
|
||||
IdtEntryCount = (IdtDescriptor.Limit + 1) / sizeof (IA32_IDT_GATE_DESCRIPTOR);
|
||||
if (IdtEntryCount < CPU_INTERRUPT_NUM) {
|
||||
if (IdtEntryCount < X86_CPU_INTERRUPT_NUM) {
|
||||
//
|
||||
// Increase Interrupt Descriptor Table and Copy the old IDT table in
|
||||
//
|
||||
IdtTable = AllocateZeroPool (sizeof (IA32_IDT_GATE_DESCRIPTOR) * CPU_INTERRUPT_NUM);
|
||||
IdtTable = AllocateZeroPool (sizeof (IA32_IDT_GATE_DESCRIPTOR) * X86_CPU_INTERRUPT_NUM);
|
||||
ASSERT (IdtTable != NULL);
|
||||
CopyMem (IdtTable, (VOID *)IdtDescriptor.Base, sizeof (IA32_IDT_GATE_DESCRIPTOR) * IdtEntryCount);
|
||||
|
||||
|
|
@ -732,7 +730,7 @@ InitInterruptDescriptorTable (
|
|||
// Load Interrupt Descriptor Table
|
||||
//
|
||||
IdtDescriptor.Base = (UINTN)IdtTable;
|
||||
IdtDescriptor.Limit = (UINT16)(sizeof (IA32_IDT_GATE_DESCRIPTOR) * CPU_INTERRUPT_NUM - 1);
|
||||
IdtDescriptor.Limit = (UINT16)(sizeof (IA32_IDT_GATE_DESCRIPTOR) * X86_CPU_INTERRUPT_NUM - 1);
|
||||
AsmWriteIdtr (&IdtDescriptor);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -19,8 +19,6 @@
|
|||
#include <Library/SynchronizationLib.h>
|
||||
#include <Library/CpuExceptionHandlerLib.h>
|
||||
|
||||
#define CPU_EXCEPTION_NUM 32
|
||||
#define CPU_INTERRUPT_NUM 256
|
||||
#define HOOKAFTER_STUB_SIZE 18
|
||||
|
||||
//
|
||||
|
|
|
|||
|
|
@ -14,10 +14,10 @@
|
|||
|
||||
CONST UINTN mDoFarReturnFlag = 0;
|
||||
|
||||
RESERVED_VECTORS_DATA mReservedVectorsData[CPU_INTERRUPT_NUM];
|
||||
EFI_CPU_INTERRUPT_HANDLER mExternalInterruptHandlerTable[CPU_INTERRUPT_NUM];
|
||||
RESERVED_VECTORS_DATA mReservedVectorsData[X86_CPU_INTERRUPT_NUM];
|
||||
EFI_CPU_INTERRUPT_HANDLER mExternalInterruptHandlerTable[X86_CPU_INTERRUPT_NUM];
|
||||
EXCEPTION_HANDLER_DATA mExceptionHandlerData = {
|
||||
CPU_INTERRUPT_NUM,
|
||||
X86_CPU_INTERRUPT_NUM,
|
||||
0, // To be fixed
|
||||
mReservedVectorsData,
|
||||
mExternalInterruptHandlerTable
|
||||
|
|
|
|||
|
|
@ -243,7 +243,7 @@ ArchSetupExceptionStack (
|
|||
// Fixup TSS
|
||||
//
|
||||
Vector = StackSwitchExceptions[Index];
|
||||
if ((Vector >= CPU_EXCEPTION_NUM) ||
|
||||
if ((Vector >= X86_CPU_INTERRUPT_NUM) ||
|
||||
(Vector >= (Idtr.Limit + 1) / sizeof (IA32_IDT_GATE_DESCRIPTOR)))
|
||||
{
|
||||
continue;
|
||||
|
|
|
|||
|
|
@ -168,7 +168,7 @@ InitializeCpuExceptionHandlers (
|
|||
EXCEPTION_HANDLER_DATA *ExceptionHandlerData;
|
||||
RESERVED_VECTORS_DATA *ReservedVectors;
|
||||
|
||||
ReservedVectors = AllocatePool (sizeof (RESERVED_VECTORS_DATA) * CPU_EXCEPTION_NUM);
|
||||
ReservedVectors = AllocatePool (sizeof (RESERVED_VECTORS_DATA) * X86_CPU_INTERRUPT_NUM);
|
||||
if (ReservedVectors == NULL) {
|
||||
ASSERT (ReservedVectors != NULL);
|
||||
return EFI_OUT_OF_RESOURCES;
|
||||
|
|
@ -181,7 +181,7 @@ InitializeCpuExceptionHandlers (
|
|||
return EFI_OUT_OF_RESOURCES;
|
||||
}
|
||||
|
||||
ExceptionHandlerData->IdtEntryCount = CPU_EXCEPTION_NUM;
|
||||
ExceptionHandlerData->IdtEntryCount = X86_CPU_INTERRUPT_NUM;
|
||||
ExceptionHandlerData->ReservedVectors = ReservedVectors;
|
||||
ExceptionHandlerData->ExternalInterruptHandler = AllocateZeroPool (sizeof (EFI_CPU_INTERRUPT_HANDLER) * ExceptionHandlerData->IdtEntryCount);
|
||||
InitializeSpinLock (&ExceptionHandlerData->DisplayMessageSpinLock);
|
||||
|
|
|
|||
|
|
@ -134,7 +134,7 @@ CommonExceptionHandlerWorker (
|
|||
(ExternalInterruptHandler[ExceptionType] != NULL))
|
||||
{
|
||||
(ExternalInterruptHandler[ExceptionType])(ExceptionType, SystemContext);
|
||||
} else if (ExceptionType < CPU_EXCEPTION_NUM) {
|
||||
} else if (ExceptionType < X86_CPU_INTERRUPT_NUM) {
|
||||
//
|
||||
// Get Spinlock to display CPU information
|
||||
//
|
||||
|
|
@ -271,7 +271,7 @@ InitializeCpuExceptionHandlersWorker (
|
|||
|
||||
//
|
||||
// Setup the exception handlers according to IDT size, but no more than
|
||||
// ExceptionHandlerData->IdtEntryCount (32 in PEI and SMM, 256 in DXE) handlers.
|
||||
// ExceptionHandlerData->IdtEntryCount (256) handlers.
|
||||
//
|
||||
AsmReadIdtr (&IdtDescriptor);
|
||||
IdtEntryCount = (IdtDescriptor.Limit + 1) / sizeof (IA32_IDT_GATE_DESCRIPTOR);
|
||||
|
|
|
|||
|
|
@ -108,7 +108,7 @@ InitializeCpuExceptionHandlers (
|
|||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
RESERVED_VECTORS_DATA ReservedVectorData[CPU_EXCEPTION_NUM];
|
||||
RESERVED_VECTORS_DATA ReservedVectorData[X86_CPU_INTERRUPT_NUM];
|
||||
IA32_DESCRIPTOR IdtDescriptor;
|
||||
UINTN IdtEntryCount;
|
||||
UINT16 CodeSegment;
|
||||
|
|
@ -118,8 +118,8 @@ InitializeCpuExceptionHandlers (
|
|||
UINTN InterruptHandler;
|
||||
|
||||
if (VectorInfo != NULL) {
|
||||
SetMem ((VOID *)ReservedVectorData, sizeof (RESERVED_VECTORS_DATA) * CPU_EXCEPTION_NUM, 0xff);
|
||||
Status = ReadAndVerifyVectorInfo (VectorInfo, ReservedVectorData, CPU_EXCEPTION_NUM);
|
||||
SetMem ((VOID *)ReservedVectorData, sizeof (RESERVED_VECTORS_DATA) * X86_CPU_INTERRUPT_NUM, 0xff);
|
||||
Status = ReadAndVerifyVectorInfo (VectorInfo, ReservedVectorData, X86_CPU_INTERRUPT_NUM);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
|
@ -130,11 +130,11 @@ InitializeCpuExceptionHandlers (
|
|||
//
|
||||
AsmReadIdtr (&IdtDescriptor);
|
||||
IdtEntryCount = (IdtDescriptor.Limit + 1) / sizeof (IA32_IDT_GATE_DESCRIPTOR);
|
||||
if (IdtEntryCount > CPU_EXCEPTION_NUM) {
|
||||
if (IdtEntryCount > X86_CPU_INTERRUPT_NUM) {
|
||||
//
|
||||
// CPU exception library only setup CPU_EXCEPTION_NUM exception handler at most
|
||||
// CPU exception library only setup X86_CPU_INTERRUPT_NUM exception handler at most
|
||||
//
|
||||
IdtEntryCount = CPU_EXCEPTION_NUM;
|
||||
IdtEntryCount = X86_CPU_INTERRUPT_NUM;
|
||||
}
|
||||
|
||||
//
|
||||
|
|
|
|||
|
|
@ -11,10 +11,10 @@
|
|||
|
||||
CONST UINTN mDoFarReturnFlag = 1;
|
||||
|
||||
RESERVED_VECTORS_DATA mReservedVectorsData[CPU_EXCEPTION_NUM];
|
||||
EFI_CPU_INTERRUPT_HANDLER mExternalInterruptHandlerTable[CPU_EXCEPTION_NUM];
|
||||
RESERVED_VECTORS_DATA mReservedVectorsData[X86_CPU_INTERRUPT_NUM];
|
||||
EFI_CPU_INTERRUPT_HANDLER mExternalInterruptHandlerTable[X86_CPU_INTERRUPT_NUM];
|
||||
EXCEPTION_HANDLER_DATA mExceptionHandlerData = {
|
||||
CPU_EXCEPTION_NUM,
|
||||
X86_CPU_INTERRUPT_NUM,
|
||||
0, // To be fixed
|
||||
mReservedVectorsData,
|
||||
mExternalInterruptHandlerTable
|
||||
|
|
|
|||
|
|
@ -54,7 +54,6 @@
|
|||
#define UNIT_TEST_APP_NAME "Cpu Exception Handler Lib Unit Tests"
|
||||
#define UNIT_TEST_APP_VERSION "1.0"
|
||||
|
||||
#define CPU_INTERRUPT_NUM 256
|
||||
#define SPEC_MAX_EXCEPTION_NUM 22
|
||||
#define CR4_RESERVED_BIT BIT15
|
||||
|
||||
|
|
|
|||
|
|
@ -26,10 +26,10 @@ InitializeBspIdt (
|
|||
|
||||
Idtr = AllocateZeroPool (sizeof (IA32_DESCRIPTOR));
|
||||
ASSERT (Idtr != NULL);
|
||||
NewIdtTable = AllocateZeroPool (sizeof (IA32_IDT_GATE_DESCRIPTOR) * CPU_INTERRUPT_NUM);
|
||||
NewIdtTable = AllocateZeroPool (sizeof (IA32_IDT_GATE_DESCRIPTOR) * X86_CPU_INTERRUPT_NUM);
|
||||
ASSERT (NewIdtTable != NULL);
|
||||
Idtr->Base = (UINTN)NewIdtTable;
|
||||
Idtr->Limit = (UINT16)(sizeof (IA32_IDT_GATE_DESCRIPTOR) * CPU_INTERRUPT_NUM - 1);
|
||||
Idtr->Limit = (UINT16)(sizeof (IA32_IDT_GATE_DESCRIPTOR) * X86_CPU_INTERRUPT_NUM - 1);
|
||||
|
||||
AsmWriteIdtr (Idtr);
|
||||
return Idtr;
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ InitializeBspIdt (
|
|||
|
||||
Idtr = AllocateZeroPool (sizeof (IA32_DESCRIPTOR));
|
||||
ASSERT (Idtr != NULL);
|
||||
NewIdtTable = AllocateZeroPool (sizeof (IA32_IDT_GATE_DESCRIPTOR) * CPU_INTERRUPT_NUM + sizeof (UINTN));
|
||||
NewIdtTable = AllocateZeroPool (sizeof (IA32_IDT_GATE_DESCRIPTOR) * X86_CPU_INTERRUPT_NUM + sizeof (UINTN));
|
||||
ASSERT (NewIdtTable != NULL);
|
||||
//
|
||||
// Store original PeiServicePointer before new Idt table
|
||||
|
|
@ -36,7 +36,7 @@ InitializeBspIdt (
|
|||
NewIdtTable = (UINTN *)((UINTN)NewIdtTable + sizeof (UINTN));
|
||||
|
||||
Idtr->Base = (UINTN)NewIdtTable;
|
||||
Idtr->Limit = (UINT16)(sizeof (IA32_IDT_GATE_DESCRIPTOR) * CPU_INTERRUPT_NUM - 1);
|
||||
Idtr->Limit = (UINT16)(sizeof (IA32_IDT_GATE_DESCRIPTOR) * X86_CPU_INTERRUPT_NUM - 1);
|
||||
|
||||
AsmWriteIdtr (Idtr);
|
||||
return Idtr;
|
||||
|
|
|
|||
|
|
@ -240,7 +240,7 @@ ArchSetupExceptionStack (
|
|||
// Set the IST field to enable corresponding IST
|
||||
//
|
||||
Vector = StackSwitchExceptions[Index];
|
||||
if ((Vector >= CPU_EXCEPTION_NUM) ||
|
||||
if ((Vector >= X86_CPU_INTERRUPT_NUM) ||
|
||||
(Vector >= (Idtr.Limit + 1) / sizeof (IA32_IDT_GATE_DESCRIPTOR)))
|
||||
{
|
||||
continue;
|
||||
|
|
|
|||
|
|
@ -33,11 +33,10 @@ SECTION .text
|
|||
|
||||
ALIGN 8
|
||||
|
||||
; Generate 32 IDT vectors.
|
||||
; 32 IDT vectors are enough because interrupts (32+) are not enabled in SEC and PEI phase.
|
||||
; Generate 256 IDT vectors.
|
||||
AsmIdtVectorBegin:
|
||||
%assign Vector 0
|
||||
%rep 32
|
||||
%rep 256
|
||||
push byte %[Vector]
|
||||
push rax
|
||||
mov rax, ASM_PFX(CommonInterruptEntry)
|
||||
|
|
@ -390,7 +389,7 @@ global ASM_PFX(AsmGetTemplateAddressMap)
|
|||
ASM_PFX(AsmGetTemplateAddressMap):
|
||||
lea rax, [AsmIdtVectorBegin]
|
||||
mov qword [rcx], rax
|
||||
mov qword [rcx + 0x8], (AsmIdtVectorEnd - AsmIdtVectorBegin) / 32
|
||||
mov qword [rcx + 0x8], (AsmIdtVectorEnd - AsmIdtVectorBegin) / 256
|
||||
lea rax, [HookAfterStubHeaderBegin]
|
||||
mov qword [rcx + 0x10], rax
|
||||
ret
|
||||
|
|
|
|||
|
|
@ -274,10 +274,10 @@ InitSmmIdt (
|
|||
CONST EFI_PEI_SERVICES **PeiServices;
|
||||
|
||||
//
|
||||
// There are 32 (not 255) entries in it since only processor
|
||||
// generated exceptions will be handled.
|
||||
// Populate 255 entries to ensure that a known state occurs
|
||||
// for all possible exception vectors.
|
||||
//
|
||||
gcSmmInitIdtr.Limit = (sizeof (IA32_IDT_GATE_DESCRIPTOR) * 32) - 1;
|
||||
gcSmmInitIdtr.Limit = (sizeof (IA32_IDT_GATE_DESCRIPTOR) * X86_CPU_INTERRUPT_NUM) - 1;
|
||||
|
||||
//
|
||||
// Allocate for IDT.
|
||||
|
|
|
|||
|
|
@ -105,9 +105,9 @@ SmmRestoreCpu (
|
|||
//
|
||||
// Setup X64 IDT table
|
||||
//
|
||||
ZeroMem (IdtEntryTable, sizeof (IA32_IDT_GATE_DESCRIPTOR) * 32);
|
||||
ZeroMem (IdtEntryTable, sizeof (IA32_IDT_GATE_DESCRIPTOR) * X86_CPU_INTERRUPT_NUM);
|
||||
X64Idtr.Base = (UINTN)IdtEntryTable;
|
||||
X64Idtr.Limit = (UINT16)(sizeof (IA32_IDT_GATE_DESCRIPTOR) * 32 - 1);
|
||||
X64Idtr.Limit = (UINT16)(sizeof (IA32_IDT_GATE_DESCRIPTOR) * X86_CPU_INTERRUPT_NUM - 1);
|
||||
AsmWriteIdtr ((IA32_DESCRIPTOR *)&X64Idtr);
|
||||
|
||||
//
|
||||
|
|
|
|||
|
|
@ -138,10 +138,10 @@ InitializeSmmIdt (
|
|||
IA32_DESCRIPTOR DxeIdtr;
|
||||
|
||||
//
|
||||
// There are 32 (not 255) entries in it since only processor
|
||||
// generated exceptions will be handled.
|
||||
// Populate 255 entries to ensure that a known state occurs
|
||||
// for all possible exception vectors.
|
||||
//
|
||||
gcSmiIdtr.Limit = (sizeof (IA32_IDT_GATE_DESCRIPTOR) * 32) - 1;
|
||||
gcSmiIdtr.Limit = (sizeof (IA32_IDT_GATE_DESCRIPTOR) * X86_CPU_INTERRUPT_NUM) - 1;
|
||||
//
|
||||
// Allocate page aligned IDT, because it might be set as read only.
|
||||
//
|
||||
|
|
|
|||
|
|
@ -12,8 +12,6 @@
|
|||
|
||||
#if defined (MDE_CPU_IA32) || defined (MDE_CPU_X64)
|
||||
|
||||
#define SEC_IDT_ENTRY_COUNT 34
|
||||
|
||||
typedef struct _SEC_IDT_TABLE {
|
||||
//
|
||||
// Reserved 8 bytes preceding IDT to store EFI_PEI_SERVICES**, since IDT base
|
||||
|
|
@ -22,7 +20,7 @@ typedef struct _SEC_IDT_TABLE {
|
|||
// EFI_PEI_SERVICES**
|
||||
//
|
||||
UINT64 PeiService;
|
||||
IA32_IDT_GATE_DESCRIPTOR IdtTable[SEC_IDT_ENTRY_COUNT];
|
||||
IA32_IDT_GATE_DESCRIPTOR IdtTable[X86_CPU_INTERRUPT_NUM];
|
||||
} SEC_IDT_TABLE;
|
||||
|
||||
//
|
||||
|
|
@ -218,7 +216,7 @@ SecStartup (
|
|||
// |-------------------|----> TempRamBase
|
||||
|
||||
IdtTableInStack.PeiService = 0;
|
||||
for (Index = 0; Index < SEC_IDT_ENTRY_COUNT; Index++) {
|
||||
for (Index = 0; Index < X86_CPU_INTERRUPT_NUM; Index++) {
|
||||
ZeroMem ((VOID *)&IdtTableInStack.IdtTable[Index], sizeof (IA32_IDT_GATE_DESCRIPTOR));
|
||||
CopyMem ((VOID *)&IdtTableInStack.IdtTable[Index], (VOID *)&mIdtEntryTemplate, sizeof (UINT64));
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue