]> git.proxmox.com Git - mirror_edk2.git/blobdiff - UefiCpuPkg/PiSmmCpuDxeSmm/MpService.c
UefiCpuPkg/PiSmmCpuDxeSmm: Check ProcessorId == INVALID_APIC_ID
[mirror_edk2.git] / UefiCpuPkg / PiSmmCpuDxeSmm / MpService.c
index 01ddaee4e71bd7e8b9e4e66216d667100e87abc7..4ac5e8e26462b146919047a61c6767e3e377585e 100644 (file)
@@ -1,7 +1,9 @@
 /** @file\r
 SMM MP service implementation\r
 \r
-Copyright (c) 2009 - 2016, Intel Corporation. All rights reserved.<BR>\r
+Copyright (c) 2009 - 2017, Intel Corporation. All rights reserved.<BR>\r
+Copyright (c) 2017, AMD Incorporated. All rights reserved.<BR>\r
+\r
 This program and the accompanying materials\r
 are licensed and made available under the terms and conditions of the BSD License\r
 which accompanies this distribution.  The full text of the license may be found at\r
@@ -405,7 +407,7 @@ BSPHandler (
   //\r
   // The BUSY lock is initialized to Acquired state\r
   //\r
-  AcquireSpinLockOrFail (mSmmMpSyncData->CpuData[CpuIndex].Busy);\r
+  AcquireSpinLock (mSmmMpSyncData->CpuData[CpuIndex].Busy);\r
 \r
   //\r
   // Perform the pre tasks\r
@@ -781,7 +783,8 @@ Gen4GPageTable (
   // Set Page Directory Pointers\r
   //\r
   for (Index = 0; Index < 4; Index++) {\r
-    Pte[Index] = (UINTN)PageTable + EFI_PAGE_SIZE * (Index + 1) + (Is32BitPageTable ? IA32_PAE_PDPTE_ATTRIBUTE_BITS : PAGE_ATTRIBUTE_BITS);\r
+    Pte[Index] = ((UINTN)PageTable + EFI_PAGE_SIZE * (Index + 1)) | mAddressEncMask |\r
+                   (Is32BitPageTable ? IA32_PAE_PDPTE_ATTRIBUTE_BITS : PAGE_ATTRIBUTE_BITS);\r
   }\r
   Pte += EFI_PAGE_SIZE / sizeof (*Pte);\r
 \r
@@ -789,7 +792,7 @@ Gen4GPageTable (
   // Fill in Page Directory Entries\r
   //\r
   for (Index = 0; Index < EFI_PAGE_SIZE * 4 / sizeof (*Pte); Index++) {\r
-    Pte[Index] = (Index << 21) | IA32_PG_PS | PAGE_ATTRIBUTE_BITS;\r
+    Pte[Index] = (Index << 21) | mAddressEncMask | IA32_PG_PS | PAGE_ATTRIBUTE_BITS;\r
   }\r
 \r
   if (FeaturePcdGet (PcdCpuSmmStackGuard)) {\r
@@ -797,8 +800,8 @@ Gen4GPageTable (
     GuardPage = mSmmStackArrayBase + EFI_PAGE_SIZE;\r
     Pdpte = (UINT64*)PageTable;\r
     for (PageIndex = Low2MBoundary; PageIndex <= High2MBoundary; PageIndex += SIZE_2MB) {\r
-      Pte = (UINT64*)(UINTN)(Pdpte[BitFieldRead32 ((UINT32)PageIndex, 30, 31)] & ~(EFI_PAGE_SIZE - 1));\r
-      Pte[BitFieldRead32 ((UINT32)PageIndex, 21, 29)] = (UINT64)Pages | PAGE_ATTRIBUTE_BITS;\r
+      Pte = (UINT64*)(UINTN)(Pdpte[BitFieldRead32 ((UINT32)PageIndex, 30, 31)] & ~mAddressEncMask & ~(EFI_PAGE_SIZE - 1));\r
+      Pte[BitFieldRead32 ((UINT32)PageIndex, 21, 29)] = (UINT64)Pages | mAddressEncMask | PAGE_ATTRIBUTE_BITS;\r
       //\r
       // Fill in Page Table Entries\r
       //\r
@@ -809,13 +812,13 @@ Gen4GPageTable (
           //\r
           // Mark the guard page as non-present\r
           //\r
-          Pte[Index] = PageAddress;\r
+          Pte[Index] = PageAddress | mAddressEncMask;\r
           GuardPage += mSmmStackSize;\r
           if (GuardPage > mSmmStackArrayEnd) {\r
             GuardPage = 0;\r
           }\r
         } else {\r
-          Pte[Index] = PageAddress | PAGE_ATTRIBUTE_BITS;\r
+          Pte[Index] = PageAddress | mAddressEncMask | PAGE_ATTRIBUTE_BITS;\r
         }\r
         PageAddress+= EFI_PAGE_SIZE;\r
       }\r
@@ -826,80 +829,12 @@ Gen4GPageTable (
   return (UINT32)(UINTN)PageTable;\r
 }\r
 \r
-/**\r
-  Set memory cache ability.\r
-\r
-  @param    PageTable              PageTable Address\r
-  @param    Address                Memory Address to change cache ability\r
-  @param    Cacheability           Cache ability to set\r
-\r
-**/\r
-VOID\r
-SetCacheability (\r
-  IN      UINT64                    *PageTable,\r
-  IN      UINTN                     Address,\r
-  IN      UINT8                     Cacheability\r
-  )\r
-{\r
-  UINTN   PTIndex;\r
-  VOID    *NewPageTableAddress;\r
-  UINT64  *NewPageTable;\r
-  UINTN   Index;\r
-\r
-  ASSERT ((Address & EFI_PAGE_MASK) == 0);\r
-\r
-  if (sizeof (UINTN) == sizeof (UINT64)) {\r
-    PTIndex = (UINTN)RShiftU64 (Address, 39) & 0x1ff;\r
-    ASSERT (PageTable[PTIndex] & IA32_PG_P);\r
-    PageTable = (UINT64*)(UINTN)(PageTable[PTIndex] & gPhyMask);\r
-  }\r
-\r
-  PTIndex = (UINTN)RShiftU64 (Address, 30) & 0x1ff;\r
-  ASSERT (PageTable[PTIndex] & IA32_PG_P);\r
-  PageTable = (UINT64*)(UINTN)(PageTable[PTIndex] & gPhyMask);\r
-\r
-  //\r
-  // A perfect implementation should check the original cacheability with the\r
-  // one being set, and break a 2M page entry into pieces only when they\r
-  // disagreed.\r
-  //\r
-  PTIndex = (UINTN)RShiftU64 (Address, 21) & 0x1ff;\r
-  if ((PageTable[PTIndex] & IA32_PG_PS) != 0) {\r
-    //\r
-    // Allocate a page from SMRAM\r
-    //\r
-    NewPageTableAddress = AllocatePageTableMemory (1);\r
-    ASSERT (NewPageTableAddress != NULL);\r
-\r
-    NewPageTable = (UINT64 *)NewPageTableAddress;\r
-\r
-    for (Index = 0; Index < 0x200; Index++) {\r
-      NewPageTable[Index] = PageTable[PTIndex];\r
-      if ((NewPageTable[Index] & IA32_PG_PAT_2M) != 0) {\r
-        NewPageTable[Index] &= ~((UINT64)IA32_PG_PAT_2M);\r
-        NewPageTable[Index] |= (UINT64)IA32_PG_PAT_4K;\r
-      }\r
-      NewPageTable[Index] |= (UINT64)(Index << EFI_PAGE_SHIFT);\r
-    }\r
-\r
-    PageTable[PTIndex] = ((UINTN)NewPageTableAddress & gPhyMask) | PAGE_ATTRIBUTE_BITS;\r
-  }\r
-\r
-  ASSERT (PageTable[PTIndex] & IA32_PG_P);\r
-  PageTable = (UINT64*)(UINTN)(PageTable[PTIndex] & gPhyMask);\r
-\r
-  PTIndex = (UINTN)RShiftU64 (Address, 12) & 0x1ff;\r
-  ASSERT (PageTable[PTIndex] & IA32_PG_P);\r
-  PageTable[PTIndex] &= ~((UINT64)((IA32_PG_PAT_4K | IA32_PG_CD | IA32_PG_WT)));\r
-  PageTable[PTIndex] |= (UINT64)Cacheability;\r
-}\r
-\r
 /**\r
   Schedule a procedure to run on the specified CPU.\r
 \r
   @param[in]       Procedure                The address of the procedure to run\r
   @param[in]       CpuIndex                 Target CPU Index\r
-  @param[in, OUT]  ProcArguments            The parameter to pass to the procedure\r
+  @param[in, out]  ProcArguments            The parameter to pass to the procedure\r
   @param[in]       BlockingMode             Startup AP in blocking mode or not\r
 \r
   @retval EFI_INVALID_PARAMETER    CpuNumber not valid\r
@@ -925,6 +860,9 @@ InternalSmmStartupThisAp (
     DEBUG((DEBUG_ERROR, "CpuIndex(%d) == gSmmCpuPrivate->SmmCoreEntryContext.CurrentlyExecutingCpu\n", CpuIndex));\r
     return EFI_INVALID_PARAMETER;\r
   }\r
+  if (gSmmCpuPrivate->ProcessorInfo[CpuIndex].ProcessorId == INVALID_APIC_ID) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
   if (!(*(mSmmMpSyncData->CpuData[CpuIndex].Present))) {\r
     if (mSmmMpSyncData->EffectiveSyncMode == SmmCpuSyncModeTradition) {\r
       DEBUG((DEBUG_ERROR, "!mSmmMpSyncData->CpuData[%d].Present\n", CpuIndex));\r
@@ -1371,7 +1309,6 @@ InitializeMpServiceData (
 {\r
   UINT32                    Cr3;\r
   UINTN                     Index;\r
-  PROCESSOR_SMM_DESCRIPTOR  *Psd;\r
   UINT8                     *GdtTssTables;\r
   UINTN                     GdtTableStepSize;\r
 \r
@@ -1406,24 +1343,16 @@ InitializeMpServiceData (
   GdtTssTables = InitGdt (Cr3, &GdtTableStepSize);\r
 \r
   //\r
-  // Initialize PROCESSOR_SMM_DESCRIPTOR for each CPU\r
+  // Install SMI handler for each CPU\r
   //\r
   for (Index = 0; Index < mMaxNumberOfCpus; Index++) {\r
-    Psd = (PROCESSOR_SMM_DESCRIPTOR *)(VOID *)(UINTN)(mCpuHotPlugData.SmBase[Index] + SMM_PSD_OFFSET);\r
-    CopyMem (Psd, &gcPsd, sizeof (gcPsd));\r
-    Psd->SmmGdtPtr = (UINT64)(UINTN)(GdtTssTables + GdtTableStepSize * Index);\r
-    Psd->SmmGdtSize = gcSmiGdtr.Limit + 1;\r
-\r
-    //\r
-    // Install SMI handler\r
-    //\r
     InstallSmiHandler (\r
       Index,\r
       (UINT32)mCpuHotPlugData.SmBase[Index],\r
       (VOID*)((UINTN)Stacks + (StackSize * Index)),\r
       StackSize,\r
-      (UINTN)Psd->SmmGdtPtr,\r
-      Psd->SmmGdtSize,\r
+      (UINTN)(GdtTssTables + GdtTableStepSize * Index),\r
+      gcSmiGdtr.Limit + 1,\r
       gcSmiIdtr.Base,\r
       gcSmiIdtr.Limit + 1,\r
       Cr3\r