public inbox for devel@edk2.groups.io
 help / color / mirror / Atom feed
From: "Ard Biesheuvel" <ardb@kernel.org>
To: Evgeny Iakovlev <eiakovlev@linux.microsoft.com>,
	kraxel@redhat.com,  Laszlo Ersek <lersek@redhat.com>,
	edk2-devel-groups-io <devel@edk2.groups.io>
Cc: rfc@edk2.groups.io, jiewen.yao@intel.com
Subject: Re: [edk2-devel] [edk2][RFC] OvmfPkg/AcpiPlatformDxe: patch FADT PSCI bits if FDT advertises it
Date: Thu, 7 Sep 2023 16:27:40 +0200	[thread overview]
Message-ID: <CAMj1kXFD4LVY_WRs-XXegcuKW4M_8AC9=J6MobByTjeyJ_e5ug@mail.gmail.com> (raw)
In-Reply-To: <20230116113931.1221-1-eiakovlev@linux.microsoft.com>

On Mon, 16 Jan 2023 at 12:39, Evgeny Iakovlev
<eiakovlev@linux.microsoft.com> wrote:
>
> EL3 firmware may implement PSCI interface on aarch64 platforms,
> including qemu-tcg-aarch64. However, EL3 firmware does not usually own
> pulling and deploying ACPI tables from qemu fw_cfg. Thus the only way
> EL3 can advertise PSCI on qemu is in FDT. One such EL3 fw is ARM trusted
> firmware. Qemu itself also won't advertise PSCI in either FDT or ACPI if
> EL3 firmware is present.
>
> PSCI can be advertised in both FDT and ACPI, and Hyper-V/NT kernel
> expect to see all information published in ACPI. To better support
> running Hyper-V/NT on qemu-tcg-aarch64 with EDK2 as UEFI implementation
> and ARM trusted firmware as EL3 PSCI implementation we can patch in PSCI
> bits in ACPI FADT when pulling tables from fw_cfg if PSCI node is
> advertised in FDT. EDK2 owns ACPI table publishing and is also aware of
> FDT on arm, so it is ideally poised to handle this.
>
> This change illustrates how it could potentially be done. I am looking
> for comments on overall validity of the idea to patch FADT and whether
> or not this particular approach of handling it in AcpiPlatformDxe is the
> way to do it or maybe it is better to handle it via
> gQemuAcpiTableNotifyProtocolGuid somehow.
>
> Signed-off-by: Evgeny Iakovlev <eiakovlev@linux.microsoft.com>

Thanks for the patch, and apologies for the lack of response.

First of all, I suspect this patch breaks non-ARM users of this
driver, so the patch is problematic as is. (It makes
gFdtClientProtocolGuid mandatory, right?)

Then, I'd like to hear from other folks on cc what they think about
this. Perhaps it is simply a matter of tweaking QEMU so it exposes the
correct PSCI setting in the FADT when it emulates secure world.
Patching it like this feels like a last resort to me, rather than a
well designed interface.


> ---
> Resending the message because i wasn't subscribed to the rfc group the
> last time, sorry.
> ---
>  OvmfPkg/AcpiPlatformDxe/AcpiPlatformDxe.inf |   4 +-
>  OvmfPkg/AcpiPlatformDxe/QemuFwCfgAcpi.c     | 108 ++++++++++++++++++++
>  2 files changed, 111 insertions(+), 1 deletion(-)
>
> diff --git a/OvmfPkg/AcpiPlatformDxe/AcpiPlatformDxe.inf b/OvmfPkg/AcpiPlatformDxe/AcpiPlatformDxe.inf
> index 8939dde425..a011a43743 100644
> --- a/OvmfPkg/AcpiPlatformDxe/AcpiPlatformDxe.inf
> +++ b/OvmfPkg/AcpiPlatformDxe/AcpiPlatformDxe.inf
> @@ -30,6 +30,7 @@
>    QemuFwCfgAcpi.c
>
>  [Packages]
> +  EmbeddedPkg/EmbeddedPkg.dec
>    MdeModulePkg/MdeModulePkg.dec
>    MdePkg/MdePkg.dec
>    OvmfPkg/OvmfPkg.dec
> @@ -50,6 +51,7 @@
>  [Protocols]
>    gEfiAcpiTableProtocolGuid                     # PROTOCOL ALWAYS_CONSUMED
>    gEfiPciIoProtocolGuid                         # PROTOCOL SOMETIMES_CONSUMED
> +  gFdtClientProtocolGuid                        # PROTOCOL SOMETIMES_CONSUMED
>    gQemuAcpiTableNotifyProtocolGuid              # PROTOCOL PRODUCES
>
>  [Guids]
> @@ -64,4 +66,4 @@
>    gEfiMdePkgTokenSpaceGuid.PcdConfidentialComputingGuestAttr
>
>  [Depex]
> -  gEfiAcpiTableProtocolGuid
> +  gEfiAcpiTableProtocolGuid AND gFdtClientProtocolGuid
> diff --git a/OvmfPkg/AcpiPlatformDxe/QemuFwCfgAcpi.c b/OvmfPkg/AcpiPlatformDxe/QemuFwCfgAcpi.c
> index c8dee17c13..31d8665d2d 100644
> --- a/OvmfPkg/AcpiPlatformDxe/QemuFwCfgAcpi.c
> +++ b/OvmfPkg/AcpiPlatformDxe/QemuFwCfgAcpi.c
> @@ -9,6 +9,7 @@
>  **/
>
>  #include <IndustryStandard/Acpi.h>            // EFI_ACPI_DESCRIPTION_HEADER
> +#include <IndustryStandard/Acpi51.h>          // EFI_ACPI_5_1_FIXED_ACPI_DESCRIPTION_TABLE
>  #include <IndustryStandard/QemuLoader.h>      // QEMU_LOADER_FNAME_SIZE
>  #include <Library/BaseLib.h>                  // AsciiStrCmp()
>  #include <Library/BaseMemoryLib.h>            // CopyMem()
> @@ -20,6 +21,7 @@
>  #include <Library/UefiBootServicesTableLib.h> // gBS
>
>  #include <Protocol/QemuAcpiTableNotify.h>
> +#include <Protocol/FdtClient.h>
>  #include "AcpiPlatform.h"
>  EFI_HANDLE                       mQemuAcpiHandle = NULL;
>  QEMU_ACPI_TABLE_NOTIFY_PROTOCOL  mAcpiNotifyProtocol;
> @@ -815,6 +817,92 @@ UndoCmdWritePointer (
>      ));
>  }
>
> +/**
> +  Locate a PSCI node in DTB published by EL3 firmware that implemented it
> +  and use information in it to patch ACPI FADT PSCI bits.
> +
> +  The reason for it is that EL3 PSCI implementation, which is not EDK2,
> +  doesn't own ACPI tables and cannot advertise it there itself, it is using DTB instead.
> +
> +  Qemu also won't advertise PSCI if EL3 firmware is present.
> +  A real example of that is running ARM trusted firmware in EL3 with PSCI enabled.
> +
> +  @param[in] PonterValue    FADT base address
> +
> +  @param[in] TableSize      Size of table in bytes
> +
> +  @return                   EFI_SUCCESS if FAST was patched or if patching was not needed,
> +                            error status returned by FDT client protocol otherwise.
> +**/
> +STATIC
> +EFI_STATUS
> +EFIAPI
> +PatchFadtPsciBits (
> +  IN UINT64     PointerValue,
> +  IN UINTN      TableSize
> +  )
> +{
> +  EFI_STATUS                                    Status;
> +  FDT_CLIENT_PROTOCOL                           *FdtClient;
> +  CONST VOID                                    *Prop;
> +  EFI_ACPI_5_1_FIXED_ACPI_DESCRIPTION_TABLE     *Fadt;
> +  UINT8                                         MajorMinorRev;
> +
> +  Status = gBS->LocateProtocol (
> +                  &gFdtClientProtocolGuid,
> +                  NULL,
> +                  (VOID **)&FdtClient
> +                  );
> +  if (Status == EFI_NOT_FOUND) {
> +    goto NoPatchingNeeded;
> +  } else if (EFI_ERROR (Status)) {
> +    return Status;
> +  }
> +
> +  Status = FdtClient->FindCompatibleNodeProperty (
> +                        FdtClient,
> +                        "arm,psci-0.2",
> +                        "method",
> +                        &Prop,
> +                        NULL
> +                        );
> +  if (Status == EFI_NOT_FOUND) {
> +    goto NoPatchingNeeded;
> +  } else if (EFI_ERROR (Status)) {
> +    return Status;
> +  }
> +
> +  //
> +  // Make sure FADT is large enough for 5.1
> +  //
> +  if (TableSize < sizeof (*Fadt)) {
> +    goto NoPatchingNeeded;
> +  }
> +
> +  Fadt = (EFI_ACPI_5_1_FIXED_ACPI_DESCRIPTION_TABLE *)(UINTN)PointerValue;
> +
> +  //
> +  // Check that FADT revision is at least 5.1 now that it's safe to read fields
> +  //
> +  MajorMinorRev = (Fadt->Header.Revision << 4) | (Fadt->MinorVersion & 0x0F);
> +  if (MajorMinorRev < 0x51) {
> +    goto NoPatchingNeeded;
> +  }
> +
> +  //
> +  // Patch FADT PSCI bits
> +  //
> +  Fadt->ArmBootArch = EFI_ACPI_5_1_ARM_PSCI_COMPLIANT;
> +  if (AsciiStrnCmp (Prop, "hvc", 3) == 0) {
> +    Fadt->ArmBootArch |= EFI_ACPI_5_1_ARM_PSCI_USE_HVC;
> +  }
> +
> +  return EFI_SUCCESS;
> +
> +NoPatchingNeeded:
> +  return EFI_SUCCESS;
> +}
> +
>  //
>  // We'll be saving the keys of installed tables so that we can roll them back
>  // in case of failure. 128 tables should be enough for anyone (TM).
> @@ -901,6 +989,7 @@ Process2ndPassCmdAddPointer (
>    UINT64                                              PointerValue;
>    UINTN                                               Blob2Remaining;
>    UINTN                                               TableSize;
> +  UINT32                                              Signature;
>    CONST EFI_ACPI_1_0_FIRMWARE_ACPI_CONTROL_STRUCTURE  *Facs;
>    CONST EFI_ACPI_DESCRIPTION_HEADER                   *Header;
>    EFI_STATUS                                          Status;
> @@ -960,6 +1049,7 @@ Process2ndPassCmdAddPointer (
>      ));
>
>    TableSize = 0;
> +  Signature = 0;
>
>    //
>    // To make our job simple, the FACS has a custom header. Sigh.
> @@ -979,6 +1069,7 @@ Process2ndPassCmdAddPointer (
>          Facs->Length
>          ));
>        TableSize = Facs->Length;
> +      Signature = Facs->Signature;
>      }
>    }
>
> @@ -1004,6 +1095,7 @@ Process2ndPassCmdAddPointer (
>          Header->Length
>          ));
>        TableSize = Header->Length;
> +      Signature = Header->Signature;
>
>        //
>        // Skip RSDT and XSDT because those are handled by
> @@ -1035,6 +1127,22 @@ Process2ndPassCmdAddPointer (
>      goto RollbackSeenPointer;
>    }
>
> +  //
> +  // For FADT also patch PSCI flag if DTB exposes it.
> +  //
> +  if (Signature == EFI_ACPI_1_0_FIXED_ACPI_DESCRIPTION_TABLE_SIGNATURE) {
> +    Status = PatchFadtPsciBits(PointerValue, TableSize);
> +    if (EFI_ERROR (Status)) {
> +      DEBUG ((
> +        DEBUG_ERROR,
> +        "%a: PatchFadtPsciBits(): %r\n",
> +        __FUNCTION__,
> +        Status
> +        ));
> +      goto RollbackSeenPointer;
> +    }
> +  }
> +
>    Status = AcpiProtocol->InstallAcpiTable (
>                             AcpiProtocol,
>                             (VOID *)(UINTN)PointerValue,
> --
> 2.38.1.vfs.0.0
>


-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#108395): https://edk2.groups.io/g/devel/message/108395
Mute This Topic: https://groups.io/mt/101215483/7686176
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [rebecca@openfw.io]
-=-=-=-=-=-=-=-=-=-=-=-



       reply	other threads:[~2023-09-07 14:27 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
     [not found] <20230116113931.1221-1-eiakovlev@linux.microsoft.com>
2023-09-07 14:27 ` Ard Biesheuvel [this message]
2023-09-07 14:50   ` [edk2-devel] [edk2][RFC] OvmfPkg/AcpiPlatformDxe: patch FADT PSCI bits if FDT advertises it Laszlo Ersek
2023-09-07 15:17     ` Ard Biesheuvel
2023-09-07 20:07       ` Laszlo Ersek

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='CAMj1kXFD4LVY_WRs-XXegcuKW4M_8AC9=J6MobByTjeyJ_e5ug@mail.gmail.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