]> git.proxmox.com Git - mirror_edk2.git/commitdiff
UefiCpuPkg/PiSmmCpuDxeSmm: Enable NXE if it's supported
authorJian J Wang <jian.j.wang@intel.com>
Mon, 15 Jan 2018 02:16:26 +0000 (10:16 +0800)
committerRuiyu Ni <ruiyu.ni@intel.com>
Thu, 18 Jan 2018 09:03:24 +0000 (17:03 +0800)
If PcdDxeNxMemoryProtectionPolicy is set to enable protection for memory
of EfiBootServicesCode, EfiConventionalMemory, the BIOS will hang at a page
fault exception triggered by PiSmmCpuDxeSmm.

The root cause is that PiSmmCpuDxeSmm will access default SMM RAM starting
at 0x30000 which is marked as non-executable, but NX feature was not
enabled during SMM initialization. Accessing memory which has invalid
attributes set will cause page fault exception. This patch fixes it by
checking NX capability in cpuid and enable NXE in EFER MSR if it's
available.

Cc: Jiewen Yao <jiewen.yao@intel.com>
Cc: Ruiyu Ni <ruiyu.ni@intel.com>
Cc: Eric Dong <eric.dong@intel.com>
Cc: Laszlo Ersek <lersek@redhat.com>
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Jian J Wang <jian.j.wang@intel.com>
Reviewed-by: Eric Dong <eric.dong@intel.com>
UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/SmmInit.nasm
UefiCpuPkg/PiSmmCpuDxeSmm/X64/SmmInit.nasm

index a5c62e77ce5e0204989ad4e05f44f5dae282b07d..e96dd8d2392aea0d321100d455c829a8c98b182b 100644 (file)
@@ -42,6 +42,11 @@ ASM_PFX(gcSmiInitGdtr):
 \r
 global ASM_PFX(SmmStartup)\r
 ASM_PFX(SmmStartup):\r
+    DB      0x66\r
+    mov     eax, 0x80000001             ; read capability\r
+    cpuid\r
+    DB      0x66\r
+    mov     ebx, edx                    ; rdmsr will change edx. keep it in ebx.\r
     DB      0x66, 0xb8\r
 ASM_PFX(gSmmCr3): DD 0\r
     mov     cr3, eax\r
@@ -50,6 +55,15 @@ ASM_PFX(gSmmCr3): DD 0
     DB      0x66, 0xb8\r
 ASM_PFX(gSmmCr4): DD 0\r
     mov     cr4, eax\r
+    DB      0x66\r
+    mov     ecx, 0xc0000080             ; IA32_EFER MSR\r
+    rdmsr\r
+    DB      0x66\r
+    test    ebx, BIT20                  ; check NXE capability\r
+    jz      .1\r
+    or      ah, BIT3                    ; set NXE bit\r
+    wrmsr\r
+.1:\r
     DB      0x66, 0xb8\r
 ASM_PFX(gSmmCr0): DD 0\r
     DB      0xbf, PROTECT_MODE_DS, 0    ; mov di, PROTECT_MODE_DS\r
index 2701689c3de4afa75fbac1a107a557bc974d7339..b147e72180191afae903c082f5a50b59822e41d1 100644 (file)
@@ -42,6 +42,11 @@ ASM_PFX(gcSmiInitGdtr):
 \r
 global ASM_PFX(SmmStartup)\r
 ASM_PFX(SmmStartup):\r
+    DB      0x66\r
+    mov     eax, 0x80000001             ; read capability\r
+    cpuid\r
+    DB      0x66\r
+    mov     ebx, edx                    ; rdmsr will change edx. keep it in ebx.\r
     DB      0x66, 0xb8                   ; mov eax, imm32\r
 ASM_PFX(gSmmCr3): DD 0\r
     mov     cr3, rax\r
@@ -54,7 +59,12 @@ ASM_PFX(gSmmCr4): DD 0
     DB      0x66\r
     mov     ecx, 0xc0000080             ; IA32_EFER MSR\r
     rdmsr\r
-    or      ah, 1                       ; set LME bit\r
+    or      ah, BIT0                    ; set LME bit\r
+    DB      0x66\r
+    test    ebx, BIT20                  ; check NXE capability\r
+    jz      .1\r
+    or      ah, BIT3                    ; set NXE bit\r
+.1:\r
     wrmsr\r
     DB      0x66, 0xb8                   ; mov eax, imm32\r
 ASM_PFX(gSmmCr0): DD 0\r