Commit Graph

1304 Commits

Author SHA1 Message Date
Michael Kubacki 2002e950ea UefiCpuPkg/SmmCpuFeaturesLib: Cleanup library constructors
There's currently two library instances:
  1. SmmCpuFeaturesLib
  2. SmmCpuFeaturesLibStm

There's two constructor functions:
  1. SmmCpuFeaturesLibConstructor()
  2. SmmCpuFeaturesLibStmConstructor()

SmmCpuFeaturesLibConstructor() is called by
SmmCpuFeaturesLibStmConstructor() since the functionality in that
function is required by both library instances.

The declaration for SmmCpuFeaturesLibConstructor() is embedded in
"SmmStm.c" instead of being declared in a header file. Further,
that constructor function is called by the STM specific constructor.

This change moves the common code to a function called
CpuFeaturesLibInitialization() which is declared in an internal
library header file "CpuFeaturesLib.h". Each constructor simply
calls this function to perform the common functionality.

Additionally, SmmCpuFeaturesLibConstructor() is moved from
SmmCpuFeaturesLibNoStm.c into a instance-specific file allowing
SmmCpuFeaturesLibNoStm.c to contain no STM implementation agnostic
to a particular library instance.

Cc: Eric Dong <eric.dong@intel.com>
Cc: Ray Ni <ray.ni@intel.com>
Cc: Laszlo Ersek <lersek@redhat.com>
Cc: Rahul Kumar <rahul1.kumar@intel.com>
Signed-off-by: Michael Kubacki <michael.kubacki@microsoft.com>
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
Message-Id: <20210217213227.1277-4-mikuback@linux.microsoft.com>
Reviewed-by: Eric Dong <eric.dong@intel.com>
2021-03-08 18:07:32 +00:00
Michael Kubacki 61dc3b3399 UefiCpuPkg/SmmCpuFeaturesLib: Rename SmmCpuFeaturesLib.c
This change renames SmmCpuFeaturesLib.c to SmmCpuFeaturesLibCommon.c
to better convey that this file contains library implementation
common to all library instances.

Cc: Eric Dong <eric.dong@intel.com>
Cc: Ray Ni <ray.ni@intel.com>
Cc: Laszlo Ersek <lersek@redhat.com>
Cc: Rahul Kumar <rahul1.kumar@intel.com>
Signed-off-by: Michael Kubacki <michael.kubacki@microsoft.com>
Message-Id: <20210217213227.1277-3-mikuback@linux.microsoft.com>
Reviewed-by: Eric Dong <eric.dong@intel.com>
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
2021-03-08 18:07:32 +00:00
Michael Kubacki 3e062ea498 UefiCpuPkg/SmmCpuFeaturesLib: Move multi-instance function decl to header
FinishSmmCpuFeaturesInitializeProcessor() is a multi-instance
internal library function that is currently not declared in a
header file but embedded in "SmmCpuFeaturesLib.c".

This change cleans up the declaration moving it to a new header
file "CpuFeaturesLib.h" and removing the local declaration in
"SmmCpuFeaturesLib.c".

Cc: Eric Dong <eric.dong@intel.com>
Cc: Ray Ni <ray.ni@intel.com>
Cc: Laszlo Ersek <lersek@redhat.com>
Cc: Rahul Kumar <rahul1.kumar@intel.com>
Signed-off-by: Michael Kubacki <michael.kubacki@microsoft.com>
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
Message-Id: <20210217213227.1277-2-mikuback@linux.microsoft.com>
Reviewed-by: Eric Dong <eric.dong@intel.com>
[lersek@redhat.com: replace the guard macro "_CPU_FEATURES_LIB_H_" with
 "CPU_FEATURES_LIB_H_", for fixing ECC 8003, per commit 6ffbb3581a]
2021-03-08 18:07:32 +00:00
Ray Ni 8c61f1934d UefiCpuPkg/MpInitLib: Remove unused Lock from MP_CPU_EXCHANGE_INFO
The Lock is no longer needed since "LOCK XADD" was used in
MpFuncs.nasm for ApIndex atomic increment.

Signed-off-by: Ray Ni <ray.ni@intel.com>
Reviewed-by: Eric Dong <eric.dong@intel.com>
Acked-by: Laszlo Ersek <lersek@redhat.com>
Cc: Rahul Kumar <rahul1.kumar@intel.com>
2021-03-08 02:22:37 +00:00
Ray Ni 2fba7d4ee4 UefiCpuPkg/MpInitLib: Use NASM struc to avoid hardcode offset
In Windows environment, "dumpbin /disasm" is used to verify the
disassembly before and after using NASM struc doesn't change.

Signed-off-by: Ray Ni <ray.ni@intel.com>
Reviewed-by: Eric Dong <eric.dong@intel.com>
Acked-by: Laszlo Ersek <lersek@redhat.com>
Cc: Rahul Kumar <rahul1.kumar@intel.com>
2021-03-08 02:22:37 +00:00
Sheng Wei ef91b07388 UefiCpuPkg/PiSmmCpuDxeSmm: Fix SMM stack offset is not correct
In function InitGdt(), SmiPFHandler() and Gen4GPageTable(), it uses
 CpuIndex * mSmmStackSize to get the SMM stack address offset for
 multi processor. It misses the SMM Shadow Stack Size. Each processor
 will use mSmmStackSize + mSmmShadowStackSize in the memory.
It should use CpuIndex * (mSmmStackSize + mSmmShadowStackSize) to get
 this SMM stack address offset. If mSmmShadowStackSize > 0 and multi
 processor enabled, it will get the wrong offset value.
CET shadow stack feature will set the value of mSmmShadowStackSize.

REF: https://bugzilla.tianocore.org/show_bug.cgi?id=3237

Signed-off-by: Sheng Wei <w.sheng@intel.com>
Cc: Eric Dong <eric.dong@intel.com>
Cc: Ray Ni <ray.ni@intel.com>
Cc: Laszlo Ersek <lersek@redhat.com>
Cc: Rahul Kumar <rahul1.kumar@intel.com>
Cc: Jiewen Yao <jiewen.yao@intel.com>
Cc: Roger Feng <roger.feng@intel.com>
Reviewed-by: Jiewen Yao <jiewen.yao@intel.com>
Reviewed-by: Ray Ni <ray.ni@intel.com>
2021-03-02 05:11:55 +00:00
Sheng Wei 0930e7ff64 UefiCpuPkg/CpuExceptionHandlerLib: Clear CET shadow stack token busy bit
If CET shadows stack feature enabled in SMM and stack switch is enabled.
When code execute from SMM handler to SMM exception, CPU will check SMM
exception shadow stack token busy bit if it is cleared or not.
If it is set, it will trigger #DF exception.
If it is not set, CPU will set the busy bit when enter SMM exception.
So, the busy bit should be cleared when return back form SMM exception to
SMM handler. Otherwise, keeping busy bit 1 will cause to trigger #DF
exception when enter SMM exception next time.
So, we use instruction SAVEPREVSSP, CLRSSBSY and RSTORSSP to clear the
shadow stack token busy bit before RETF instruction in SMM exception.

REF: https://bugzilla.tianocore.org/show_bug.cgi?id=3192

Signed-off-by: Sheng Wei <w.sheng@intel.com>
Cc: Eric Dong <eric.dong@intel.com>
Cc: Ray Ni <ray.ni@intel.com>
Cc: Laszlo Ersek <lersek@redhat.com>
Cc: Rahul Kumar <rahul1.kumar@intel.com>
Cc: Jiewen Yao <jiewen.yao@intel.com>
Cc: Roger Feng <roger.feng@intel.com>
Reviewed-by: Jiewen Yao <jiewen.yao@intel.com>
Reviewed-by: Ray Ni <ray.ni@intel.com>
2021-03-02 05:11:55 +00:00
Ray Ni 62f2cf5784 UefiCpuPkg/MpInitLib: Use XADD to avoid lock acquire/release
When AP firstly wakes up, MpFuncs.nasm contains below logic to assign
an unique ApIndex to each AP according to who comes first:
---ASM---
TestLock:
    xchg       [edi], eax
    cmp        eax, NotVacantFlag
    jz         TestLock

    mov        ecx, esi
    add        ecx, ApIndexLocation
    inc        dword [ecx]
    mov        ebx, [ecx]

Releaselock:
    mov        eax, VacantFlag
    xchg       [edi], eax
---ASM END---

"lock inc" cannot be used to increase ApIndex because not only the
global ApIndex should be increased, but also the result should be
stored to a local general purpose register EBX.

This patch learns from the NASM implementation of
InternalSyncIncrement() to use "XADD" instruction which can increase
the global ApIndex and store the original ApIndex to EBX in one
instruction.

With this patch, OVMF when running in a 255 threads QEMU spends about
one second to wakeup all APs. Original implementation needs more than
10 seconds.

Signed-off-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: Michael D Kinney <michael.d.kinney@intel.com>
Acked-by: Laszlo Ersek <lersek@redhat.com>
Reviewed-by: Eric Dong <eric.dong@intel.com>
2021-02-26 11:51:37 +00:00
Guomin Jiang f6ec1dd34f UefiCpuPkg: Move MigrateGdt from DiscoverMemory to TempRamDone. (CVE-2019-11098)
REF: https://bugzilla.tianocore.org/show_bug.cgi?id=1614
REF: https://bugzilla.tianocore.org/show_bug.cgi?id=3160

The GDT still in flash with commit 60b12e69fb
after TempRamDone

So move the action to TempRamDone event to avoid reading GDT from flash.

Signed-off-by: Guomin Jiang <guomin.jiang@intel.com>
Cc: Eric Dong <eric.dong@intel.com>
Cc: Ray Ni <ray.ni@intel.com>
Cc: Laszlo Ersek <lersek@redhat.com>
Cc: Rahul Kumar <rahul1.kumar@intel.com>
Cc: Debkumar De <debkumar.de@intel.com>
Cc: Harry Han <harry.han@intel.com>
Cc: Catharine West <catharine.west@intel.com>
Reviewed-by: Ray Ni <ray.ni@intel.com>
2021-02-04 01:30:05 +00:00
Lou, Yun e806bb29cf UefiCpuPkg/CpuCacheInfoLib: Support no enabled AP case in DxeLib
REF: https://bugzilla.tianocore.org/show_bug.cgi?id=3195

Support system has no enabled AP case in DxeCpuCacheInfoLib.
Otherwise, if the system only has 1 BSP without any enabled AP,
UEFI POST hangs when invoking StartupAllAPs protocol because
EFI_NOT_STARTED is returned.

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>
2021-02-03 07:41:46 +00:00
Lou, Yun 51b96e4b4c UefiCpuPkg/CpuCacheInfoLib: Add MpService dependency
REF: https://bugzilla.tianocore.org/show_bug.cgi?id=3190

Add MpService dependency to enforce the executability of CpuCacheInfoLib.

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>
2021-02-03 07:41:46 +00:00
Kun Qin 3b468095cd UefiCpuPkg: SmmCpuExceptionHandlerLib: Added StandaloneMm module support
This change of SmmCpuExceptionHandlerLib adds support for StandaloneMm
components to allow x64 StandaloneMm environment setting up exception
handlers.

Cc: Eric Dong <eric.dong@intel.com>
Cc: Ray Ni <ray.ni@intel.com>
Cc: Laszlo Ersek <lersek@redhat.com>
Cc: Rahul Kumar <rahul1.kumar@intel.com>

Signed-off-by: Kun Qin <kun.q@outlook.com>
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
Reviewed-by: Ray Ni <ray.ni@intel.com>
2021-02-01 10:07:13 -08:00
Kun Qin c2432b31ed UefiCpuPkg: CpuIo2Smm: Support of CpuIo driver under StandaloneMm
This change adds a new CpuIo driver instance for MM_STANDALONE type. The
new driver entrypoint is implemented in a separate file to match the
interface definition of MM_STANDALONE modules.

Cc: Eric Dong <eric.dong@intel.com>
Cc: Ray Ni <ray.ni@intel.com>
Cc: Laszlo Ersek <lersek@redhat.com>
Cc: Rahul Kumar <rahul1.kumar@intel.com>

Signed-off-by: Kun Qin <kun.q@outlook.com>
Reviewed-by: Ray Ni <ray.ni@intel.com>
2021-02-01 10:04:42 -08:00
Kun Qin 1ea21af13d UefiCpuPkg: CpuIo2Smm: Abstract SMM specific functions into separate file
This change abstracts CpuIo2Smm driver entrypoint into separate file and
moves functions/definitions that are not substantially specific to
Traditional MM (SMM) into CpuIo2Mm.* in order to set ways for Standalone
MM support in the future.

Cc: Eric Dong <eric.dong@intel.com>
Cc: Ray Ni <ray.ni@intel.com>
Cc: Laszlo Ersek <lersek@redhat.com>
Cc: Rahul Kumar <rahul1.kumar@intel.com>

Signed-off-by: Kun Qin <kun.q@outlook.com>
Reviewed-by: Ray Ni <ray.ni@intel.com>
2021-02-01 10:03:58 -08:00
Kun Qin e414a3e936 UefiCpuPkg: CpuIo2Smm: Move CpuIo2Smm driver to consume gMmst
This change replaced gSmst with gMmst to support broader compatibility
under MM environment for CpuIo2Smm driver.

Cc: Eric Dong <eric.dong@intel.com>
Cc: Ray Ni <ray.ni@intel.com>
Cc: Laszlo Ersek <lersek@redhat.com>
Cc: Rahul Kumar <rahul1.kumar@intel.com>

Signed-off-by: Kun Qin <kun.q@outlook.com>
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
Reviewed-by: Ray Ni <ray.ni@intel.com>
2021-02-01 10:03:36 -08:00
Ray Ni c6be6dab9c UefiCpuPkg/MpInitLib: Don't increase CpuCount in ApWakeupFunction
REF: https://bugzilla.tianocore.org/show_bug.cgi?id=3179

When BSP first time wakes all APs, each AP atomically increases
CpuMpData->CpuCount and CpuMpData->FinishedCount.

Each AP atomically increases CpuMpData->NumApsExecuting
in early assembly code and decreases it before it enters to HLT or
MWAIT state.

Putting them together, the 3 variables are changed in the following order:
1. NumApsExecuting++ // in assembly
2. CpuCpunt++
4. FinishedCount++
3. NumApsExecuting-- // in C

BSP waits for a certain timeout and then polls NumApsExecuting
until it drops to zero. It assumes all APs are waken up concurrently
and NumApsExecuting only drops to zero when all APs have checked in.

Then it additionally waits for FinishedCount == CpuCount - 1. (FinishedCount doesn't include BSP while CpuCount includes BSP.)

There is no need to additionally wait for
FinishedCount == CpuCount - 1 because when NumApsExecuting == 0,
the number of increament of FinishedCount and CpuCount should equal.

This patch simplifies the code to remove "CpuCount++" in
ApWakeupFunction() and
assigns FinishedCount + 1 to CpuCount after WakeUpAP().

Signed-off-by: Ray Ni <ray.ni@intel.com>
Reviewed-by: Eric Dong <eric.dong@intel.com>
Acked-by: Laszlo Ersek <lersek@redhat.com>
2021-01-29 03:09:35 +00:00
Lou, Yun 2d6fc9d36f MdePkg/Cpuid.h: Change and add some macro definitions.
REF: https://bugzilla.tianocore.org/show_bug.cgi?id=3105

Change and add some macro definitions about
CPUID_HYBRID_INFORMATION Leaf(1Ah).

Signed-off-by: Jason Lou <yun.lou@intel.com>
Cc: Michael D Kinney <michael.d.kinney@intel.com>
Reviewed-by: Liming Gao <gaoliming@byosoft.com.cn>
Cc: Zhiguang Liu <zhiguang.liu@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>
2021-01-26 04:14:10 +00:00
Michael D Kinney 1c5c7bcd1d UefiCpuPkg/Library/MpInitLib: Fix AP VolatileRegisters race condition
REF: https://bugzilla.tianocore.org/show_bug.cgi?id=3182

Fix the order of operations in ApWakeupFunction() when PcdCpuApLoopMode
is set to HLT mode that uses INIT-SIPI-SIPI to wake APs.  In this mode,
volatile state is restored and saved each time a INIT-SIPI-SIPI is sent
to an AP to request a function to be executed on the AP.  When the
function is completed the volatile state of the AP is saved.  However,
the counters NumApsExecuting and FinishedCount are updated before
the volatile state is saved.  This allows for a race condition window
for the BSP that is waiting on these counters to request a new
INIT-SIPI-SIPI before all the APs have completely saved their volatile
state.  The fix is to save the AP volatile state before updating the
NumApsExecuting and FinishedCount counters.

Cc: Eric Dong <eric.dong@intel.com>
Reviewed-by: Ray Ni <ray.ni@intel.com>
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
Cc: Rahul Kumar <rahul1.kumar@intel.com>
Reviewed-by: Star Zeng <star.zeng@intel.com>
Signed-off-by: Michael D Kinney <michael.d.kinney@intel.com>
2021-01-26 03:18:40 +00:00
Ray Ni 3b769c5110 UefiCpuPkg/CpuMp: Fix hang when StackGuard is enabled in 16-core cpu
REF: https://bugzilla.tianocore.org/show_bug.cgi?id=3167

When StackGuard is enabled, the CpuMp driver allocates
known good stacks for all CPUs for DF# and PF# exceptions.
It uses AllocatePool to do so.

The size needed equals to 64KB
= StackSize (2K) * ExceptionNumber (2) * NumberOfProcessors (16)

However, AllocatePool max allocation size is less than 64K.
To fix the issue, AllocatePages() is used.

Signed-off-by: Ray Ni <ray.ni@intel.com>
Reviewed-by: Eric Dong <eric.dong@intel.com>
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
Cc: Rahul Kumar <rahul1.kumar@intel.com>
2021-01-22 03:23:53 +00:00
Zeng, Star 6c5801be6e UefiCpuPkg RegisterCpuFeaturesLib: NumberOfCpus may be uninitialized
NumberOfCpus local variable in GetAcpiCpuData will be uninitialized
when CpuS3DataDxe runs before DxeRegisterCpuFeaturesLib (linked by
CpuFeaturesDxe) because there is no code to initialize it at
(AcpiCpuData != NULL) execution path.

The issue is exposed after cefad282fb
and 38ee7bafa7.
There was negligence in that code review.
One further topic may be "Could EDK2 CI be enhanced to catch this kind
of uninitialized local variable case?". :)

This patch fixes this regression issue.

Cc: Eric Dong <eric.dong@intel.com>
Cc: Ray Ni <ray.ni@intel.com>
Cc: Laszlo Ersek <lersek@redhat.com>
Signed-off-by: Star Zeng <star.zeng@intel.com>
Message-Id: <20210121093944.1621-1-star.zeng@intel.com>
Reviewed-by: Ray Ni <ray.ni@intel.com>
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
2021-01-21 14:30:06 +00:00
Laszlo Ersek 38ee7bafa7 UefiCpuPkg/CpuS3DataDxe: do not allocate useless register tables
CpuS3DataDxe allocates the "RegisterTable" and "PreSmmInitRegisterTable"
arrays in ACPI_CPU_DATA just so every processor in the system can have its
own empty register table, matched by APIC ID. This has never been useful
in practice.

Given commit e992cc3f48 ("UefiCpuPkg PiSmmCpuDxeSmm: Reduce SMRAM
consumption in CpuS3.c", 2021-01-11), simply leave both
"AcpiCpuData->RegisterTable" and "AcpiCpuData->PreSmmInitRegisterTable"
initialized to the zero address. This simplifies the driver, and saves
both normal RAM (boot services data type memory) and -- in PiSmmCpuDxeSmm
-- SMRAM.

Cc: Eric Dong <eric.dong@intel.com>
Cc: Philippe Mathieu-Daudé <philmd@redhat.com>
Cc: Rahul Kumar <rahul1.kumar@intel.com>
Cc: Ray Ni <ray.ni@intel.com>
Cc: Star Zeng <star.zeng@intel.com>
Ref: https://bugzilla.tianocore.org/show_bug.cgi?id=3159
Signed-off-by: Laszlo Ersek <lersek@redhat.com>
Reviewed-by: Ray Ni <ray.ni@intel.com>
Message-Id: <20210119155440.2262-4-lersek@redhat.com>
Reviewed-by: Star Zeng <star.zeng@intel.com>
2021-01-20 18:20:14 +00:00
Laszlo Ersek 1487c13ce0 UefiCpuPkg/AcpiCpuData: update comments on register table fields
After commit e992cc3f48 ("UefiCpuPkg PiSmmCpuDxeSmm: Reduce SMRAM
consumption in CpuS3.c", 2021-01-11), it is valid for a CPU S3 Data DXE
Driver to set "ACPI_CPU_DATA.PreSmmInitRegisterTable" and/or
"ACPI_CPU_DATA.RegisterTable" to 0, in case none of the CPUs needs a
register table of the corresponding kind, during S3 resume.

Document this fact in the "UefiCpuPkg/Include/AcpiCpuData.h" header file.

Cc: Eric Dong <eric.dong@intel.com>
Cc: Philippe Mathieu-Daudé <philmd@redhat.com>
Cc: Rahul Kumar <rahul1.kumar@intel.com>
Cc: Ray Ni <ray.ni@intel.com>
Cc: Star Zeng <star.zeng@intel.com>
Ref: https://bugzilla.tianocore.org/show_bug.cgi?id=3159
Signed-off-by: Laszlo Ersek <lersek@redhat.com>
Reviewed-by: Ray Ni <ray.ni@intel.com>
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Message-Id: <20210119155440.2262-3-lersek@redhat.com>
Reviewed-by: Star Zeng <star.zeng@intel.com>
2021-01-20 18:20:14 +00:00
Ray Ni cefad282fb UefiCpuPkg/CpuFeature: Don't assume CpuS3DataDxe alloc RegisterTable
There are lots of fields in ACPI_CPU_DATA structure while only
followings are accessed by CpuFeature infra:
* NumberOfCpus
* PreSmmInitRegisterTable // pointer
* RegisterTable  // pointer
* CpuStatus
* ApLocation  // pointer

So it's possible that an implementation of CpuS3DataDxe doesn't
allocate memory for PreSmmInitRegisterTable/RegisterTable/ApLocation.

This patch handles the case when CpuS3DataDxe doesn't allocate
memory for PreSmmInitRegisterTable/RegisterTable.

Cc: Eric Dong <eric.dong@intel.com>
Cc: Philippe Mathieu-Daudé <philmd@redhat.com>
Cc: Rahul Kumar <rahul1.kumar@intel.com>
Cc: Ray Ni <ray.ni@intel.com>
Cc: Star Zeng <star.zeng@intel.com>
Ref: https://bugzilla.tianocore.org/show_bug.cgi?id=3159
Signed-off-by: Ray Ni <ray.ni@intel.com>
[lersek@redhat.com: update CC list, add BZ reference, add my S-o-b]
[lersek@redhat.com: deal with RegisterTable and PreSmmInitRegisterTable
 being zero independently of each other; replacing the ASSERT()]
Signed-off-by: Laszlo Ersek <lersek@redhat.com>
Message-Id: <20210119155440.2262-2-lersek@redhat.com>
Reviewed-by: Star Zeng <star.zeng@intel.com>
2021-01-20 18:20:14 +00:00
Lou, Yun 83facfd184 UefiCpuPkg/CpuCacheInfoLib: Add new CpuCacheInfoLib.
REF: https://bugzilla.tianocore.org/show_bug.cgi?id=3105

This new library uses a platform agnostic algorithm to get CPU
cache information. It provides user with an API(GetCpuCacheInfo)
to get detailed CPU cache information by each package, each core
type included in this package, and each cache level & type.
This library can be used by code that produces SMBIOS_TABLE_TYPE7
SMBIOS table.

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>
2021-01-19 14:03:04 +00:00
Guo Dong ebfe2d3eb5 UefiCpuPkg/CpuDxe: Fix boot error
REF: https://bugzilla.tianocore.org/show_bug.cgi?id=3084

When DXE drivers are dispatched above 4GB memory in 64bit
mode, the address setCodeSelectorLongJump in stack will
be override by parameter. Jump to Qword is not supported
by some processors. So use "o64 retf" instead.

Signed-off-by: Guo Dong <guo.dong@intel.com>
Acked-by: Laszlo Ersek <lersek@redhat.com>
Tested-by: Tom Lendacky <thomas.lendacky@amd.com>
Reviewed-by: Michael D Kinney <michael.d.kinney@intel.com>
Tested-by: James Bottomley <jejb@linux.ibm.com>
Reviewed-by: Ray Ni <ray.ni@intel.com>
2021-01-12 06:35:30 +00:00
Guo Dong edd74ad3ad UefiCpuPkg/MpInitLib: Fix a hang in above 4GB case
This patch fixed the hang in UEFICpuPkg when it is dispatched above 4GB.
In UEFI BIOS case CpuInfoInHob is provided to DXE under 4GB from PEI.
When using UEFI payload and bootloaders, CpuInfoInHob will be allocated
above 4GB since it is not provided from bootloader. so we need update
the code to make sure this hob could be accessed correctly in this case.

Signed-off-by: Guo Dong <guo.dong@intel.com>
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
Reviewed-by: Ray Ni <ray.ni@intel.com>
2021-01-12 06:35:30 +00:00
Zeng, Star e992cc3f48 UefiCpuPkg PiSmmCpuDxeSmm: Reduce SMRAM consumption in CpuS3.c
This patch makes two refinements to reduce SMRAM consumption in CpuS3.c.
1. Only do CopyRegisterTable() when register table is not empty,
  IsRegisterTableEmpty() is created to check whether the register table
  is empty or not.

  Take empty PreSmmInitRegisterTable as example, about 24K SMRAM consumption
  could be reduced when mAcpiCpuData.NumberOfCpus=1024.
  sizeof (CPU_REGISTER_TABLE) = 24
  mAcpiCpuData.NumberOfCpus = 1024 = 1K
  mAcpiCpuData.NumberOfCpus * sizeof (CPU_REGISTER_TABLE) = 24K

2. Only copy table entries buffer instead of whole buffer.
  AllocatedSize in SourceRegisterTableList is the whole buffer size.
  Actually, only the table entries buffer needs to be copied, and the size
  is TableLength * sizeof (CPU_REGISTER_TABLE_ENTRY).

  Take AllocatedSize=0x1000=4096, TableLength=100 and NumberOfCpus=1024 as example,
  about 1696K SMRAM consumption could be reduced.
  sizeof (CPU_REGISTER_TABLE_ENTRY) = 24
  TableLength = 100
  TableLength * sizeof (CPU_REGISTER_TABLE_ENTRY) = 2400
  AllocatedSize = 0x1000 = 4096
  AllocatedSize - TableLength * sizeof (CPU_REGISTER_TABLE_ENTRY) = 4096 - 2400 = 1696
  NumberOfCpus = 1024 = 1K
  NumberOfCpus * (AllocatedSize - TableLength * sizeof (CPU_REGISTER_TABLE_ENTRY)) = 1696K

This patch also corrects the CopyRegisterTable() function description.

Signed-off-by: Star Zeng <star.zeng@intel.com>
Reviewed-by: Ray Ni <ray.ni@intel.com>
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
Cc: Ray Ni <ray.ni@intel.com>
Cc: Eric Dong <eric.dong@intel.com>
Cc: Laszlo Ersek <lersek@redhat.com>
Message-Id: <20210111015419.28368-1-star.zeng@intel.com>
2021-01-11 09:13:48 +00:00
Laszlo Ersek 089285b42c Revert "UefiCpuPkg/CpuDxe: Fix boot error"
This reverts commit cee5b0441a.

Commit cee5b0441a ("UefiCpuPkg/CpuDxe: Fix boot error", 2020-12-08)
breaks CpuDxe (and with it, OVMF boot) on AMD processors. AMD processors
cannot do far jumps to 64-bit targets, as documented in the AMD64
Architecture Programmer's Manual.

Revert the patch until a RETFQ-based substitute is posted.

Cc: Eric Dong <eric.dong@intel.com>
Cc: Guo Dong <guo.dong@intel.com>
Cc: James Bottomley <James.Bottomley@HansenPartnership.com>
Cc: Rahul Kumar <rahul1.kumar@intel.com>
Cc: Ray Ni <ray.ni@intel.com>
Cc: Thomas Lendacky <thomas.lendacky@amd.com>
Ref: https://edk2.groups.io/g/devel/message/68597
Ref: https://www.redhat.com/archives/edk2-devel-archive/2020-December/msg00493.html
Reported-by: Thomas Lendacky <thomas.lendacky@amd.com>
Ref: https://edk2.groups.io/g/devel/message/68832
Ref: https://www.redhat.com/archives/edk2-devel-archive/2020-December/msg00737.html
Reported-by: James Bottomley <James.Bottomley@HansenPartnership.com>
Signed-off-by: Laszlo Ersek <lersek@redhat.com>
Message-Id: <20201217085055.15131-1-lersek@redhat.com>
Ref: https://bugzilla.tianocore.org/show_bug.cgi?id=3121
[lersek@redhat.com: add BZ link]
2020-12-18 11:20:55 +00:00
Ray Ni 793c59da13 UefiCpuPkg/CpuFeature: reduce time complexty to calc CpuInfo.First
CpuInfo.First stores whether the current thread belongs to the first
package in the platform, first core in a package, first thread in a
core.

But the time complexity of original algorithm to calculate the
CpuInfo.First is O (n) * O (p) * O (c).
  n: number of processors
  p: number of packages
  c: number of cores per package

The patch trades time with space by storing the first package, first
core per package, first thread per core in an array.
The time complexity becomes O (n).

Signed-off-by: Ray Ni <ray.ni@intel.com>
Reviewed-by: Eric Dong <eric.dong@intel.com>
Reviewed-by: Star Zeng <star.zeng@intel.com>
Cc: Yun Lou <yun.lou@intel.com>
Cc: Laszlo Ersek <lersek@redhat.com>
2020-12-14 08:54:22 +00:00
Star Zeng 004f9776f4 UefiCpuPkg RegisterCpuFeaturesLib: Use AllocatePages() for InitOrder
The required buffer size for InitOrder will be 96K when NumberOfCpus=1024.
sizeof (CPU_FEATURES_INIT_ORDER) = 96
NumberOfCpus = 1024 = 1K
sizeof (CPU_FEATURES_INIT_ORDER) * NumberOfCpus = 96K

AllocateZeroPool() will call to PeiServicesAllocatePool() which will use
EFI_HOB_MEMORY_POOL to management memory pool.
EFI_HOB_MEMORY_POOL.Header.HobLength is UINT16 type, so there is no way
for AllocateZeroPool() to allocate > 64K memory.

So AllocateZeroPool() could not be used anymore for the case above or
even bigger required buffer size.

This patch updates the code to use AllocatePages() instead of
AllocateZeroPool() to allocate buffer for InitOrder.

Signed-off-by: Star Zeng <star.zeng@intel.com>
Reviewed-by: Ray Ni <ray.ni@intel.com>
Cc: Ray Ni <ray.ni@intel.com>
Cc: Eric Dong <eric.dong@intel.com>
Cc: Laszlo Ersek <lersek@redhat.com>
2020-12-14 05:49:50 +00:00
Guo Dong 7061294be5 UefiCpuPkg/SmmCpuFeaturesLib: Add Tiger Lake support
Add Tiger Lake ModelId support in the SMM CPU feature lib.

Signed-off-by: Guo Dong <guo.dong@intel.com>
Reviewed-by: Eric Dong <eric.dong@intel.com>
2020-12-08 23:07:22 +00:00
Guo Dong cee5b0441a UefiCpuPkg/CpuDxe: Fix boot error
REF: https://bugzilla.tianocore.org/show_bug.cgi?id=3084

When DXE drivers are dispatched above 4GB memory and
the system is already in 64bit mode, the address
setCodeSelectorLongJump in stack will be override
by parameter. so change to use 64bit address and
jump to qword address.

Signed-off-by: Guo Dong <guo.dong@intel.com>
Reviewed-by: Ray Ni <ray.ni@intel.com>
Reviewed-by: Eric Dong <eric.dong@intel.com>
2020-12-08 22:17:55 +00:00
Ray Ni 6af76adbbf UefiCpuPkg/Feature: Support different thread count per core
Today's code assumes every core contains the same number of threads.
It's not always TRUE for certain model.
Such assumption causes system hang when thread count per core
is different and there is core or package dependency between CPU
features (using CPU_FEATURE_CORE_BEFORE/AFTER,
CPU_FEATURE_PACKAGE_BEFORE/AFTER).

The change removes such assumption by calculating the actual thread
count per package and per core.

Signed-off-by: Ray Ni <ray.ni@intel.com>
Reviewed-by: Eric Dong <eric.dong@intel.com>
Cc: Yun Lou <yun.lou@intel.com>
Acked-by: Laszlo Ersek <lersek@redhat.com>
2020-12-04 01:18:56 +00:00
Sheng Wei 404250c8f7 UefiCpuPkg/PiSmmCpuDxeSmm: Reflect page table depth with page table address
When trying to get page table base, if mInternalCr3 is zero, it will use
 the page table from CR3, and reflect the page table depth by CR4 LA57 bit.
If mInternalCr3 is non zero, it will use the page table from mInternalCr3
 and reflect the page table depth of mInternalCr3 at same time.
In the case of X64, we use m5LevelPagingNeeded to reflect the depth of
 the page table. And in the case of IA32, it will not the page table depth
 information.

This patch is a bug fix when enable CET feature with 5 level paging.
The SMM page tables are allocated / initialized in PiCpuSmmEntry().
When CET is enabled, PiCpuSmmEntry() must further modify the attribute of
 shadow stack pages. This page table is not set to CR3 in PiCpuSmmEntry().
 So the page table base address is set to mInternalCr3 for modifty the
 page table attribute. It could not use CR4 LA57 bit to reflect the
 page table depth for mInternalCr3.
So we create a architecture-specific implementation GetPageTable() with
 2 output parameters. One parameter is used to output the page table
 address. Another parameter is used to reflect if it is 5 level paging
 or not.

REF: https://bugzilla.tianocore.org/show_bug.cgi?id=3015

Signed-off-by: Sheng Wei <w.sheng@intel.com>
Cc: Eric Dong <eric.dong@intel.com>
Cc: Ray Ni <ray.ni@intel.com>
Cc: Laszlo Ersek <lersek@redhat.com>
Cc: Rahul Kumar <rahul1.kumar@intel.com>
Cc: Jiewen Yao <jiewen.yao@intel.com>
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
Reviewed-by: Eric Dong <eric.dong@intel.com>
2020-11-18 04:52:26 +00:00
Sheng Wei 1a110fcd4e UefiCpuPkg/PiSmmCpuDxeSmm: Correct the Cr3 typo
Change the variable name from mInternalGr3 to mInternalCr3.

REF: https://bugzilla.tianocore.org/show_bug.cgi?id=3015

Signed-off-by: Sheng Wei <w.sheng@intel.com>
Cc: Eric Dong <eric.dong@intel.com>
Cc: Ray Ni <ray.ni@intel.com>
Cc: Laszlo Ersek <lersek@redhat.com>
Cc: Rahul Kumar <rahul1.kumar@intel.com>
Cc: Jiewen Yao <jiewen.yao@intel.com>
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
Reviewed-by: Ray Ni <ray.ni@intel.com>
Reviewed-by: Eric Dong <eric.dong@intel.com>
2020-11-18 04:52:26 +00:00
Tom Lendacky d150439b72 UefiCpuPkg/MpInitLib: For SEV-ES guest, set stack based on processor number
BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=3008

Set the SEV-ES reset stack address for an AP based on the processor number
instead of the APIC ID in case the APIC IDs are not zero-based and densely
packed/enumerated. This will ensure an AP reset stack address does not get
set outside of the AP reset stack memory allocation.

Cc: Eric Dong <eric.dong@intel.com>
Cc: Ray Ni <ray.ni@intel.com>
Cc: Laszlo Ersek <lersek@redhat.com>
Cc: Rahul Kumar <rahul1.kumar@intel.com>
Acked-by: Ray Ni <ray.ni@intel.com>
Signed-off-by: Tom Lendacky <thomas.lendacky@amd.com>
Message-Id: <24866de07d2a954dec71df70972f1851273020d8.1604685192.git.thomas.lendacky@amd.com>
2020-11-10 19:07:55 +00:00
Tom Lendacky 1b0db1ec87 UefiCpuPkg, OvmfPkg: Disable interrupts when using the GHCB
BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=3008

The QemuFlashPtrWrite() flash services runtime uses the GHCB and VmgExit()
directly to perform the flash write when running as an SEV-ES guest. If an
interrupt arrives between VmgInit() and VmgExit(), the Dr7 read in the
interrupt handler will generate a #VC, which can overwrite information in
the GHCB that QemuFlashPtrWrite() has set. This has been seen with the
timer interrupt firing and the CpuExceptionHandlerLib library code,
UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/
  Xcode5ExceptionHandlerAsm.nasm and
  ExceptionHandlerAsm.nasm
reading the Dr7 register while QemuFlashPtrWrite() is using the GHCB. In
general, it is necessary to protect the GHCB whenever it is used, not just
in QemuFlashPtrWrite().

Disable interrupts around the usage of the GHCB by modifying the VmgInit()
and VmgDone() interfaces:
- VmgInit() will take an extra parameter that is a pointer to a BOOLEAN
  that will hold the interrupt state at the time of invocation. VmgInit()
  will get and save this interrupt state before updating the GHCB.
- VmgDone() will take an extra parameter that is used to indicate whether
  interrupts are to be (re)enabled. Before exiting, VmgDone() will enable
  interrupts if that is requested.

Fixes: 437eb3f7a8
Cc: Eric Dong <eric.dong@intel.com>
Cc: Ray Ni <ray.ni@intel.com>
Cc: Laszlo Ersek <lersek@redhat.com>
Cc: Rahul Kumar <rahul1.kumar@intel.com>
Cc: Jordan Justen <jordan.l.justen@intel.com>
Cc: Ard Biesheuvel <ard.biesheuvel@arm.com>
Cc: Tom Lendacky <thomas.lendacky@amd.com>
Cc: Brijesh Singh <brijesh.singh@amd.com>
Acked-by: Eric Dong <eric.dong@intel.com>
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
Signed-off-by: Tom Lendacky <thomas.lendacky@amd.com>
Message-Id: <c326a4fd78253f784b42eb317589176cf7d8592a.1604685192.git.thomas.lendacky@amd.com>
2020-11-10 19:07:55 +00:00
Tom Lendacky fb2a1a36a2 UefiCpuPkg/MpInitLib: Set the SW exit fields when performing VMGEXIT
BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=3008

All fields that are set in the GHCB should have their associated bit in
the GHCB ValidBitmap field set. Add support to set the bits for the
software exit information fields when performing a VMGEXIT (SwExitCode,
SwExitInfo1, SwExitInfo2).

Fixes: 20da7ca42a
Cc: Eric Dong <eric.dong@intel.com>
Cc: Ray Ni <ray.ni@intel.com>
Cc: Laszlo Ersek <lersek@redhat.com>
Cc: Rahul Kumar <rahul1.kumar@intel.com>
Acked-by: Ray Ni <ray.ni@intel.com>
Signed-off-by: Tom Lendacky <thomas.lendacky@amd.com>
Message-Id: <6e11dd7e161bddeacc3fb4817467cef24510c31c.1604685192.git.thomas.lendacky@amd.com>
2020-11-10 19:07:55 +00:00
Tom Lendacky 8a7ca9923e UefiCpuPkg/VmgExitLib: Add interfaces to set/read GHCB ValidBitmap bits
BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=3008

In upcoming patches, the setting of the bits in the GHCB ValidBitmap will
be performed in multiple places. In order to reduce code duplication, add
an interface, VmgSetOffsetValid(), to VmgExitLib library to perform this
function. Also, to keep management of the ValidBitmap within the library,
add an inteface, VmgIsOffsetValid(), to return whether the bit in the
ValidBitmap is set for a specified offset.

The new VmgSetOffsetValid() function is a VOID function and will be an
empty function in the VmgExitLibNull implementation of the VmgExitLib
library.

The new VmgIsOffsetValid() function returns a BOOLEAN to indicate if the
offset is valid. This will always return FALSE in the VmgExitLibNull
implementation of the VmgExitLib library.

Cc: Eric Dong <eric.dong@intel.com>
Cc: Ray Ni <ray.ni@intel.com>
Cc: Laszlo Ersek <lersek@redhat.com>
Cc: Rahul Kumar <rahul1.kumar@intel.com>
Acked-by: Eric Dong <eric.dong@intel.com>
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
Signed-off-by: Tom Lendacky <thomas.lendacky@amd.com>
Message-Id: <0bcb2373f8c6e0171ae277d3d7c2eb284621355e.1604685192.git.thomas.lendacky@amd.com>
2020-11-10 19:07:55 +00:00
Tom Lendacky 93edd1887e UefiCpuPkg/MpInitLib: Reduce reset vector memory pressure
The AP reset vector stack allocation is only required if running as an
SEV-ES guest. Since the reset vector allocation is below 1MB in memory,
eliminate the requirement for bare-metal systems and non SEV-ES guests
to allocate the extra stack area, which can be large if the
PcdCpuMaxLogicalProcessorNumber value is large, and also remove the
CPU_STACK_ALIGNMENT alignment.

Fixes: 7b7508ad78 ("UefiCpuPkg: Allow AP booting under SEV-ES")
Cc: Garrett Kirkendall <garrett.kirkendall@amd.com>
Signed-off-by: Tom Lendacky <thomas.lendacky@amd.com>
Message-Id: <21345cdbc906519558202b3851257ca07b9239ba.1600884239.git.thomas.lendacky@amd.com>
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
[lersek@redhat.com: supply missing space character after "PcdGet32"]
2020-10-19 21:47:21 +00:00
Chasel Chiu 1b461403ee UefiCpuPkg/RegisterCpuFeaturesLib: Support MpServices2 only case.
REF: https://bugzilla.tianocore.org/show_bug.cgi?id=2883

MpServices Ppi can be replaced by MpServices2 Ppi and MpServices2
Ppi is mandatory for RegisterCpuFeaturesLib functionality,
basing on this we can drop MpServices Ppi usage from the library
and the constraint that both Ppis must be installed.

Cc: Eric Dong <eric.dong@intel.com>
Cc: Ray Ni <ray.ni@intel.com>
Cc: Laszlo Ersek <lersek@redhat.com>
Cc: Rahul Kumar <rahul1.kumar@intel.com>
Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>
Signed-off-by: Chasel Chiu <chasel.chiu@intel.com>
Reviewed-by: Eric Dong <eric.dong@intel.com>
Reviewed-by: Ray Ni <ray.ni@intel.com>
2020-09-14 13:07:37 +00:00
Tom Lendacky 48a83481d2 UefiCpuPkg/MpInitLib: Always initialize the DoDecrement variable
REF: https://bugzilla.tianocore.org/show_bug.cgi?id=2901

The DoDecrement variable in ApWakeupFunction () wasn't always being
initialized. Update the code to always fully initialize it.

Cc: Eric Dong <eric.dong@intel.com>
Cc: Ray Ni <ray.ni@intel.com>
Cc: Laszlo Ersek <lersek@redhat.com>
Cc: Rahul Kumar <rahul1.kumar@intel.com>
Signed-off-by: Tom Lendacky <thomas.lendacky@amd.com>
Message-Id: <76a9f18992475b915e5f8457704676067210cacf.1597935198.git.thomas.lendacky@amd.com>
Reviewed-by: Eric Dong <eric.dong@intel.com>
Tested-by: Liming Gao <liming.gao@intel.com>
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
2020-08-24 19:02:40 +00:00
Shenglei Zhang 739adc8ba4 UefiCpuPkg/UefiCpuPkg.ci.yaml: Add configuration for Ecc check
Add configuration ExceptionList and IgnoreFiles for package config
files. So users can rely on this to ignore some Ecc issues.

Cc: Eric Dong <eric.dong@intel.com>
Cc: Ray Ni <ray.ni@intel.com>
Cc: Laszlo Ersek <lersek@redhat.com>
Signed-off-by: Shenglei Zhang <shenglei.zhang@intel.com>
Acked-by: Ray Ni <ray.ni@intel.com>
Reviewed-by: Eric Dong <eric.dong@intel.com>
Acked-by: Laszlo Ersek <lersek@redhat.com>
Reviewed-by: Liming Gao <liming.gao@intel.com>
2020-08-17 03:28:09 +00:00
Tom Lendacky 20da7ca42a UefiCpuPkg/MpInitLib: Prepare SEV-ES guest APs for OS use
BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=2198

Before UEFI transfers control to the OS, it must park the AP. This is
done using the AsmRelocateApLoop function to transition into 32-bit
non-paging mode. For an SEV-ES guest, a few additional things must be
done:
  - AsmRelocateApLoop must be updated to support SEV-ES. This means
    performing a VMGEXIT AP Reset Hold instead of an MWAIT or HLT loop.
  - Since the AP must transition to real mode, a small routine is copied
    to the WakeupBuffer area. Since the WakeupBuffer will be used by
    the AP during OS booting, it must be placed in reserved memory.
    Additionally, the AP stack must be located where it can be accessed
    in real mode.
  - Once the AP is in real mode it will transfer control to the
    destination specified by the OS in the SEV-ES AP Jump Table. The
    SEV-ES AP Jump Table address is saved by the hypervisor for the OS
    using the GHCB VMGEXIT AP Jump Table exit code.

Cc: Eric Dong <eric.dong@intel.com>
Cc: Ray Ni <ray.ni@intel.com>
Cc: Laszlo Ersek <lersek@redhat.com>
Reviewed-by: Eric Dong <eric.dong@intel.com>
Signed-off-by: Tom Lendacky <thomas.lendacky@amd.com>
Regression-tested-by: Laszlo Ersek <lersek@redhat.com>
2020-08-17 02:46:39 +00:00
Tom Lendacky 7b7508ad78 UefiCpuPkg: Allow AP booting under SEV-ES
BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=2198

Typically, an AP is booted using the INIT-SIPI-SIPI sequence. This
sequence is intercepted by the hypervisor, which sets the AP's registers
to the values requested by the sequence. At that point, the hypervisor can
start the AP, which will then begin execution at the appropriate location.

Under SEV-ES, AP booting presents some challenges since the hypervisor is
not allowed to alter the AP's register state. In this situation, we have
to distinguish between the AP's first boot and AP's subsequent boots.

First boot:
 Once the AP's register state has been defined (which is before the guest
 is first booted) it cannot be altered. Should the hypervisor attempt to
 alter the register state, the change would be detected by the hardware
 and the VMRUN instruction would fail. Given this, the first boot for the
 AP is required to begin execution with this initial register state, which
 is typically the reset vector. This prevents the BSP from directing the
 AP startup location through the INIT-SIPI-SIPI sequence.

 To work around this, the firmware will provide a build time reserved area
 that can be used as the initial IP value. The hypervisor can extract this
 location value by checking for the SEV-ES reset block GUID that must be
 located 48-bytes from the end of the firmware. The format of the SEV-ES
 reset block area is:

   0x00 - 0x01 - SEV-ES Reset IP
   0x02 - 0x03 - SEV-ES Reset CS Segment Base[31:16]
   0x04 - 0x05 - Size of the SEV-ES reset block
   0x06 - 0x15 - SEV-ES Reset Block GUID
                   (00f771de-1a7e-4fcb-890e-68c77e2fb44e)

   The total size is 22 bytes. Any expansion to this block must be done
   by adding new values before existing values.

 The hypervisor will use the IP and CS values obtained from the SEV-ES
 reset block to set as the AP's initial values. The CS Segment Base
 represents the upper 16 bits of the CS segment base and must be left
 shifted by 16 bits to form the complete CS segment base value.

 Before booting the AP for the first time, the BSP must initialize the
 SEV-ES reset area. This consists of programming a FAR JMP instruction
 to the contents of a memory location that is also located in the SEV-ES
 reset area. The BSP must program the IP and CS values for the FAR JMP
 based on values drived from the INIT-SIPI-SIPI sequence.

Subsequent boots:
 Again, the hypervisor cannot alter the AP register state, so a method is
 required to take the AP out of halt state and redirect it to the desired
 IP location. If it is determined that the AP is running in an SEV-ES
 guest, then instead of calling CpuSleep(), a VMGEXIT is issued with the
 AP Reset Hold exit code (0x80000004). The hypervisor will put the AP in
 a halt state, waiting for an INIT-SIPI-SIPI sequence. Once the sequence
 is recognized, the hypervisor will resume the AP. At this point the AP
 must transition from the current 64-bit long mode down to 16-bit real
 mode and begin executing at the derived location from the INIT-SIPI-SIPI
 sequence.

 Another change is around the area of obtaining the (x2)APIC ID during AP
 startup. During AP startup, the AP can't take a #VC exception before the
 AP has established a stack. However, the AP stack is set by using the
 (x2)APIC ID, which is obtained through CPUID instructions. A CPUID
 instruction will cause a #VC, so a different method must be used. The
 GHCB protocol supports a method to obtain CPUID information from the
 hypervisor through the GHCB MSR. This method does not require a stack,
 so it is used to obtain the necessary CPUID information to determine the
 (x2)APIC ID.

The new 16-bit protected mode GDT entry is used in order to transition
from 64-bit long mode down to 16-bit real mode.

A new assembler routine is created that takes the AP from 64-bit long mode
to 16-bit real mode.  This is located under 1MB in memory and transitions
from 64-bit long mode to 32-bit compatibility mode to 16-bit protected
mode and finally 16-bit real mode.

Cc: Eric Dong <eric.dong@intel.com>
Cc: Ray Ni <ray.ni@intel.com>
Cc: Laszlo Ersek <lersek@redhat.com>
Reviewed-by: Eric Dong <eric.dong@intel.com>
Signed-off-by: Tom Lendacky <thomas.lendacky@amd.com>
Regression-tested-by: Laszlo Ersek <lersek@redhat.com>
2020-08-17 02:46:39 +00:00
Tom Lendacky e88a5b9833 UefiCpuPkg/MpInitLib: Add CPU MP data flag to indicate if SEV-ES is enabled
BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=2198

When starting APs in an SMP configuration, the AP needs to know if it is
running as an SEV-ES guest in order to assign a GHCB page.

Add a field to the CPU_MP_DATA structure that will indicate if SEV-ES is
enabled. This new field is set during MP library initialization with the
PCD value PcdSevEsIsEnabled. This flag can then be used to determine if
SEV-ES is enabled.

Cc: Eric Dong <eric.dong@intel.com>
Cc: Ray Ni <ray.ni@intel.com>
Cc: Laszlo Ersek <lersek@redhat.com>
Reviewed-by: Eric Dong <eric.dong@intel.com>
Signed-off-by: Tom Lendacky <thomas.lendacky@amd.com>
Regression-tested-by: Laszlo Ersek <lersek@redhat.com>
2020-08-17 02:46:39 +00:00
Tom Lendacky 0d7601e546 UefiCpuPkg: Add a 16-bit protected mode code segment descriptor
BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=2198

A hypervisor is not allowed to update an SEV-ES guests register state,
so when booting an SEV-ES guest AP, the hypervisor is not allowed to
set the RIP to the guest requested value. Instead, an SEV-ES AP must be
transition from 64-bit long mode to 16-bit real mode in response to an
INIT-SIPI-SIPI sequence. This requires a 16-bit code segment descriptor.
For PEI, create this descriptor in the reset vector GDT table. For DXE,
create this descriptor from the newly reserved entry at location 0x28.

Cc: Eric Dong <eric.dong@intel.com>
Cc: Ray Ni <ray.ni@intel.com>
Cc: Laszlo Ersek <lersek@redhat.com>
Reviewed-by: Eric Dong <eric.dong@intel.com>
Signed-off-by: Tom Lendacky <thomas.lendacky@amd.com>
Regression-tested-by: Laszlo Ersek <lersek@redhat.com>
2020-08-17 02:46:39 +00:00
Tom Lendacky 88a363009a UefiCpuPkg: Create an SEV-ES workarea PCD
BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=2198

Create an SEV-ES workarea PCD. This PCD will be used for BSP communication
during SEC and for AP startup during PEI and DXE phases, the latter is the
reason for creating it in the UefiCpuPkg.

Cc: Eric Dong <eric.dong@intel.com>
Cc: Ray Ni <ray.ni@intel.com>
Cc: Laszlo Ersek <lersek@redhat.com>
Reviewed-by: Eric Dong <eric.dong@intel.com>
Signed-off-by: Tom Lendacky <thomas.lendacky@amd.com>
Regression-tested-by: Laszlo Ersek <lersek@redhat.com>
2020-08-17 02:46:39 +00:00
Tom Lendacky 5277540e37 UefiCpuPkg/CpuExceptionHandler: Add base support for the #VC exception
BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=2198

Add base support to handle #VC exceptions. Update the common exception
handlers to invoke the VmgExitHandleVc () function of the VmgExitLib
library when a #VC is encountered. A non-zero return code will propagate
to the targeted exception handler.

Under SEV-ES, a DR7 read or write intercept generates a #VC exception.
To avoid exception recursion, a #VC exception will not try to read and
push the actual debug registers into the EFI_SYSTEM_CONTEXT_X64 struct
and instead push zeroes. The #VC exception handler does not make use of
the debug registers from the saved context and the exception processing
exit code does not attempt to restore the debug register values.

Cc: Eric Dong <eric.dong@intel.com>
Cc: Ray Ni <ray.ni@intel.com>
Cc: Laszlo Ersek <lersek@redhat.com>
Reviewed-by: Eric Dong <eric.dong@intel.com>
Signed-off-by: Tom Lendacky <thomas.lendacky@amd.com>
Regression-tested-by: Laszlo Ersek <lersek@redhat.com>
2020-08-17 02:46:39 +00:00
Tom Lendacky 8714978781 UefiCpuPkg: Implement library support for VMGEXIT
BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=2198

To support handling #VC exceptions and issuing VMGEXIT instructions,
create a library with functions that can be used to perform these
#VC/VMGEXIT related operations. This includes functions for:
  - Handling #VC exceptions
  - Preparing for and issuing a VMGEXIT
  - Performing MMIO-related write operations to support flash emulation
  - Performing AP related boot opeations

The base functions in this driver will not do anything and will return
an error if a return value is required. It is expected that other packages
(like OvmfPkg) will create a version of the library to fully support an
SEV-ES guest.

Cc: Eric Dong <eric.dong@intel.com>
Cc: Ray Ni <ray.ni@intel.com>
Cc: Laszlo Ersek <lersek@redhat.com>
Reviewed-by: Eric Dong <eric.dong@intel.com>
Signed-off-by: Tom Lendacky <thomas.lendacky@amd.com>
Regression-tested-by: Laszlo Ersek <lersek@redhat.com>
2020-08-16 16:45:42 +00:00
Tom Lendacky c9db7bf10a UefiCpuPkg: Create PCD to be used in support of SEV-ES
BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=2198

A new dynamic UefiCpuPkg PCD is needed to support SEV-ES under OVMF:
  - PcdSevEsIsEnabled: BOOLEAN value used to indicate if SEV-ES is enabled

Cc: Eric Dong <eric.dong@intel.com>
Cc: Ray Ni <ray.ni@intel.com>
Cc: Laszlo Ersek <lersek@redhat.com>
Reviewed-by: Eric Dong <eric.dong@intel.com>
Signed-off-by: Tom Lendacky <thomas.lendacky@amd.com>
Regression-tested-by: Laszlo Ersek <lersek@redhat.com>
2020-08-16 16:45:42 +00:00
Ray Ni 65904cdbb3 UefiCpuPkg/MtrrLibUnitTest: Change to use static array for CI test
The unit test app supports running in 3 mode:
1. MtrrLibUnitTest generate-random-numbers
     <path to MtrrLib/UnitTest/RandomNumber.c> <random-number count>
   It generates random numbers and writes to RandomNumber.c.

2. MtrrLibUnitTest [<iterations>]
   It tests MtrrLib APIs using configurations generated from static
   numbers generated by mode #1.
   This is the default execution mode running in CI environment.

3. MtrrLibUnitTest <iterations> random
   It tests MtrrLib APIs using configurations generated from random
   numbers.
   This is what developers can use to test MtrrLib for regressions.

Signed-off-by: Ray Ni <ray.ni@intel.com>
Cc: Michael D Kinney <michael.d.kinney@intel.com>
Cc: Eric Dong <eric.dong@intel.com>
Cc: Laszlo Ersek <lersek@redhat.com>
Cc: Ming Shao <ming.shao@intel.com>
Cc: Sean Brogan <sean.brogan@microsoft.com>
Cc: Bret Barkelew <Bret.Barkelew@microsoft.com>
Cc: Jiewen Yao <jiewen.yao@intel.com>
2020-08-12 11:38:37 +00:00
Ray Ni e17f459af2 UefiCpuPkg/MtrrLib/UnitTest: Add host based unit test
Add host based unit tests for the MtrrLib services.
The BaseLib services AsmCpuid(), AsmReadMsr64(), and
AsmWriteMsr64() are hooked and provide simple emulation
of the CPUID leafs and MSRs required by the MtrrLib to
run as a host based unit test.

Test cases are developed for each of the API.

For the most important APIs MtrrSetMemoryAttributesInMtrrSettings()
and MtrrSetMemoryAttributeInMtrrSettings(), random inputs are
generated and fed to the APIs to make sure the implementation is
good. The test application accepts an optional parameter which
specifies how many iterations of feeding random inputs to the two
APIs. The overall number of test cases increases when the iteration
increases. Default iteration is 10 when no parameter is specified.

Signed-off-by: Ray Ni <ray.ni@intel.com>
Signed-off-by: Michael D Kinney <michael.d.kinney@intel.com>
Signed-off-by: Ming Shao <ming.shao@intel.com>
Cc: Michael D Kinney <michael.d.kinney@intel.com>
Cc: Eric Dong <eric.dong@intel.com>
Cc: Laszlo Ersek <lersek@redhat.com>
Cc: Ming Shao <ming.shao@intel.com>
Cc: Sean Brogan <sean.brogan@microsoft.com>
Cc: Bret Barkelew <Bret.Barkelew@microsoft.com>
Cc: Jiewen Yao <jiewen.yao@intel.com>
2020-08-12 11:38:37 +00:00
Michael D Kinney 548c9669df UefiCpuPkg/CpuCommonFeaturesLib: Fix spelling mistake
REF: https://bugzilla.tianocore.org/show_bug.cgi?id=2357

Cc: Eric Dong <eric.dong@intel.com>
Cc: Ray Ni <ray.ni@intel.com>
Cc: Laszlo Ersek <lersek@redhat.com>
Cc: Rahul Kumar <rahul1.kumar@intel.com>
Signed-off-by: Michael D Kinney <michael.d.kinney@intel.com>
Reviewed-by: Eric Dong <eric.dong@intel.com>
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
2020-08-03 16:31:36 +00:00
Laszlo Ersek 9001b750df UefiCpuPkg/PiSmmCpuDxeSmm: pause in WaitForSemaphore() before re-fetch
Most busy waits (spinlocks) in "UefiCpuPkg/PiSmmCpuDxeSmm/MpService.c"
already call CpuPause() in their loop bodies; see SmmWaitForApArrival(),
APHandler(), and SmiRendezvous(). However, the "main wait" within
APHandler():

>     //
>     // Wait for something to happen
>     //
>     WaitForSemaphore (mSmmMpSyncData->CpuData[CpuIndex].Run);

doesn't do so, as WaitForSemaphore() keeps trying to acquire the semaphore
without pausing.

The performance impact is especially notable in QEMU/KVM + OVMF
virtualization with CPU overcommit (that is, when the guest has
significantly more VCPUs than the host has physical CPUs). The guest BSP
is working heavily in:

  BSPHandler()                  [MpService.c]
    PerformRemainingTasks()     [PiSmmCpuDxeSmm.c]
      SetUefiMemMapAttributes() [SmmCpuMemoryManagement.c]

while the many guest APs are spinning in the "Wait for something to
happen" semaphore acquisition, in APHandler(). The guest APs are
generating useless memory traffic and saturating host CPUs, hindering the
guest BSP's progress in SetUefiMemMapAttributes().

Rework the loop in WaitForSemaphore(): call CpuPause() in every iteration
after the first check fails. Due to Pause Loop Exiting (known as Pause
Filter on AMD), the host scheduler can favor the guest BSP over the guest
APs.

Running a 16 GB RAM + 512 VCPU guest on a 448 PCPU host, this patch
reduces OVMF boot time (counted until reaching grub) from 20-30 minutes to
less than 4 minutes.

The patch should benefit physical machines as well -- according to the
Intel SDM, PAUSE "Improves the performance of spin-wait loops". Adding
PAUSE to the generic WaitForSemaphore() function is considered a general
improvement.

Cc: Eric Dong <eric.dong@intel.com>
Cc: Philippe Mathieu-Daudé <philmd@redhat.com>
Cc: Rahul Kumar <rahul1.kumar@intel.com>
Cc: Ray Ni <ray.ni@intel.com>
Ref: https://bugzilla.redhat.com/show_bug.cgi?id=1861718
Signed-off-by: Laszlo Ersek <lersek@redhat.com>
Message-Id: <20200729185217.10084-1-lersek@redhat.com>
Reviewed-by: Eric Dong <eric.dong@intel.com>
2020-07-31 13:27:50 +00:00
Shenglei Zhang 22f89fea1e UefiCpuPkg/UefiCpuPkg.ci.yaml: Add configuration for LicenseCheck
Add configuration IgnoreFiles for package config files.
So users can rely on this to skip license conflict for
some generated files.

Cc: Eric Dong <eric.dong@intel.com>
Cc: Ray Ni <ray.ni@intel.com>
Cc: Laszlo Ersek <lersek@redhat.com>
Signed-off-by: Shenglei Zhang <shenglei.zhang@intel.com>
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
Reviewed-by: Eric Dong <eric.dong@intel.com>
2020-07-31 02:49:51 +00:00
Guomin Jiang 92c19c68cb UefiCpuPkg: Correct some typos.
Correct some typos.

Cc: Eric Dong <eric.dong@intel.com>
Cc: Ray Ni <ray.ni@intel.com>
Cc: Laszlo Ersek <lersek@redhat.com>
Cc: Rahul Kumar <rahul1.kumar@intel.com>
Signed-off-by: Guomin Jiang <guomin.jiang@intel.com>
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
Reviewed-by: Liming Gao <liming.gao@intel.com>
2020-07-28 01:43:16 +00:00
Guomin Jiang d7c9de51d2 UefiCpuPkg/CpuMpPei: Enable paging and set NP flag to avoid TOCTOU (CVE-2019-11098)
REF:https://bugzilla.tianocore.org/show_bug.cgi?id=1614

To avoid the TOCTOU, enable paging and set Not Present flag so when
access any code in the flash range, it will trigger #PF exception.

Cc: Eric Dong <eric.dong@intel.com>
Cc: Ray Ni <ray.ni@intel.com>
Cc: Laszlo Ersek <lersek@redhat.com>
Cc: Rahul Kumar <rahul1.kumar@intel.com>
Signed-off-by: Guomin Jiang <guomin.jiang@intel.com>
Acked-by: Laszlo Ersek <lersek@redhat.com>
Reviewed-by: Jian J Wang <jian.j.wang@intel.com>
Reviewed-by: Liming Gao <liming.gao@intel.com>
2020-07-28 01:43:16 +00:00
Michael Kubacki 479613bd06 UefiCpuPkg/SecMigrationPei: Add initial PEIM (CVE-2019-11098)
REF:https://bugzilla.tianocore.org/show_bug.cgi?id=1614

Adds a PEIM that republishes structures produced in SEC. This
is done because SEC modules may not be shadowed in some platforms
due to space constraints or special alignment requirements. The
SecMigrationPei module locates interfaces that may be published in
SEC and reinstalls the interface with permanent memory addresses.

This is important if pre-memory address access is forbidden after
memory initialization and data such as a PPI descriptor, PPI GUID,
or PPI inteface reside in pre-memory.

Cc: Eric Dong <eric.dong@intel.com>
Cc: Ray Ni <ray.ni@intel.com>
Cc: Laszlo Ersek <lersek@redhat.com>
Cc: Rahul Kumar <rahul1.kumar@intel.com>
Cc: Debkumar De <debkumar.de@intel.com>
Cc: Harry Han <harry.han@intel.com>
Cc: Catharine West <catharine.west@intel.com>
Signed-off-by: Michael Kubacki <michael.a.kubacki@intel.com>
Acked-by: Laszlo Ersek <lersek@redhat.com>
Reviewed-by: Liming Gao <liming.gao@intel.com>
2020-07-28 01:43:16 +00:00
Michael Kubacki 60b12e69fb UefiCpuPkg/CpuMpPei: Add GDT migration support (CVE-2019-11098)
REF:https://bugzilla.tianocore.org/show_bug.cgi?id=1614

Moves the GDT to permanent memory in a memory discovered
callback. This is done to ensure the GDT authenticated in
pre-memory is not fetched from outside a verified location
after the permanent memory transition.

Cc: Eric Dong <eric.dong@intel.com>
Cc: Ray Ni <ray.ni@intel.com>
Cc: Laszlo Ersek <lersek@redhat.com>
Cc: Rahul Kumar <rahul1.kumar@intel.com>
Signed-off-by: Michael Kubacki <michael.a.kubacki@intel.com>
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
Reviewed-by: Jian J Wang <jian.j.wang@intel.com>
Reviewed-by: Liming Gao <liming.gao@intel.com>
2020-07-28 01:43:16 +00:00
Oleksiy Yakovlev e77966b341 UefiCpuPkg: Add New Memory Attributes
Add usage of EFI_MEMORY_SP and EFI_MEMORY_CPU_CRYPTO
attributes introduced in UEFI 2.8.
(UEFI 2.8, mantis 1919 and 1872).
Use attributes bitmasks, defined in MdePkg.

Signed-off-by: Oleksiy Yakovlev <oleksiyy@ami.com>
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
Message-Id: <20200702205039.52400-5-oleksiyy@ami.com>
Reviewed-by: Eric Dong <eric.dong@intel.com>
Tested-by: Laszlo Ersek <lersek@redhat.com>
2020-07-15 14:58:25 +00:00
Oleksiy Yakovlev c2e38a520e UefiCpuPkg: Update EFI_MEMORY_CACHETYPE_MASK definition
Add EFI_MEMORY_WP attribute to
EFI_MEMORY_CACHETYPE_MASK definition.

Signed-off-by: Oleksiy Yakovlev <oleksiyy@ami.com>
Message-Id: <20200702205039.52400-4-oleksiyy@ami.com>
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
Acked-by: Eric Dong <eric.dong@intel.com>
Tested-by: Laszlo Ersek <lersek@redhat.com>
2020-07-15 14:58:25 +00:00
Ray Ni 9c6f3545ae UefiCpuPkg/MtrrLib: Remove unnecessary API MtrrSetFixedMtrr()
REF: https://bugzilla.tianocore.org/show_bug.cgi?id=2849

MtrrSetFixedMtrr() sets all the fixed MTRR settings.
But in fact MtrrSetAllMtrrs() is always used by callers to set all
MTRR settings including the fixed and variable ones.

The patch removes the unnecessary API MtrrSetFixedMtrr()
to simplify the MtrrLib API.

There is no code in edk2 and edk2-platforms repo that calls
MtrrSetFixedMtrr().

Signed-off-by: Ray Ni <ray.ni@intel.com>
Reviewed-by: Eric Dong <eric.dong@intel.com>
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
Cc: Rahul Kumar <rahul1.kumar@intel.com>
2020-07-14 03:24:24 +00:00
Ray Ni 3c92912885 UefiCpuPkg/MtrrLib: Remove unnecessary API MtrrSetVariableMtrr()
REF: https://bugzilla.tianocore.org/show_bug.cgi?id=2849

MtrrSetVariableMtrr() sets all the variable MTRR settings.
But in fact MtrrSetAllMtrrs() is always used by callers to set all
MTRR settings including the fixed and variable ones.

The patch removes the unnecessary API MtrrSetVariableMtrr() to
simplify the MtrrLib API.

There is no code in edk2 and edk2-platforms repo that calls
MtrrSetVariableMtrr().

Signed-off-by: Ray Ni <ray.ni@intel.com>
Reviewed-by: Eric Dong <eric.dong@intel.com>
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
Cc: Rahul Kumar <rahul1.kumar@intel.com>
2020-07-14 03:24:24 +00:00
Ray Ni abc16e2531 UefiCpuPkg/MtrrLib: Remove unnecessary API MtrrGetVariableMtrr()
REF: https://bugzilla.tianocore.org/show_bug.cgi?id=2849

MtrrGetVariableMtrr() returns all the variable MTRR settings.
But in fact MtrrGetAllMtrrs() and
MtrrGetMemoryAttributeInVariableMtrr() are used by callers to get the
MTRR settings. The former one returns both the fixed and variable
MTRR settings.

The patch removes the unnecessary API MtrrGetVariableMtrr() to
simplify the MtrrLib API.

There is no code in edk2 and edk2-platforms repo that calls
MtrrGetVariableMtrr().

Signed-off-by: Ray Ni <ray.ni@intel.com>
Reviewed-by: Eric Dong <eric.dong@intel.com>
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
Cc: Rahul Kumar <rahul1.kumar@intel.com>
2020-07-14 03:24:24 +00:00
Kirkendall, Garrett bdafda8c45 UefiCpuPkg: PiSmmCpuDxeSmm skip MSR_IA32_MISC_ENABLE manipulation on AMD
AMD does not support MSR_IA32_MISC_ENABLE.  Accessing that register
causes and exception on AMD processors.  If Execution Disable is
supported, but if the processor is an AMD processor, skip manipulating
MSR_IA32_MISC_ENABLE[34] XD Disable bit.

Cc: Eric Dong <eric.dong@intel.com>
Cc: Ray Ni <ray.ni@intel.com>
Cc: Laszlo Ersek <lersek@redhat.com>
Signed-off-by: Garrett Kirkendall <garrett.kirkendall@amd.com>
Message-Id: <20200622131825.1352-5-Garrett.Kirkendall@amd.com>
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
Tested-by: Laszlo Ersek <lersek@redhat.com>
Reviewed-by: Eric Dong <eric.dong@intel.com>
2020-07-07 23:25:16 +00:00
Kirkendall, Garrett df667535ed UefiCpuPkg: Move StandardSignatureIsAuthenticAMD to BaseUefiCpuLib
Refactor StandardSignatureIsAuthenticAMD into BaseUefiCpuLib from
separate copies in BaseXApicLib, BaseXApicX2ApicLib, and MpInitLib.
This allows for future use of StandarSignatureIsAuthinticAMD without
creating more instances in other modules.

This function allows IA32/X64 code to determine if it is running on an
AMD brand processor.

UefiCpuLib is already included directly or indirectly in all modified
modules.  Complete move is made in this change.

Cc: Eric Dong <eric.dong@intel.com>
Cc: Ray Ni <ray.ni@intel.com>
Cc: Laszlo Ersek <lersek@redhat.com>
Signed-off-by: Garrett Kirkendall <garrett.kirkendall@amd.com>
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
Reviewed-by: Eric Dong <eric.dong@intel.com>
Message-Id: <20200622131825.1352-4-Garrett.Kirkendall@amd.com>
2020-07-07 23:25:16 +00:00
Cole, Deric 00b8bf7eda UefiCpuPkg/SecCore: Add pre-memory AP vector
REF:https://bugzilla.tianocore.org/show_bug.cgi?id=2776

Add a vector at 0xFF000 (0xFFFFF000) that can be used by Init-SIPI-SIPI
to start an AP before memory is initialized. This vector jumps into the
same SEC entry point as the ordinary reset vector, with a special value
of "AP" in the DI register. The platform-specific SEC code is expected
to check for that value and take a different path for APs, if this
feature is supported by the platform.

Reviewed-by: Eric Dong <eric.dong@intel.com>
Reviewed-by: Ray Ni <ray.ni@intel.com>
Cc: Laszlo Ersek <lersek@redhat.com>
Signed-off-by: Deric Cole <deric.cole@intel.com>
2020-06-23 01:50:29 +00:00
Ray Ni 9099dcbd61 UefiCpuPkg/MpService: GetProcessorInfo returns 6-level topology
Intel SDM introduces 6-levels for describing the CPU topology:
* Package
* Module
* Tile
* Die
* Core
* Thread

A PI spec ECR was submitted to enhance CPU_MP PPI/Protocol to
support returning such information through GetProcessorInfo().
An accordingly change was implemented and pushed to edk2-staging.

Now the PI spec has been published.
The patch is cherry-picked from edk2-staging to edk2.

Signed-off-by: Ray Ni <ray.ni@intel.com>
Reviewed-by: Eric Dong <eric.dong@intel.com>
2020-05-15 08:48:35 +00:00
Lendacky, Thomas 9378310dd8 UefiCpuPkg/CpuExceptionHandler: Revert CpuExceptionHandler binary patching
BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=2340

Now that an XCODE5 specific CpuExceptionHandlerLib library is in place,
revert the changes made to the ExceptionHandlerAsm.nasm in commit
2db0ccc2d7 ("UefiCpuPkg: Update CpuExceptionHandlerLib pass XCODE5 tool
chain") so that binary patching of flash code is not performed.

Cc: Eric Dong <eric.dong@intel.com>
Cc: Ray Ni <ray.ni@intel.com>
Cc: Laszlo Ersek <lersek@redhat.com>
Cc: Liming Gao <liming.gao@intel.com>
Acked-by: Bret Barkelew <bret.barkelew@microsoft.com>
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
Signed-off-by: Tom Lendacky <thomas.lendacky@amd.com>
Message-Id: <810f67d8604c054c09d17a22f0bcfaeb41ee8e3b.1588856809.git.thomas.lendacky@amd.com>
Reviewed-by: Liming Gao <liming.gao@intel.com>
Reviewed-by: Eric Dong <eric.dong@intel.com>
2020-05-11 19:25:33 +00:00
Lendacky, Thomas ec94e97a6e UefiCpuPkg/CpuExceptionHandler: Make XCODE5 changes toolchain specific
BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=2340

Commit 2db0ccc2d7 ("UefiCpuPkg: Update CpuExceptionHandlerLib pass
XCODE5 tool chain") introduced binary patching into the exception handling
support. CPU exception handling is allowed during SEC and this results in
binary patching of flash, which should not be done.

Separate the changes from commit 2db0ccc2d7 into an XCODE5 toolchain
specific file, Xcode5ExceptionHandlerAsm.nasm, and create a new SEC INF
file for the XCODE5 version of CpuExceptionHandlerLib.

Since binary patching is allowed when running outside of flash, switch
the Dxe, Pei and Smm versions of the CpuExceptionHandlerLib over to use
the Xcode5ExceptionHandlerAsm.nasm file to retain current functionality.

Cc: Eric Dong <eric.dong@intel.com>
Cc: Ray Ni <ray.ni@intel.com>
Cc: Laszlo Ersek <lersek@redhat.com>
Cc: Liming Gao <liming.gao@intel.com>
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
Signed-off-by: Tom Lendacky <thomas.lendacky@amd.com>
Message-Id: <9075570487616c731033a5738f6a444a15d71b74.1588856809.git.thomas.lendacky@amd.com>
Reviewed-by: Liming Gao <liming.gao@intel.com>
Reviewed-by: Eric Dong <eric.dong@intel.com>
2020-05-11 19:25:33 +00:00
Leo Duran 8dd962a657 UefiCpuPkg/MpInitLib: Remove Executable attribute from MpLib.h
REF: https://bugzilla.tianocore.org/show_bug.cgi?id=2678

This patch fixes a file permission issue introduced by accident.

Cc: Eric Dong <eric.dong@intel.com>
Cc: Ray Ni <ray.ni@intel.com>
Cc: Laszlo Ersek <lersek@redhat.com>
Signed-off-by: Leo Duran <leo.duran@amd.com>
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
Acked-by: Eric Dong <eric.dong@intel.com>
2020-05-06 01:12:25 +00:00
Dong, Eric f07fb43b2d UefiCpuPkg/MpInitLib: Avoid ApInitReconfig in PEI.
REF: https://bugzilla.tianocore.org/show_bug.cgi?id=2683

In PEI phase, AP already been waked up through ApInitConfig,
so it can directly wake up it through change wakup buffer
instead of use ApInitReconfig flag. It can save some time.

Change code to only use ApInitReconfig flag in DXE phase
which must need to update the wake up buffer.

Regression-tested-by: Laszlo Ersek <lersek@redhat.com>
Cc: Chandana Kumar <chandana.c.kumar@intel.com>
Signed-off-by: Eric Dong <eric.dong@intel.com>
Reviewed-by: Ray Ni <ray.ni@intel.com>
2020-04-30 04:11:13 +00:00
Eric Dong 052aa07da4 UefiCpuPkg/MpInitLib: Restore IDT context for APs.
REF: https://bugzilla.tianocore.org/show_bug.cgi?id=2683

This patch fixes an assertion because AP can't find the CpuMpData.
When AP is waken up through Init-Sipi-Sipi, AP's IDT should
be restored to pre-allocated buffer so AP can get the CpuMpData
through the IDT base address.
Current code already has logic to handle this when CpuMpData->
InitFlag is ApInitConfig but misses the logic
when CpuMpData->InitFlag is ApInitReconfig.
This patch fixes this gap.

Reviewed-by: Ray Ni <ray.ni@intel.com>
Regression-tested-by: Laszlo Ersek <lersek@redhat.com>
Cc: Chandana Kumar <chandana.c.kumar@intel.com>
Signed-off-by: Eric Dong <eric.dong@intel.com>
2020-04-30 04:11:13 +00:00
Hao A Wu d5339c04d7 UefiCpuPkg/MpInitLib: Add missing explicit PcdLib dependency
REF:https://bugzilla.tianocore.org/show_bug.cgi?id=2632

Both PEI and DXE instances of the MpInitLib are using PcdLib APIs, but
none of them list the dependency of the PcdLib in INF & header files.

This commit will explicitly add such dependency in .H and .INF files.

Test done:
Library level build pass for VS2015x86 tool chain

Cc: Eric Dong <eric.dong@intel.com>
Signed-off-by: Hao A Wu <hao.a.wu@intel.com>
Reviewed-by: Ray Ni <ray.ni@intel.com>
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
2020-04-23 08:48:54 +00:00
Dong, Eric 1cae0d4215 UefiCpuPkg/PiSmmCpuDxeSmm: Remove useless code in ResetTokens.
REF: https://bugzilla.tianocore.org/show_bug.cgi?id=2388

After remove Used parameter, below code in ResetTokens can also be
removed:
1. The RunningApCount parameter will be reset in GetFreeToken.
2. The ReleaseSpinLock should be called in ReleaseToken function,
   Code in this function seems like a later fix if ReleaseToken not
   Release it. We should remove code here and fix the real issue if
   existed.

Signed-off-by: Eric Dong <eric.dong@intel.com>
Reviewed-by: Ray Ni <ray.ni@intel.com>
Cc: Star Zeng <star.zeng@intel.com>
Cc: Laszlo Ersek <lersek@redhat.com>
2020-04-13 03:13:36 +00:00
Dong, Eric d84f090fd7 UefiCpuPkg/PiSmmCpuDxeSmm: Remove Used parameter.
REF: https://bugzilla.tianocore.org/show_bug.cgi?id=2388

After patch "UefiCpuPkg/PiSmmCpuDxeSmm: Improve the
performance of GetFreeToken()" which adds new parameter
FirstFreeToken, it's not need to use Uses parameter.
This patch used to remove this parameter.

Signed-off-by: Eric Dong <eric.dong@intel.com>
Reviewed-by: Ray Ni <ray.ni@intel.com>
Cc: Star Zeng <star.zeng@intel.com>
Cc: Laszlo Ersek <lersek@redhat.com>
2020-04-13 03:13:36 +00:00
Ray Ni 3fdc47c65b UefiCpuPkg/PiSmmCpuDxeSmm: Improve the performance of GetFreeToken()
Today's GetFreeToken() runs at the algorithm complexity of O(n)
where n is the size of the token list.

The change introduces a new global variable FirstFreeToken and it
always points to the first free token. So the algorithm complexity
of GetFreeToken() decreases from O(n) to O(1).

The improvement matters when some SMI code uses StartupThisAP()
service for each of the AP such that the algorithm complexity
becomes O(n) * O(m) where m is the AP count.

As next steps,
1. PROCEDURE_TOKEN.Used field can be optimized out because
all tokens before FirstFreeToken should have "Used" set while all
after FirstFreeToken should have "Used" cleared.
2. ResetTokens() can be optimized to only reset tokens before
FirstFreeToken.

v2: add missing line in InitializeDataForMmMp.
v3: update copyright year to 2020.

Signed-off-by: Ray Ni <ray.ni@intel.com>
Reviewed-by: Eric Dong <eric.dong@intel.com>
Reviewed-by: Star Zeng <star.zeng@intel.com>
2020-04-13 03:13:36 +00:00
GuoMinJ 4ac82ea1e1 UefiCpuPkg/MpInitLib: Add out attribute for parameter.
REF: https://bugzilla.tianocore.org/show_bug.cgi?id=2553

The comment haven't indicate the output attribute.

Cc: Eric Dong <eric.dong@intel.com>
Cc: Ray Ni <ray.ni@intel.com>
Cc: Laszlo Ersek <lersek@redhat.com>
Signed-off-by: Guomin Jiang <guomin.jiang@intel.com>
Reviewed-by: Eric Dong <eric.dong@intel.com>
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
2020-03-27 02:20:02 +00:00
Hao A Wu a1c35ff312 UefiCpuPkg/MpInitLib DXE: Add PCD to control AP status check interval
REF:https://bugzilla.tianocore.org/show_bug.cgi?id=2627

The commit will introduce a static PCD to specify the periodic interval
for checking the AP status when MP services StartupAllAPs() and
StartupThisAP() are being executed in a non-blocking manner. Or in other
words, specifies the interval for callback function CheckApsStatus().

The purpose is to provide the platform owners with the ability to choose
the proper interval value to trigger CheckApsStatus() according to:
A) The number of processors in the system;
B) How MP services (StartupAllAPs & StartupThisAP) being used.

Setting the PCD to a small value means the AP status check callback will
be triggered more frequently, it can benefit the performance for the case
when the BSP uses WaitForEvent() or uses CheckEvent() in a loop to wait
for AP(s) to complete the task, especially when the task can be finished
considerably fast on AP(s).

An example is within function CpuFeaturesInitialize() under
UefiCpuPkg/Library/RegisterCpuFeaturesLib/DxeRegisterCpuFeaturesLib.c,
where BSP will perform the same task with APs and requires all the
processors to finish the task before BSP proceeds to its next task.

Setting the PCD to a big value, on the other hand, can reduce the impact
on BSP by the time being consumed in CheckApsStatus(), especially when the
number of processors is huge so that the time consumed in CheckApsStatus()
is not negligible.

The type of the PCD is UINT32, which means the maximum possible interval
value can be set to:
4,294,967,295 microseconds = 4,295 seconds = 71.58 minutes = 1.19 hours
which should be sufficient for usage.

For least impact, the default value of the new PCD will be the same with
the current interval value. It will be set to 100,000 microseconds, which
is 100 milliseconds.

Unitest done:
A) OS boot successfully;
B) Use debug message to confirm the 'TriggerTime' parameter for the
   'SetTimer' service is the same before & after this patch.

Cc: Eric Dong <eric.dong@intel.com>
Cc: Michael D Kinney <michael.d.kinney@intel.com>
Cc: Brian J. Johnson <brian.johnson@hpe.com>
Signed-off-by: Hao A Wu <hao.a.wu@intel.com>
Reviewed-by: Star Zeng <star.zeng@intel.com>
Reviewed-by: Ray Ni <ray.ni@intel.com>
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
2020-03-27 00:46:39 +00:00
Laszlo Ersek 90e11edd16 UefiCpuPkg/PiSmmCpuDxeSmm: fix S3 Resume for CPU hotplug
The "ACPI_CPU_DATA.NumberOfCpus" field is specified as follows, in
"UefiCpuPkg/Include/AcpiCpuData.h" (rewrapped for this commit message):

  //
  // The number of CPUs.  If a platform does not support hot plug CPUs,
  // then this is the number of CPUs detected when the platform is booted,
  // regardless of being enabled or disabled.  If a platform does support
  // hot plug CPUs, then this is the maximum number of CPUs that the
  // platform supports.
  //

The InitializeCpuBeforeRebase() and InitializeCpuAfterRebase() functions
in "UefiCpuPkg/PiSmmCpuDxeSmm/CpuS3.c" try to restore CPU configuration on
the S3 Resume path for *all* CPUs accounted for in
"ACPI_CPU_DATA.NumberOfCpus". This is wrong, as with CPU hotplug, not all
of the possible CPUs may be present at the time of S3 Suspend / Resume.
The symptom is an infinite wait.

Instead, the "mNumberOfCpus" variable should be used, which is properly
maintained through the EFI_SMM_CPU_SERVICE_PROTOCOL implementation (see
SmmAddProcessor(), SmmRemoveProcessor(), SmmCpuUpdate() in
"UefiCpuPkg/PiSmmCpuDxeSmm/CpuService.c").

When CPU hotplug is disabled, "mNumberOfCpus" is constant, and equals
"ACPI_CPU_DATA.NumberOfCpus" at all times.

Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Cc: Eric Dong <eric.dong@intel.com>
Cc: Igor Mammedov <imammedo@redhat.com>
Cc: Jiewen Yao <jiewen.yao@intel.com>
Cc: Jordan Justen <jordan.l.justen@intel.com>
Cc: Michael Kinney <michael.d.kinney@intel.com>
Cc: Philippe Mathieu-Daudé <philmd@redhat.com>
Cc: Ray Ni <ray.ni@intel.com>
Ref: https://bugzilla.tianocore.org/show_bug.cgi?id=1512
Signed-off-by: Laszlo Ersek <lersek@redhat.com>
Message-Id: <20200226221156.29589-3-lersek@redhat.com>
Acked-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Reviewed-by: Eric Dong <eric.dong@intel.com>
Tested-by: Boris Ostrovsky <boris.ostrovsky@oracle.com>
[lersek@redhat.com: shut up UINTN->UINT32 warning from Windows VS2019 PR]
2020-03-04 12:22:07 +00:00
Leo Duran 4c0f6e349d UefiCpuPkg/MpInitLib: Skip reading PlatformId on AMD processors.
REF: https://bugzilla.tianocore.org/show_bug.cgi?id=2556

This patch uses CPUID signature check to skip reading the PlatformId MSR,
which is not implemented on AMD processors.

The PlatformId is used for loading microcode patches, which is also not
supported and AMD-based platforms. To mitigate the PlatformId dependency,
PcdCpuMicrocodePatchAddress and PcdCpuMicrodePatchRegionSize must be set
to 0 (default value), in order to bypass microcode loading code paths.

Cc: Eric Dong <eric.dong@intel.com>
Cc: Ray Ni <ray.ni@intel.com>
Cc: Laszlo Ersek <lersek@redhat.com>
Signed-off-by: Leo Duran <leo.duran@amd.com>
Reviewed-by: Ray Ni <ray.ni@intel.com>
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
2020-03-02 05:47:06 +00:00
Zeng, Star c73fce3d12 UefiCpuPkg RegisterCpuFeaturesLib: Match data type and format specifier
Match data type and format specifier for printing.
1. Type cast ProcessorNumber and FeatureIndex to UINT32
  as %d only expects a UINT32.
2. Use %08x instead of %08lx for CacheControl to print Index
  as it is UINT32 type.
3. Use %016lx instead of %08lx for MemoryMapped to print
  (Index | LShiftU64 (HighIndex, 32)) as it is UINT64 type.

Cc: Eric Dong <eric.dong@intel.com>
Cc: Ray Ni <ray.ni@intel.com>
Cc: Laszlo Ersek <lersek@redhat.com>
Signed-off-by: Star Zeng <star.zeng@intel.com>
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
Reviewed-by: Eric Dong <eric.dong@intel.com>
2020-02-19 05:36:42 +00:00
Siyuan Fu c788c2b1ad UefiCpuPkg: Remove FIT based microcode shadow logic from MpInitLib.
Commit c7c964b and dd01704 add header file for FIT table and update
MpInitLib to support FIT based microcode shadow operation. There are
comments that FIT is Intel specific specification instead of industry
standard, which should not be placed in EDK2 MdePkg and UefiCpuPkg.
So this patch adds a platform PPI for the microcode shadow logic, and
remove the FIT related code from EDK2.
The FIT based microcode shadow support will be implemented as a new
platform PEIM in IntelSiliconPkg in edk2-platforms.
This patch doesn't provide a DXE version shadow microcode protocol,
a platform which only uses DxeMpInitLib instance only supports PCD
based microcode shadowing.

A detailed design doc can be found here:
https://edk2.groups.io/g/devel/files/Designs/2020/0214/Support%20
the%202nd%20Microcode%20FV%20Flash%20Region.pdf

TEST: Tested on FIT enabled platform.
BZ: https://tianocore.acgmultimedia.com/show_bug.cgi?id=2449

Cc: Eric Dong <eric.dong@intel.com>
Cc: Ray Ni <ray.ni@intel.com>
Cc: Laszlo Ersek <lersek@redhat.com>
Signed-off-by: Siyuan Fu <siyuan.fu@intel.com>
Reviewed-by: Michael D Kinney <michael.d.kinney@intel.com>
Reviewed-by: Ray Ni <ray.ni@intel.com>
Acked-by: Laszlo Ersek <lersek@redhat.com>
2020-02-14 04:31:18 +00:00
Ray Ni 534fcb84de UefiCpuPkg/CpuFeature: Introduce First to indicate 1st unit.
REF: https://bugzilla.tianocore.org/show_bug.cgi?id=1584

The flow of CPU feature initialization logic is:
1. BSP calls GetConfigDataFunc() for each thread/AP;
2. Each thread/AP calls SupportFunc() to detect its own capability;
3. BSP calls InitializeFunc() for each thread/AP.

There is a design gap in step #3. For a package scope feature that only
requires one thread of each package does the initialization operation,
what InitializeFunc() currently does is to do the initialization
operation only CPU physical location Core# is 0.
But in certain platform, Core#0 might be disabled in hardware level
which results the certain package scope feature isn't initialized at
all.

The patch adds a new field First to indicate the CPU's location in
its parent scope.
First.Package is set for all APs/threads under first package;
First.Core is set for all APs/threads under first core of each
package;
First.Thread is set for the AP/thread of each core.

Signed-off-by: Ray Ni <ray.ni@intel.com>
Reviewed-by: Eric Dong <eric.dong@intel.com>
Reviewed-by: Star Zeng <star.zeng@intel.com>
Cc: Michael D Kinney <michael.d.kinney@intel.com>
2020-02-14 03:15:00 +00:00
Ray Ni 0f1ddb21ff UefiCpuPkg/RegisterCpuFeaturesLib: Rename [Before|After]FeatureBitMask
The patch doesn't have any functionality impact.

Signed-off-by: Ray Ni <ray.ni@intel.com>
Reviewed-by: Eric Dong <eric.dong@intel.com>
2020-02-14 03:15:00 +00:00
Ray Ni 707e6be745 UefiCpuPkg/RegisterCpuFeaturesLib: Delete CPU_FEATURE_[BEFORE|AFTER]
REF: https://bugzilla.tianocore.org/show_bug.cgi?id=1366

Commit b3c71b472d supported MSR setting
in different scopes. It added below macro:
 CPU_FEATURE_THREAD_BEFORE
 CPU_FEATURE_THREAD_AFTER
 CPU_FEATURE_CORE_BEFORE
 CPU_FEATURE_CORE_AFTER
 CPU_FEATURE_PACKAGE_BEFORE
 CPU_FEATURE_PACKAGE_AFTER

And it re-interpreted CPU_FEATURE_BEFORE as CPU_FEATURE_THREAD_BEFORE
and CPU_FEATURE_AFTER as CPU_FEATURE_THREAD_AFTER.

This patch retires CPU_FEATURE_BEFORE and CPU_FEATURE_AFTER
completely.

Signed-off-by: Ray Ni <ray.ni@intel.com>
Reviewed-by: Eric Dong <eric.dong@intel.com>
Cc: Star Zeng <star.zeng@intel.com>
2020-02-14 03:15:00 +00:00
Hao A Wu 348a34d984 UefiCpuPkg/MpInitLib: Not pass microcode info between archs in CPU_MP_DATA
REF:https://bugzilla.tianocore.org/show_bug.cgi?id=2465

Commit 89164babec:
UefiCpuPkg/MpInitLib: don't shadow the microcode patch twice.

attempted to use 'MicrocodePatchRegionSize' and 'MicrocodePatchAddress'
fields to avoid loading the microcode patches data into memory again in
the DXE phase.

However, the CPU_MP_DATA structure has members with type 'UINTN' or
pointer before the microcode patch related fields. This may cause issues
when PEI and DXE are of different archs (e.g. PEI - IA32, DXE - x64),
since the microcode patch related fields will have different offsets in
the CPU_MP_DATA structure.

Commit 88bd066166:
UefiCpuPkg/MpInitLib: Relocate microcode patch fields in CPU_MP_DATA

tried to resolve the above-mentioned issue by relocating the fields
'MicrocodePatchRegionSize' and 'MicrocodePatchAddress' before members with
different size between different archs. But it failed to take the case of
pre-built binaries (e.g. FSP) into consideration.

Binaries can be built when the code base had a different version of the
CPU_MP_DATA structure definition. This may cause issues when accessing
these microcode patch related fields, since their offsets are different
(between PEI phase in the binaries and DXE phase in current code
implementation).

This commit will use the newly introduced EDKII microcode patch HOB
instead for the DXE phase to get the information of the loaded microcode
patches data done in the PEI phase. And the 'MicrocodePatchRegionSize' and
'MicrocodePatchAddress' fields in CPU_MP_DATA will not be used to pass
information between phases.

For pre-built binaries, they can be classified into 3 types with regard to
the time when they are being built:

A. Before commit 89164babec
   (In other words, 'MicrocodePatchRegionSize' and 'MicrocodePatchAddress'
    were not being used to skip microcode load in DXE)

For this case, the EDKII microcode patch HOB will not be produced. This
commit will load the microcode patches data again in DXE. Such behavior is
the same with the code base back then.

B. After commit 89164babec, before commit e1ed55738e
   (In other words, 'MicrocodePatchRegionSize' and 'MicrocodePatchAddress'
    being used to skip microcode load in DXE, but failed to work properly
    between differnt archs.)

For this case, the EDKII microcode patch HOB will not be produced as well.
This commit will also load the microcode patches data again in DXE.

But since commit 89164babec failed to keep the detection and application
of microcode patches working properly in DXE after skipping the load, we
fall back to the origin behavior (that is to load the microcode patches
data again in DXE).

C. After commit e1ed55738e
   (In other words, EDKII microcode patch HOB will be produced.)

For this case, it will have the same behavior with the BIOS built from
the current source codes.

Cc: Michael Kubacki <michael.a.kubacki@intel.com>
Cc: Michael D Kinney <michael.d.kinney@intel.com>
Cc: Eric Dong <eric.dong@intel.com>
Cc: Ray Ni <ray.ni@intel.com>
Cc: Laszlo Ersek <lersek@redhat.com>
Signed-off-by: Hao A Wu <hao.a.wu@intel.com>
Acked-by: Laszlo Ersek <lersek@redhat.com>
Reviewed-by: Eric Dong <eric.dong@intel.com>
Reviewed-by: Ray Ni <ray.ni@intel.com>
2020-02-11 03:50:54 +00:00
Hao A Wu d148a178c1 Revert UefiCpuPkg/MpInitLib: Relocate microcode patch fields in CPU_MP_DATA
This reverts commit 88bd066166.

REF:https://bugzilla.tianocore.org/show_bug.cgi?id=2465

Commit 88bd066166 relocates the 'MicrocodePatchAddress' and
'MicrocodePatchRegionSize' fields in structure CPU_MP_DATA to ensure that
they can be properly passed between different architectures.

However, such change is not backward compatible with the scenario like
pre-existing binaries such as FSP. These binaries are built when the code
base has a different version of the CPU_MP_DATA structure definition. This
may cause issues when accessing the 'MicrocodePatchAddress' and
'MicrocodePatchRegionSize' fields, since their offsets are different
(between PEI phase in the FSP binaries and DXE phase in current code
implementation).

Cc: Michael Kubacki <michael.a.kubacki@intel.com>
Cc: Michael D Kinney <michael.d.kinney@intel.com>
Cc: Eric Dong <eric.dong@intel.com>
Cc: Ray Ni <ray.ni@intel.com>
Cc: Laszlo Ersek <lersek@redhat.com>
Signed-off-by: Hao A Wu <hao.a.wu@intel.com>
Acked-by: Laszlo Ersek <lersek@redhat.com>
Reviewed-by: Eric Dong <eric.dong@intel.com>
Reviewed-by: Ray Ni <ray.ni@intel.com>
2020-02-11 03:50:54 +00:00
Antoine Coeur 418aded964 UefiCpuPkg/Smm: Fix various typos
Fix various typos in comments and documentation.

Cc: Eric Dong <eric.dong@intel.com>
Cc: Ray Ni <ray.ni@intel.com>
Cc: Laszlo Ersek <lersek@redhat.com>
Signed-off-by: Antoine Coeur <coeur@gmx.fr>
Reviewed-by: Philippe Mathieu-Daude <philmd@redhat.com>
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
Reviewed-by: Eric Dong <eric.dong@intel.com>
Signed-off-by: Philippe Mathieu-Daude <philmd@redhat.com>
Message-Id: <20200207010831.9046-79-philmd@redhat.com>
2020-02-10 22:30:07 +00:00
Antoine Coeur ef62da4ff7 UefiCpuPkg/PiSmm: Fix various typos
Fix various typos in comments and documentation.

Cc: Eric Dong <eric.dong@intel.com>
Cc: Ray Ni <ray.ni@intel.com>
Cc: Laszlo Ersek <lersek@redhat.com>
Signed-off-by: Antoine Coeur <coeur@gmx.fr>
Reviewed-by: Philippe Mathieu-Daude <philmd@redhat.com>
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
Reviewed-by: Eric Dong <eric.dong@intel.com>
Signed-off-by: Philippe Mathieu-Daude <philmd@redhat.com>
Message-Id: <20200207010831.9046-78-philmd@redhat.com>
2020-02-10 22:30:07 +00:00
Antoine Coeur f60f4cfeb4 UefiCpuPkg/CpuDxe: Fix few typos
Fix few typos in comments and documentation.

Cc: Eric Dong <eric.dong@intel.com>
Cc: Ray Ni <ray.ni@intel.com>
Cc: Laszlo Ersek <lersek@redhat.com>
Signed-off-by: Antoine Coeur <coeur@gmx.fr>
Reviewed-by: Philippe Mathieu-Daude <philmd@redhat.com>
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
Reviewed-by: Eric Dong <eric.dong@intel.com>
Signed-off-by: Philippe Mathieu-Daude <philmd@redhat.com>
Message-Id: <20200207010831.9046-77-philmd@redhat.com>
2020-02-10 22:30:07 +00:00
Hao A Wu a9e3458ba7 UefiCpuPkg/MpInitLib: Always get CPUID & PlatformID in MicrocodeDetect()
REF:https://bugzilla.tianocore.org/show_bug.cgi?id=2498

Commit fd30b00707 updated the logic in function MicrocodeDetect() that
will directly use the CPUID and PlatformID information from the 'CpuData'
field in the CPU_MP_DATA structure, instead of collecting these
information for each processor via AsmCpuid() and AsmReadMsr64() calls
respectively.

At that moment, this approach worked fine for APs. Since:
a) When the APs are waken up for the 1st time (1st MpInitLibInitialize()
   entry at PEI phase), the function InitializeApData() will be called for
   each AP and the CPUID and PlatformID information will be collected.

b) During the 2nd entry of MpInitLibInitialize() at DXE phase, when the
   APs are waken up again, the function InitializeApData() will not be
   called, which means the CPUID and PlatformID information will not be
   collected. However, the below logics in MicrocodeDetect() function:

  CurrentRevision = GetCurrentMicrocodeSignature ();
  IsBspCallIn     = (ProcessorNumber == (UINTN)CpuMpData->BspNumber) ? TRUE : FALSE;
  if (CurrentRevision != 0 && !IsBspCallIn) {
    //
    // Skip loading microcode if it has been loaded successfully
    //
    return;
  }

   will ensure that the microcode detection and application will be
   skipped due to the fact that such process has already been done in the
   PEI phase.

But after commit 396e791059, which removes the above skip loading logic,
the CPUID and PlatformID information on APs will be used upon the 2nd
entry of the MpInitLibInitialize(). But since the CPUID and PlatformID
information has not been collected, it will bring issue to the microcode
detection process.

This commit will update the logic in MicrocodeDetect() back to always
collecting the CPUID and PlatformID information explicitly.

Cc: Eric Dong <eric.dong@intel.com>
Cc: Ray Ni <ray.ni@intel.com>
Cc: Laszlo Ersek <lersek@redhat.com>
Cc: Siyuan Fu <siyuan.fu@intel.com>
Cc: Michael D Kinney <michael.d.kinney@intel.com>
Signed-off-by: Hao A Wu <hao.a.wu@intel.com>
Reviewed-by: Siyuan Fu <siyuan.fu@intel.com>
Reviewed-by: Eric Dong <eric.dong@intel.com>
2020-02-06 00:31:28 +00:00
Hao A Wu 18fcb37598 UefiCpuPkg/MpInitLib: Fix possible uninitialized 'InitFlag' field
REF:https://bugzilla.tianocore.org/show_bug.cgi?id=2474

Previous commit d786a17232:
UefiCpuPkg/MpInitLib: Reduce the size when loading microcode patches

Removed the below assignments for the 'InitFlag' field of CPU_MP_DATA
structure in function MpInitLibInitialize() when APs are waken up to do
some initialize sync:

CpuMpData->InitFlag  = ApInitReconfig;
...
CpuMpData->InitFlag = ApInitDone;

The above commit mistakenly assumed the 'InitFlag' field will have a value
of 'ApInitDone' when the APs have been successfully waken up before. And
since there is no explicit comparision for the 'InitFlag' field with the
'ApInitReconfig' value. The commit removed those assignments.

However, under some cases (e.g. when variable OldCpuMpData is not NULL,
which means function CollectProcessorCount() will not be called), removing
the above assignments will left the 'InitFlag' field being uninitialized
with a value of 0, which is a invalid value for the type of 'InitFlag'
(AP_INIT_STATE).

It may potentially cause the WakeUpAP() function to run some unnecessary
codes when the APs have been successfully waken up before:

  if (CpuMpData->WakeUpByInitSipiSipi ||
      CpuMpData->InitFlag   != ApInitDone) {
    ResetVectorRequired = TRUE;
    AllocateResetVector (CpuMpData);
    FillExchangeInfoData (CpuMpData);
    SaveLocalApicTimerSetting (CpuMpData);
  }

This commit will address the above-mentioned issue.

Test done:
* OS boot on a real platform with multi processors

Cc: Eric Dong <eric.dong@intel.com>
Cc: Ray Ni <ray.ni@intel.com>
Cc: Laszlo Ersek <lersek@redhat.com>
Cc: Michael D Kinney <michael.d.kinney@intel.com>
Signed-off-by: Hao A Wu <hao.a.wu@intel.com>
Reviewed-by: Ray Ni <ray.ni@intel.com>
Acked-by: Laszlo Ersek <lersek@redhat.com>
2020-01-19 04:10:43 +00:00
Laszlo Ersek a523556244 UefiCpuPkg/PiSmmCpuDxeSmm: fix 2M->4K page splitting regression for PDEs
In commit 4eee0cc7cc ("UefiCpuPkg/PiSmmCpu: Enable 5 level paging when
CPU supports", 2019-07-12), the Page Directory Entry setting was regressed
(corrupted) when splitting a 2MB page to 512 4KB pages, in the
InitPaging() function.

Consider the following hunk, displayed with

$ git show --function-context --ignore-space-change 4eee0cc7cc

>            //
>            // If it is 2M page, check IsAddressSplit()
>            //
>            if (((*Pd & IA32_PG_PS) != 0) && IsAddressSplit (Address)) {
>              //
>              // Based on current page table, create 4KB page table for split area.
>              //
>              ASSERT (Address == (*Pd & PHYSICAL_ADDRESS_MASK));
>
>              Pt = AllocatePageTableMemory (1);
>              ASSERT (Pt != NULL);
>
> +            *Pd = (UINTN) Pt | IA32_PG_RW | IA32_PG_P;
> +
>              // Split it
> -          for (PtIndex = 0; PtIndex < SIZE_4KB / sizeof(*Pt); PtIndex++) {
> -            Pt[PtIndex] = Address + ((PtIndex << 12) | mAddressEncMask | PAGE_ATTRIBUTE_BITS);
> +            for (PtIndex = 0; PtIndex < SIZE_4KB / sizeof(*Pt); PtIndex++, Pt++) {
> +              *Pt = Address + ((PtIndex << 12) | mAddressEncMask | PAGE_ATTRIBUTE_BITS);
>              } // end for PT
>              *Pd = (UINT64)(UINTN)Pt | mAddressEncMask | PAGE_ATTRIBUTE_BITS;
>            } // end if IsAddressSplit
>          } // end for PD

First, the new assignment to the Page Directory Entry (*Pd) is
superfluous. That's because (a) we set (*Pd) after the Page Table Entry
loop anyway, and (b) here we do not attempt to access the memory starting
at "Address" (which is mapped by the original value of the Page Directory
Entry).

Second, appending "Pt++" to the incrementing expression of the PTE loop is
a bug. It causes "Pt" to point *right past* the just-allocated Page Table,
once we finish the loop. But the PDE assignment that immediately follows
the loop assumes that "Pt" still points to the *start* of the new Page
Table.

The result is that the originally mapped 2MB page disappears from the
processor's view. The PDE now points to a "Page Table" that is filled with
garbage. The random entries in that "Page Table" will cause some virtual
addresses in the original 2MB area to fault. Other virtual addresses in
the same range will no longer have a 1:1 physical mapping, but be
scattered over random physical page frames.

The second phase of the InitPaging() function ("Go through page table and
set several page table entries to absent or execute-disable") already
manipulates entries in wrong Page Tables, for such PDEs that got split in
the first phase.

This issue has been caught as follows:

- OVMF is started with 2001 MB of guest RAM.

- This places the main SMRAM window at 0x7C10_1000.

- The SMRAM management in the SMM Core links this SMRAM window into
  "mSmmMemoryMap", with a FREE_PAGE_LIST record placed at the start of the
  area.

- At "SMM Ready To Lock" time, PiSmmCpuDxeSmm calls InitPaging(). The
  first phase (quoted above) decides to split the 2MB page at 0x7C00_0000
  into 512 4KB pages, and corrupts the PDE. The new Page Table is
  allocated at 0x7CE0_D000, but the PDE is set to 0x7CE0_E000 (plus
  attributes 0x67).

- Due to the corrupted PDE, the second phase of InitPaging() already looks
  up the PTE for Address=0x7C10_1000 in the wrong place. The second phase
  goes on to mark bogus PTEs as "NX".

- PiSmmCpuDxeSmm calls SetMemMapAttributes(). Address 0x7C10_1000 is at
  the base of the SMRAM window, therefore it happens to be listed in the
  SMRAM map as an EfiConventionalMemory region. SetMemMapAttributes()
  calls SmmSetMemoryAttributes() to mark the region as XP. However,
  GetPageTableEntry() in ConvertMemoryPageAttributes() fails -- address
  0x7C10_1000 is no longer mapped by anything! -- and so the attribute
  setting fails with RETURN_UNSUPPORTED. This error goes unnoticed, as
  SetMemMapAttributes() ignores the return value of
  SmmSetMemoryAttributes().

- When SetMemMapAttributes() reaches another entry in the SMRAM map,
  ConvertMemoryPageAttributes() decides it needs to split a 2MB page, and
  calls SplitPage().

- SplitPage() calls AllocatePageTableMemory() for the new Page Table,
  which takes us to InternalAllocMaxAddress() in the SMM Core.

- The SMM core attempts to read the FREE_PAGE_LIST record at 0x7C10_1000.
  Because this virtual address is no longer mapped, the firmware crashes
  in InternalAllocMaxAddress(), when accessing (Pages->NumberOfPages).

Remove the useless assignment to (*Pd) from before the loop. Revert the
loop incrementing and the PTE assignment to the known good version.

Cc: Eric Dong <eric.dong@intel.com>
Cc: Ray Ni <ray.ni@intel.com>
Ref: https://bugzilla.redhat.com/show_bug.cgi?id=1789335
Fixes: 4eee0cc7cc
Signed-off-by: Laszlo Ersek <lersek@redhat.com>
Reviewed-by: Philippe Mathieu-Daude <philmd@redhat.com>
Reviewed-by: Ray Ni <ray.ni@intel.com>
2020-01-17 09:41:05 +00:00
Siyuan Fu dd01704111 UefiCpuPkg: Shadow microcode patch according to FIT microcode entry.
The existing MpInitLib will shadow the microcode update patches from
flash to memory and this is done by searching microcode region specified
by PCD PcdCpuMicrocodePatchAddress and PcdCpuMicrocodePatchRegionSize.
This brings a limition to platform FW that all the microcode patches must
be placed in one continuous flash space.

This patch shadows microcode update according to FIT microcode entries if
it's present, otherwise it will fallback to original logic (by PCD).

A new featured PCD gUefiCpuPkgTokenSpaceGuid.PcdCpuShadowMicrocodeByFit
is added for enabling/disabling this support.

TEST: Tested on FIT enabled platform.
BZ: https://tianocore.acgmultimedia.com/show_bug.cgi?id=2449

Cc: Eric Dong <eric.dong@intel.com>
Cc: Ray Ni <ray.ni@intel.com>
Cc: Laszlo Ersek <lersek@redhat.com>
Signed-off-by: Siyuan Fu <siyuan.fu@intel.com>
Reviewed-by: Eric Dong <eric.dong@intel.com>
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
2020-01-10 06:20:42 +00:00
Jason Voelz 1f0d809629 UefiCpuPkg/CpuCommonFeaturesLib: SMXE bit of CR4 should set
Add code to set SMXE in CR4 in the SmxInitialize flow when SMX is enabled.

Signed-off-by: Jason Voelz <jason.voelz@intel.com>
Cc: Ray Ni <ray.ni@intel.com>
Reviewed-by: Ray Ni <ray.ni@intel.com>
2020-01-10 03:41:55 +00:00
Eric Dong e18792566c UefiCpuPkg/PiSmmCpuDxeSmm: Add missed comments for parameter.
This issue caused by below change:
  SHA-1: b948a49615
  * UefiCpuPkg/PiSmmCpuDxeSmm: Pre-allocate PROCEDURE_TOKEN buffer
  REF: https://bugzilla.tianocore.org/show_bug.cgi?id=2388

Reviewed-by: Ray Ni <ray.ni@intel.com>
Acked-by: Laszlo Ersek <lersek@redhat.com>
Signed-off-by: Eric Dong <eric.dong@intel.com>
2020-01-10 02:50:48 +00:00
Siyuan, Fu 396e791059 UefiCpuPkg: Always load microcode patch on AP processor.
This patch updates the microcode loader to always perform a microcode
detect and load on both BSP and AP processor. This is to fix a potential
microcode revision mismatch issue in below situation:
1. Assume there are two microcode co-exists in flash: one production
   version and one debug version microcode.
2. FIT loads production microcode to BSP and all AP.
3. UefiCpuPkg loader loads debug microcode to BSP, and skip the loading
   on AP.
As a result, different microcode patches are loaded to BSP and AP, and
trigger microcode mismatch error during OS boot.

BZ link: https://bugzilla.tianocore.org/show_bug.cgi?id=2431

Cc: Eric Dong <eric.dong@intel.com>
Cc: Ray Ni <ray.ni@intel.com>
Signed-off-by: Siyuan Fu <siyuan.fu@intel.com>
Reviewed-by: Eric Dong <eric.dong@intel.com>
2020-01-08 02:49:40 +00:00
Siyuan Fu 08a475df10 UefiCpuPkg: Remove alignment check when calculate microcode size.
This patch removes the unnecessary alignment check on microcode patch
TotalSize introduced by commit d786a172. The TotalSize has already been
checked with 1K alignment and MAX_ADDRESS in previous code as below:

    if ( (UINTN)MicrocodeEntryPoint > (MAX_ADDRESS - TotalSize) ||
         ((UINTN)MicrocodeEntryPoint + TotalSize) > MicrocodeEnd ||
         (DataSize & 0x3) != 0 ||
         (TotalSize & (SIZE_1KB - 1)) != 0 ||
         TotalSize < DataSize
       ) {

Cc: Eric Dong <eric.dong@intel.com>
Cc: Ray Ni <ray.ni@intel.com>
Cc: Hao A Wu <hao.a.wu@intel.com>
Signed-off-by: Siyuan Fu <siyuan.fu@intel.com>
Reviewed-by: Ray Ni <ray.ni@intel.com>
Reviewed-by: Eric Dong <eric.dong@intel.com>
2020-01-08 00:47:43 +00:00
Eric Dong 70911f1f4a UefiCpuPkg/PiSmmCpuDxeSmm: improve the coding style
REF: https://bugzilla.tianocore.org/show_bug.cgi?id=2434

Current code use below loops to enumerate the CPUs:
  for (Index = mMaxNumberOfCpus; Index-- > 0;) {
it has no issue but not easy for the developers to read the code.

Update above code to below style,
  for (Index = 0; Index < mMaxNumberOfCpus; Index++) {
It make the developers easy to read and consistent with other
similar cases in this driver.

Reviewed-by: Laszlo Ersek <lersek@redhat.com>
Cc: Ray Ni <ray.ni@intel.com>
Signed-off-by: Eric Dong <eric.dong@intel.com>
2020-01-08 00:32:15 +00:00
Eric Dong 4bb34b6df1 Revert "UefiCpuPkg/PiSmmCpuDxeSmm: Fix buffer overflow issue."
This reverts commit 123b720eeb.

The commit message for commit 123b720eeb is not correct.

Cc: Ray Ni <ray.ni@intel.com>
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
Signed-off-by: Eric Dong <eric.dong@intel.com>
2020-01-08 00:32:15 +00:00
Eric Dong b948a49615 UefiCpuPkg/PiSmmCpuDxeSmm: Pre-allocate PROCEDURE_TOKEN buffer
REF: https://bugzilla.tianocore.org/show_bug.cgi?id=2388

Token is new introduced by MM MP Protocol. Current logic allocate Token
every time when need to use it. The logic caused SMI latency raised to
very high. Update logic to allocate Token buffer at driver's entry point.
Later use the token from the allocated token buffer. Only when all the
buffer have been used, then need to allocate new buffer.

Former change (9caaa79dd7) missed
PROCEDURE_TOKEN part, this change covers it.

Reviewed-by: Ray Ni <ray.ni@intel.com>
Cc: Laszlo Ersek <lersek@redhat.com>
Signed-off-by: Eric Dong <eric.dong@intel.com>
2020-01-02 05:48:20 +00:00
Hao A Wu fd30b00707 UefiCpuPkg/MpInitLib: Remove redundant microcode fields in CPU_MP_DATA
Previous commits have introduced below fields in structure CPU_AP_DATA:

  UINT32                         ProcessorSignature;
  UINT8                          PlatformId;
  UINT64                         MicrocodeEntryAddr;

which store the information of:

A. CPUID
B. Platform ID
C. Detected microcode patch entry address (including the microcode patch
   header)

for each processor within system.

Therefore, the below fields in structure CPU_MP_DATA:

  UINT32                         ProcessorSignature;
  UINT32                         ProcessorFlags;
  UINT64                         MicrocodeDataAddress;
  UINT32                         MicrocodeRevision;

which store the BSP's information of:

A. CPUID
B. Platform ID
C. The address and revision of detected microcode patch

are redundant and can be removed.

Cc: Eric Dong <eric.dong@intel.com>
Cc: Ray Ni <ray.ni@intel.com>
Cc: Laszlo Ersek <lersek@redhat.com>
Cc: Star Zeng <star.zeng@intel.com>
Cc: Siyuan Fu <siyuan.fu@intel.com>
Cc: Michael D Kinney <michael.d.kinney@intel.com>
Signed-off-by: Hao A Wu <hao.a.wu@intel.com>
Reviewed-by: Eric Dong <eric.dong@intel.com>
Reviewed-by: Ray Ni <ray.ni@intel.com>
2020-01-02 03:10:36 +00:00
Hao A Wu 88bd066166 UefiCpuPkg/MpInitLib: Relocate microcode patch fields in CPU_MP_DATA
The below 2 microcode patch related fields in structure CPU_MP_DATA:

  UINT64                         MicrocodePatchAddress;
  UINT64                         MicrocodePatchRegionSize;

They will be passed from PEI phase and be reused DXE phase.

Previously, these 2 fields were placed after some fields with type
'UINTN', this will lead to different field offset in different
architecture for them.

This commit will move them before the fields with different size in
different architecture to ensure they can be properly used in DXE phase.

Cc: Eric Dong <eric.dong@intel.com>
Cc: Ray Ni <ray.ni@intel.com>
Cc: Laszlo Ersek <lersek@redhat.com>
Cc: Star Zeng <star.zeng@intel.com>
Cc: Siyuan Fu <siyuan.fu@intel.com>
Cc: Michael D Kinney <michael.d.kinney@intel.com>
Signed-off-by: Hao A Wu <hao.a.wu@intel.com>
Reviewed-by: Ray Ni <ray.ni@intel.com>
Reviewed-by: Eric Dong <eric.dong@intel.com>
2020-01-02 03:10:36 +00:00
Hao A Wu e1ed55738e UefiCpuPkg/MpInitLib: Produce EDKII microcode patch HOB
REF:https://bugzilla.tianocore.org/show_bug.cgi?id=2430

This commit will update the MpInitLib to:

A. Collect the base address and size information after microcode patches
   being loaded into memory;
B. Collect the detected microcode patch for each processor within system;
C. Based on the collected information, produce the EDKII microcode patch
   HOB.

Cc: Eric Dong <eric.dong@intel.com>
Cc: Ray Ni <ray.ni@intel.com>
Cc: Laszlo Ersek <lersek@redhat.com>
Cc: Star Zeng <star.zeng@intel.com>
Cc: Siyuan Fu <siyuan.fu@intel.com>
Cc: Michael D Kinney <michael.d.kinney@intel.com>
Signed-off-by: Hao A Wu <hao.a.wu@intel.com>
Reviewed-by: Eric Dong <eric.dong@intel.com>
Reviewed-by: Ray Ni <ray.ni@intel.com>
2020-01-02 03:10:36 +00:00
Hao A Wu 253909974a UefiCpuPkg: Add definitions for EDKII microcode patch HOB
REF:https://bugzilla.tianocore.org/show_bug.cgi?id=2430

This commit will add the definitions for EDKII microcode patch HOB.

The intention of adding this HOB is to provide a scheme to store the below
information:

A. The base address and size of the microcode patches that are being
   loaded (from flash) into memory;
B. The information of detected microcode patch for each processor within
   the system.

The producer of the HOB will be the UefiCpuPkg/MpInitLib (where the load,
detect and apply of the microcode happen). The consumer of the HOB can be
modules that want to detect/apply the microcode patch by themselves again
later during the boot flow.

Cc: Eric Dong <eric.dong@intel.com>
Cc: Ray Ni <ray.ni@intel.com>
Cc: Laszlo Ersek <lersek@redhat.com>
Cc: Star Zeng <star.zeng@intel.com>
Cc: Siyuan Fu <siyuan.fu@intel.com>
Cc: Michael D Kinney <michael.d.kinney@intel.com>
Signed-off-by: Hao A Wu <hao.a.wu@intel.com>
Reviewed-by: Ray Ni <ray.ni@intel.com>
Reviewed-by: Eric Dong <eric.dong@intel.com>
2020-01-02 03:10:36 +00:00
Hao A Wu d786a17232 UefiCpuPkg/MpInitLib: Reduce the size when loading microcode patches
REF:https://bugzilla.tianocore.org/show_bug.cgi?id=2429

This commit will attempt to reduce the copy size when loading the
microcode patches data from flash into memory.

Such optimization is done by a pre-process of the microcode patch headers
(on flash). A microcode patch will be loaded into memory only when the
below 3 criteria are met:

A. With a microcode patch header (which means the data is not padding data
   between microcode patches);
B. The 'ProcessorSignature' & 'ProcessorFlags' fields in the header match
   at least one processor within system;
C. If the Extended Signature Table exists in a microcode patch, the
   'ProcessorSignature' & 'ProcessorFlag' fields in the table entries
   match at least one processor within system.

Criterion B and C will require all the processors to be woken up once to
collect their CPUID and Platform ID information. Hence, this commit will
move the copy, detect and apply of microcode patch on BSP and APs after
all the processors have been woken up.

Cc: Eric Dong <eric.dong@intel.com>
Cc: Ray Ni <ray.ni@intel.com>
Cc: Laszlo Ersek <lersek@redhat.com>
Cc: Star Zeng <star.zeng@intel.com>
Cc: Siyuan Fu <siyuan.fu@intel.com>
Cc: Michael D Kinney <michael.d.kinney@intel.com>
Signed-off-by: Hao A Wu <hao.a.wu@intel.com>
Reviewed-by: Eric Dong <eric.dong@intel.com>
Reviewed-by: Ray Ni <ray.ni@intel.com>
2020-01-02 03:10:36 +00:00
Hao A Wu 999463c865 UefiCpuPkg/MpInitLib: Collect processors' CPUID & Platform ID info
REF:https://bugzilla.tianocore.org/show_bug.cgi?id=2429

This commit will collect the CPUID and Platform ID information for each
processor within system. They will be stored in the CPU_AP_DATA structure.

These information will be used in the next commit to decide whether a
microcode patch will be loaded into memory.

Cc: Eric Dong <eric.dong@intel.com>
Cc: Ray Ni <ray.ni@intel.com>
Cc: Laszlo Ersek <lersek@redhat.com>
Cc: Star Zeng <star.zeng@intel.com>
Cc: Siyuan Fu <siyuan.fu@intel.com>
Cc: Michael D Kinney <michael.d.kinney@intel.com>
Signed-off-by: Hao A Wu <hao.a.wu@intel.com>
Reviewed-by: Ray Ni <ray.ni@intel.com>
Reviewed-by: Eric Dong <eric.dong@intel.com>
2020-01-02 03:10:36 +00:00
Eric Dong 123b720eeb UefiCpuPkg/PiSmmCpuDxeSmm: Fix buffer overflow issue.
The size for the array of mSmmMpSyncData->CpuData[] is 0 ~
mMaxNumberOfCpus -1. But current code may use
mSmmMpSyncData->CpuData[mMaxNumberOfCpus].

This patch fixed this issue.

Reviewed-by: Ray Ni <ray.ni@intel.com>
Cc: Laszlo Ersek <lersek@redhat.com>
Signed-off-by: Eric Dong <eric.dong@intel.com>
2019-12-24 03:59:14 +00:00
Eric Dong a457823f27 UefiCpuPkg/PiSmmCpuDxeSmm: Remove dependence between APs
REF: https://bugzilla.tianocore.org/show_bug.cgi?id=2268

In current implementation, when check whether APs called by StartUpAllAPs
or StartUpThisAp, it checks the Tokens value used by other APs. Also the AP
will update the Token value for itself if its task finished. In this
case, the potential race condition  issues happens for the tokens.
Because of this, system may trig ASSERT during cycling test.

This change enhance the code logic, add new attributes for the token to
remove the reference for the tokens belongs to other APs.

Reviewed-by: Ray Ni <ray.ni@intel.com>
Cc: Laszlo Ersek <lersek@redhat.com>
Signed-off-by: Eric Dong <eric.dong@intel.com>
2019-12-24 03:59:14 +00:00
Eric Dong 9caaa79dd7 UefiCpuPkg/PiSmmCpuDxeSmm: Avoid allocate Token every time
REF: https://bugzilla.tianocore.org/show_bug.cgi?id=2388

Token is new introduced by MM MP Protocol. Current logic allocate Token
every time when need to use it. The logic caused SMI latency raised to
very high. Update logic to allocate Token buffer at driver's entry point.
Later use the token from the allocated token buffer. Only when all the
buffer have been used, then need to allocate new buffer.

Reviewed-by: Ray Ni <ray.ni@intel.com>
Signed-off-by: Eric Dong <eric.dong@intel.com>
Acked-by: Laszlo Ersek <lersek@redhat.com>
2019-12-06 06:41:16 +00:00
Shenglei Zhang 9c33f16f8c UefiCpuPkg: Update the coding styles
In MpLib.c, remove the white space on a new line.
In PageTbl.c and PiSmmCpuDxeSmm.h, update the comment style.

Cc: Eric Dong <eric.dong@intel.com>
Cc: Ray Ni <ray.ni@intel.com>
Cc: Laszlo Ersek <lersek@redhat.com>
Signed-off-by: Shenglei Zhang <shenglei.zhang@intel.com>
Reviewed-by: Eric Dong <eric.dong@intel.com>
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
2019-12-04 06:00:24 +00:00
Shenglei Zhang 0a58c9a391 UefiCpuPkg/UefiCpuPkg.uni: Add missing strings for PCD
Cc: Eric Dong <eric.dong@intel.com>
Cc: Ray Ni <ray.ni@intel.com>
Cc: Laszlo Ersek <lersek@redhat.com>
Signed-off-by: Shenglei Zhang <shenglei.zhang@intel.com>
Reviewed-by: Eric Dong <eric.dong@intel.com>
2019-12-04 05:05:57 +00:00
Ray Ni c801f33d81 UefiCpuPkg/RegisterCpuFeature: Remove CPU_FEATURE_XD macro
REF: https://bugzilla.tianocore.org/show_bug.cgi?id=2329

Signed-off-by: Ray Ni <ray.ni@intel.com>
Reviewed-by: Eric Dong <eric.dong@intel.com>
Acked-by: Laszlo Ersek <lersek@redhat.com>
2019-11-13 07:26:16 +00:00
Ray Ni 6d17c9c24a UefiCpuPkg/CpuCommonFeaturesLib: Remove XD enable/disable logic
REF: https://bugzilla.tianocore.org/show_bug.cgi?id=2329

XD (ExecutionDisable) feature, when turned on, allows page table
entry BIT63 set to 1 indicating the memory pointed by the page table
is disallowed to execute.
DxeIpl::CreateIdentityMappingPageTables() enables the XD when CPU
supports it.
Later DxeCore modifies the page table to set the BIT63 to protect
the stack/heap to disallow code execution in stack/heap.

UefiCpuPkg/CpuCommonFeaturesLib enables/disables the XD feature
according to PcdCpuFeaturesSetting.
When XD is disabled, GP fault is generated immediately because some
page entries have BIT63 set.

To fix this issue, this patch removes the XD feature logic from
UefiCpuPkg/CpuCommonFeaturesLib so the XD feature is only taken
care of by DxeIpl.

Signed-off-by: Ray Ni <ray.ni@intel.com>
Reviewed-by: Eric Dong <eric.dong@intel.com>
Acked-by: Laszlo Ersek <lersek@redhat.com>
2019-11-13 07:26:16 +00:00
Michael D Kinney 30c00d7f19 UefiCpuPkg: Add YAML file for CI builds
https://bugzilla.tianocore.org/show_bug.cgi?id=2315

Add YAML file to the package directory with the
configuration of the checks to perform during a
CI build.

Cc: Eric Dong <eric.dong@intel.com>
Cc: Ray Ni <ray.ni@intel.com>
Cc: Laszlo Ersek <lersek@redhat.com>
Signed-off-by: Michael D Kinney <michael.d.kinney@intel.com>
Acked-by: Laszlo Ersek <lersek@redhat.com>
Acked-by: Ray Ni <ray.ni@intel.com>
Reviewed-by: Liming Gao <liming.gao@intel.com>
2019-11-11 13:02:38 -08:00
Ray Ni fe3ca5fd25 UefiCpuPkg/MpInitLib: Remove global variable X2ApicEnable
MpInitLib sets X2ApicEnable in two places.
1. CollectProcessorCount()
   This function is called when MpInitLibInitialize() hasn't been
   called before.
   It sets X2ApicEnable and later in the same function it configures
   all CPUs to operate in X2 APIC mode.
2. MpInitLibInitialize()
   The X2ApicEnable setting happens when this function is called in
   second time. But after that setting, no code consumes that flag.

With the above analysis and with the purpose of simplifying the code,
the X2ApicEnable in #1 is changed to local variable and the #2 can be
changed to remove the setting of X2ApicEnable.

Signed-off-by: Ray Ni <ray.ni@intel.com>
Reviewed-by: Eric Dong <eric.dong@intel.com>
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
2019-11-05 10:03:44 +08:00
Ray Ni 54d1e76f4e UefiCpuPkg/MpInitLib: Set X2ApicEnable flag from BSP
Today's logic sets X2ApicEnable flag in each AP's initialization
path when InitFlag == ApInitConfig.
Since all CPUs update the same global data, a spin-lock is used
to avoid modifications from multiple CPUs happen at the same time.
The spin-lock causes two problems:
1. Potential performance downgrade.
2. Undefined behavior when improper timer lib is used.
   For example we saw certain platforms used AcpiTimerLib from
   PcAtChipsetPkg and that library depends on retrieving PeiServices
   from idtr. But in fact AP's (idtr - 4) doesn't point to
   PeiServices.

The patch simplifies the code to let BSP set the X2ApicEnable flag so
the spin-lock acquisition from AP is not needed any more.

Signed-off-by: Ray Ni <ray.ni@intel.com>
Reviewed-by: Eric Dong <eric.dong@intel.com>
Acked-by: Laszlo Ersek <lersek@redhat.com>
2019-11-05 10:03:43 +08:00
Sean Brogan 20c082e8d7 UefiCpuPkg: Add missing components to UefiCpuPkg.dsc
https://bugzilla.tianocore.org/show_bug.cgi?id=2255

Update UefiCpuPkg.dsc to guarantee all libraries and
modules are always built.  Add the following components.

* UefiCpuPkg/ResetVector/Vtf0/Bin/ResetVector.inf
* UefiCpuPkg/Library/CpuCommonFeaturesLib/CpuCommonFeaturesLib.inf

ResetVector.inf is a binary INF, so no source builds are
triggered from adding this line.  However, a build with
this component does verify the contents of the INF file.

Cc: Eric Dong <eric.dong@intel.com>
Cc: Ray Ni <ray.ni@intel.com>
Cc: Laszlo Ersek <lersek@redhat.com>
Signed-off-by: Michael D Kinney <michael.d.kinney@intel.com>
Reviewed-by: Eric Dong <eric.dong@intel.com>
Reviewed-by: Ray Ni <ray.ni@intel.com>
2019-10-23 17:47:29 -07:00
Laszlo Ersek 778832bcad UefiCpuPkg/MpInitLib: honor the platform's boot CPU count in AP detection
- If a platform boots such that the boot CPU count is smaller than
  PcdCpuMaxLogicalProcessorNumber, then the platform cannot use the "fast
  AP detection" logic added in commit 6e1987f19a. (Which has been
  documented as a subset of use case (2) in the previous patch.)

  Said logic depends on the boot CPU count being equal to
  PcdCpuMaxLogicalProcessorNumber. If the equality does not hold, the
  platform either has to wait too long, or risk missing APs due to an
  early timeout.

- The platform may not be able to use the variant added in commit
  0594ec417c either. (Which has been documented as use case (1) in the
  previous patch.)

  See commit 861218740d. When OVMF runs on QEMU/KVM, APs may check in
  with the BSP in arbitrary order, plus the individual AP may take
  arbitrarily long to check-in. If "NumApsExecuting" falls to zero
  mid-enumeration, APs will be missed.

Allow platforms to specify the exact boot CPU count, independently of
PcdCpuMaxLogicalProcessorNumber. In this mode, the BSP waits for all APs
to check-in regardless of timeout. If at least one AP fails to check-in,
then the AP enumeration hangs forever. That is the desired behavior when
the exact boot CPU count is known in advance. (A hung boot is better than
an AP checking-in after timeout, and executing code from released
storage.)

Cc: Eric Dong <eric.dong@intel.com>
Cc: Ray Ni <ray.ni@intel.com>
Ref: https://bugzilla.tianocore.org/show_bug.cgi?id=1515
Signed-off-by: Laszlo Ersek <lersek@redhat.com>
Reviewed-by: Ray Ni <ray.ni@intel.com>
2019-10-11 23:20:09 +02:00
Laszlo Ersek 30459ddde6 UefiCpuPkg/MpInitLib: expand comment on initial AP enumeration
Before adding another AP enumeration mode, clarify the documentation on
the current logic. No functional changes.

Cc: Eric Dong <eric.dong@intel.com>
Cc: Ray Ni <ray.ni@intel.com>
Ref: https://bugzilla.tianocore.org/show_bug.cgi?id=1515
Signed-off-by: Laszlo Ersek <lersek@redhat.com>
Reviewed-by: Ray Ni <ray.ni@intel.com>
2019-10-11 23:19:41 +02:00
Leif Lindholm d19040804a UefiCpuPkg: strip trailing whitespace
Cc: Eric Dong <eric.dong@intel.com>
Cc: Ray Ni <ray.ni@intel.com>
Cc: Laszlo Ersek <lersek@redhat.com>
Signed-off-by: Leif Lindholm <leif.lindholm@linaro.org>
Reviewed-by: Ray Ni <ray.ni@intel.com>
Reviewed-by: Philippe Mathieu-Daude <philmd@redhat.com>
2019-10-04 11:18:32 +01:00
Dong, Eric c70fef962e UefiCpuPkg/CpuDxe: clean up PAGE_TABLE_LIB_PAGING_CONTEXT usage.
REF: https://bugzilla.tianocore.org/show_bug.cgi?id=1039

Current implementation not checks system mode before using
PAGE_TABLE_LIB_PAGING_CONTEXT.ContextData.X64 or
PAGE_TABLE_LIB_PAGING_CONTEXT.ContextData.Ia32. This patch check the
mode before using the correct one.

Signed-off-by: Eric Dong <eric.dong@intel.com>
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
2019-09-25 14:29:24 +08:00
John E Lofgren f4c898f2b2 UefiCpuPkg/CpuExceptionHandlerLib: Fix split lock
REF: https://bugzilla.tianocore.org/show_bug.cgi?id=2150

v4:
The v3 posting didn't do what it promised to do, so do it now for real.

V3 changes:
change to mov instruction (non locking instuction) instead
of xchg to simplify design.

V2 changes:
Add xchg 16 bit instructions to handle sgdt and sidt base
63:48 bits and 47:32 bits.
Add comment to explain why xchg 64bit isnt being used

Split lock happens when a locking instruction is used on mis-aligned data
that crosses two cachelines. If close source platform enables Alignment
Check Exception(#AC), They can hit a double fault due to split lock being
in CpuExceptionHandlerLib.

sigt and sgdt saves 10 bytes to memory, 8 bytes is base and 2 bytes is limit.
The data is mis-aligned, can cross two cacheline, and a xchg
instruction(locking instuction) is being utilize.

Signed-off-by: John E Lofgren <john.e.lofgren@intel.com>
Reviewed-by: Eric Dong <eric.dong@intel.com>
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
2019-09-20 14:37:42 +08:00
Damian Nikodem 832c4c7ad6 UefiCpuPkg: Fix potential spinLock issue in SmmStartupThisAp
Due to needs a tackling the deficiency of the AP API, it's necessary to
ensure that in non-blocking mode previous AP executed command is
finished before starting new one.

To remedy above:
  1) execute AcquireSpinLock instead AcquireSpinLockOrFail - this will
     ensure time "window" to eliminate potential race condition between
     BSP and AP spinLock release in non-blocking mode.
     This also will eliminate possibility to start executing new AP
     function before last is finished.
  2) remove returns EFI_STATUS - EFI_NOT_READY - in new scenario returned
     status is not necessary to caller.

Signed-off-by: Damian Nikodem <damian.nikodem@intel.com>
Reviewed-by: Eric Dong <eric.dong@intel.com>
Reviewed-by: Ray Ni <ray.ni@intel.com>
Cc: Benjamin You <benjamin.you@intel.com>
Cc: Laszlo Ersek <lersek@redhat.com>
Cc: Krzysztof Rusocki <krzysztof.rusocki@intel.com>
2019-09-20 14:37:42 +08:00
Ray Ni 136dad0956 UefiCpuPkg: Remove PcdCpuSmmStaticPageTable
PcdCpuSmmRestrictedMemoryAccess is introduced to replace
PcdCpuSmmStaticPageTable.

Signed-off-by: Ray Ni <ray.ni@intel.com>
Reviewed-by: Eric Dong <eric.dong@intel.com>
Cc: Jiewen Yao <jiewen.yao@intel.com>
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
2019-09-19 14:25:24 +08:00
Ray Ni 86ad762fa7 UefiCpuPkg/PiSmmCpu: Enable 5L paging only when phy addr line > 48
Today's behavior is to enable 5l paging when CPU supports it
(CPUID[7,0].ECX.BIT[16] is set).

The patch changes the behavior to enable 5l paging when two
conditions are both met:
1. CPU supports it;
2. The max physical address bits is bigger than 48.

Because 4-level paging can support to address physical address up to
2^48 - 1, there is no need to enable 5-level paging with max
physical address bits <= 48.

Signed-off-by: Ray Ni <ray.ni@intel.com>
Cc: Liming Gao <liming.gao@intel.com>
Reviewed-by: Eric Dong <eric.dong@intel.com>
Cc: Laszlo Ersek <lersek@redhat.com>
2019-09-13 16:20:54 +08:00
Chasel Chiu 8a1305a11f UefiCpuPkg: support single EFI_PEI_CORE_FV_LOCATION_PPI in PpiList
REF: https://bugzilla.tianocore.org/show_bug.cgi?id=2153

Current logic will skip searching EFI_PEI_CORE_FV_LOCATION_PPI when the
PPI in PpiList having EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST flag,
but platform may pass single PPI in PpiList that should be supported.

Changed the logic to verify PpiList first before checking
EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST flag.

Test: Verified both single EFI_PEI_CORE_FV_LOCATION_PPI and multiple
      PPIs in PpiList cases and both can boot with the PeiCore
      specified by EFI_PEI_CORE_FV_LOCATION_PPI.

Cc: Eric Dong <eric.dong@intel.com>
Cc: Ray Ni <ray.ni@intel.com>
Cc: Laszlo Ersek <lersek@redhat.com>
Signed-off-by: Chasel Chiu <chasel.chiu@intel.com>
Reviewed-by: Eric Dong <eric.dong@intel.com>
Reviewed-by: Ray Ni <ray.ni@intel.com>
Reviewed-by: Star Zeng <star.zeng@intel.com>
2019-09-05 20:42:20 +08:00
Ray Ni f64a597d45 UefiCpuPkg: Explain relationship between several SMM PCDs
There are three PCDs that may impact the behavior of each other in
SMM environment:
  PcdCpuSmmProfileEnable
  PcdHeapGuardPropertyMask in MdeModulePkg
  PcdCpuSmmRestrictedMemoryAccess

The patch updates the comments in DEC file to document it.

Signed-off-by: Ray Ni <ray.ni@intel.com>
Reviewed-by: Eric Dong <eric.dong@intel.com>
Cc: Jiewen Yao <jiewen.yao@intel.com>
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
2019-09-04 01:00:11 +08:00
Ray Ni 79186ddcdd UefiCpuPkg/PiSmmCpu: Restrict access per PcdCpuSmmRestrictedMemoryAccess
Today's behavior is to always restrict access to non-SMRAM regardless
the value of PcdCpuSmmRestrictedMemoryAccess.

Because RAS components require to access all non-SMRAM memory, the
patch changes the code logic to honor PcdCpuSmmRestrictedMemoryAccess
so that only when the PCD is true, the restriction takes affect and
page table memory is also protected.

Because IA32 build doesn't reference this PCD, such restriction
always takes affect in IA32 build.

Signed-off-by: Ray Ni <ray.ni@intel.com>
Reviewed-by: Eric Dong <eric.dong@intel.com>
Cc: Jiewen Yao <jiewen.yao@intel.com>
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
2019-09-04 01:00:10 +08:00
Ray Ni 09f7c82b4c UefiCpuPkg/PiSmmCpu: Use new PCD PcdCpuSmmRestrictedMemoryAccess
The patch changes PiSmmCpu driver to consume PCD
PcdCpuSmmRestrictedMemoryAccess.
Because the behavior controlled by PcdCpuSmmStaticPageTable in
original code is not changed after switching to
PcdCpuSmmRestrictedMemoryAccess.

The functionality is not impacted by this patch.

Signed-off-by: Ray Ni <ray.ni@intel.com>
Reviewed-by: Eric Dong <eric.dong@intel.com>
Cc: Jiewen Yao <jiewen.yao@intel.com>
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
2019-09-04 01:00:10 +08:00
Ray Ni 87184487d2 UefiCpuPkg: Add PcdCpuSmmRestrictedMemoryAccess
The patch adds a new X64 only PCD PcdCpuSmmRestrictedMemoryAccess.
The PCD indicates access to non-SMRAM memory is restricted to
reserved, runtime and ACPI NVS type after SmmReadyToLock.
MMIO access is always allowed regardless of the value of this PCD.
Loose of such restriction is only required by RAS components in X64
platforms.
The PCD value is considered as constantly TRUE in IA32 platforms.
When the PCD value is TRUE, page table is initialized to cover all
memory spaces and the memory occupied by page table is protected by
page table itself as read-only.

Signed-off-by: Ray Ni <ray.ni@intel.com>
Reviewed-by: Eric Dong <eric.dong@intel.com>
Cc: Jiewen Yao <jiewen.yao@intel.com>
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
2019-09-04 01:00:10 +08:00
Eric Dong 47f167f47e UefiCpuPkg/SecCore: get AllSecPpiList after SecPlatformMain.
REF: https://bugzilla.tianocore.org/show_bug.cgi?id=2136

SecPlatformMain is a platform hook function which let platform does
some update. Some platform may adjust SecCoreData->PeiTemporaryRamBase
which caused former saved AllSecPpiList variable invalid.

This patch update the logic to get AllSecPpiList after SecPlatformMain.
If SecPlatformMain() returns no platform-specific PPI list, then there
is nothing to merge, so we don't need "AllSecPpiList" at all.

Cc: Ray Ni <ray.ni@intel.com>
Signed-off-by: Eric Dong <eric.dong@intel.com>
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
2019-08-30 21:49:49 +08:00
Donald Kuo 30781febe2 UefiCpuPkg: Adding a new TSC library by using CPUID(0x15) TSC leaf
REF: https://bugzilla.tianocore.org/show_bug.cgi?id=1909

Cc: Ray Ni <ray.ni@intel.com>
Cc: Star Zeng <star.zeng@intel.com>
Cc: Eric Dong <eric.dong@intel.com>
Cc: Amy Chan <amy.chan@intel.com>
Cc: Rangasai V Chaganty <rangasai.v.chaganty@intel.com>
Signed-off-by: Donald Kuo <donald.kuo@intel.com>
Reviewed-by: Eric Dong <eric.dong@intel.com>
2019-08-21 21:36:56 +08:00
Dong, Eric 9c90d39b60 UefiCpuPkg/CpuCommonFeaturesLib: Use new macros.
REF: https://bugzilla.tianocore.org/show_bug.cgi?id=2040

Below code is current implementation:
  if (MsrRegister[ProcessorNumber].Bits.Lock == 0) {
    CPU_REGISTER_TABLE_WRITE_FIELD (
      ProcessorNumber,
      Msr,
      MSR_IA32_FEATURE_CONTROL,
      MSR_IA32_FEATURE_CONTROL_REGISTER,
      Bits.Lock,
      1
    );
  }

1. In first normal boot, the Bits.Lock is 0, 1 will be added
   into the register table and then will set to the MSR.
2. Trig warm reboot, MSR value preserves. After normal boot phase,
   the Bits.Lock is 1, so it will not be added into the register
   table during the warm reboot phase.
3. Trig S3 then resume, the Bits.Lock change to 0 and Bits.Lock is
   not added in register table, so it's still 0 after resume. This
   is not an expect behavior. The expect value is the value should
   always 1 after booting or resuming from S3.

The root cause for this issue is
1. driver bases on current value to insert the "set value action" to
   the register table.
2. Some MSRs may reserve their value during warm reboot.

The solution for this issue is using new added macros for the MSRs which
preserve value during warm reboot.

Signed-off-by: Eric Dong <eric.dong@intel.com>
Reviewed-by: Ray Ni <ray.ni@intel.com>
Acked-by: Laszlo Ersek <lersek@redhat.com>
2019-08-21 02:44:50 +08:00
Dong, Eric 95cfe6c247 UefiCpuPkg/RegisterCpuFeaturesLib: Supports test then write new value logic.
REF: https://bugzilla.tianocore.org/show_bug.cgi?id=2040

Supports new logic which test current value before write new value.
Only write new value when current value not same as new value.

Signed-off-by: Eric Dong <eric.dong@intel.com>
Reviewed-by: Ray Ni <ray.ni@intel.com>
Acked-by: Laszlo Ersek <lersek@redhat.com>
2019-08-21 02:44:49 +08:00
Dong, Eric 6b3645ade5 UefiCpuPkg/RegisterCpuFeaturesLib: Combine CR read/write action.
Signed-off-by: Eric Dong <eric.dong@intel.com>
Reviewed-by: Ray Ni <ray.ni@intel.com>
Acked-by: Laszlo Ersek <lersek@redhat.com>
2019-08-21 02:44:49 +08:00
Dong, Eric cfbcaad251 UefiCpuPkg/PiSmmCpuDxeSmm: Supports test then write new value logic.
REF: https://bugzilla.tianocore.org/show_bug.cgi?id=2040

Supports new logic which test current value before write new value.
Only write new value when current value not same as new value.

Signed-off-by: Eric Dong <eric.dong@intel.com>
Reviewed-by: Ray Ni <ray.ni@intel.com>
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
2019-08-21 02:44:49 +08:00
Dong, Eric ef21a304e0 UefiCpuPkg/PiSmmCpuDxeSmm: Combine CR read/write action.
Signed-off-by: Eric Dong <eric.dong@intel.com>
Reviewed-by: Ray Ni <ray.ni@intel.com>
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
2019-08-21 02:44:48 +08:00
Dong, Eric 35c2809ba6 UefiCpuPkg/RegisterCpuFeaturesLib: Add "Test Then Write" Macros.
REF: https://bugzilla.tianocore.org/show_bug.cgi?id=2040

Add below new micros which test the current value before write the new
value. Only write new value when current value not same as new value.
  CPU_REGISTER_TABLE_TEST_THEN_WRITE32
  CPU_REGISTER_TABLE_TEST_THEN_WRITE64
  CPU_REGISTER_TABLE_TEST_THEN_WRITE_FIELD

Also add below API:
  CpuRegisterTableTestThenWrite

Signed-off-by: Eric Dong <eric.dong@intel.com>
Reviewed-by: Ray Ni <ray.ni@intel.com>
Acked-by: Laszlo Ersek <lersek@redhat.com>
Cc: Star Zeng <star.zeng@intel.com>
2019-08-21 02:44:48 +08:00
Damian Nikodem 4201098e97 UefiCpuPkg/PiSmmCpuDxeSmm: don't free page table pages that are required to handle current page fault
Reclaim may free page table pages that are required to handle current page
fault. This causes a page leak, and, after sufficent number of specific
page fault+reclaim pairs, we run out of reclaimable pages and hit:

ASSERT (MinAcc != (UINT64)-1);

To remedy, prevent pages essential to handling current page fault:
(1) from being considered as reclaim candidates (first reclaim phase)
(2) from being freed as part of "branch cleanup" (second reclaim phase)

Signed-off-by: Damian Nikodem <damian.nikodem@intel.com>
Cc: Eric Dong <eric.dong@intel.com>
Reviewed-by: Ray Ni <ray.ni@intel.com>
Reviewed-by: Jian J Wang <jian.j.wang@intel.com>
Cc: Laszlo Ersek <lersek@redhat.com>
Cc: Krzysztof Rusocki <krzysztof.rusocki@intel.com>
2019-08-21 02:44:48 +08:00
Shenglei Zhang 501de8146d UefiCpuPkg/Cpuid: Add description for parameter LeafFunction
LeafFunction needs to be described in comments.
https://bugzilla.tianocore.org/show_bug.cgi?id=2052

Cc: Eric Dong <eric.dong@intel.com>
Cc: Ray Ni <ray.ni@intel.com>
Cc: Laszlo Ersek <lersek@redhat.com>
Signed-off-by: Shenglei Zhang <shenglei.zhang@intel.com>
Reviewed-by: Eric Dong <eric.dong@intel.com>
2019-08-16 14:01:49 +08:00
Shenglei Zhang 073f2cede8 UefiCpuPkg/PiSmmCpuDxeSmm: Fix coding style
1. Update CPUStatus to CpuStatus in comments to align comments
   with code.
2. Add "OUT" attribute for "ProcedureArguments" parameter in function
   header.

Cc: Eric Dong <eric.dong@intel.com>
Cc: Ray Ni <ray.ni@intel.com>
Cc: Laszlo Ersek <lersek@redhat.com>
Signed-off-by: Shenglei Zhang <shenglei.zhang@intel.com>
Reviewed-by: Eric Dong <eric.dong@intel.com>
2019-08-13 17:20:32 +08:00
Eric Dong 466f5e89c3 UefiCpuPkg/PiSmmCpuDxeSmm: Clean up useless ConsoleLogLock spinlock.
REF: https://bugzilla.tianocore.org/show_bug.cgi?id=2060

Remove the useless ConsoleLogLock spinlock.

Signed-off-by: Eric Dong <eric.dong@intel.com>
Cc: Ray Ni <ray.ni@intel.com>
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
2019-08-09 08:55:57 +08:00
Eric Dong 800aeeda74 UefiCpuPkg/RegisterCpuFeaturesLib: Clean up useless ConsoleLogLock spinlock.
REF: https://bugzilla.tianocore.org/show_bug.cgi?id=2060

Remove the useless ConsoleLogLock spinlock.

Signed-off-by: Eric Dong <eric.dong@intel.com>
Cc: Ray Ni <ray.ni@intel.com>
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
2019-08-09 08:55:57 +08:00
Ni, Ray 01acb06c4f UefiCpuPkg: Update code to include register definitions from MdePkg
Signed-off-by: Ray Ni <ray.ni@intel.com>
Reviewed-by: Eric Dong <eric.dong@intel.com>
Regression-tested-by: Laszlo Ersek <lersek@redhat.com>
Signed-off-by: Eric Dong <eric.dong@intel.com>
2019-08-09 08:52:09 +08:00
Ni, Ray e057908f8d UefiCpuPkg|MdePkg: Move Register/ folder to MdePkg/Include/
The patch moves all files under UefiCpuPkg/Include/Register/ to
MdePkg/Include/Register using following detailed approaches:
1. Move UefiCpuPkg/Include/Register/Amd/ to
   MdePkg/Include/Register/Amd folder.
2. Move remaining in UefiCpuPkg/Include/Register/ to
   MdePkg/Include/Register/Intel folder.
3. Create wrapper header files under UefiCpuPkg/Include/Register/
   to include the accordingly files in MdePkg/Include/Register/Intel.
   This is to avoid build break because code in other repos like
   edk2-platform includes the file from UefiCpuPkg.

The wrapper header files will be removed after all consumers code
is updated.

Signed-off-by: Ray Ni <ray.ni@intel.com>
Reviewed-by: Eric Dong <eric.dong@intel.com>
Regression-tested-by: Laszlo Ersek <lersek@redhat.com>
Reviewed-by: Liming Gao <liming.gao@intel.com>
Signed-off-by: Eric Dong <eric.dong@intel.com>
2019-08-09 08:52:09 +08:00
Ni, Ray 236d5c66c4 MdePkg/Cpuid.h: Move Cpuid.h from UefiCpuPkg to MdePkg
REF: https://bugzilla.tianocore.org/show_bug.cgi?id=2008

MdeModulePkg/DxeIpl needs to get CPUID output for CPU
5-level paging capability detection.

In order to use the macros/structures defined in
UefiCpuPkg/Include/Register/Cpuid.h, the patch adds Intel/Cpuid.h
to MdePkg/Include/Register/ directory and updates Cpuid.h
in UefiCpuPkg to include the new one in MdePkg.

Cc: Michael D Kinney <michael.d.kinney@intel.com>
Signed-off-by: Ray Ni <ray.ni@intel.com>
Reviewed-by: Liming Gao <liming.gao@intel.com>
Reviewed-by: Eric Dong <eric.dong@intel.com>
Regression-tested-by: Laszlo Ersek <lersek@redhat.com>
Signed-off-by: Eric Dong <eric.dong@intel.com>
2019-08-09 08:52:08 +08:00
Ni, Ray e58aa47432 UefiCpuPkg/CpuDxe: Support parsing 5-level page table
REF: https://bugzilla.tianocore.org/show_bug.cgi?id=2008

Signed-off-by: Ray Ni <ray.ni@intel.com>
Reviewed-by: Eric Dong <eric.dong@intel.com>
Regression-tested-by: Laszlo Ersek <lersek@redhat.com>
Signed-off-by: Eric Dong <eric.dong@intel.com>
2019-08-09 08:52:08 +08:00