]> git.proxmox.com Git - mirror_edk2.git/commitdiff
ArmPlatformPkg/PrePeiCore: replace set/way cache ops with by-VA ones
authorArd Biesheuvel <ard.biesheuvel@arm.com>
Fri, 21 Feb 2020 10:30:31 +0000 (11:30 +0100)
committermergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
Wed, 4 Mar 2020 17:42:43 +0000 (17:42 +0000)
Cache maintenance operations by set/way are only intended to be used
in the context of on/offlining a core, while it has been taken out of
the coherency domain. Any use intended to ensure that the contents of
the cache have made it to main memory is unreliable, since cacheline
migration and non-architected system caches may cause these contents
to linger elsewhere, without being visible in main memory once the
MMU and caches are disabled.

In KVM on Linux, there are horrid hacks in place to ensure that such
set/way operations are trapped, and replaced with a single by-VA
clean/invalidate of the entire guest VA space once the MMU state
changes, which can be costly, and is unnecessary if we manage the
caches a bit more carefully, and perform maintenance by virtual
address only.

So let's get rid of the call to ArmInvalidateDataCache () in the
PrePeiCore startup code, and instead, invalidate the temporary RAM
region by virtual address, which is the only memory region we will
be touching with the caches and MMU both disabled and enabled,
which will lead to data corruption if data written with the MMU off
is shadowed by clean, stale cachelines that stick around when the
MMU is enabled again.

Signed-off-by: Ard Biesheuvel <ard.biesheuvel@arm.com>
Reviewed-by: Leif Lindholm <leif@nuviainc.com>
Acked-by: Laszlo Ersek <lersek@redhat.com>
ArmPlatformPkg/PrePeiCore/PrePeiCore.c
ArmPlatformPkg/PrePeiCore/PrePeiCoreMPCore.inf
ArmPlatformPkg/PrePeiCore/PrePeiCoreUniCore.inf

index 4f691d62cf3bce415f052f4e694813f2e562f26f..5202aa641ecdb4a2a61fe0ac53b2f923c145808f 100644 (file)
@@ -8,6 +8,7 @@
 **/\r
 \r
 #include <Library/BaseLib.h>\r
+#include <Library/CacheMaintenanceLib.h>\r
 #include <Library/DebugAgentLib.h>\r
 #include <Library/ArmLib.h>\r
 \r
@@ -59,13 +60,14 @@ CEntryPoint (
 {\r
   // Data Cache enabled on Primary core when MMU is enabled.\r
   ArmDisableDataCache ();\r
-  // Invalidate Data cache\r
-  ArmInvalidateDataCache ();\r
   // Invalidate instruction cache\r
   ArmInvalidateInstructionCache ();\r
   // Enable Instruction Caches on all cores.\r
   ArmEnableInstructionCache ();\r
 \r
+  InvalidateDataCacheRange ((VOID *)(UINTN)PcdGet64 (PcdCPUCoresStackBase),\r
+                            PcdGet32 (PcdCPUCorePrimaryStackSize));\r
+\r
   //\r
   // Note: Doesn't have to Enable CPU interface in non-secure world,\r
   // as Non-secure interface is already enabled in Secure world.\r
index 104c7da53317b80042398f98c86203bb9ce00a98..fb01dd1a113e2d05568340e6a7d9c6e88cde10fb 100644 (file)
@@ -44,6 +44,7 @@
 [LibraryClasses]\r
   ArmLib\r
   ArmPlatformLib\r
+  CacheMaintenanceLib\r
   BaseLib\r
   DebugLib\r
   DebugAgentLib\r
index ceb173d34f5dff0f4f17c12bed3e819b76cf349a..e9eb092d3ac93d44d15341ee83a4c997159a9f18 100644 (file)
@@ -44,6 +44,7 @@
 [LibraryClasses]\r
   ArmLib\r
   ArmPlatformLib\r
+  CacheMaintenanceLib\r
   BaseLib\r
   DebugLib\r
   DebugAgentLib\r