Commit Graph

1130 Commits

Author SHA1 Message Date
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