ClearCache.c 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116
  1. /**@file
  2. Install a callback to clear cache on all processors.
  3. This is for conformance with the TCG "Platform Reset Attack Mitigation
  4. Specification". Because clearing the CPU caches at boot doesn't impact
  5. performance significantly, do it unconditionally, for simplicity's
  6. sake.
  7. Copyright (C) 2018, Red Hat, Inc.
  8. Copyright (c) 2019, Citrix Systems, Inc.
  9. SPDX-License-Identifier: BSD-2-Clause-Patent
  10. **/
  11. #include <Library/CacheMaintenanceLib.h>
  12. #include <Library/DebugLib.h>
  13. #include <Library/PeiServicesLib.h>
  14. #include <Ppi/MpServices.h>
  15. #include "Platform.h"
  16. /**
  17. Invalidate data & instruction caches.
  18. All APs execute this function in parallel. The BSP executes the function
  19. separately.
  20. @param[in,out] WorkSpace Pointer to the input/output argument workspace
  21. shared by all processors.
  22. **/
  23. STATIC
  24. VOID
  25. EFIAPI
  26. ClearCache (
  27. IN OUT VOID *WorkSpace
  28. )
  29. {
  30. WriteBackInvalidateDataCache ();
  31. InvalidateInstructionCache ();
  32. }
  33. /**
  34. Notification function called when EFI_PEI_MP_SERVICES_PPI becomes available.
  35. @param[in] PeiServices Indirect reference to the PEI Services Table.
  36. @param[in] NotifyDescriptor Address of the notification descriptor data
  37. structure.
  38. @param[in] Ppi Address of the PPI that was installed.
  39. @return Status of the notification. The status code returned from this
  40. function is ignored.
  41. **/
  42. STATIC
  43. EFI_STATUS
  44. EFIAPI
  45. ClearCacheOnMpServicesAvailable (
  46. IN EFI_PEI_SERVICES **PeiServices,
  47. IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor,
  48. IN VOID *Ppi
  49. )
  50. {
  51. EFI_PEI_MP_SERVICES_PPI *MpServices;
  52. EFI_STATUS Status;
  53. DEBUG ((DEBUG_INFO, "%a: %a\n", gEfiCallerBaseName, __FUNCTION__));
  54. //
  55. // Clear cache on all the APs in parallel.
  56. //
  57. MpServices = Ppi;
  58. Status = MpServices->StartupAllAPs (
  59. (CONST EFI_PEI_SERVICES **)PeiServices,
  60. MpServices,
  61. ClearCache, // Procedure
  62. FALSE, // SingleThread
  63. 0, // TimeoutInMicroSeconds: inf.
  64. NULL // ProcedureArgument
  65. );
  66. if (EFI_ERROR (Status) && (Status != EFI_NOT_STARTED)) {
  67. DEBUG ((DEBUG_ERROR, "%a: StartupAllAps(): %r\n", __FUNCTION__, Status));
  68. return Status;
  69. }
  70. //
  71. // Now clear cache on the BSP too.
  72. //
  73. ClearCache (NULL);
  74. return EFI_SUCCESS;
  75. }
  76. //
  77. // Notification object for registering the callback, for when
  78. // EFI_PEI_MP_SERVICES_PPI becomes available.
  79. //
  80. STATIC CONST EFI_PEI_NOTIFY_DESCRIPTOR mMpServicesNotify = {
  81. EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK | // Flags
  82. EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST,
  83. &gEfiPeiMpServicesPpiGuid, // Guid
  84. ClearCacheOnMpServicesAvailable // Notify
  85. };
  86. VOID
  87. InstallClearCacheCallback (
  88. VOID
  89. )
  90. {
  91. EFI_STATUS Status;
  92. Status = PeiServicesNotifyPpi (&mMpServicesNotify);
  93. if (EFI_ERROR (Status)) {
  94. DEBUG ((
  95. DEBUG_ERROR,
  96. "%a: failed to set up MP Services callback: %r\n",
  97. __FUNCTION__,
  98. Status
  99. ));
  100. }
  101. }