ClearCache.c 3.2 KB

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