]> git.proxmox.com Git - mirror_edk2.git/blobdiff - UefiCpuPkg/PiSmmCpuDxeSmm/SmmProfile.c
UefiCpuPkg/PiSmmCpuDxeSmm: fix infinite loop issue in SMM profile
[mirror_edk2.git] / UefiCpuPkg / PiSmmCpuDxeSmm / SmmProfile.c
index 9588eaf02964b175d029cac637664691226d2186..c90167f160608fa79bafd663cfb90909181f8052 100644 (file)
@@ -1302,6 +1302,8 @@ SmmProfilePFHandler (
 {\r
   UINT64                *PageTable;\r
   UINT64                PFAddress;\r
+  UINT64                RestoreAddress;\r
+  UINTN                 RestorePageNumber;\r
   UINTN                 CpuIndex;\r
   UINTN                 Index;\r
   UINT64                InstructionAddress;\r
@@ -1331,10 +1333,21 @@ SmmProfilePFHandler (
   PFAddress         = AsmReadCr2 ();\r
   CpuIndex          = GetCpuIndex ();\r
 \r
-  if (PFAddress <= 0xFFFFFFFF) {\r
-    RestorePageTableBelow4G (PageTable, PFAddress, CpuIndex, ErrorCode);\r
-  } else {\r
-    RestorePageTableAbove4G (PageTable, PFAddress, CpuIndex, ErrorCode, &IsValidPFAddress);\r
+  //\r
+  // Memory operation cross pages, like "rep mov" instruction, will cause\r
+  // infinite loop between this and Debug Trap handler. We have to make sure\r
+  // that current page and the page followed are both in PRESENT state.\r
+  //\r
+  RestorePageNumber = 2;\r
+  RestoreAddress = PFAddress;\r
+  while (RestorePageNumber > 0) {\r
+    if (RestoreAddress <= 0xFFFFFFFF) {\r
+      RestorePageTableBelow4G (PageTable, RestoreAddress, CpuIndex, ErrorCode);\r
+    } else {\r
+      RestorePageTableAbove4G (PageTable, RestoreAddress, CpuIndex, ErrorCode, &IsValidPFAddress);\r
+    }\r
+    RestoreAddress += EFI_PAGE_SIZE;\r
+    RestorePageNumber--;\r
   }\r
 \r
   if (!IsValidPFAddress) {\r