Skip to content

Commit

Permalink
UefiCpuPkg: restore strict page attributes via #DB in nonstop mode only
Browse files Browse the repository at this point in the history
REF: https://bugzilla.tianocore.org/show_bug.cgi?id=1576

The root cause of this issue is that non-stop mode of Heap Guard and
NULL Detection set TF bit (single-step) in EFLAG unconditionally in
the common handler in CpuExceptionLib.

If PcdCpuSmmStaticPageTable is FALSE, the SMM will only create page
table for memory below 4G. If SMM tries to access memory beyond 4G,
a page fault exception will be triggered and the memory to access
will be added to page table so that SMM code can continue the access.

Because of above issue, the TF bit is set after the page fault is
handled and then fall into another DEBUG exception. Since non-stop
mode of Heap Guard and NULL Detection are not enabled, no special
DEBUG exception handler is registered. The default handler just
prints exception context and go into dead loop.

Actually EFLAGS can be changed in any standard exception handler.
There's no need to do single-step setup in assembly code. So the fix
is to move the logic to C code part of page fault exception handler
so that we can fully validate the configuration and prevent TF bit
from being set unexpectedly.

Fixes: dcc0262
       16b918b
Test:
 - Pass special test of accessing memory beyond 4G in SMM mode
 - Boot to OS with Qemu emulator platform (Fedora27, Ubuntu18.04,
   Windows7, Windows10)

Cc: Eric Dong <eric.dong@intel.com>
Cc: Laszlo Ersek <lersek@redhat.com>
Cc: Ruiyu Ni <ruiyu.ni@intel.com>
Cc: Star Zeng <star.zeng@intel.com>
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Jian J Wang <jian.j.wang@intel.com>
Acked-by: Laszlo Ersek <lersek@redhat.com>
Reviewed-by: Eric Dong <eric.dong@intel.com>
  • Loading branch information
jwang36 committed Mar 1, 2019
1 parent a6c63ee commit 2a93ccc
Show file tree
Hide file tree
Showing 3 changed files with 10 additions and 12 deletions.
11 changes: 10 additions & 1 deletion UefiCpuPkg/CpuDxe/CpuPageTable.c
Expand Up @@ -1300,7 +1300,16 @@ PageFaultExceptionHandler (
// Display ExceptionType, CPU information and Image information
//
DumpCpuContext (ExceptionType, SystemContext);
if (!NonStopMode) {
if (NonStopMode) {
//
// Set TF in EFLAGS
//
if (mPagingContext.MachineType == IMAGE_FILE_MACHINE_I386) {
SystemContext.SystemContextIa32->Eflags |= (UINT32)BIT8;
} else {
SystemContext.SystemContextX64->Rflags |= (UINT64)BIT8;
}
} else {
CpuDeadLoop ();
}
}
Expand Down
Expand Up @@ -383,13 +383,6 @@ ErrorCodeAndVectorOnStack:
pop dword [ebp - 4]
mov esp, ebp
pop ebp

; Enable TF bit after page fault handler runs
cmp dword [esp], 14 ; #PF?
jne .5
bts dword [esp + 16], 8 ; EFLAGS

.5:
add esp, 8
cmp dword [esp - 16], 0 ; check EXCEPTION_HANDLER_CONTEXT.OldIdtHandler
jz DoReturn
Expand Down
Expand Up @@ -336,10 +336,6 @@ HasErrorCode:
pop r15

mov rsp, rbp
cmp qword [rbp + 8], 14 ; #PF?
jne .1
bts qword [rsp + 40], 8 ; RFLAGS.TF
.1:
pop rbp
add rsp, 16
cmp qword [rsp - 32], 0 ; check EXCEPTION_HANDLER_CONTEXT.OldIdtHandler
Expand Down

0 comments on commit 2a93ccc

Please sign in to comment.