public inbox for devel@edk2.groups.io
 help / color / mirror / Atom feed
From: "Laszlo Ersek" <lersek@redhat.com>
To: Michael D Kinney <michael.d.kinney@intel.com>, devel@edk2.groups.io
Cc: Eric Dong <eric.dong@intel.com>, Ray Ni <ray.ni@intel.com>,
	Jian J Wang <jian.j.wang@intel.com>
Subject: Re: [Patch 2/4] UefiCpuPkg/MpInitLib: Avoid MSR_IA32_APIC_BASE for single core
Date: Fri, 26 Apr 2019 21:24:57 +0200	[thread overview]
Message-ID: <8c03f148-8b61-2477-7708-0e55f32b581b@redhat.com> (raw)
In-Reply-To: <20190425175334.5944-3-michael.d.kinney@intel.com>

(+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

  parent reply	other threads:[~2019-04-26 19:25 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 [this message]
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
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=8c03f148-8b61-2477-7708-0e55f32b581b@redhat.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