public inbox for devel@edk2.groups.io
 help / color / mirror / Atom feed
From: "Michael D Kinney" <michael.d.kinney@intel.com>
To: "devel@edk2.groups.io" <devel@edk2.groups.io>,
	"lersek@redhat.com" <lersek@redhat.com>,
	"Kinney, Michael D" <michael.d.kinney@intel.com>
Cc: "Dong, Eric" <eric.dong@intel.com>, "Ni, Ray" <ray.ni@intel.com>,
	"Wang, Jian J" <jian.j.wang@intel.com>
Subject: Re: [edk2-devel] [Patch 2/4] UefiCpuPkg/MpInitLib: Avoid MSR_IA32_APIC_BASE for single core
Date: Tue, 30 Apr 2019 15:21:38 +0000	[thread overview]
Message-ID: <E92EE9817A31E24EB0585FDF735412F5B9CA031C@ORSMSX113.amr.corp.intel.com> (raw)
In-Reply-To: <e77dc9a9-6506-a33c-dfd5-121d5867a31b@redhat.com>

Laszlo,

I agree with your analysis.  I will work on a 
different solution.

Thanks,

Mike

> -----Original Message-----
> From: devel@edk2.groups.io
> [mailto:devel@edk2.groups.io] On Behalf Of Laszlo Ersek
> Sent: Tuesday, April 30, 2019 3:02 AM
> To: Kinney, Michael D <michael.d.kinney@intel.com>;
> devel@edk2.groups.io
> Cc: Dong, Eric <eric.dong@intel.com>; Ni, Ray
> <ray.ni@intel.com>; Wang, Jian J
> <jian.j.wang@intel.com>
> Subject: Re: [edk2-devel] [Patch 2/4]
> UefiCpuPkg/MpInitLib: Avoid MSR_IA32_APIC_BASE for
> single core
> 
> On 04/29/19 19:11, Kinney, Michael D wrote:
> > Laszlo,
> >
> > I was attempting to follow the equivalent detection
> logic
> > that is used in the SourceLevelDebugPkg.
> >
> >
> https://github.com/tianocore/edk2/blob/e2d3a25f1a313522
> 1a9c8061e1b8f90245d727eb/SourceLevelDebugPkg/Library/De
> bugAgent/DebugAgentCommon/DebugMp.c#L140
> >
> > Yes.  CPUID can be used to determine availability of
> > MSR_IA32_APIC_BASE.  That would be safer if the
> maximum
> > number of CPUs can start with a value of 1 and change
> to
> > a higher value later.  But based on your analysis,
> > it looks like the max number of CPUs is known when
> this
> > function runs which is always after memory is
> discovered.
> 
> The proposed patch is safe wrt. the PCD production-
> consumption sequence,
> yes.
> 
> However, the patch is unsafe due to APs calling a PPI
> member function
> (namely, the PCD_PPI.Get32 function).
> 
> To my understanding, APs may not call PPIs.
> 
> > The MSR access is in the function GetCpuMpData(),
> which is
> > called from all the MP service functions.  I was
> trying
> > to avoid an extra CPUID check on all those paths.
> >
> > I prefer the current patch if it is safe.  Please let
> me
> > know if you think extra comments are required in the
> code
> > or the commit message.
> 
> I think the patch is unsafe, because it is possible for
> both of the
> following conditions to hold, at the same time:
> 
> - the function may be entered by an AP
> - the PCD may be dynamic
> 
> That would lead to an AP calling
> 
>   (GetPcdPpiPointer ())->Get32 (TokenNumber)
> 
> which I believe is forbidden.
> 
> 
> If the patch called FixedPcdGet32(), then the patch
> would be safe.
> Unfortunately, in that case, the patch wouldn't compile
> for OvmfPkg.
> 
> If we can use a new PCD for this, such that
> UefiCpuPkg.dec does not
> permit platforms to pick "dynamic" for that PCD -- i.e.
> it would have to
> be Feature, Fixed, or Patch --, and then the patch is
> updated to call
> the appropriate flavor-specific PCD macro
> (FeaturePcdGet, PatchPcdGet*,
> FixedPcdGet*), then the patch will be fine.
> 
> The point is that the "getting the PCD" action never
> enter a library
> function that is not explicitly MP-safe, nor enter a
> PPI member function.
> 
> Thanks
> Laszlo
> 
> >> -----Original Message-----
> >> From: devel@edk2.groups.io
> [mailto:devel@edk2.groups.io]
> >> On Behalf Of Laszlo Ersek
> >> Sent: Friday, April 26, 2019 12:25 PM
> >> To: Kinney, Michael D <michael.d.kinney@intel.com>;
> >> devel@edk2.groups.io
> >> Cc: Dong, Eric <eric.dong@intel.com>; Ni, Ray
> >> <ray.ni@intel.com>; Wang, Jian J
> <jian.j.wang@intel.com>
> >> Subject: Re: [edk2-devel] [Patch 2/4]
> >> UefiCpuPkg/MpInitLib: Avoid MSR_IA32_APIC_BASE for
> >> single core
> >>
> >> (+Jian)
> >>
> >> Hi Mike,
> >>
> >> thank you for the CC.
> >>
> >> On 04/25/19 19:53, Michael D Kinney wrote:
> >>> Avoid access to MSR_IA32_APIC_BASE that may not be
> >> supported
> >>> on single core CPUs.  If
> >> PcdCpuMaxLogicalProcessorNumber is 1,
> >>> then there is only one CPU that must be the BSP.
> >>>
> >>> 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>
> >>> ---
> >>>  UefiCpuPkg/Library/MpInitLib/PeiMpLib.c | 15
> >> ++++++++++++++-
> >>>  1 file changed, 14 insertions(+), 1 deletion(-)
> >>>
> >>> diff --git
> a/UefiCpuPkg/Library/MpInitLib/PeiMpLib.c
> >> b/UefiCpuPkg/Library/MpInitLib/PeiMpLib.c
> >>> index 35dff91fd2..5488049c08 100644
> >>> --- a/UefiCpuPkg/Library/MpInitLib/PeiMpLib.c
> >>> +++ b/UefiCpuPkg/Library/MpInitLib/PeiMpLib.c
> >>> @@ -1,7 +1,7 @@
> >>>  /** @file
> >>>    MP initialize support functions for PEI phase.
> >>>
> >>> -  Copyright (c) 2016 - 2018, Intel Corporation.
> All
> >> rights reserved.<BR>
> >>> +  Copyright (c) 2016 - 2019, Intel Corporation.
> All
> >> rights reserved.<BR>
> >>>    SPDX-License-Identifier: BSD-2-Clause-Patent
> >>>
> >>>  **/
> >>> @@ -101,6 +101,19 @@ GetCpuMpData (
> >>>    MSR_IA32_APIC_BASE_REGISTER  ApicBaseMsr;
> >>>    IA32_DESCRIPTOR              Idtr;
> >>>
> >>> +  //
> >>> +  // If there is only 1 CPU, then it must be the
> BSP.
> >> This avoids an access to
> >>> +  // MSR_IA32_APIC_BASE that may not be supported
> on
> >> single core CPUs.
> >>> +  //
> >>> +  if (PcdGet32 (PcdCpuMaxLogicalProcessorNumber)
> ==
> >> 1) {
> >>> +    CpuMpData = GetCpuMpDataFromGuidedHob ();
> >>> +    ASSERT (CpuMpData != NULL);
> >>> +    return CpuMpData;
> >>> +  }
> >>> +
> >>> +  //
> >>> +  // Otherwise use MSR_IA32_APIC_BASE to determine
> if
> >> the CPU is BSP or AP.
> >>> +  //
> >>>    ApicBaseMsr.Uint64 = AsmReadMsr64
> >> (MSR_IA32_APIC_BASE);
> >>>    if (ApicBaseMsr.Bits.BSP == 1) {
> >>>      CpuMpData = GetCpuMpDataFromGuidedHob ();
> >>>
> >>
> >> This patch leads me down on two paths:
> >>
> >> (1) Specifically regarding the code change. I think
> this
> >> patch is unsafe
> >>     on platforms that dynamically set the PCD to a
> value
> >> larger than 1.
> >>     (Including OVMF.)
> >>
> >>     If the value is larger than 1, then the system
> has
> >> at least one AP,
> >>     and the AP may enter the function. In addition,
> >> because the PCD is
> >>     dynamic, the PcdGet32() call will invoke the PCD
> PPI
> >> (if I
> >>     understand correctly), which is not allowed for
> an
> >> AP.
> >>
> >>     Is it not possible to determine the availability
> of
> >>     MSR_IA32_APIC_BASE from CPUID, or a different
> MSR?
> >>
> >>
> >> (2) More generally, this patch made me review
> >> OvmfPkg/PlatformPei:
> >>
> >>     (a) OvmfPkg/PlatformPei sets the PCD in
> >> MaxCpuCountInitialization(),
> >>
> >>     (b) later, OvmfPkg/PlatformPei publishes the
> >> permanent PEI RAM in
> >>         PublishPeiMemory()
> >>
> >>     (c) which in turn leads to the installation of
> >>         gEfiPeiMemoryDiscoveredPpiGuid intto the PPI
> >> database, by the
> >>         PEI Core
> >>
> >>     (d) CpuMpPei can now be dispatched, because it
> has a
> >> depex on the
> >>         "memory discovered" PPI
> >>
> >>     (e) PeiMpInitLib, which is linked into CpuMpPei,
> can
> >> consume the PCD
> >>         safely.
> >>
> >>     I relied on this behavior in the following OVMF
> >> commit:
> >>
> >>     commit 45a70db3c3a59b64e0f517870415963fbfacf507
> >>     Author: Laszlo Ersek <lersek@redhat.com>
> >>     Date:   Thu Nov 24 15:18:44 2016 +0100
> >>
> >>         OvmfPkg/PlatformPei: take VCPU count from
> QEMU
> >> and configure MpInitLib
> >>
> >>         These settings will allow CpuMpPei and
> CpuDxe to
> >> wait for the initial AP
> >>         check-ins exactly as long as necessary.
> >>
> >>         It is safe to set
> >> PcdCpuMaxLogicalProcessorNumber and
> >>         PcdCpuApInitTimeOutInMicroSeconds in
> >> OvmfPkg/PlatformPei.
> >>         OvmfPkg/PlatformPei installs the permanent
> PEI
> >> RAM, producing
> >>         gEfiPeiMemoryDiscoveredPpiGuid, and
> >> UefiCpuPkg/CpuMpPei has a depex on
> >>         gEfiPeiMemoryDiscoveredPpiGuid.
> >>
> >>         [...]
> >>
> >>     Except... in commit 0a0d5296e448
> >> ("UefiCpuPkg/CpuMpPei: support
> >>     stack guard feature", 2018-09-10), the DEPEX
> >> mentioned in step (d)
> >>     was deleted.
> >>
> >>     So now I got a bit nervous, because how are then
> the
> >> setting and
> >>     reading of the PCD serialized between
> >> OvmfPkg/PlatformPei, and
> >>     PeiMpInitLib in CpuMpPei?
> >>
> >>     Luckily however, I think we're safe:
> >>
> >>     - CpuMpPei itself doesn't consume the PCD,
> >>
> >>     - MpInitLib consumes the PCD in several
> functions,
> >> but all clients
> >>       of MpInitLib must call MpInitLibInitialize()
> >> first, before using
> >>       other library APIs
> >>
> >>     - CpuMpPei calls MpInitLibInitialize() in the
> >>       InitializeCpuMpWorker() function
> >>
> >>     - the InitializeCpuMpWorker() function is only
> >> called from the
> >>       MemoryDiscoveredPpiNotifyCallback().
> >>
> >>     So the PCD set/get order remains safe and
> >> deterministic. Even though
> >>     CpuMpPei can now be dispatched before permanent
> >> memory is
> >>     discovered, MpInitLibInitialize() -- and so the
> >> reading of the PCD
> >>     -- is still delayed until after permanent PEI
> RAM is
> >> available.
> >>     That's a relief.
> >>
> >>     In fact, it looks like commit 0a0d5296e448
> >> ("UefiCpuPkg/CpuMpPei:
> >>     support stack guard feature", 2018-09-10)
> delayed
> >> the entire
> >>     original entry point of CpuMpPei into the
> "memory
> >> discovered"
> >>     callback. That appears OK to me, it's just that
> the
> >> patch (~1000
> >>     lines) could have been split at least in two:
> one
> >> patch could have
> >>     implemented the "PPI DEPEX --> PPI notify"
> >> transformation, without
> >>     other changes in behavior, and the second patch
> >> could have extended
> >>     the (now delayed) startup logic with
> >>     InitializeMpExceptionStackSwitchHandlers() &
> >> friends.
> >>
> >> Thanks
> >> Laszlo
> >>
> >>
> >
> 
> 
> 


  reply	other threads:[~2019-04-30 15:21 UTC|newest]

Thread overview: 21+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-04-25 17:53 [Patch 0/4] Resolve Quark build and boot issues Michael D Kinney
2019-04-25 17:53 ` [Patch 1/4] MdePkg/BaseLib: Verify SSE2 support in IA32 AsmLfence() Michael D Kinney
2019-04-26 20:27   ` [edk2-devel] " Laszlo Ersek
2019-04-26 21:08     ` Brian J. Johnson
2019-04-29 11:15       ` Laszlo Ersek
2019-04-29 14:09         ` Liming Gao
2019-04-29 18:23           ` Michael D Kinney
2019-04-30 10:03             ` Laszlo Ersek
2019-04-28  8:28   ` Liming Gao
2019-04-25 17:53 ` [Patch 2/4] UefiCpuPkg/MpInitLib: Avoid MSR_IA32_APIC_BASE for single core Michael D Kinney
2019-04-25 18:07   ` Ni, Ray
2019-04-26  0:04   ` Dong, Eric
2019-04-26 19:24   ` Laszlo Ersek
2019-04-29 17:11     ` [edk2-devel] " Michael D Kinney
2019-04-30 10:02       ` Laszlo Ersek
2019-04-30 15:21         ` Michael D Kinney [this message]
2019-04-25 17:53 ` [Patch 3/4] QuarkSocPkg/SmmAccessDxe: Set region to UC on SMRAM close Michael D Kinney
2019-04-25 21:40   ` Steele, Kelly
2019-04-25 17:53 ` [Patch 4/4] QuarkPlatformPkg/PlatformInit: Resolve ResetSystemLib name collision Michael D Kinney
2019-04-25 21:40   ` Steele, Kelly
2019-04-28  8:25   ` [edk2-devel] " Liming Gao

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-list from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=E92EE9817A31E24EB0585FDF735412F5B9CA031C@ORSMSX113.amr.corp.intel.com \
    --to=devel@edk2.groups.io \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox