VirtualBox

Ignore:
Timestamp:
Mar 31, 2025 11:31:09 AM (2 weeks ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
168237
Message:

Devices/EFI/FirmwareNew: Merge edk2-stable202502 from the vendor branch and make it build for the important platforms, bugref:4643

Location:
trunk/src/VBox/Devices/EFI/FirmwareNew
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Devices/EFI/FirmwareNew

  • trunk/src/VBox/Devices/EFI/FirmwareNew/UefiCpuPkg/Library/MpInitLib/DxeMpLib.c

    r101291 r108794  
    22  MP initialize support functions for DXE phase.
    33
    4   Copyright (c) 2016 - 2023, Intel Corporation. All rights reserved.<BR>
     4  Copyright (c) 2016 - 2024, Intel Corporation. All rights reserved.<BR>
     5  Copyright (c) 2024, AMD Inc. All rights reserved.<BR>
    56  SPDX-License-Identifier: BSD-2-Clause-Patent
    67
     
    1415#include <Library/DxeServicesTableLib.h>
    1516#include <Library/CcExitLib.h>
    16 #include <Register/Amd/Fam17Msr.h>
     17#include <Register/Amd/SevSnpMsr.h>
    1718#include <Register/Amd/Ghcb.h>
    1819
     
    2122#define  AP_SAFE_STACK_SIZE  128
    2223
    23 CPU_MP_DATA             *mCpuMpData                  = NULL;
    24 EFI_EVENT               mCheckAllApsEvent            = NULL;
    25 EFI_EVENT               mMpInitExitBootServicesEvent = NULL;
    26 EFI_EVENT               mLegacyBootEvent             = NULL;
    27 volatile BOOLEAN        mStopCheckAllApsStatus       = TRUE;
    28 RELOCATE_AP_LOOP_ENTRY  mReservedApLoop;
    29 UINTN                   mReservedTopOfApStack;
    30 volatile UINT32         mNumberToFinish = 0;
    31 UINTN                   mApPageTable;
     24CPU_MP_DATA       *mCpuMpData                  = NULL;
     25EFI_EVENT         mCheckAllApsEvent            = NULL;
     26EFI_EVENT         mMpInitExitBootServicesEvent = NULL;
     27EFI_EVENT         mLegacyBootEvent             = NULL;
     28volatile BOOLEAN  mStopCheckAllApsStatus       = TRUE;
    3229
    3330//
     
    317314  IA32_SEGMENT_DESCRIPTOR  *GdtEntry;
    318315  UINTN                    GdtEntryCount;
    319   UINT16                   Index;
     316  UINTN                    Index;
     317  UINT16                   CodeSegmentValue;
     318  EFI_STATUS               Status;
    320319
    321320  Index = (UINT16)-1;
     
    333332  }
    334333
    335   ASSERT (Index != GdtEntryCount);
    336   return Index * 8;
     334  Status = SafeUintnToUint16 (Index, &CodeSegmentValue);
     335  if (EFI_ERROR (Status)) {
     336    ASSERT_EFI_ERROR (Status);
     337    return 0;
     338  }
     339
     340  Status = SafeUint16Mult (CodeSegmentValue, 8, &CodeSegmentValue);
     341  if (EFI_ERROR (Status)) {
     342    ASSERT_EFI_ERROR (Status);
     343    return 0;
     344  }
     345
     346  return CodeSegmentValue;
    337347}
    338348
     
    350360  IA32_SEGMENT_DESCRIPTOR  *GdtEntry;
    351361  UINTN                    GdtEntryCount;
    352   UINT16                   Index;
     362  UINTN                    Index;
     363  UINT16                   CodeSegmentValue;
     364  EFI_STATUS               Status;
    353365
    354366  AsmReadGdtr (&GdtrDesc);
     
    365377  }
    366378
    367   ASSERT (Index != GdtEntryCount);
    368   return Index * 8;
    369 }
    370 
    371 /**
    372   Do sync on APs.
    373 
    374   @param[in, out] Buffer  Pointer to private data buffer.
     379  Status = SafeUintnToUint16 (Index, &CodeSegmentValue);
     380  if (EFI_ERROR (Status)) {
     381    ASSERT_EFI_ERROR (Status);
     382    return 0;
     383  }
     384
     385  Status = SafeUint16Mult (CodeSegmentValue, 8, &CodeSegmentValue);
     386  if (EFI_ERROR (Status)) {
     387    ASSERT_EFI_ERROR (Status);
     388    return 0;
     389  }
     390
     391  return CodeSegmentValue;
     392}
     393
     394/**
     395  Allocate buffer for ApLoopCode.
     396
     397  @param[in]      Pages    Number of pages to allocate.
     398  @param[in, out] Address  Pointer to the allocated buffer.
    375399**/
    376400VOID
    377 EFIAPI
    378 RelocateApLoop (
    379   IN OUT VOID  *Buffer
    380   )
    381 {
    382   CPU_MP_DATA  *CpuMpData;
    383   BOOLEAN      MwaitSupport;
    384   UINTN        ProcessorNumber;
    385   UINTN        StackStart;
    386 
    387   MpInitLibWhoAmI (&ProcessorNumber);
    388   CpuMpData    = GetCpuMpData ();
    389   MwaitSupport = IsMwaitSupport ();
    390   if (CpuMpData->UseSevEsAPMethod) {
    391     //
    392     // 64-bit AMD processors with SEV-ES
    393     //
    394     StackStart = CpuMpData->SevEsAPResetStackStart;
    395     mReservedApLoop.AmdSevEntry (
    396                       MwaitSupport,
    397                       CpuMpData->ApTargetCState,
    398                       CpuMpData->PmCodeSegment,
    399                       StackStart - ProcessorNumber * AP_SAFE_STACK_SIZE,
    400                       (UINTN)&mNumberToFinish,
    401                       CpuMpData->Pm16CodeSegment,
    402                       CpuMpData->SevEsAPBuffer,
    403                       CpuMpData->WakeupBuffer
    404                       );
    405   } else {
    406     //
    407     // Intel processors (32-bit or 64-bit), 32-bit AMD processors, or 64-bit AMD processors without SEV-ES
    408     //
    409     StackStart = mReservedTopOfApStack;
    410     mReservedApLoop.GenericEntry (
    411                       MwaitSupport,
    412                       CpuMpData->ApTargetCState,
    413                       StackStart - ProcessorNumber * AP_SAFE_STACK_SIZE,
    414                       (UINTN)&mNumberToFinish,
    415                       mApPageTable
    416                       );
    417   }
    418 
    419   //
    420   // It should never reach here
    421   //
    422   ASSERT (FALSE);
     401AllocateApLoopCodeBuffer (
     402  IN UINTN                     Pages,
     403  IN OUT EFI_PHYSICAL_ADDRESS  *Address
     404  )
     405{
     406  EFI_STATUS  Status;
     407
     408  Status = gBS->AllocatePages (
     409                  AllocateMaxAddress,
     410                  EfiReservedMemoryType,
     411                  Pages,
     412                  Address
     413                  );
     414  ASSERT_EFI_ERROR (Status);
     415}
     416
     417/**
     418  Remove Nx protection for the range specific by BaseAddress and Length.
     419
     420  The PEI implementation uses CpuPageTableLib to change the attribute.
     421  The DXE implementation uses gDS to change the attribute.
     422
     423  @param[in] BaseAddress  BaseAddress of the range.
     424  @param[in] Length       Length of the range.
     425**/
     426VOID
     427RemoveNxprotection (
     428  IN EFI_PHYSICAL_ADDRESS  BaseAddress,
     429  IN UINTN                 Length
     430  )
     431{
     432  EFI_STATUS                       Status;
     433  EFI_GCD_MEMORY_SPACE_DESCRIPTOR  MemDesc;
     434
     435  //
     436  // TODO: Check EFI_MEMORY_XP bit set or not once it's available in DXE GCD
     437  //       service.
     438  //
     439  Status = gDS->GetMemorySpaceDescriptor (BaseAddress, &MemDesc);
     440  if (!EFI_ERROR (Status)) {
     441    gDS->SetMemorySpaceAttributes (
     442           BaseAddress,
     443           Length,
     444           MemDesc.Attributes & (~EFI_MEMORY_XP)
     445           );
     446  }
    423447}
    424448
     
    478502{
    479503  EFI_STATUS                       Status;
    480   EFI_PHYSICAL_ADDRESS             Address;
    481504  UINTN                            Index;
    482505  EFI_GCD_MEMORY_SPACE_DESCRIPTOR  MemDesc;
    483506  UINTN                            StackBase;
    484507  CPU_INFO_IN_HOB                  *CpuInfoInHob;
    485   MP_ASSEMBLY_ADDRESS_MAP          *AddressMap;
    486   UINT8                            *ApLoopFunc;
    487   UINTN                            ApLoopFuncSize;
    488   UINTN                            StackPages;
    489   UINTN                            FuncPages;
    490508
    491509  SaveCpuMpData (CpuMpData);
     
    542560  }
    543561
    544   AddressMap = &CpuMpData->AddressMap;
    545   if (CpuMpData->UseSevEsAPMethod) {
    546     //
    547     // 64-bit AMD processors with SEV-ES
    548     //
    549     Address        = BASE_4GB - 1;
    550     ApLoopFunc     = AddressMap->RelocateApLoopFuncAddressAmdSev;
    551     ApLoopFuncSize = AddressMap->RelocateApLoopFuncSizeAmdSev;
    552   } else {
    553     //
    554     // Intel processors (32-bit or 64-bit), 32-bit AMD processors, or 64-bit AMD processors without SEV-ES
    555     //
    556     Address        = MAX_ADDRESS;
    557     ApLoopFunc     = AddressMap->RelocateApLoopFuncAddressGeneric;
    558     ApLoopFuncSize = AddressMap->RelocateApLoopFuncSizeGeneric;
    559   }
    560 
    561   //
    562   // Avoid APs access invalid buffer data which allocated by BootServices,
    563   // so we will allocate reserved data for AP loop code. We also need to
    564   // allocate this buffer below 4GB due to APs may be transferred to 32bit
    565   // protected mode on long mode DXE.
    566   // Allocating it in advance since memory services are not available in
    567   // Exit Boot Services callback function.
    568   //
    569   // +------------+ (TopOfApStack)
    570   // |  Stack * N |
    571   // +------------+ (stack base, 4k aligned)
    572   // |  Padding   |
    573   // +------------+
    574   // |  Ap Loop   |
    575   // +------------+ ((low address, 4k-aligned)
    576   //
    577 
    578   StackPages = EFI_SIZE_TO_PAGES (CpuMpData->CpuCount * AP_SAFE_STACK_SIZE);
    579   FuncPages  = EFI_SIZE_TO_PAGES (ApLoopFuncSize);
    580 
    581   Status = gBS->AllocatePages (
    582                   AllocateMaxAddress,
    583                   EfiReservedMemoryType,
    584                   StackPages + FuncPages,
    585                   &Address
    586                   );
    587   ASSERT_EFI_ERROR (Status);
    588 
    589   //
    590   // Make sure that the buffer memory is executable if NX protection is enabled
    591   // for EfiReservedMemoryType.
    592   //
    593   // TODO: Check EFI_MEMORY_XP bit set or not once it's available in DXE GCD
    594   //       service.
    595   //
    596   Status = gDS->GetMemorySpaceDescriptor (Address, &MemDesc);
    597   if (!EFI_ERROR (Status)) {
    598     gDS->SetMemorySpaceAttributes (
    599            Address,
    600            EFI_PAGES_TO_SIZE (FuncPages),
    601            MemDesc.Attributes & (~EFI_MEMORY_XP)
    602            );
    603   }
    604 
    605   mReservedTopOfApStack = (UINTN)Address + EFI_PAGES_TO_SIZE (StackPages+FuncPages);
    606   ASSERT ((mReservedTopOfApStack & (UINTN)(CPU_STACK_ALIGNMENT - 1)) == 0);
    607   mReservedApLoop.Data = (VOID *)(UINTN)Address;
    608   ASSERT (mReservedApLoop.Data != NULL);
    609   CopyMem (mReservedApLoop.Data, ApLoopFunc, ApLoopFuncSize);
    610   if (!CpuMpData->UseSevEsAPMethod) {
    611     //
    612     // processors without SEV-ES
    613     //
    614     mApPageTable = CreatePageTable (
    615                      (UINTN)Address,
    616                      EFI_PAGES_TO_SIZE (StackPages+FuncPages)
    617                      );
    618   }
     562  PrepareApLoopCode (CpuMpData);
    619563
    620564  Status = gBS->CreateEvent (
Note: See TracChangeset for help on using the changeset viewer.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette