Reviewed-by: Michael D Kinney <[email protected]>

Mike

> -----Original Message-----
> From: edk2-devel [mailto:edk2-devel-
> [email protected]] On Behalf Of
> [email protected]
> Sent: Tuesday, October 2, 2018 5:17 AM
> To: [email protected]
> Cc: Justen, Jordan L <[email protected]>;
> Anthony Perard <[email protected]>; Laszlo Ersek
> <[email protected]>
> Subject: [edk2] [PATCH v3 1/1] OvmfPkg/PlatformPei:
> clear CPU caches
> 
> From: Marc-AndrĂ© Lureau <[email protected]>
> 
> This is for conformance with the TCG "Platform Reset
> Attack Mitigation
> Specification". Because clearing the CPU caches at boot
> doesn't impact
> performance significantly, do it unconditionally, for
> simplicity's
> sake.
> 
> Flush the cache on all logical processors, thanks to
> EFI_PEI_MP_SERVICES_PPI and CacheMaintenanceLib.
> 
> Cc: Jordan Justen <[email protected]>
> Cc: Laszlo Ersek <[email protected]>
> Cc: Ard Biesheuvel <[email protected]>
> Cc: Anthony Perard <[email protected]>
> Cc: Julien Grall <[email protected]>
> Contributed-under: TianoCore Contribution Agreement 1.1
> Signed-off-by: Marc-André Lureau
> <[email protected]>
> Message-Id: <20181002120730.13013-1-
> [email protected]>
> ---
> 
> v3:
>   - update top comment with notes about TCG spec
>   - sort headers inclusion
> 
>  OvmfPkg/PlatformPei/PlatformPei.inf |   2 +
>  OvmfPkg/PlatformPei/Platform.h      |   5 +
>  OvmfPkg/PlatformPei/ClearCache.c    | 117
> ++++++++++++++++++++
>  OvmfPkg/PlatformPei/Platform.c      |   1 +
>  4 files changed, 125 insertions(+)
> 
> diff --git a/OvmfPkg/PlatformPei/PlatformPei.inf
> b/OvmfPkg/PlatformPei/PlatformPei.inf
> index 9c5ad9961c4a..5c8dd0fe6d72 100644
> --- a/OvmfPkg/PlatformPei/PlatformPei.inf
> +++ b/OvmfPkg/PlatformPei/PlatformPei.inf
> @@ -30,6 +30,7 @@
> 
>  [Sources]
>    AmdSev.c
> +  ClearCache.c
>    Cmos.c
>    Cmos.h
>    FeatureControl.c
> @@ -54,6 +55,7 @@
> 
>  [LibraryClasses]
>    BaseLib
> +  CacheMaintenanceLib
>    DebugLib
>    HobLib
>    IoLib
> diff --git a/OvmfPkg/PlatformPei/Platform.h
> b/OvmfPkg/PlatformPei/Platform.h
> index f942e61bb4f9..b12a5c1f5f78 100644
> --- a/OvmfPkg/PlatformPei/Platform.h
> +++ b/OvmfPkg/PlatformPei/Platform.h
> @@ -83,6 +83,11 @@ InstallFeatureControlCallback (
>    VOID
>    );
> 
> +VOID
> +InstallClearCacheCallback (
> +  VOID
> +  );
> +
>  EFI_STATUS
>  InitializeXen (
>    VOID
> diff --git a/OvmfPkg/PlatformPei/ClearCache.c
> b/OvmfPkg/PlatformPei/ClearCache.c
> new file mode 100644
> index 000000000000..7d15fd925c3c
> --- /dev/null
> +++ b/OvmfPkg/PlatformPei/ClearCache.c
> @@ -0,0 +1,117 @@
> +/**@file
> +  Install a callback to clear cache on all processors.
> +  This is for conformance with the TCG "Platform Reset
> Attack Mitigation
> +  Specification". Because clearing the CPU caches at
> boot doesn't impact
> +  performance significantly, do it unconditionally, for
> simplicity's
> +  sake.
> +
> +  Copyright (C) 2018, Red Hat, Inc.
> +
> +  This program and the accompanying materials are
> licensed and made available
> +  under the terms and conditions of the BSD License
> which accompanies this
> +  distribution.  The full text of the license may be
> found at
> +  http://opensource.org/licenses/bsd-license.php
> +
> +  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON
> AN "AS IS" BASIS, WITHOUT
> +  WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER
> EXPRESS OR IMPLIED.
> +**/
> +
> +#include <Library/CacheMaintenanceLib.h>
> +#include <Library/DebugLib.h>
> +#include <Library/PeiServicesLib.h>
> +#include <Ppi/MpServices.h>
> +
> +#include "Platform.h"
> +
> +/**
> +  Invalidate data & instruction caches.
> +  All APs execute this function in parallel. The BSP
> executes the function
> +  separately.
> +
> +  @param[in,out] WorkSpace  Pointer to the input/output
> argument workspace
> +                            shared by all processors.
> +**/
> +STATIC
> +VOID
> +EFIAPI
> +ClearCache (
> +  IN OUT VOID *WorkSpace
> +  )
> +{
> +  WriteBackInvalidateDataCache ();
> +  InvalidateInstructionCache ();
> +}
> +
> +/**
> +  Notification function called when
> EFI_PEI_MP_SERVICES_PPI becomes available.
> +
> +  @param[in] PeiServices      Indirect reference to the
> PEI Services Table.
> +  @param[in] NotifyDescriptor Address of the
> notification descriptor data
> +                              structure.
> +  @param[in] Ppi              Address of the PPI that
> was installed.
> +
> +  @return  Status of the notification. The status code
> returned from this
> +           function is ignored.
> +**/
> +STATIC
> +EFI_STATUS
> +EFIAPI
> +ClearCacheOnMpServicesAvailable (
> +  IN EFI_PEI_SERVICES           **PeiServices,
> +  IN EFI_PEI_NOTIFY_DESCRIPTOR  *NotifyDescriptor,
> +  IN VOID                       *Ppi
> +  )
> +{
> +  EFI_PEI_MP_SERVICES_PPI *MpServices;
> +  EFI_STATUS              Status;
> +
> +  DEBUG ((DEBUG_INFO, "%a: %a\n", gEfiCallerBaseName,
> __FUNCTION__));
> +
> +  //
> +  // Clear cache on all the APs in parallel.
> +  //
> +  MpServices = Ppi;
> +  Status = MpServices->StartupAllAPs (
> +                         (CONST EFI_PEI_SERVICES
> **)PeiServices,
> +                         MpServices,
> +                         ClearCache,          //
> Procedure
> +                         FALSE,               //
> SingleThread
> +                         0,                   //
> TimeoutInMicroSeconds: inf.
> +                         NULL                 //
> ProcedureArgument
> +                         );
> +  if (EFI_ERROR (Status) && Status != EFI_NOT_STARTED)
> {
> +    DEBUG ((DEBUG_ERROR, "%a: StartupAllAps(): %r\n",
> __FUNCTION__, Status));
> +    return Status;
> +  }
> +
> +  //
> +  // Now clear cache on the BSP too.
> +  //
> +  ClearCache (NULL);
> +  return EFI_SUCCESS;
> +}
> +
> +//
> +// Notification object for registering the callback,
> for when
> +// EFI_PEI_MP_SERVICES_PPI becomes available.
> +//
> +STATIC CONST EFI_PEI_NOTIFY_DESCRIPTOR
> mMpServicesNotify = {
> +  EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK | // Flags
> +  EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST,
> +  &gEfiPeiMpServicesPpiGuid,               // Guid
> +  ClearCacheOnMpServicesAvailable          // Notify
> +};
> +
> +VOID
> +InstallClearCacheCallback (
> +  VOID
> +  )
> +{
> +  EFI_STATUS           Status;
> +
> +  Status = PeiServicesNotifyPpi (&mMpServicesNotify);
> +  if (EFI_ERROR (Status)) {
> +    DEBUG ((DEBUG_ERROR, "%a: failed to set up MP
> Services callback: %r\n",
> +      __FUNCTION__, Status));
> +  }
> +}
> diff --git a/OvmfPkg/PlatformPei/Platform.c
> b/OvmfPkg/PlatformPei/Platform.c
> index 5a78668126b4..22139a64cbf4 100644
> --- a/OvmfPkg/PlatformPei/Platform.c
> +++ b/OvmfPkg/PlatformPei/Platform.c
> @@ -672,6 +672,7 @@ InitializePlatform (
>      NoexecDxeInitialization ();
>    }
> 
> +  InstallClearCacheCallback ();
>    AmdSevInitialize ();
>    MiscInitialization ();
>    InstallFeatureControlCallback ();
> --
> 2.19.0.271.gfe8321ec05
> 
> _______________________________________________
> edk2-devel mailing list
> [email protected]
> https://lists.01.org/mailman/listinfo/edk2-devel
_______________________________________________
edk2-devel mailing list
[email protected]
https://lists.01.org/mailman/listinfo/edk2-devel

Reply via email to