TianoCore EDK2 master
Loading...
Searching...
No Matches
PageTbl.c
Go to the documentation of this file.
1
11#include "PiSmmCpuCommon.h"
12
19UINT32
21 VOID
22 )
23{
24 UINTN PageFaultHandlerHookAddress;
25 IA32_IDT_GATE_DESCRIPTOR *IdtEntry;
26 EFI_STATUS Status;
27
28 //
29 // Initialize spin lock
30 //
31 InitializeSpinLock (mPFLock);
32
33 mPhysicalAddressBits = 32;
34 mPagingMode = PagingPae;
35
36 if (mSmmProfileEnabled ||
37 HEAP_GUARD_NONSTOP_MODE ||
38 NULL_DETECTION_NONSTOP_MODE)
39 {
40 //
41 // Set own Page Fault entry instead of the default one, because SMM Profile
42 // feature depends on IRET instruction to do Single Step
43 //
44 PageFaultHandlerHookAddress = (UINTN)PageFaultIdtHandlerSmmProfile;
45 IdtEntry = (IA32_IDT_GATE_DESCRIPTOR *)gcSmiIdtr.Base;
46 IdtEntry += EXCEPT_IA32_PAGE_FAULT;
47 IdtEntry->Bits.OffsetLow = (UINT16)PageFaultHandlerHookAddress;
48 IdtEntry->Bits.Reserved_0 = 0;
49 IdtEntry->Bits.GateType = IA32_IDT_GATE_TYPE_INTERRUPT_32;
50 IdtEntry->Bits.OffsetHigh = (UINT16)(PageFaultHandlerHookAddress >> 16);
51 } else {
52 //
53 // Register SMM Page Fault Handler
54 //
55 Status = SmmRegisterExceptionHandler (&mSmmCpuService, EXCEPT_IA32_PAGE_FAULT, SmiPFHandler);
56 ASSERT_EFI_ERROR (Status);
57 }
58
59 //
60 // Additional SMM IDT initialization for SMM stack guard
61 //
62 if (FeaturePcdGet (PcdCpuSmmStackGuard)) {
64 }
65
66 return GenSmmPageTable (PagingPae, mPhysicalAddressBits);
67}
68
75UINT64
77 VOID
78 )
79{
80 CpuDeadLoop ();
81
82 return 0;
83}
84
93VOID
94EFIAPI
96 IN EFI_EXCEPTION_TYPE InterruptType,
97 IN EFI_SYSTEM_CONTEXT SystemContext
98 )
99{
100 UINTN PFAddress;
101 UINTN GuardPageAddress;
102 UINTN CpuIndex;
103
104 ASSERT (InterruptType == EXCEPT_IA32_PAGE_FAULT);
105
106 AcquireSpinLock (mPFLock);
107
108 PFAddress = AsmReadCr2 ();
109
110 //
111 // If a page fault occurs in SMRAM range, it might be in a SMM stack guard page,
112 // or SMM page protection violation.
113 //
114 if ((PFAddress >= mCpuHotPlugData.SmrrBase) &&
115 (PFAddress < (mCpuHotPlugData.SmrrBase + mCpuHotPlugData.SmrrSize)))
116 {
117 DumpCpuContext (InterruptType, SystemContext);
118 CpuIndex = GetCpuIndex ();
119 GuardPageAddress = (mSmmStackArrayBase + EFI_PAGE_SIZE + CpuIndex * mSmmStackSize);
120 if ((FeaturePcdGet (PcdCpuSmmStackGuard)) &&
121 (PFAddress >= GuardPageAddress) &&
122 (PFAddress < (GuardPageAddress + EFI_PAGE_SIZE)))
123 {
124 DEBUG ((DEBUG_ERROR, "SMM stack overflow!\n"));
125 } else {
126 if ((SystemContext.SystemContextIa32->ExceptionData & IA32_PF_EC_ID) != 0) {
127 DEBUG ((DEBUG_ERROR, "SMM exception at execution (0x%x)\n", PFAddress));
128 DEBUG_CODE (
129 DumpModuleInfoByIp (*(UINTN *)(UINTN)SystemContext.SystemContextIa32->Esp);
130 );
131 } else {
132 DEBUG ((DEBUG_ERROR, "SMM exception at access (0x%x)\n", PFAddress));
133 DEBUG_CODE (
134 DumpModuleInfoByIp ((UINTN)SystemContext.SystemContextIa32->Eip);
135 );
136 }
137
138 if (HEAP_GUARD_NONSTOP_MODE) {
139 GuardPagePFHandler (SystemContext.SystemContextIa32->ExceptionData);
140 goto Exit;
141 }
142 }
143
144 CpuDeadLoop ();
145 goto Exit;
146 }
147
148 //
149 // If a page fault occurs in non-SMRAM range.
150 //
151 if ((PFAddress < mCpuHotPlugData.SmrrBase) ||
152 (PFAddress >= mCpuHotPlugData.SmrrBase + mCpuHotPlugData.SmrrSize))
153 {
154 if ((SystemContext.SystemContextIa32->ExceptionData & IA32_PF_EC_ID) != 0) {
155 DumpCpuContext (InterruptType, SystemContext);
156 DEBUG ((DEBUG_ERROR, "Code executed on IP(0x%x) out of SMM range after SMM is locked!\n", PFAddress));
157 DEBUG_CODE (
158 DumpModuleInfoByIp (*(UINTN *)(UINTN)SystemContext.SystemContextIa32->Esp);
159 );
160 CpuDeadLoop ();
161 goto Exit;
162 }
163
164 //
165 // If NULL pointer was just accessed
166 //
167 if (((PcdGet8 (PcdNullPointerDetectionPropertyMask) & BIT1) != 0) &&
168 (PFAddress < EFI_PAGE_SIZE))
169 {
170 DumpCpuContext (InterruptType, SystemContext);
171 DEBUG ((DEBUG_ERROR, "!!! NULL pointer access !!!\n"));
172 DEBUG_CODE (
173 DumpModuleInfoByIp ((UINTN)SystemContext.SystemContextIa32->Eip);
174 );
175
176 if (NULL_DETECTION_NONSTOP_MODE) {
177 GuardPagePFHandler (SystemContext.SystemContextIa32->ExceptionData);
178 goto Exit;
179 }
180
181 CpuDeadLoop ();
182 goto Exit;
183 }
184
185 if (IsSmmCommBufferForbiddenAddress (PFAddress)) {
186 DEBUG ((DEBUG_ERROR, "Access SMM communication forbidden address (0x%x)!\n", PFAddress));
187 }
188 }
189
190 if (mSmmProfileEnabled) {
192 SystemContext.SystemContextIa32->Eip,
193 SystemContext.SystemContextIa32->ExceptionData
194 );
195 } else {
196 DumpCpuContext (InterruptType, SystemContext);
197 DEBUG_CODE (
198 DumpModuleInfoByIp ((UINTN)SystemContext.SystemContextIa32->Eip);
199 );
200 CpuDeadLoop ();
201 }
202
203Exit:
204 ReleaseSpinLock (mPFLock);
205}
206
212VOID
214 OUT UINTN *Cr2
215 )
216{
217 return;
218}
219
225VOID
227 IN UINTN Cr2
228 )
229{
230 return;
231}
UINT64 UINTN
VOID EFIAPI CpuDeadLoop(VOID)
Definition: CpuDeadLoop.c:25
EFI_STATUS EFIAPI SmmRegisterExceptionHandler(IN EFI_SMM_CPU_SERVICE_PROTOCOL *This, IN EFI_EXCEPTION_TYPE ExceptionType, IN EFI_CPU_INTERRUPT_HANDLER InterruptHandler)
Definition: CpuService.c:353
UINTN EFIAPI AsmReadCr2(VOID)
UINT32 SmmInitPageTable(VOID)
Definition: PageTbl.c:20
UINT64 AllocPage(VOID)
Definition: PageTbl.c:76
VOID RestoreCr2(IN UINTN Cr2)
Definition: PageTbl.c:226
VOID EFIAPI SmiPFHandler(IN EFI_EXCEPTION_TYPE InterruptType, IN EFI_SYSTEM_CONTEXT SystemContext)
Definition: PageTbl.c:95
VOID SaveCr2(OUT UINTN *Cr2)
Definition: PageTbl.c:213
VOID EFIAPI InitializeIDTSmmStackGuard(VOID)
Definition: SmmFuncsArch.c:29
VOID EFIAPI DumpCpuContext(IN EFI_EXCEPTION_TYPE ExceptionType, IN EFI_SYSTEM_CONTEXT SystemContext)
#define IN
Definition: Base.h:279
#define OUT
Definition: Base.h:284
#define ASSERT_EFI_ERROR(StatusParameter)
Definition: DebugLib.h:462
#define DEBUG(Expression)
Definition: DebugLib.h:434
#define DEBUG_CODE(Expression)
Definition: DebugLib.h:590
INTN EFI_EXCEPTION_TYPE
Definition: DebugSupport.h:35
BOOLEAN IsSmmCommBufferForbiddenAddress(IN UINT64 Address)
#define PcdGet8(TokenName)
Definition: PcdLib.h:336
#define FeaturePcdGet(TokenName)
Definition: PcdLib.h:50
VOID DumpModuleInfoByIp(IN UINTN CallerIpAddress)
UINTN GenSmmPageTable(IN PAGING_MODE PagingMode, IN UINT8 PhysicalAddressBits)
VOID SmmProfilePFHandler(UINTN Rip, UINTN ErrorCode)
Definition: SmmProfile.c:1249
VOID GuardPagePFHandler(UINTN ErrorCode)
Definition: SmmProfile.c:1208
UINTN GetCpuIndex(VOID)
Definition: SmmProfile.c:166
VOID EFIAPI PageFaultIdtHandlerSmmProfile(VOID)
SPIN_LOCK *EFIAPI AcquireSpinLock(IN OUT SPIN_LOCK *SpinLock)
SPIN_LOCK *EFIAPI InitializeSpinLock(OUT SPIN_LOCK *SpinLock)
SPIN_LOCK *EFIAPI ReleaseSpinLock(IN OUT SPIN_LOCK *SpinLock)
VOID EFIAPI Exit(IN EFI_STATUS Status)
RETURN_STATUS EFI_STATUS
Definition: UefiBaseType.h:29