]> git.proxmox.com Git - mirror_edk2.git/commitdiff
Revert "UefiCpuPkg: Has APs in 64 bit long-mode before booting to OS."
authorYuanhao Xie <yuanhao.xie@intel.com>
Mon, 9 Jan 2023 03:37:21 +0000 (11:37 +0800)
committermergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
Mon, 9 Jan 2023 17:53:41 +0000 (17:53 +0000)
This reverts commit 73ccde8f6d04a246377cabaed2875e69d4b6b719 since it
results in a hang of the IA32 processor and needs further clean-up.

Ref: https://bugzilla.tianocore.org/show_bug.cgi?id=4234
Cc: Eric Dong <eric.dong@intel.com>
Cc: Ray Ni <ray.ni@intel.com>
Cc: Rahul Kumar <rahul1.kumar@intel.com>
Cc: Gerd Hoffmann <kraxel@redhat.com>
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
Signed-off-by: Yuanhao Xie <yuanhao.xie@intel.com>
UefiCpuPkg/Library/MpInitLib/DxeMpInitLib.inf
UefiCpuPkg/Library/MpInitLib/DxeMpLib.c
UefiCpuPkg/Library/MpInitLib/Ia32/CreatePageTable.c [deleted file]
UefiCpuPkg/Library/MpInitLib/MpLib.h
UefiCpuPkg/Library/MpInitLib/X64/CreatePageTable.c [deleted file]
UefiCpuPkg/Library/MpInitLib/X64/MpFuncs.nasm
UefiCpuPkg/UefiCpuPkg.dsc

index 8c8b81d93379f6f6a8790cf3b91cdca5ead344c4..cd07de3a3c0bf8bb9c8b28b9d21cd0315fa78160 100644 (file)
@@ -1,7 +1,7 @@
 ## @file\r
 #  MP Initialize Library instance for DXE driver.\r
 #\r
-#  Copyright (c) 2016 - 2022, Intel Corporation. All rights reserved.<BR>\r
+#  Copyright (c) 2016 - 2021, Intel Corporation. All rights reserved.<BR>\r
 #  SPDX-License-Identifier: BSD-2-Clause-Patent\r
 #\r
 ##\r
 [Sources.IA32]\r
   Ia32/AmdSev.c\r
   Ia32/MpFuncs.nasm\r
-  Ia32/CreatePageTable.c\r
 \r
 [Sources.X64]\r
   X64/AmdSev.c\r
-  X64/CreatePageTable.c\r
   X64/MpFuncs.nasm\r
 \r
 [Sources.common]\r
@@ -59,9 +57,6 @@
   CcExitLib\r
   MicrocodeLib\r
 \r
-[LibraryClasses.X64]\r
-  CpuPageTableLib\r
-\r
 [Protocols]\r
   gEfiTimerArchProtocolGuid                     ## SOMETIMES_CONSUMES\r
 \r
index beab06a5b1874c983209377ffb3af2482d071bb2..445e0853d2fb4b90339b05fcf8a88240221c62f2 100644 (file)
@@ -28,7 +28,6 @@ volatile BOOLEAN  mStopCheckAllApsStatus       = TRUE;
 VOID              *mReservedApLoopFunc         = NULL;\r
 UINTN             mReservedTopOfApStack;\r
 volatile UINT32   mNumberToFinish = 0;\r
-UINTN             mApPageTable;\r
 \r
 //\r
 // Begin wakeup buffer allocation below 0x88000\r
@@ -408,9 +407,12 @@ RelocateApLoop (
     AsmRelocateApLoopFunc (\r
       MwaitSupport,\r
       CpuMpData->ApTargetCState,\r
+      CpuMpData->PmCodeSegment,\r
       StackStart - ProcessorNumber * AP_SAFE_STACK_SIZE,\r
       (UINTN)&mNumberToFinish,\r
-      mApPageTable\r
+      CpuMpData->Pm16CodeSegment,\r
+      CpuMpData->SevEsAPBuffer,\r
+      CpuMpData->WakeupBuffer\r
       );\r
   }\r
 \r
@@ -475,6 +477,7 @@ InitMpGlobalData (
   )\r
 {\r
   EFI_STATUS                       Status;\r
+  EFI_PHYSICAL_ADDRESS             Address;\r
   UINTN                            ApSafeBufferSize;\r
   UINTN                            Index;\r
   EFI_GCD_MEMORY_SPACE_DESCRIPTOR  MemDesc;\r
@@ -542,45 +545,60 @@ InitMpGlobalData (
   // Allocating it in advance since memory services are not available in\r
   // Exit Boot Services callback function.\r
   //\r
-  // +------------+\r
-  // | Ap Loop    |\r
-  // +------------+\r
-  // | Stack * N  |\r
-  // +------------+ (low address)\r
-  //\r
   ApSafeBufferSize = EFI_PAGES_TO_SIZE (\r
                        EFI_SIZE_TO_PAGES (\r
-                         CpuMpData->CpuCount * AP_SAFE_STACK_SIZE\r
-                         + CpuMpData->AddressMap.RelocateApLoopFuncSize\r
+                         CpuMpData->AddressMap.RelocateApLoopFuncSize\r
                          )\r
                        );\r
+  Address = BASE_4GB - 1;\r
+  Status  = gBS->AllocatePages (\r
+                   AllocateMaxAddress,\r
+                   EfiReservedMemoryType,\r
+                   EFI_SIZE_TO_PAGES (ApSafeBufferSize),\r
+                   &Address\r
+                   );\r
+  ASSERT_EFI_ERROR (Status);\r
 \r
-  mReservedTopOfApStack = (UINTN)AllocateReservedPages (EFI_SIZE_TO_PAGES (ApSafeBufferSize));\r
-  ASSERT (mReservedTopOfApStack != 0);\r
-  ASSERT ((mReservedTopOfApStack & (UINTN)(CPU_STACK_ALIGNMENT - 1)) == 0);\r
-  ASSERT ((AP_SAFE_STACK_SIZE & (CPU_STACK_ALIGNMENT - 1)) == 0);\r
-\r
-  mReservedApLoopFunc = (VOID *)(mReservedTopOfApStack + CpuMpData->CpuCount * AP_SAFE_STACK_SIZE);\r
-  if (StandardSignatureIsAuthenticAMD ()) {\r
-    CopyMem (\r
-      mReservedApLoopFunc,\r
-      CpuMpData->AddressMap.RelocateApLoopFuncAddressAmd,\r
-      CpuMpData->AddressMap.RelocateApLoopFuncSizeAmd\r
-      );\r
-  } else {\r
-    CopyMem (\r
-      mReservedApLoopFunc,\r
-      CpuMpData->AddressMap.RelocateApLoopFuncAddress,\r
-      CpuMpData->AddressMap.RelocateApLoopFuncSize\r
-      );\r
+  mReservedApLoopFunc = (VOID *)(UINTN)Address;\r
+  ASSERT (mReservedApLoopFunc != NULL);\r
 \r
-    mApPageTable = CreatePageTable (\r
-                     mReservedTopOfApStack,\r
-                     ApSafeBufferSize\r
-                     );\r
+  //\r
+  // Make sure that the buffer memory is executable if NX protection is enabled\r
+  // for EfiReservedMemoryType.\r
+  //\r
+  // TODO: Check EFI_MEMORY_XP bit set or not once it's available in DXE GCD\r
+  //       service.\r
+  //\r
+  Status = gDS->GetMemorySpaceDescriptor (Address, &MemDesc);\r
+  if (!EFI_ERROR (Status)) {\r
+    gDS->SetMemorySpaceAttributes (\r
+           Address,\r
+           ApSafeBufferSize,\r
+           MemDesc.Attributes & (~EFI_MEMORY_XP)\r
+           );\r
   }\r
 \r
-  mReservedTopOfApStack += CpuMpData->CpuCount * AP_SAFE_STACK_SIZE;\r
+  ApSafeBufferSize = EFI_PAGES_TO_SIZE (\r
+                       EFI_SIZE_TO_PAGES (\r
+                         CpuMpData->CpuCount * AP_SAFE_STACK_SIZE\r
+                         )\r
+                       );\r
+  Address = BASE_4GB - 1;\r
+  Status  = gBS->AllocatePages (\r
+                   AllocateMaxAddress,\r
+                   EfiReservedMemoryType,\r
+                   EFI_SIZE_TO_PAGES (ApSafeBufferSize),\r
+                   &Address\r
+                   );\r
+  ASSERT_EFI_ERROR (Status);\r
+\r
+  mReservedTopOfApStack = (UINTN)Address + ApSafeBufferSize;\r
+  ASSERT ((mReservedTopOfApStack & (UINTN)(CPU_STACK_ALIGNMENT - 1)) == 0);\r
+  CopyMem (\r
+    mReservedApLoopFunc,\r
+    CpuMpData->AddressMap.RelocateApLoopFuncAddress,\r
+    CpuMpData->AddressMap.RelocateApLoopFuncSize\r
+    );\r
 \r
   Status = gBS->CreateEvent (\r
                   EVT_TIMER | EVT_NOTIFY_SIGNAL,\r
diff --git a/UefiCpuPkg/Library/MpInitLib/Ia32/CreatePageTable.c b/UefiCpuPkg/Library/MpInitLib/Ia32/CreatePageTable.c
deleted file mode 100644 (file)
index 525885b..0000000
+++ /dev/null
@@ -1,27 +0,0 @@
-/** @file\r
-  Function to create page talbe.\r
-  Only create page table for x64, and leave the CreatePageTable empty for Ia32.\r
-\r
-  Copyright (c) 2022, Intel Corporation. All rights reserved.<BR>\r
-  SPDX-License-Identifier: BSD-2-Clause-Patent\r
-\r
-**/\r
-\r
-#include <Base.h>\r
-\r
-/**\r
-  Only create page table for x64, and leave the CreatePageTable empty for Ia32.\r
-\r
-  @param[in]      LinearAddress  The start of the linear address range.\r
-  @param[in]      Length         The length of the linear address range.\r
-\r
-  @return The page table to be created.\r
-**/\r
-UINTN\r
-CreatePageTable (\r
-  IN UINTN  Address,\r
-  IN UINTN  Length\r
-  )\r
-{\r
-  return 0;\r
-}\r
index 13d515c2df461c3023d9ca255c365ba93008cf5c..1102003a9318184f363d683ffc7e8064cf94821f 100644 (file)
@@ -392,9 +392,12 @@ typedef
 (EFIAPI *ASM_RELOCATE_AP_LOOP)(\r
   IN BOOLEAN                 MwaitSupport,\r
   IN UINTN                   ApTargetCState,\r
+  IN UINTN                   PmCodeSegment,\r
   IN UINTN                   TopOfApStack,\r
   IN UINTN                   NumberToFinish,\r
-  IN UINTN                   Cr3\r
+  IN UINTN                   Pm16CodeSegment,\r
+  IN UINTN                   SevEsAPJumpTable,\r
+  IN UINTN                   WakeupBuffer\r
   );\r
 \r
 /**\r
@@ -509,20 +512,6 @@ WakeUpAP (
   IN BOOLEAN           WakeUpDisabledAps\r
   );\r
 \r
-/**\r
-  Create 1:1 mapping page table in reserved memory to map the specified address range.\r
-\r
-  @param[in]      LinearAddress  The start of the linear address range.\r
-  @param[in]      Length         The length of the linear address range.\r
-\r
-  @return The page table to be created.\r
-**/\r
-UINTN\r
-CreatePageTable (\r
-  IN UINTN  Address,\r
-  IN UINTN  Length\r
-  );\r
-\r
 /**\r
   Initialize global data for MP support.\r
 \r
diff --git a/UefiCpuPkg/Library/MpInitLib/X64/CreatePageTable.c b/UefiCpuPkg/Library/MpInitLib/X64/CreatePageTable.c
deleted file mode 100644 (file)
index 548ef3f..0000000
+++ /dev/null
@@ -1,75 +0,0 @@
-/** @file\r
-  Function to create page talbe.\r
-  Only create page table for x64, and leave the CreatePageTable empty for Ia32.\r
-\r
-  Copyright (c) 2022, Intel Corporation. All rights reserved.<BR>\r
-  SPDX-License-Identifier: BSD-2-Clause-Patent\r
-\r
-**/\r
-#include <Library/CpuPageTableLib.h>\r
-#include <Library/MemoryAllocationLib.h>\r
-#include <Base.h>\r
-#include <Library/BaseMemoryLib.h>\r
-#include <Library/DebugLib.h>\r
-\r
-/**\r
-  Create 1:1 mapping page table in reserved memory to map the specified address range.\r
-\r
-  @param[in]      LinearAddress  The start of the linear address range.\r
-  @param[in]      Length         The length of the linear address range.\r
-\r
-  @return The page table to be created.\r
-**/\r
-UINTN\r
-CreatePageTable (\r
-  IN UINTN  Address,\r
-  IN UINTN  Length\r
-  )\r
-{\r
-  EFI_STATUS  Status;\r
-  VOID        *PageTableBuffer;\r
-  UINTN       PageTableBufferSize;\r
-  UINTN       PageTable;\r
-\r
-  IA32_MAP_ATTRIBUTE  MapAttribute;\r
-  IA32_MAP_ATTRIBUTE  MapMask;\r
-\r
-  MapAttribute.Uint64         = Address;\r
-  MapAttribute.Bits.Present   = 1;\r
-  MapAttribute.Bits.ReadWrite = 1;\r
-\r
-  MapMask.Bits.PageTableBaseAddress = 1;\r
-  MapMask.Bits.Present              = 1;\r
-  MapMask.Bits.ReadWrite            = 1;\r
-\r
-  PageTable           = 0;\r
-  PageTableBufferSize = 0;\r
-\r
-  Status = PageTableMap (\r
-             &PageTable,\r
-             Paging4Level,\r
-             NULL,\r
-             &PageTableBufferSize,\r
-             Address,\r
-             Length,\r
-             &MapAttribute,\r
-             &MapMask\r
-             );\r
-  ASSERT (Status == EFI_BUFFER_TOO_SMALL);\r
-  DEBUG ((DEBUG_INFO, "AP Page Table Buffer Size = %x\n", PageTableBufferSize));\r
-\r
-  PageTableBuffer = AllocateReservedPages (EFI_SIZE_TO_PAGES (PageTableBufferSize));\r
-  ASSERT (PageTableBuffer != NULL);\r
-  Status = PageTableMap (\r
-             &PageTable,\r
-             Paging4Level,\r
-             PageTableBuffer,\r
-             &PageTableBufferSize,\r
-             Address,\r
-             Length,\r
-             &MapAttribute,\r
-             &MapMask\r
-             );\r
-  ASSERT_EFI_ERROR (Status);\r
-  return PageTable;\r
-}\r
index 8ae287dd8d96b71338cb721d3ac8e9cbf7aa8fdb..39c3e8606a8391ddefadddd37c82a257043785fb 100644 (file)
@@ -279,42 +279,120 @@ CProcedureInvoke:
 RendezvousFunnelProcEnd:\r
 \r
 ;-------------------------------------------------------------------------------------\r
-;  AsmRelocateApLoop (MwaitSupport, ApTargetCState, TopOfApStack, CountTofinish, Cr3);\r
-;  This function is called during the finalizaiton of Mp initialization before booting\r
-;  to OS, and aim to put Aps either in Mwait or HLT.\r
+;  AsmRelocateApLoop (MwaitSupport, ApTargetCState, PmCodeSegment, TopOfApStack, CountTofinish, Pm16CodeSegment, SevEsAPJumpTable, WakeupBuffer);\r
 ;-------------------------------------------------------------------------------------\r
-; +----------------+\r
-; | Cr3            |  rsp+40\r
-; +----------------+\r
-; | CountTofinish  |  r9\r
-; +----------------+\r
-; | TopOfApStack   |  r8\r
-; +----------------+\r
-; | ApTargetCState |  rdx\r
-; +----------------+\r
-; | MwaitSupport   |  rcx\r
-; +----------------+\r
-; | the return     |\r
-; +----------------+ low address\r
-\r
 AsmRelocateApLoopStart:\r
-    mov        rax, r9           ; CountTofinish\r
+BITS 64\r
+    cmp        qword [rsp + 56], 0  ; SevEsAPJumpTable\r
+    je         NoSevEs\r
+\r
+    ;\r
+    ; Perform some SEV-ES related setup before leaving 64-bit mode\r
+    ;\r
+    push       rcx\r
+    push       rdx\r
+\r
+    ;\r
+    ; Get the RDX reset value using CPUID\r
+    ;\r
+    mov        rax, 1\r
+    cpuid\r
+    mov        rsi, rax          ; Save off the reset value for RDX\r
+\r
+    ;\r
+    ; Prepare the GHCB for the AP_HLT_LOOP VMGEXIT call\r
+    ;   - Must be done while in 64-bit long mode so that writes to\r
+    ;     the GHCB memory will be unencrypted.\r
+    ;   - No NAE events can be generated once this is set otherwise\r
+    ;     the AP_RESET_HOLD SW_EXITCODE will be overwritten.\r
+    ;\r
+    mov        rcx, 0xc0010130\r
+    rdmsr                        ; Retrieve current GHCB address\r
+    shl        rdx, 32\r
+    or         rdx, rax\r
+\r
+    mov        rdi, rdx\r
+    xor        rax, rax\r
+    mov        rcx, 0x800\r
+    shr        rcx, 3\r
+    rep stosq                    ; Clear the GHCB\r
+\r
+    mov        rax, 0x80000004   ; VMGEXIT AP_RESET_HOLD\r
+    mov        [rdx + 0x390], rax\r
+    mov        rax, 114          ; Set SwExitCode valid bit\r
+    bts        [rdx + 0x3f0], rax\r
+    inc        rax               ; Set SwExitInfo1 valid bit\r
+    bts        [rdx + 0x3f0], rax\r
+    inc        rax               ; Set SwExitInfo2 valid bit\r
+    bts        [rdx + 0x3f0], rax\r
+\r
+    pop        rdx\r
+    pop        rcx\r
+\r
+NoSevEs:\r
+    cli                          ; Disable interrupt before switching to 32-bit mode\r
+    mov        rax, [rsp + 40]   ; CountTofinish\r
     lock dec   dword [rax]       ; (*CountTofinish)--\r
 \r
-    mov        rax, [rsp + 40]    ; Cr3\r
-    ; Do not push on old stack, since old stack is not mapped\r
-    ; in the page table pointed by cr3\r
-    mov        cr3, rax\r
-    mov        rsp, r8            ; TopOfApStack\r
+    mov        r10, [rsp + 48]   ; Pm16CodeSegment\r
+    mov        rax, [rsp + 56]   ; SevEsAPJumpTable\r
+    mov        rbx, [rsp + 64]   ; WakeupBuffer\r
+    mov        rsp, r9           ; TopOfApStack\r
+\r
+    push       rax               ; Save SevEsAPJumpTable\r
+    push       rbx               ; Save WakeupBuffer\r
+    push       r10               ; Save Pm16CodeSegment\r
+    push       rcx               ; Save MwaitSupport\r
+    push       rdx               ; Save ApTargetCState\r
+\r
+    lea        rax, [PmEntry]    ; rax <- The start address of transition code\r
+\r
+    push       r8\r
+    push       rax\r
+\r
+    ;\r
+    ; Clear R8 - R15, for reset, before going into 32-bit mode\r
+    ;\r
+    xor        r8, r8\r
+    xor        r9, r9\r
+    xor        r10, r10\r
+    xor        r11, r11\r
+    xor        r12, r12\r
+    xor        r13, r13\r
+    xor        r14, r14\r
+    xor        r15, r15\r
+\r
+    ;\r
+    ; Far return into 32-bit mode\r
+    ;\r
+    retfq\r
+\r
+BITS 32\r
+PmEntry:\r
+    mov        eax, cr0\r
+    btr        eax, 31           ; Clear CR0.PG\r
+    mov        cr0, eax          ; Disable paging and caches\r
+\r
+    mov        ecx, 0xc0000080\r
+    rdmsr\r
+    and        ah, ~ 1           ; Clear LME\r
+    wrmsr\r
+    mov        eax, cr4\r
+    and        al, ~ (1 << 5)    ; Clear PAE\r
+    mov        cr4, eax\r
+\r
+    pop        edx\r
+    add        esp, 4\r
+    pop        ecx,\r
+    add        esp, 4\r
 \r
 MwaitCheck:\r
     cmp        cl, 1              ; Check mwait-monitor support\r
     jnz        HltLoop\r
-    mov        rbx, rdx           ; Save C-State to ebx\r
-\r
+    mov        ebx, edx           ; Save C-State to ebx\r
 MwaitLoop:\r
     cli\r
-    mov        rax, rsp           ; Set Monitor Address\r
+    mov        eax, esp           ; Set Monitor Address\r
     xor        ecx, ecx           ; ecx = 0\r
     xor        edx, edx           ; edx = 0\r
     monitor\r
@@ -324,10 +402,49 @@ MwaitLoop:
     jmp        MwaitLoop\r
 \r
 HltLoop:\r
+    pop        edx                ; PM16CodeSegment\r
+    add        esp, 4\r
+    pop        ebx                ; WakeupBuffer\r
+    add        esp, 4\r
+    pop        eax                ; SevEsAPJumpTable\r
+    add        esp, 4\r
+    cmp        eax, 0             ; Check for SEV-ES\r
+    je         DoHlt\r
+\r
+    cli\r
+    ;\r
+    ; SEV-ES is enabled, use VMGEXIT (GHCB information already\r
+    ; set by caller)\r
+    ;\r
+BITS 64\r
+    rep        vmmcall\r
+BITS 32\r
+\r
+    ;\r
+    ; Back from VMGEXIT AP_HLT_LOOP\r
+    ;   Push the FLAGS/CS/IP values to use\r
+    ;\r
+    push       word 0x0002        ; EFLAGS\r
+    xor        ecx, ecx\r
+    mov        cx, [eax + 2]      ; CS\r
+    push       cx\r
+    mov        cx, [eax]          ; IP\r
+    push       cx\r
+    push       word 0x0000        ; For alignment, will be discarded\r
+\r
+    push       edx\r
+    push       ebx\r
+\r
+    mov        edx, esi           ; Restore RDX reset value\r
+\r
+    retf\r
+\r
+DoHlt:\r
     cli\r
     hlt\r
-    jmp        HltLoop\r
+    jmp        DoHlt\r
 \r
+BITS 64\r
 AsmRelocateApLoopEnd:\r
 \r
 ;-------------------------------------------------------------------------------------\r
index 781acedfc516c9926b10ab93f37c3ecb1d325914..f9a46089d2c7fb2c8c228cdfa62ec5dbf489da59 100644 (file)
@@ -94,7 +94,6 @@
   MemoryAllocationLib|MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAllocationLib.inf\r
   HobLib|MdePkg/Library/DxeHobLib/DxeHobLib.inf\r
   CpuExceptionHandlerLib|UefiCpuPkg/Library/CpuExceptionHandlerLib/DxeCpuExceptionHandlerLib.inf\r
-  CpuPageTableLib|UefiCpuPkg/Library/CpuPageTableLib/CpuPageTableLib.inf\r
   MpInitLib|UefiCpuPkg/Library/MpInitLib/DxeMpInitLib.inf\r
   RegisterCpuFeaturesLib|UefiCpuPkg/Library/RegisterCpuFeaturesLib/DxeRegisterCpuFeaturesLib.inf\r
   CpuCacheInfoLib|UefiCpuPkg/Library/CpuCacheInfoLib/DxeCpuCacheInfoLib.inf\r