Commit Graph

1330 Commits

Author SHA1 Message Date
Tan, Dun 72a9386f67 UefiCpuPkg: Simplify the code to set smm page table as RO
Simplify the code to set memory used by smm page table as RO.
Since memory used by smm page table are in PageTablePool list,
we only need to set all PageTablePool as ReadOnly in smm page
table itself. Also, we only need to flush tlb once after
setting all page table pool as Read Only.

Signed-off-by: Dun Tan <dun.tan@intel.com>
Cc: Eric Dong <eric.dong@intel.com>
Reviewed-by: Ray Ni <ray.ni@intel.com>
Cc: Rahul Kumar <rahul1.kumar@intel.com>
2022-12-21 11:13:48 +00:00
Tan, Dun 0426115b67 UefiCpuPkg: Remove unused API in SmmCpuFeaturesLib.h
Remove SmmCpuFeaturesAllocatePageTableMemory in this headfile.
This API is not used by PiSmmCpuDxeSmm driver any more. Also
no other files use this API.

Signed-off-by: Dun Tan <dun.tan@intel.com>
Cc: Eric Dong <eric.dong@intel.com>
Reviewed-by: Ray Ni <ray.ni@intel.com>
Cc: Rahul Kumar <rahul1.kumar@intel.com>
2022-12-21 11:13:48 +00:00
duntan b822be1a20 UefiCpuPkg/PiSmmCpuDxeSmm: Introduce page table pool mechanism
Introduce page table pool mechanism for smm page table to simplify
page table memory management and protection. This mechanism has been
used in DxeIpl. The basic idea is to allocate a bunch of continuous
pages of memory in advance, and all future page tables consumption
will happen in those pool instead of system memory.
Since we have centralized page tables, we only need to mark all page
table pools as RO, instead of searching page table memory layer by
layer in smm page table. Once current page table pool has been used
up, another memory pool will be allocated and the new pool will also
be set as RO if current page table memory has been marked as RO.

Signed-off-by: Dun Tan <dun.tan@intel.com>
Cc: Eric Dong <eric.dong@intel.com>
Reviewed-by: Ray Ni <ray.ni@intel.com>
Cc: Rahul Kumar <rahul1.kumar@intel.com>
2022-12-21 11:13:48 +00:00
Xie, Yuanhao 73ccde8f6d UefiCpuPkg: Has APs in 64 bit long-mode before booting to OS.
During the finalization of Mp initialization before booting into the OS,
 depending on whether Mwait is supported or not, AsmRelocateApLoop
 places Aps in MWAIT-loop or HLT-loop.

Since paging is necessary for long mode, the original implementation of
moving APs to 32-bit was to disable paging to ensure that the booting
does not crash.

The current modification creates a page table in reserved memory,
avoiding switching modes and reclaiming memory by OS. This modification
is only for 64 bit mode.

More specifically, we keep the AMD logic as the original code flow,
extract and update the Intel-related code, where the APs would stay
in 64-bit, and run in a Mwait or Hlt loop until the OS wake them up.

Signed-off-by: Ray Ni <ray.ni@intel.com>
Signed-off-by: Yuanhao Xie <yuanhao.xie@intel.com>
Reviewed-by: Ray Ni <ray.ni@intel.com>
2022-12-20 08:38:28 +00:00
Yuanhao Xie 7bda8c6481 UefiCpuPkg: Duplicated AsmRelocateApLoop as AsmRelocateApLoopAmd
AsmRelocateApLoop is replicated for future Intel Logic Extraction,
further brings AP into 64-bit, and enables paging.

Signed-off-by: Yuanhao Xie <yuanhao.xie@intel.com>
Reviewed-by: Ray Ni <ray.ni@intel.com>
2022-12-20 08:38:28 +00:00
Kuo, Ted 6acf72901a UefiCpuPkg: Supporting S3 in 64bit PEI
https://bugzilla.tianocore.org/show_bug.cgi?id=4195
1.Updated the GDT table in VTF0 to align with the one in S3Resume2Pei.
  By doing so can simplify the changes to enable S3 in 64bit PEI.
2.Use SwitchStack() between PEI and SMM in S3 resume path when both
  are in the same execution mode.
3.Transfer from PEI to OS waking vector by calling SwitchStack() when
  both are in the same execution mode.
4.Removed the debug assertion in S3Resume.c to support 64bit PEI.

Reviewed-by: Ray Ni <ray.ni@intel.com>
Reviewed-by: Zhiguang Liu <zhiguang.liu@intel.com>
Cc: Chasel Chiu <chasel.chiu@intel.com>
Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>
Cc: Star Zeng <star.zeng@intel.com>
Cc: Ashraf Ali S <ashraf.ali.s@intel.com>
Cc: Chinni B Duggapu <chinni.b.duggapu@intel.com>
Signed-off-by: Ted Kuo <ted.kuo@intel.com>
2022-12-19 06:12:56 +00:00
Robert Guenzel 1c75bf3c21 UefiCpuPkg: Bug fix in 5LPage handling
When build in DEBUG, the code asserts that 5LPage support is there
when the physical address width is larger than 48.
In a RELEASE build it will just force LA57 to 1 in CR4
even if CPUID(7).ECX[16] says it is not supported.

UefiCpuPkg: Bug fix in 5LPage handling

The hang (in the ASSERT) in DEBUG is not warranted as there are
legal configurations with CPUID(7).ECX[16](==LA57)=0
and with a physical address width of larger than 48 (like 52).

This is also supported by this code:
https://github.com/tianocore/edk2/blob/master/UefiCpuPkg/PiSmmCpuDxeSmm/X64/PageTbl.c#L221
There (as long as physical address width is smaller or equal to 52)
any address width above 48 will be reduced to 48 and the
system can and will work without 5LPaging.

The forced setting of LA57 in CR4 (in the absence of LA57 in CPUID(7).ECX)
is a spec violation and should not happen.

Hence the proposed fix
a) removes the assert.
b) only returns TRUE from Is5LevelPagingNeeded if 5LPaging is actually
   supported by HW.

Signed-off-by: Robert Guenzel <robert.guenzel@intel.com>
2022-12-08 10:04:24 +00:00
Wu, Jiaxin c14c4719f9 UefiCpuPkg: Check SMM Delayed/Blocked AP Count
REF: https://bugzilla.tianocore.org/show_bug.cgi?id=4173

Due to more core count increasement, it's hard to reflect all APs
state via AP bitvector support in the register. Actually, SMM CPU
driver doesn't need to check each AP state to know all CPUs in SMI
or not, one alternative method is to check the SMM Delayed & Blocked
AP Count number:

APs in SMI + Blocked Count + Disabled Count >= All supported Aps
(code comments explained why can be > All supported Aps)

With above change, the returned value of "SmmRegSmmEnable" &
"SmmRegSmmDelayed" & "SmmRegSmmBlocked" from SmmCpuFeaturesLib
should be the AP count number within the existing CPU package.

For register that return the bitvector state, require
SmmCpuFeaturesGetSmmRegister() returns count number of all bit per
logical processor within the same package.

For register that return the AP count, require
SmmCpuFeaturesGetSmmRegister() returns the register value directly.

v3:
- Refine the coding style

v2:
- Rename "mPackageBspInfo" to "mPackageFirstThreadIndex"
- Clarify the expected value of "SmmRegSmmEnable" & "SmmRegSmmDelayed" &
  "SmmRegSmmBlocked" returned from SmmCpuFeaturesLib.
- Thread: https://edk2.groups.io/g/devel/message/96722

v1:
- Thread: https://edk2.groups.io/g/devel/message/96671

Cc: Eric Dong <eric.dong@intel.com>
Reviewed-by: Ray Ni <ray.ni@intel.com>
Cc: Zeng Star <star.zeng@intel.com>
Signed-off-by: Jiaxin Wu <jiaxin.wu@intel.com>
2022-12-08 10:04:24 +00:00
Jason Lou 2280af5ff8 UefiCpuPkg/Test: develop UEFI App and dynamic cmd for MP services UT
The code changes develop UEFI application and dynamic command for
EfiMpServiceProtocol unit tests based on current UnitTestFramework.

Signed-off-by: Jason Lou <yun.lou@intel.com>
Reviewed-by: Ray Ni <ray.ni@intel.com>
Cc: Eric Dong <eric.dong@intel.com>
Cc: Laszlo Ersek <lersek@redhat.com>
Cc: Rahul Kumar <rahul1.kumar@intel.com>
Reviewed-by: Zhiguang Liu <zhiguang.liu@intel.com>
Reviewed-by: Dun Tan <dun.tan@intel.com>
2022-12-08 10:04:24 +00:00
Jason Lou cf3d4508b2 UefiCpuPkg/Test: Move EfiMpServiceProtocol UT in a separate function
Move the implementation of EfiMpServiceProtocol unit tests in a separate
function in preparation for developing the UEFI application and dynamic
command for the same unit tests.

Signed-off-by: Jason Lou <yun.lou@intel.com>
Reviewed-by: Ray Ni <ray.ni@intel.com>
Cc: Eric Dong <eric.dong@intel.com>
Cc: Laszlo Ersek <lersek@redhat.com>
Cc: Rahul Kumar <rahul1.kumar@intel.com>
Reviewed-by: Zhiguang Liu <zhiguang.liu@intel.com>
Reviewed-by: Dun Tan <dun.tan@intel.com>
2022-12-08 10:04:24 +00:00
Min M Xu 765ba5bf05 OvmfPkg/UefiCpuPkg: Add CcExit prefix to the APIs of CcExitLib
BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=4123

APIs which are defined in CcExitLib.h are added with the CcExit prefix.
This is to make the APIs' name more meaningful.

This change impacts OvmfPkg/UefiCpuPkg.

Cc: Eric Dong <eric.dong@intel.com>
Cc: Ray Ni <ray.ni@intel.com>
Cc: Brijesh Singh <brijesh.singh@amd.com>
Cc: Erdem Aktas <erdemaktas@google.com>
Cc: Gerd Hoffmann <kraxel@redhat.com>
Cc: James Bottomley <jejb@linux.ibm.com>
Cc: Jiewen Yao <jiewen.yao@intel.com>
Cc: Tom Lendacky <thomas.lendacky@amd.com>
Reviewed-by: Jiewen Yao <jiewen.yao@intel.com>
Reviewed-by: Ray Ni <ray.ni@intel.com>
Signed-off-by: Min Xu <min.m.xu@intel.com>
2022-11-14 04:55:34 +00:00
Min M Xu a89f558d3c OvmfPkg/UefiCpuPkg/UefiPayloadPkg: Rename VmgExitLib to CcExitLib
BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=4123

VmgExitLib once was designed to provide interfaces to support #VC handler
and issue VMGEXIT instruction. After TDVF (enable TDX feature in OVMF) is
introduced, this library is updated to support #VE as well. Now the name
of VmgExitLib cannot reflect what the lib does.

This patch renames VmgExitLib to CcExitLib (Cc means Confidential
Computing). This is a simple renaming and there is no logic changes.
After renaming all the VmgExitLib related codes are updated with
CcExitLib. These changes are in OvmfPkg/UefiCpuPkg/UefiPayloadPkg.

Cc: Guo Dong <guo.dong@intel.com>
Cc: Sean Rhodes <sean@starlabs.systems>
Cc: James Lu <james.lu@intel.com>
Cc: Gua Guo <gua.guo@intel.com>
Cc: Eric Dong <eric.dong@intel.com>
Cc: Ray Ni <ray.ni@intel.com>
Cc: Brijesh Singh <brijesh.singh@amd.com>
Cc: Erdem Aktas <erdemaktas@google.com>
Cc: Gerd Hoffmann <kraxel@redhat.com>
Cc: James Bottomley <jejb@linux.ibm.com>
Cc: Jiewen Yao <jiewen.yao@intel.com>
Cc: Tom Lendacky <thomas.lendacky@amd.com>
Reviewed-by: James Lu <james.lu@intel.com>
Reviewed-by: Gua Guo <gua.guo@intel.com>
Reviewed-by: Jiewen Yao <jiewen.yao@intel.com>
Reviewed-by: Ray Ni <ray.ni@intel.com>
Signed-off-by: Min Xu <min.m.xu@intel.com>
2022-11-14 04:55:34 +00:00
Duggapu, Chinni B b9e702c3c9 UefiCpuPkg/ResetVector:Add Option to reserve 4K region at 4GB
REF: https://bugzilla.tianocore.org/show_bug.cgi?id=4140

Some implementations may need to keep the initial Reset code to be
separated out from rest of the code.This request is to add padding at
lower 4K region below 4 GB which will result having only few jmp
instructions and data at that region.

Reviewed-by: Ray Ni <ray.ni@intel.com>
Signed-off-by: Duggapu Chinni B <chinni.b.duggapu@intel.com>
2022-11-11 06:20:12 +00:00
Abner Chang 957a15adaf UefiCpuPkg/SmmCpuFeaturesLib: Clean up header file inclusion in SmmStm.c
BZ# 4093: Abstract SmmCpuFeaturesLib for sharing common code

Remove the header files those are already included in
CpuFeatureLib.h.

Signed-off-by: Abner Chang <abner.chang@amd.com>
Cc: Abdul Lateef Attar <abdattar@amd.com>
Cc: Garrett Kirkendall <garrett.kirkendall@amd.com>
Cc: Paul Grimes <paul.grimes@amd.com>
Cc: Eric Dong <eric.dong@intel.com>
Cc: Ray Ni <ray.ni@intel.com>
Cc: Rahul Kumar <rahul1.kumar@intel.com>
Reviewed-by: Ray Ni <ray.ni@intel.com>
2022-11-02 07:29:13 +00:00
Abner Chang ae62a6e44d UefiCpuPkg/SmmCpuFeaturesLib: Abstract arch dependent code
BZ# 4093: Abstract SmmCpuFeaturesLib for sharing common code

This change stripped away the code that can be
shared with other archs or vendors from Intel
implementation and put in to the common file,
leaves the Intel X86 implementation in the
IntelSmmCpuFeatureLib. Also updates the header
file and INF file.

Signed-off-by: Abner Chang <abner.chang@amd.com>
Cc: Abdul Lateef Attar <abdattar@amd.com>
Cc: Garrett Kirkendall <garrett.kirkendall@amd.com>
Cc: Paul Grimes <paul.grimes@amd.com>
Cc: Eric Dong <eric.dong@intel.com>
Cc: Ray Ni <ray.ni@intel.com>
Cc: Rahul Kumar <rahul1.kumar@intel.com>
Reviewed-by: Ray Ni <ray.ni@intel.com>
2022-11-02 07:29:13 +00:00
Abner Chang ed8bfada03 UefiCpuPkg/SmmCpuFeaturesLib: Rename the common C file
BZ# 4093: Abstract SmmCpuFeaturesLib for sharing common code

Rename SmmCpuFeaturesLiCommon.c to
IntelSmmCpuFeaturesLib, because it was developed
specifically for Intel implementation. The code
that can be shared by other archs or vendors
will be stripped away and put in the common
file in the next patch.

Signed-off-by: Abner Chang <abner.chang@amd.com>
Cc: Abdul Lateef Attar <abdattar@amd.com>
Cc: Garrett Kirkendall <garrett.kirkendall@amd.com>
Cc: Paul Grimes <paul.grimes@amd.com>
Cc: Eric Dong <eric.dong@intel.com>
Cc: Ray Ni <ray.ni@intel.com>
Cc: Rahul Kumar <rahul1.kumar@intel.com>
Reviewed-by: Ray Ni <ray.ni@intel.com>
2022-11-02 07:29:13 +00:00
Tan, Dun d98efb4682 UefiCpuPkg: Restore HpetTimer after CpuExceptionHandlerLib test
Disable/Restore HpetTimer before and after running the Dxe
CpuExceptionHandlerLib unit test module. During the UnitTest, a
new Idt is initialized for the test. There is no handler for timer
intrrupt in this new idt. After the test module, HpetTimer does
not work any more since the comparator value register and main
counter value register for timer does not match. To fix this issue,
disable/restore HpetTimer before and after Unit Test if HpetTimer
driver has been dispatched. We don't need to send Apic Eoi in this
unit test module.When disabling timer, after RaiseTPL(), if there
is a pending timer interrupt, bit64 of Interrupt Request Register
(IRR) will be set to 1 to indicate there is a pending timer
interrupt. After RestoreTPL(), CPU will handle the pending
interrupt in IRR.Then TimerInterruptHandler calls SendApicEoi().

Signed-off-by: Dun Tan <dun.tan@intel.com>
Cc: Eric Dong <eric.dong@intel.com>
Reviewed-by: Ray Ni <ray.ni@intel.com>
Cc: Rahul Kumar <rahul1.kumar@intel.com>
Cc: Michael D Kinney <michael.d.kinney@intel.com>
2022-10-28 09:02:46 +00:00
Jason Lou 9d6915ca91 UefiCpuPkg/Test: Add unit tests for MP service PPI and Protocol
The code changes add unit tests based on current UnitTestFramework.
EdkiiPeiMpServices2PpiPeiUnitTest PEI module is used to test
EdkiiPeiMpServices2Ppi and EfiMpServiceProtocolDxeUnitTest DXE driver is
used to test EfiMpServiceProtocol.

Signed-off-by: Jason Lou <yun.lou@intel.com>
Reviewed-by: Ray Ni <ray.ni@intel.com>
Cc: Eric Dong <eric.dong@intel.com>
Cc: Laszlo Ersek <lersek@redhat.com>
Cc: Rahul Kumar <rahul1.kumar@intel.com>
2022-10-17 08:03:06 +00:00
Tan, Dun 6f1bb567aa UefiCpuPkg: Add R8/R9 etc in EccCheck ExceptionList
Add GENERAL_REGISTER.R8/R9 etc in EccCheck ExceptionList
of UefiCpuPkg/UefiCpuPkg.ci.yaml to pass CI EccCheck.R8/R9
in structure GENERAL_REGISTER of CpuExceptionHandlerTest.h
lead to EccCheck failure since no lower case characters in
R8/R9/R10 etc.

Signed-off-by: Dun Tan <dun.tan@intel.com>
Cc: Eric Dong <eric.dong@intel.com>
Reviewed-by: Ray Ni <ray.ni@intel.com>
Cc: Rahul Kumar <rahul1.kumar@intel.com>
2022-10-17 08:03:06 +00:00
Tan, Dun 012e424601 UefiCpuPkg: Add Pei/DxeCpuExceptionHandlerLibUnitTest in dsc
Add Pei/DxeCpuExceptionHandlerLibUnitTest module in UefiCpuPkg.dsc

Signed-off-by: Dun Tan <dun.tan@intel.com>
Cc: Eric Dong <eric.dong@intel.com>
Reviewed-by: Ray Ni <ray.ni@intel.com>
Cc: Rahul Kumar <rahul1.kumar@intel.com>
2022-10-17 08:03:06 +00:00
Tan, Dun 055eaacc34 UefiCpuPkg: Add Unit tests for PeiCpuExceptionHandlerLib
The previous change adds unit test for DxeCpuExeptionHandlerLib
in 64bit mode. This change create a PEIM to add unit test for
PeiCpuExceptionHandlerLib based on previous change.It can run
in both 32bit and 64bit modes.

Signed-off-by: Dun Tan <dun.tan@intel.com>
Cc: Eric Dong <eric.dong@intel.com>
Reviewed-by: Ray Ni <ray.ni@intel.com>
Cc: Rahul Kumar <rahul1.kumar@intel.com>
2022-10-17 08:03:06 +00:00
Tan, Dun beabde5875 UefiCpuPkg: Add Unit tests for DxeCpuExceptionHandlerLib
Add target based unit tests for the DxeCpuExceptionHandlerLib.
A DXE driver is created to test DxeCpuExceptionHandlerLib.

Four test cases are created in this Unit Test module:
a.Test if exception handler can be registered/unregistered
for no error code exception.In the test case, only no error
code exception is triggered and tested by INTn instruction.

b.Test if exception handler can be registered/unregistered
for GP and PF. In the test case, GP exception is triggered
and tested by setting CR4_RESERVED_BIT to 1. PF exception
is triggered by writting to not-present or RO address.

c.Test if CpuContext is consistent before and after exception.
In this test case:
1.Set Cpu register to mExpectedContextInHandler before
exception. 2.Trigger exception specified by ExceptionType.
3.Store SystemContext in mActualContextInHandler and set
SystemContext to mExpectedContextAfterException in handler.
4.After return from exception, store Cpu registers in
mActualContextAfterException.
The expectation is:
1.Register values in mActualContextInHandler are the same
with register values in mExpectedContextInHandler.
2.Register values in mActualContextAfterException are the
same with register values mActualContextAfterException.

d.Test if stack overflow can be captured by CpuStackGuard
in both Bsp and AP. In this test case, stack overflow is
triggered by a funtion which calls itself continuously.
This test case triggers stack overflow in both BSP and AP.
All AP use same Idt with Bsp. The expectation is:
1. PF exception is triggered (leading to a DF if sepereated
stack is not prepared for PF) when Rsp<=StackBase+SIZE_4KB
since [StackBase, StackBase + SIZE_4KB] is marked as not
present in page table when PcdCpuStackGuard is TRUE.
2. Stack for PF/DF exception handler in both Bsp and AP is
succussfully switched by InitializeSeparateExceptionStacks.

Signed-off-by: Dun Tan <dun.tan@intel.com>
Cc: Eric Dong <eric.dong@intel.com>
Reviewed-by: Ray Ni <ray.ni@intel.com>
Cc: Rahul Kumar <rahul1.kumar@intel.com>
2022-10-17 08:03:06 +00:00
Tan, Dun b8e54e15de UefiCpuPkg/CpuPageTableLib:Support PAE paging for PageTableParse
Support PAE paging for PageTableParse API in CpuPageTableLib.

Signed-off-by: Dun Tan <dun.tan@intel.com>
Cc: Eric Dong <eric.dong@intel.com>
Reviewed-by: Ray Ni <ray.ni@intel.com>
Cc: Rahul Kumar <rahul1.kumar@intel.com>
2022-10-17 08:03:06 +00:00
Liu, Zhiguang a7e070808c UefiCpuPkg:Add RegisterExceptionHandler in PeiCpuExceptionHandlerLib
The PEI instance of the CpuExceptionHandlerLib didn't implement the
RegisterCpuInterruptHandler() API. This patch adds the missing API.

Signed-off-by: Zhiguang Liu <zhiguang.liu@intel.com>
Cc: Eric Dong <eric.dong@intel.com>
Reviewed-by: Ray Ni <ray.ni@intel.com>
Cc: Rahul Kumar <rahul1.kumar@intel.com>
2022-10-17 08:03:06 +00:00
Zhihao Li 4364d66168 UefiCpuPkg: Reset a parameter when BSP Exit in CPU relaxed mode.
REF: https://bugzilla.tianocore.org/show_bug.cgi?id=4083

In CPU relaxed mode, it doesn't reset the value of
mSmmMpSyncData->AllApArrivedWithException when BSP exit smm mode.
So this patch will reset this variable.

Cc: Eric Dong <eric.dong@intel.com>
Reviewed-by: Ray Ni <ray.ni@intel.com>

Signed-off-by: Zhihao Li <zhihao.li@intel.com>
Reviewed-by: Abner Chang <abner.chang@amd.com>
2022-10-08 06:55:46 +00:00
Tan, Dun a670f12a74 UefiCpuPkg/CpuExceptionHandlerLib: Code optimization to allow bigger stack
This commit is a code optimization to allow bigger seperate stack size in
ArchSetupExceptionStack. In previous code logic, CPU_STACK_ALIGNMENT bytes
will be wasted if StackTop is already CPU_STACK_ALIGNMENT aligned.

Signed-off-by: Dun Tan <dun.tan@intel.com>
Cc: Eric Dong <eric.dong@intel.com>
Reviewed-by: Ray Ni <ray.ni@intel.com>
Cc: Rahul Kumar <rahul1.kumar@intel.com>
Reviewed-by: Abner Chang <abner.chang@amd.com>
2022-10-08 05:45:22 +00:00
Liu, Zhiguang 4b7bd4c591 UefiCpuPkg: Enhance logic in InitializeMpExceptionStackSwitchHandlers
Parallelly run the function to SeparateExceptionStacks for all CPUs and
allocate buffers together for better performance.

Cc: Eric Dong <eric.dong@intel.com>
Reviewed-by: Ray Ni <ray.ni@intel.com>
Cc: Rahul Kumar <rahul1.kumar@intel.com>
Signed-off-by: Zhiguang Liu <zhiguang.liu@intel.com>
2022-08-31 04:23:55 +00:00
Yuanhao Xie 9ab2b34dd4 UefiCpuPkg: Use Top of each AP's stack to save CpuMpData
To remove the dependency of CPU register, 4/8 byte at the top of the
stack is occupied for CpuMpData. BIST information is also taken care
here. This modification is only for PEI phase, since in DXE phase
CpuMpData is accessed via global variable.

Signed-off-by: Yuanhao Xie <yuanhao.xie@intel.com>
Cc: Eric Dong <eric.dong@intel.com>
Reviewed-by: Ray Ni <ray.ni@intel.com>
Cc: Rahul Kumar <rahul1.kumar@intel.com>
2022-08-31 04:23:55 +00:00
Liu, Zhiguang 76cf3d35e6 UefiCpuPkg: Simplify the implementation when separate exception stacks
The API of InitializeSeparateExceptionStacks is just changed before, and
makes the struct CPU_EXCEPTION_INIT_DATA an internal definition.
Furthermore, we can even remove the struct to make core simpler.

Cc: Eric Dong <eric.dong@intel.com>
Reviewed-by: Ray Ni <ray.ni@intel.com>
Cc: Rahul Kumar <rahul1.kumar@intel.com>
Signed-off-by: Zhiguang Liu <zhiguang.liu@intel.com>
2022-08-31 04:23:55 +00:00
Liu, Zhiguang d1abb876f4 UefiCpuPkg/MpInitLib: Simplify logic in SwitchBsp
When switch bsp, old bsp and new bsp put CR0/CR4 into stack, and put IDT
and GDT register into a structure. After they exchange their stack, they
restore these registers. This logic is now implemented by assembly code.
This patch aims to reuse (Save/Restore)VolatileRegisters function to
replace such assembly code for better code readability.

Cc: Eric Dong <eric.dong@intel.com>
Reviewed-by: Ray Ni <ray.ni@intel.com>
Cc: Rahul Kumar <rahul1.kumar@intel.com>
Signed-off-by: Zhiguang Liu <zhiguang.liu@intel.com>
2022-08-31 04:23:55 +00:00
Wu, Jiaxin 76ec17526b UefiCpuPkg: Add PCD to control SMRR enable & SmmFeatureControl support
REF: https://bugzilla.tianocore.org/show_bug.cgi?id=3962

Two SMM variables (mSmrrSupported & mSmmFeatureControlSupported) are global
variables, they control whether the SMRR and SMM Feature Control MSR will
be restored respectively.
To avoid the TOCTOU, add PCD to control SMRR & SmmFeatureControl enable.

Cc: Eric Dong <eric.dong@intel.com>
Reviewed-by: Ray Ni <ray.ni@intel.com>
Cc: Star Zeng <star.zeng@intel.com>
Cc: Michael D Kinney <michael.d.kinney@intel.com>
Signed-off-by: Jiaxin Wu <jiaxin.wu@intel.com>
2022-08-31 04:23:55 +00:00
Liu, Zhiguang 367604b2f4 UefiCpuPkg/MpInitLib: Fix potential issue when IDT table is at above 4G
Currently, when waking up AP, IDT table of AP will be set in 16 bit code,
and assume the IDT table base is 32 bit. However, the IDT table is created
by BSP. Issue will happen if the BSP allocates memory above 4G for BSP's
IDT table. Moreover, even the IDT table location is below 4G, the handler
function inside the IDT table is 64 bit, and it won't take effect until
CPU transfers to 64 bit long mode. There is no benefit to set IDT table in
such an early phase.
To avoid such issue, this patch moves the LIDT instruction into 64 bit
code.

Cc: Eric Dong <eric.dong@intel.com>
Reviewed-by: Ray Ni <ray.ni@intel.com>
Cc: Rahul Kumar <rahul1.kumar@intel.com>
Signed-off-by: Zhiguang Liu <zhiguang.liu@intel.com>
2022-08-31 04:23:55 +00:00
Zhiguang Liu 04ecdc38cd UefiCpuPkg/CpuPageTableLib/UnitTest: Add host based unit test
Add host based unit tests for the CpuPageTableLib services.

Unit test focuses on PageTableMap function, containing two kinds of test
cases: manual test case and random test case.
Manual test case creates some corner case to test function PageTableMap.
Random test case generates multiple random memory entries (with random
attribute) as the input of function PageTableMap to get the output
pagetable. Output pagetable will be validated and be parsed to get output
memory entries, and then the input and output memory entries will be
compared to verify the functionality.

The unit test is not perfect yet. There are options for random test, and
some of them control the test coverage, and some option are not ready.
Will enhance in the future.

Cc: Eric Dong <eric.dong@intel.com>
Reviewed-by: Ray Ni <ray.ni@intel.com>
Cc: Rahul Kumar <rahul1.kumar@intel.com>
Signed-off-by: Zhiguang Liu <zhiguang.liu@intel.com>
2022-08-31 01:57:58 +00:00
Liming Gao 722e03bc2e Revert "UefiCpuPkg/CpuPageTableLib/UnitTest: Add host based unit test"
This reverts commit 2812668bfc for tag202208.
This feature will be merged after stable tag 202208 is created.

Signed-off-by: Liming Gao <gaoliming@byosoft.com.cn>
Reviewed-by: Zhiguang Liu <zhiguang.liu@intel.com>
Acked-by: Ard Biesheuvel <ardb@kernel.org>
2022-08-28 02:17:24 +00:00
Zhiguang Liu 2812668bfc UefiCpuPkg/CpuPageTableLib/UnitTest: Add host based unit test
Add host based unit tests for the CpuPageTableLib services.

Unit test focuses on PageTableMap function, containing two kinds of test
cases: manual test case and random test case.
Manual test case creates some corner case to test function PageTableMap.
Random test case generates multiple random memory entries (with random
attribute) as the input of function PageTableMap to get the output
pagetable. Output pagetable will be validated and be parsed to get output
memory entries, and then the input and output memory entries will be
compared to verify the functionality.

The unit test is not perfect yet. There are options for random test, and
some of them control the test coverage, and some option are not ready.
Will enhance in the future.

Cc: Eric Dong <eric.dong@intel.com>
Reviewed-by: Ray Ni <ray.ni@intel.com>
Cc: Rahul Kumar <rahul1.kumar@intel.com>
Signed-off-by: Zhiguang Liu <zhiguang.liu@intel.com>
2022-08-16 02:44:08 +00:00
Dun Tan 7b4754904e UefiCpuPkg/PiSmmCpuDxeSmm: Remove mInternalCr3 in PiSmmCpuDxeSmm
This patch is code refactoring and doesn't change any functionality.
Remove mInternalCr3 in PiSmmCpuDxe pagetable related code. In previous
code, mInternalCr3 is used to pass address of page table which is
different from Cr3 register in different level of SetMemoryAttributes
function. Now remove it and pass the page table base address from the
root function parameter to simplify the code logic.

Signed-off-by: Dun Tan <dun.tan@intel.com>
Cc: Eric Dong <eric.dong@intel.com>
Cc: Rahul Kumar <rahul1.kumar@intel.com>
Reviewed-by: Ray Ni <ray.ni@intel.com>
2022-08-15 05:15:43 +00:00
Dun Tan 83d5871184 UefiCpuPkg/PiSmmCpuDxeSmm: Add a new mIsShadowStack flag
This patch is code refactoring and doesn't change any functionality.
Add a new mIsShadowStack flag to identify whether current memory is
shadow stack. Previous smm code logic regards a RO range as shadow
stack and set the dirty bit in corresponding page table entry if
mInternalCr3 is not 0, which may be confusing.

Signed-off-by: Dun Tan <dun.tan@intel.com>
Cc: Eric Dong <eric.dong@intel.com>
Cc: Rahul Kumar <rahul1.kumar@intel.com>
Reviewed-by: Ray Ni <ray.ni@intel.com>
2022-08-15 05:15:43 +00:00
Ray Ni e9e2ecab2d CpuPageTableLib: define IA32_PAGE_LEVEL enum type internally
The change doesn't change functionality behavior.

Signed-off-by: Ray Ni <ray.ni@intel.com>
Cc: Zhiguang Liu <zhiguang.liu@intel.com>
Reviewed-by: Eric Dong <eric.dong@intel.com>
2022-08-09 07:08:05 +00:00
Ray Ni 927113c83b CpuPageTableLib: Fix bug that wrongly requires extra size for mapping
With following paging structure to map
  [2M-4K, 2M] as P = 1, RW = 0,
  [2M, 4M]    as P = 1, RW = 1:

PML4[0] -> PDPTE[0] -> PDE[0](RW = 0) -> PTE[255](P = 0, RW = 0)
                    -> PDE[1](RW = 1)

When a new request to map [2M-4K, 2M+4K] as P = 1, RW = 1,
CpuPageTableMap() wrongly requests 4K buffer size for the new mapping
request.

But in fact, for [2M-4K, 2M] request, PTE[255] can be changed in place,
for [2M, 2M+4K], no change is needed because PDE[1].RW = 1 already.

The change fixes the bug.

Signed-off-by: Ray Ni <ray.ni@intel.com>
Signed-off-by: Zhiguang Liu <zhiguang.liu@intel.com>
Reviewed-by: Eric Dong <eric.dong@intel.com>
2022-08-09 07:08:05 +00:00
Ray Ni 9f53fd4ba7 CpuPageTableLib: Fix a bug to avoid unnecessary changing to page table
With the following paging structure that maps [0, 2G] with ReadWrite
bit set.
PML4[0] --> PDPTE[0] --> PDE[0-255]
              \-> PDPTE[1] --> PDE[0-255]

If ReadWrite bit is cleared in PML4[0] and PageTableMap() is called
to change [0, 2M] as read-only, today's logic unnecessarily changes
the paging structure in 2 aspects:
1. When setting PageTableBaseAddress in the entry, the code clears
    all attributes.
2. Even the ReadWrite bit in parent entry is not set, the code clears
    the ReadWrite bit in the leaf entry.

First change is wrong. It should not change other attributes when
setting the PA.
Second change is unnecessary. Because the parent entry already
declares the whole region as read-only, there is no need to clear
ReadWrite bit in the leaf entry again.

Signed-off-by: Zhiguang Liu <zhiguang.liu@intel.com>
Signed-off-by: Ray Ni <ray.ni@intel.com>
Reviewed-by: Eric Dong <eric.dong@intel.com>
2022-08-09 07:08:05 +00:00
Ray Ni f4c845e46b CpuPageTableLib: Fix parent attributes are not inherited properly
With the following paging structure that maps [0, 2G] with ReadWrite
bit set.
PML4[0] --> PDPTE[0] --> PDE[0-255]
              \-> PDPTE[1] --> PDE[0-255]

If ReadWrite bit is cleared in PML4[0] and PageTableMap() is called
to change [0, 2M] as writable, today's logic doesn't inherit the
parent entry's attributes when determining the child entry's
attributes. It just sets the PDPTE[0].PDE[0].ReadWrite bit.
But since the PML4[0].ReadWrite is 0, [0, 2M] is still read-only.

The change fixes the bug.
If the inheritable attributes in ParentPagingEntry conflicts with the
requested attributes, let the child entries take the parent attributes
and loosen the attribute in the parent entry.

E.g.: when PDPTE[0].ReadWrite = 0 but caller wants to map [0-2MB as
ReadWrite = 1 (PDE[0].ReadWrite = 1), we need to change
PDPTE[0].ReadWrite = 1 and let all PDE[0-255].ReadWrite = 0 first.
Then change PDE[0].ReadWrite = 1.

Signed-off-by: Zhiguang Liu <zhiguang.liu@intel.com>
Signed-off-by: Ray Ni <ray.ni@intel.com>
Reviewed-by: Eric Dong <eric.dong@intel.com>
2022-08-09 07:08:05 +00:00
Ray Ni c16f02f776 CpuPageTableLib: Avoid treating non-leaf entry as leaf one
Today's logic wrongly treats the non-leaf entry as leaf entry and
updates its paging attributes.

The patch fixes the bug to only update paging attributes for
non-present entries or leaf entries.

Signed-off-by: Ray Ni <ray.ni@intel.com>
Signed-off-by: Zhiguang Liu <zhiguang.liu@intel.com>
Reviewed-by: Eric Dong <eric.dong@intel.com>
2022-08-09 07:08:05 +00:00
Ray Ni 9cb8974f06 CpuPageTableLib: Split the page entry when LA is aligned but PA is not
When PageTableMap() is called to create non 1:1 mapping
such as [0, 1G) to [8K, 1G+8K), it should split the page entry to the
4K page level, but old logic has a bug that it just uses 1G page
entry.

The patch fixes the bug.

Signed-off-by: Zhiguang Liu <zhiguang.liu@intel.com>
Reviewed-by: Ray Ni <ray.ni@intel.com>
Reviewed-by: Eric Dong <eric.dong@intel.com>
2022-08-09 07:08:05 +00:00
Ray Ni 13a0471bfd CpuPageTableLib: Refactor the logic
The patch replaces
  LinearAddress + Offset == RegionStart
with
  ((LinearAddress + Offset) & RegionMask) == 0

The replace should not cause any behavior change.

Because:
1. In first loop of while when LinearAddress + Offset == RegionStart,
  because the lower "BitStart" bits of RegionStart are all-zero,
  all lower "BitStart" bits of (LinearAddress + Offset) are all-zero.
  Because all lower "BitStart" bits of RegionMask is all-one and
  bits are all-zero, ((LinearAddress + Offset) & RegionMask) == 0.

2. In following loops of the while, even RegionStart is increased
  by RegionLength, the lower "BitStart" bits are still all-zero.
  So the two expressions still semantically equal to each other.

Signed-off-by: Ray Ni <ray.ni@intel.com>
Cc: Zhiguang Liu <zhiguang.liu@intel.com>
Reviewed-by: Eric Dong <eric.dong@intel.com>
2022-08-09 07:08:05 +00:00
Ray Ni bf334513b3 CpuPageTableLib: Fix a bug when a bit is 1 in Attribute, 0 in Mask
To reproduce the issue:
  UINTN               PageTable;
  VOID                *Buffer;
  UINTN               PageTableBufferSize;
  IA32_MAP_ATTRIBUTE  Attribute;
  IA32_MAP_ATTRIBUTE  Mask;
  RETURN_STATUS       Status;

  Attribute.Uint64       = 0;
  Mask.Uint64            = 0;
  PageTableBufferSize    = 0;
  PageTable              = 0;
  Buffer                 = NULL;
  Attribute.Bits.Present = 1;
  Attribute.Bits.Nx      = 1;
  Mask.Bits.Present      = 1;
  Mask.Uint64            = MAX_UINT64;

  //
  // Create page table to cover [0, 10M)
  //
  Status = PageTableMap (
             &PageTable, PagingMode, Buffer, &PageTableBufferSize,
             0, (UINT64)SIZE_2MB * 5, &Attribute, &Mask
             );
  ASSERT (Status == RETURN_BUFFER_TOO_SMALL);
  Buffer = AllocatePages (EFI_SIZE_TO_PAGES (PageTableBufferSize));
  Status = PageTableMap (
             &PageTable, PagingMode, Buffer, &PageTableBufferSize,
             0, (UINT64)SIZE_2MB * 5, &Attribute, &Mask
             );
  ASSERT (Status == RETURN_SUCCESS);

  //
  // Change the mapping for [0, 4KB)
  // No change actually. Just clear Nx bit in Mask.
  //
  Mask.Bits.Nx        = 0;
  PageTableBufferSize = 0;

  Status = PageTableMap (
             &PageTable, PagingMode, NULL, &PageTableBufferSize,
             0, (UINT64)SIZE_4KB, &Attribute, &Mask
             );
  ASSERT (Status == RETURN_SUCCESS); // FAIL!!

The root cause is when comparing the existing mapping attributes
against the requested one, Mask is not used but it should be used.

Signed-off-by: Zhiguang Liu <zhiguang.liu@intel.com>
Reviewed-by: Ray Ni <ray.ni@intel.com>
Reviewed-by: Eric Dong <eric.dong@intel.com>
2022-08-09 07:08:05 +00:00
Ray Ni f336e30ba1 UefiCpuPkg/CpuPageTableLib: Return error on invalid parameters
When LinearAddress or Length is not aligned on 4KB, PageTableMap()
should return Invalid Parameter.

Signed-off-by: Zhiguang Liu <zhiguang.liu@intel.com>
Reviewed-by: Ray Ni <ray.ni@intel.com>
Reviewed-by: Eric Dong <eric.dong@intel.com>
2022-08-09 07:08:05 +00:00
Ray Ni 75e3c2435c UefiCpuPkg: Create CpuPageTableLib for manipulating X86 paging structs
The lib includes two APIs:
* PageTableMap
  It creates/updates mapping from LA to PA.
  The implementation only supports paging structures used in 64bit
  mode now. PAE paging structure support will be added in future.

* PageTableParse
   It parses the page table and returns the mapping relations in an
  array of IA32_MAP_ENTRY.

It passed some stress tests. These test code will be upstreamed in
other patches following edk2 Unit Test framework.

Signed-off-by: Ray Ni <ray.ni@intel.com>
Reviewed-by: Eric Dong <eric.dong@intel.com>
2022-08-09 07:08:05 +00:00
Liu, Zhiguang f1688ec9da UefiCpuPkg: Simplify the struct definition of CPU_EXCEPTION_INIT_DATA
CPU_EXCEPTION_INIT_DATA is now an internal implementation of
CpuExceptionHandlerLib. Union can be removed since Ia32 and X64 have the
same definition. Also, two fields (Revision and InitDefaultHandlers)are
useless, can be removed.

Cc: Eric Dong <eric.dong@intel.com>
Reviewed-by: Ray Ni <ray.ni@intel.com>
Cc: Rahul Kumar <rahul1.kumar@intel.com>
Signed-off-by: Zhiguang Liu <zhiguang.liu@intel.com>
2022-08-09 04:12:28 +00:00
Liu, Zhiguang 9a24c3546e MdeModulePkg: Move CPU_EXCEPTION_INIT_DATA to UefiCpuPkg
Since the API InitializeSeparateExceptionStacks is simplified and does't
use the struct CPU_EXCEPTION_INIT_DATA, CPU_EXCEPTION_INIT_DATA become
a inner implementation of CpuExcetionHandlerLib.

Cc: Eric Dong <eric.dong@intel.com>
Reviewed-by: Ray Ni <ray.ni@intel.com>
Cc: Rahul Kumar <rahul1.kumar@intel.com>
Cc: Leif Lindholm <quic_llindhol@quicinc.com>
Cc: Dandan Bi <dandan.bi@intel.com>
Cc: Liming Gao <gaoliming@byosoft.com.cn>
Cc: Jian J Wang <jian.j.wang@intel.com>
Signed-off-by: Zhiguang Liu <zhiguang.liu@intel.com>
2022-08-09 04:12:28 +00:00
Liu, Zhiguang 0f7bccf584 UefiCpuPkg: Simplify InitializeSeparateExceptionStacks
Hide the Exception implementation details in CpuExcetionHandlerLib and
caller only need to provide buffer

Cc: Eric Dong <eric.dong@intel.com>
Reviewed-by: Ray Ni <ray.ni@intel.com>
Cc: Rahul Kumar <rahul1.kumar@intel.com>
Cc: Leif Lindholm <quic_llindhol@quicinc.com>
Cc: Dandan Bi <dandan.bi@intel.com>
Cc: Liming Gao <gaoliming@byosoft.com.cn>
Cc: Jian J Wang <jian.j.wang@intel.com>
Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
Reviewed-by: Sami Mujawar <sami.mujawar@arm.com>
Signed-off-by: Zhiguang Liu <zhiguang.liu@intel.com>
2022-08-09 04:12:28 +00:00