diff options
Diffstat (limited to 'IntelFsp2Pkg')
-rw-r--r-- | IntelFsp2Pkg/FspSecCore/Fsp24SecCoreM.inf | 1 | ||||
-rw-r--r-- | IntelFsp2Pkg/FspSecCore/FspSecCoreM.inf | 1 | ||||
-rw-r--r-- | IntelFsp2Pkg/FspSecCore/Ia32/Fsp24ApiEntryM.nasm | 30 | ||||
-rw-r--r-- | IntelFsp2Pkg/FspSecCore/Ia32/FspApiEntryM.nasm | 30 | ||||
-rw-r--r-- | IntelFsp2Pkg/FspSecCore/X64/Fsp24ApiEntryM.nasm | 33 | ||||
-rw-r--r-- | IntelFsp2Pkg/FspSecCore/X64/FspApiEntryM.nasm | 33 | ||||
-rw-r--r-- | IntelFsp2Pkg/IntelFsp2Pkg.dec | 8 | ||||
-rw-r--r-- | IntelFsp2Pkg/Library/BaseFspCommonLib/FspCommonLib.c | 31 | ||||
-rw-r--r-- | IntelFsp2Pkg/Library/BaseFspSwitchStackLib/BaseFspSwitchStackLib.inf | 4 | ||||
-rw-r--r-- | IntelFsp2Pkg/Library/BaseFspSwitchStackLib/Ia32/Stack.nasm | 132 | ||||
-rw-r--r-- | IntelFsp2Pkg/Library/BaseFspSwitchStackLib/X64/Stack.nasm | 109 |
11 files changed, 382 insertions, 30 deletions
diff --git a/IntelFsp2Pkg/FspSecCore/Fsp24SecCoreM.inf b/IntelFsp2Pkg/FspSecCore/Fsp24SecCoreM.inf index 762d485bab..40ff9f22f7 100644 --- a/IntelFsp2Pkg/FspSecCore/Fsp24SecCoreM.inf +++ b/IntelFsp2Pkg/FspSecCore/Fsp24SecCoreM.inf @@ -69,6 +69,7 @@ gIntelFsp2PkgTokenSpaceGuid.PcdFspHeapSizePercentage ## CONSUMES
gIntelFsp2PkgTokenSpaceGuid.PcdFspMaxInterruptSupported ## CONSUMES
gIntelFsp2PkgTokenSpaceGuid.PcdFspPrivateTemporaryRamSize ## CONSUMES
+ gIntelFsp2PkgTokenSpaceGuid.PcdFspSaveRestorePageTableEnable ## CONSUMES
[Ppis]
gEfiTemporaryRamSupportPpiGuid ## PRODUCES
diff --git a/IntelFsp2Pkg/FspSecCore/FspSecCoreM.inf b/IntelFsp2Pkg/FspSecCore/FspSecCoreM.inf index 3acf4f6f9d..ac572a6168 100644 --- a/IntelFsp2Pkg/FspSecCore/FspSecCoreM.inf +++ b/IntelFsp2Pkg/FspSecCore/FspSecCoreM.inf @@ -68,6 +68,7 @@ gIntelFsp2PkgTokenSpaceGuid.PcdFspHeapSizePercentage ## CONSUMES
gIntelFsp2PkgTokenSpaceGuid.PcdFspMaxInterruptSupported ## CONSUMES
gIntelFsp2PkgTokenSpaceGuid.PcdFspPrivateTemporaryRamSize ## CONSUMES
+ gIntelFsp2PkgTokenSpaceGuid.PcdFspSaveRestorePageTableEnable ## CONSUMES
[Ppis]
gEfiTemporaryRamSupportPpiGuid ## PRODUCES
diff --git a/IntelFsp2Pkg/FspSecCore/Ia32/Fsp24ApiEntryM.nasm b/IntelFsp2Pkg/FspSecCore/Ia32/Fsp24ApiEntryM.nasm index 5fa5c03569..e9bf0cbed2 100644 --- a/IntelFsp2Pkg/FspSecCore/Ia32/Fsp24ApiEntryM.nasm +++ b/IntelFsp2Pkg/FspSecCore/Ia32/Fsp24ApiEntryM.nasm @@ -13,6 +13,7 @@ extern ASM_PFX(PcdGet32(PcdTemporaryRamBase))
extern ASM_PFX(PcdGet32(PcdFspTemporaryRamSize))
extern ASM_PFX(PcdGet8 (PcdFspHeapSizePercentage))
+extern ASM_PFX(FeaturePcdGet (PcdFspSaveRestorePageTableEnable))
struc FSPM_UPD_COMMON
; FSP_UPD_HEADER {
@@ -64,7 +65,7 @@ extern ASM_PFX(AsmGetFspInfoHeader) extern ASM_PFX(FspMultiPhaseMemInitApiHandler)
STACK_SAVED_EAX_OFFSET EQU 4 * 7 ; size of a general purpose register * eax index
-API_PARAM1_OFFSET EQU 34h ; ApiParam1 [ sub esp,8 + pushad + pushfd + push eax + call]
+API_PARAM1_OFFSET EQU 44h ; ApiParam1 [ sub esp,8 + push cr0/cr3/cr4/EFER + pushad + pushfd + push eax + call]
FSP_HEADER_IMGBASE_OFFSET EQU 1Ch
FSP_HEADER_CFGREG_OFFSET EQU 24h
@@ -153,6 +154,33 @@ NotMultiPhaseMemoryInitApi: cli
pushad
+ ;
+ ; Allocate 4x4 bytes on the stack.
+ ;
+ sub esp, 16
+ cmp byte [dword ASM_PFX(FeaturePcdGet (PcdFspSaveRestorePageTableEnable))], 0
+ jz SkipPagetableSave
+
+ add esp, 16
+ ; Save EFER MSR lower 32 bits
+ push ecx
+ push eax
+ mov ecx, 0xC0000080
+ rdmsr
+ mov edx, eax
+ pop eax
+ pop ecx
+ push edx
+
+ ; Save CR registers
+ mov edx, cr4
+ push edx
+ mov edx, cr3
+ push edx
+ mov edx, cr0
+ push edx
+SkipPagetableSave:
+
; Reserve 8 bytes for IDT save/restore
sub esp, 8
sidt [esp]
diff --git a/IntelFsp2Pkg/FspSecCore/Ia32/FspApiEntryM.nasm b/IntelFsp2Pkg/FspSecCore/Ia32/FspApiEntryM.nasm index 861cce4d01..b1623063ef 100644 --- a/IntelFsp2Pkg/FspSecCore/Ia32/FspApiEntryM.nasm +++ b/IntelFsp2Pkg/FspSecCore/Ia32/FspApiEntryM.nasm @@ -13,6 +13,7 @@ extern ASM_PFX(PcdGet32(PcdTemporaryRamBase))
extern ASM_PFX(PcdGet32(PcdFspTemporaryRamSize))
extern ASM_PFX(PcdGet8 (PcdFspHeapSizePercentage))
+extern ASM_PFX(FeaturePcdGet (PcdFspSaveRestorePageTableEnable))
struc FSPM_UPD_COMMON
; FSP_UPD_HEADER {
@@ -62,7 +63,7 @@ extern ASM_PFX(FspApiCommon) extern ASM_PFX(AsmGetFspBaseAddress)
extern ASM_PFX(AsmGetFspInfoHeader)
-API_PARAM1_OFFSET EQU 34h ; ApiParam1 [ sub esp,8 + pushad + pushfd + push eax + call]
+API_PARAM1_OFFSET EQU 44h ; ApiParam1 [ sub esp,8 + push cr0/cr3/cr4/EFER +pushad + pushfd + push eax + call]
FSP_HEADER_IMGBASE_OFFSET EQU 1Ch
FSP_HEADER_CFGREG_OFFSET EQU 24h
@@ -124,6 +125,33 @@ ASM_PFX(FspApiCommonContinue): cli
pushad
+ ;
+ ; Allocate 4x4 bytes on the stack.
+ ;
+ sub esp, 16
+ cmp byte [dword ASM_PFX(FeaturePcdGet (PcdFspSaveRestorePageTableEnable))], 0
+ jz SkipPagetableSave
+
+ add esp, 16
+ ; Save EFER MSR lower 32-bit
+ push ecx
+ push eax
+ mov ecx, 0xC0000080
+ rdmsr
+ mov edx, eax
+ pop eax
+ pop ecx
+ push edx
+
+ ; Save CR registers
+ mov edx, cr4
+ push edx
+ mov edx, cr3
+ push edx
+ mov edx, cr0
+ push edx
+
+SkipPagetableSave:
; Reserve 8 bytes for IDT save/restore
sub esp, 8
sidt [esp]
diff --git a/IntelFsp2Pkg/FspSecCore/X64/Fsp24ApiEntryM.nasm b/IntelFsp2Pkg/FspSecCore/X64/Fsp24ApiEntryM.nasm index a3b38e4585..3066156bcf 100644 --- a/IntelFsp2Pkg/FspSecCore/X64/Fsp24ApiEntryM.nasm +++ b/IntelFsp2Pkg/FspSecCore/X64/Fsp24ApiEntryM.nasm @@ -4,7 +4,7 @@ ; Copyright (c) 2022, Intel Corporation. All rights reserved.<BR>
; SPDX-License-Identifier: BSD-2-Clause-Patent
;;
-
+ DEFAULT REL
SECTION .text
%include "PushPopRegsNasm.inc"
@@ -13,6 +13,7 @@ ; Following are fixed PCDs
;
extern ASM_PFX(PcdGet8 (PcdFspHeapSizePercentage))
+extern ASM_PFX(FeaturePcdGet (PcdFspSaveRestorePageTableEnable))
struc FSPM_UPD_COMMON_FSP24
; FSP_UPD_HEADER {
@@ -142,6 +143,36 @@ NotMultiPhaseMemoryInitApi: cli
PUSHA_64
+ ;
+ ; Allocate 4x8 bytes on the stack.
+ ;
+ sub rsp, 32
+ lea rdx, [ASM_PFX(FeaturePcdGet (PcdFspSaveRestorePageTableEnable))]
+ mov dl, byte [rdx]
+ cmp dl, 0
+ jz SkipPagetableSave
+
+ add rsp, 32
+ ; Save EFER MSR
+ push rcx
+ push rax
+ mov rcx, 0xC0000080
+ rdmsr
+ shl rdx, 0x20
+ or rdx, rax
+ pop rax
+ pop rcx
+ push rdx
+
+ ; Save CR registers
+ mov rdx, cr4
+ push rdx
+ mov rdx, cr3
+ push rdx
+ mov rdx, cr0
+ push rdx
+SkipPagetableSave:
+
; Reserve 16 bytes for IDT save/restore
sub rsp, 16
sidt [rsp]
diff --git a/IntelFsp2Pkg/FspSecCore/X64/FspApiEntryM.nasm b/IntelFsp2Pkg/FspSecCore/X64/FspApiEntryM.nasm index 2d2f75b1f0..b0b6b6a4aa 100644 --- a/IntelFsp2Pkg/FspSecCore/X64/FspApiEntryM.nasm +++ b/IntelFsp2Pkg/FspSecCore/X64/FspApiEntryM.nasm @@ -4,7 +4,7 @@ ; Copyright (c) 2022, Intel Corporation. All rights reserved.<BR>
; SPDX-License-Identifier: BSD-2-Clause-Patent
;;
-
+ DEFAULT REL
SECTION .text
%include "PushPopRegsNasm.inc"
@@ -13,6 +13,7 @@ ; Following are fixed PCDs
;
extern ASM_PFX(PcdGet8 (PcdFspHeapSizePercentage))
+extern ASM_PFX(FeaturePcdGet (PcdFspSaveRestorePageTableEnable))
struc FSPM_UPD_COMMON_FSP24
; FSP_UPD_HEADER {
@@ -110,6 +111,36 @@ ASM_PFX(FspApiCommonContinue): cli
PUSHA_64
+ ;
+ ; Allocate 4x8 bytes on the stack.
+ ;
+ sub rsp, 32
+ lea rdx, [ASM_PFX(FeaturePcdGet (PcdFspSaveRestorePageTableEnable))]
+ mov dl, byte [rdx]
+ cmp dl, 0
+ jz SkipPagetableSave
+
+ add rsp, 32
+ ; Save EFER MSR
+ push rcx
+ push rax
+ mov rcx, 0xC0000080
+ rdmsr
+ shl rdx, 0x20
+ or rdx, rax
+ pop rax
+ pop rcx
+ push rdx
+
+ ; Save CR registers
+ mov rdx, cr4
+ push rdx
+ mov rdx, cr3
+ push rdx
+ mov rdx, cr0
+ push rdx
+SkipPagetableSave:
+
; Reserve 16 bytes for IDT save/restore
sub rsp, 16
sidt [rsp]
diff --git a/IntelFsp2Pkg/IntelFsp2Pkg.dec b/IntelFsp2Pkg/IntelFsp2Pkg.dec index d1c3d3ee7b..8fe6b64f99 100644 --- a/IntelFsp2Pkg/IntelFsp2Pkg.dec +++ b/IntelFsp2Pkg/IntelFsp2Pkg.dec @@ -114,6 +114,14 @@ #
gIntelFsp2PkgTokenSpaceGuid.PcdFspPrivateTemporaryRamSize |0x00000000|UINT32|0x10000006
+[PcdsFeatureFlag]
+ #
+ # Indicates if the FSP will save and restore page table. Only works in FSP API mode
+ # TRUE - FSP will save and restore page table
+ # FALSE - FSP will not save and restore page table
+ #
+ gIntelFsp2PkgTokenSpaceGuid.PcdFspSaveRestorePageTableEnable |FALSE|BOOLEAN|0x10000007
+
[PcdsFixedAtBuild,PcdsDynamic,PcdsDynamicEx]
gIntelFsp2PkgTokenSpaceGuid.PcdFspReservedMemoryLength |0x00100000|UINT32|0x46530000
gIntelFsp2PkgTokenSpaceGuid.PcdBootLoaderEntry |0xFFFFFFE4|UINT32|0x46530100
diff --git a/IntelFsp2Pkg/Library/BaseFspCommonLib/FspCommonLib.c b/IntelFsp2Pkg/Library/BaseFspCommonLib/FspCommonLib.c index 54dbf546c3..3ecc5bd265 100644 --- a/IntelFsp2Pkg/Library/BaseFspCommonLib/FspCommonLib.c +++ b/IntelFsp2Pkg/Library/BaseFspCommonLib/FspCommonLib.c @@ -15,21 +15,14 @@ #pragma pack(1)
-//
-// API Parameter +0x34
-// API return address +0x30
-//
-// push FspInfoHeader +0x2C
-// pushfd +0x28
-// cli
-// pushad +0x24
-// sub esp, 8 +0x00
-// sidt fword ptr [esp]
-//
typedef struct {
UINT16 IdtrLimit;
UINT32 IdtrBase;
UINT16 Reserved;
+ UINT32 Cr0;
+ UINT32 Cr3;
+ UINT32 Cr4;
+ UINT32 Efer; // lower 32-bit of EFER since only NXE bit (BIT11) need to be restored.
UINT32 Registers[8]; // General Purpose Registers: Edi, Esi, Ebp, Esp, Ebx, Edx, Ecx and Eax
UINT16 Flags[2];
UINT32 FspInfoHeader;
@@ -37,20 +30,12 @@ typedef struct { UINT32 ApiParam[2];
} CONTEXT_STACK;
-//
-// API return address +0xB8
-// Reserved +0xB0
-// push API Parameter2 +0xA8
-// push API Parameter1 +0xA0
-// push FspInfoHeader +0x98
-// pushfq +0x90
-// cli
-// PUSHA_64 +0x10
-// sub rsp, 16 +0x00
-// sidt [rsp]
-//
typedef struct {
UINT64 Idtr[2]; // IDTR Limit - bit0:bi15, IDTR Base - bit16:bit79
+ UINT64 Cr0;
+ UINT64 Cr3;
+ UINT64 Cr4;
+ UINT64 Efer;
UINT64 Registers[16]; // General Purpose Registers: RDI, RSI, RBP, RSP, RBX, RDX, RCX, RAX, and R15 to R8
UINT32 Flags[2];
UINT64 FspInfoHeader;
diff --git a/IntelFsp2Pkg/Library/BaseFspSwitchStackLib/BaseFspSwitchStackLib.inf b/IntelFsp2Pkg/Library/BaseFspSwitchStackLib/BaseFspSwitchStackLib.inf index 6909aec651..0194c2e955 100644 --- a/IntelFsp2Pkg/Library/BaseFspSwitchStackLib/BaseFspSwitchStackLib.inf +++ b/IntelFsp2Pkg/Library/BaseFspSwitchStackLib/BaseFspSwitchStackLib.inf @@ -32,5 +32,5 @@ BaseLib
IoLib
-
-
+[Pcd]
+ gIntelFsp2PkgTokenSpaceGuid.PcdFspSaveRestorePageTableEnable
diff --git a/IntelFsp2Pkg/Library/BaseFspSwitchStackLib/Ia32/Stack.nasm b/IntelFsp2Pkg/Library/BaseFspSwitchStackLib/Ia32/Stack.nasm index 6599901906..d13842451c 100644 --- a/IntelFsp2Pkg/Library/BaseFspSwitchStackLib/Ia32/Stack.nasm +++ b/IntelFsp2Pkg/Library/BaseFspSwitchStackLib/Ia32/Stack.nasm @@ -12,6 +12,12 @@ SECTION .text
extern ASM_PFX(SwapStack)
+extern ASM_PFX(FeaturePcdGet (PcdFspSaveRestorePageTableEnable))
+
+; Page table related bits in CR0/CR4/EFER
+%define CR0_PG_MASK 0x80010000 ; CR0.PG and CR0.WP
+%define CR4_PG_MASK 0x10B0 ; CR4.PSE, CR4.PAE, CR4.PGE and CR4.LA57
+%define EFER_PG_MASK 0x800 ; EFER.NXE
;------------------------------------------------------------------------------
; UINT32
@@ -50,6 +56,34 @@ ASM_PFX(FspSwitchStack): pushfd
cli
pushad
+
+ ;
+ ; Allocate 4x4 bytes on the stack.
+ ;
+ sub esp, 16
+ cmp byte [dword ASM_PFX(FeaturePcdGet (PcdFspSaveRestorePageTableEnable))], 0
+ jz SkipPagetableSave
+
+ add esp, 16
+ ; Save EFER MSR lower 32 bits
+ push ecx
+ push eax
+ mov ecx, 0xC0000080
+ rdmsr
+ mov edx, eax
+ pop eax
+ pop ecx
+ push edx
+
+ ; Save CR registers
+ mov eax, cr4
+ push eax
+ mov eax, cr3
+ push eax
+ mov eax, cr0
+ push eax
+SkipPagetableSave:
+
sub esp, 8
sidt [esp]
@@ -61,6 +95,104 @@ ASM_PFX(FspSwitchStack): ; Restore previous contexts
lidt [esp]
add esp, 8
+
+ cmp byte [dword ASM_PFX(FeaturePcdGet (PcdFspSaveRestorePageTableEnable))], 0
+ jz SkipPagetableRestore
+ ; [esp] stores new cr0
+ ; [esp+4] stores new cr3
+ ; [esp+8] stores new cr4
+ ; [esp+12] stores new Efer
+ ;
+ ; When new EFER.NXE == 1, the restore flow is: EFER --> CRx
+ ; Otherwise: CRx --> EFER
+ ; When new CR0.PG == 1, the restore flow for CRx is: CR3 --> CR4 --> CR0
+ ; Otherwise, the restore flow is: CR0 --> CR3 --> CR4
+ ;
+ ; If NXE bit is changed to 1, change NXE before CR register
+ ; This is because Nx bit in page table entry in new CR3 will be invalid
+ ; if updating CR3 before EFER MSR.
+ ;
+ mov eax, [esp+12]
+ bt eax, 11
+ jnc SkipEferLabel1
+
+ ; Restore EFER MSR
+ mov ecx, 0xC0000080
+ rdmsr
+ and eax, ~EFER_PG_MASK
+ mov ebx, [esp+12]
+ and ebx, EFER_PG_MASK
+ or eax, ebx
+ wrmsr
+
+SkipEferLabel1:
+
+ ;
+ ; if new cr0 is to disable page table, change CR0 before CR3/CR4
+ ;
+ mov eax, [esp]
+ bt eax, 31
+ jc SkipCr0Label1
+
+ ; Restore CR0
+ mov edx, cr0
+ and edx, ~CR0_PG_MASK
+ mov eax, [esp]
+ and eax, CR0_PG_MASK
+ or edx, eax
+ mov cr0, edx
+
+SkipCr0Label1:
+
+ ; Restore CR3/CR4
+ mov eax, [esp+4]
+ mov cr3, eax
+
+ mov edx, cr4
+ and edx, ~CR4_PG_MASK
+ mov eax, [esp+8]
+ and eax, CR4_PG_MASK
+ or edx, eax
+ mov cr4, edx
+
+ ;
+ ; if new cr0 is to enable page table, change CR0 after CR3/CR4
+ ;
+ mov eax, [esp]
+ bt eax, 31
+ jnc SkipCr0Label2
+
+ ; Restore CR0
+ mov edx, cr0
+ and edx, ~CR0_PG_MASK
+ mov eax, [esp]
+ and eax, CR0_PG_MASK
+ or edx, eax
+ mov cr0, edx
+
+SkipCr0Label2:
+ ;
+ ; If NXE bit is changed to 0, change NXE after than CR regiser
+ ;
+ mov eax, [esp+12]
+ bt eax, 11
+ jc SkipEferLabel2
+
+ ; Restore EFER MSR
+ mov ecx, 0xC0000080
+ rdmsr
+ and eax, ~EFER_PG_MASK
+ mov ebx, [esp+12]
+ and ebx, EFER_PG_MASK
+ or eax, ebx
+ wrmsr
+
+SkipEferLabel2:
+SkipPagetableRestore:
+
+ ; pop page table related registers.
+ add esp, 16
+
popad
popfd
add esp, 4
diff --git a/IntelFsp2Pkg/Library/BaseFspSwitchStackLib/X64/Stack.nasm b/IntelFsp2Pkg/Library/BaseFspSwitchStackLib/X64/Stack.nasm index e3a7cf002f..f40df51ab4 100644 --- a/IntelFsp2Pkg/Library/BaseFspSwitchStackLib/X64/Stack.nasm +++ b/IntelFsp2Pkg/Library/BaseFspSwitchStackLib/X64/Stack.nasm @@ -8,12 +8,18 @@ ; Switch the stack from temporary memory to permanent memory.
;
;------------------------------------------------------------------------------
-
+ DEFAULT REL
SECTION .text
%include "PushPopRegsNasm.inc"
+; Page table related bits in CR0/CR4/EFER
+%define CR0_PG_MASK 0x80010000 ; CR0.PG and CR0.WP
+%define CR4_PG_MASK 0x10B0 ; CR4.PSE, CR4.PAE, CR4.PGE and CR4.LA57
+%define EFER_PG_MASK 0x800 ; EFER.NXE
+
extern ASM_PFX(SwapStack)
+extern ASM_PFX(FeaturePcdGet (PcdFspSaveRestorePageTableEnable))
;------------------------------------------------------------------------------
; UINT32
@@ -55,6 +61,37 @@ ASM_PFX(FspSwitchStack): pushfq
cli
PUSHA_64
+
+ ;
+ ; Allocate 4x8 bytes on the stack.
+ ;
+ sub rsp, 32
+ lea rdx, [ASM_PFX(FeaturePcdGet (PcdFspSaveRestorePageTableEnable))]
+ mov dl, byte [rdx]
+ cmp dl, 0
+ jz SkipPagetableSave
+
+ add rsp, 32
+ ; Save EFER MSR
+ push rcx
+ push rax
+ mov rcx, 0xC0000080
+ rdmsr
+ shl rdx, 0x20
+ or rdx, rax
+ pop rax
+ pop rcx
+ push rdx
+
+ ; Save CR registers
+ mov rdx, cr4
+ push rdx
+ mov rdx, cr3
+ push rdx
+ mov rdx, cr0
+ push rdx
+SkipPagetableSave:
+
sub rsp, 16
sidt [rsp]
@@ -68,6 +105,76 @@ ASM_PFX(FspSwitchStack): ; Restore previous contexts
lidt [rsp]
add rsp, 16
+
+ lea rax, [ASM_PFX(FeaturePcdGet (PcdFspSaveRestorePageTableEnable))]
+ mov al, byte [rax]
+ cmp al, 0
+ jz SkipPagetableRestore
+ ; [rsp] stores new cr0
+ ; [rsp+8] stores new cr3
+ ; [rsp+16] stores new cr4
+ ; [rsp+24] stores new Efer
+ ;
+ ; When new EFER.NXE == 1, the restore flow is: EFER --> CRx
+ ; Otherwise: CRx --> EFER
+ ;
+ ; If NXE bit is changed to 1, change NXE before CR register
+ ; This is because Nx bit in page table entry in new CR3 will be invalid
+ ; if updating CR3 before EFER MSR.
+ ;
+ mov rax, [rsp + 24]
+ bt rax, 11
+ jnc SkipEferLabel1
+
+ ; Restore EFER MSR
+ mov ecx, 0xC0000080
+ rdmsr
+ and eax, ~EFER_PG_MASK
+ mov ebx, [rsp + 24]
+ and ebx, EFER_PG_MASK
+ or eax, ebx
+ wrmsr
+
+SkipEferLabel1:
+
+ mov rbx, [rsp]
+ mov rdx, cr0
+ and rdx, ~CR0_PG_MASK
+ and rbx, CR0_PG_MASK
+ or rdx, rbx
+ mov cr0, rdx
+
+ mov rbx, [rsp + 8]
+ mov cr3, rbx
+
+ mov rbx, [rsp + 16]
+ mov rdx, cr4
+ and rdx, ~CR4_PG_MASK
+ and rbx, CR4_PG_MASK
+ or rdx, rbx
+ mov cr4, rdx
+
+ ;
+ ; If NXE bit is changed to 0, change NXE after than CR regiser
+ ;
+ mov rax, [rsp + 24]
+ bt rax, 11
+ jc SkipEferLabel2
+
+ ; Restore EFER MSR
+ mov ecx, 0xC0000080
+ rdmsr
+ and eax, ~EFER_PG_MASK
+ mov ebx, [rsp + 24]
+ and ebx, EFER_PG_MASK
+ or eax, ebx
+ wrmsr
+
+SkipEferLabel2:
+SkipPagetableRestore:
+ ; pop page table related registers.
+ add rsp, 32
+
POPA_64
popfq
add rsp, 32 ; FspInfoHeader + ApiParam[2] + Reserved QWORD
|