X-Git-Url: https://git.proxmox.com/?a=blobdiff_plain;f=UefiCpuPkg%2FLibrary%2FMpInitLib%2FDxeMpLib.c;h=02bc9c2bd2c4f763ba471ffb222b0ced8a8cea89;hb=b95908e04317a2b1e3641845ba36f673d5aebada;hp=2c00d72ddefe1487b72189dd9d16d6a20cd4bd2b;hpb=20da7ca42a33d3ef767ce4129f11496af7f67c9f;p=mirror_edk2.git diff --git a/UefiCpuPkg/Library/MpInitLib/DxeMpLib.c b/UefiCpuPkg/Library/MpInitLib/DxeMpLib.c index 2c00d72dde..02bc9c2bd2 100644 --- a/UefiCpuPkg/Library/MpInitLib/DxeMpLib.c +++ b/UefiCpuPkg/Library/MpInitLib/DxeMpLib.c @@ -18,16 +18,21 @@ #include -#define AP_SAFE_STACK_SIZE 128 - -CPU_MP_DATA *mCpuMpData = NULL; -EFI_EVENT mCheckAllApsEvent = NULL; -EFI_EVENT mMpInitExitBootServicesEvent = NULL; -EFI_EVENT mLegacyBootEvent = NULL; -volatile BOOLEAN mStopCheckAllApsStatus = TRUE; -VOID *mReservedApLoopFunc = NULL; -UINTN mReservedTopOfApStack; -volatile UINT32 mNumberToFinish = 0; +#define AP_SAFE_STACK_SIZE 128 + +CPU_MP_DATA *mCpuMpData = NULL; +EFI_EVENT mCheckAllApsEvent = NULL; +EFI_EVENT mMpInitExitBootServicesEvent = NULL; +EFI_EVENT mLegacyBootEvent = NULL; +volatile BOOLEAN mStopCheckAllApsStatus = TRUE; +VOID *mReservedApLoopFunc = NULL; +UINTN mReservedTopOfApStack; +volatile UINT32 mNumberToFinish = 0; + +// +// Begin wakeup buffer allocation below 0x88000 +// +STATIC EFI_PHYSICAL_ADDRESS mSevEsDxeWakeupBuffer = 0x88000; /** Enable Debug Agent to support source debugging on AP function. @@ -65,7 +70,7 @@ GetCpuMpData ( **/ VOID SaveCpuMpData ( - IN CPU_MP_DATA *CpuMpData + IN CPU_MP_DATA *CpuMpData ) { mCpuMpData = CpuMpData; @@ -81,14 +86,14 @@ SaveCpuMpData ( **/ UINTN GetWakeupBuffer ( - IN UINTN WakeupBufferSize + IN UINTN WakeupBufferSize ) { - EFI_STATUS Status; - EFI_PHYSICAL_ADDRESS StartAddress; - EFI_MEMORY_TYPE MemoryType; + EFI_STATUS Status; + EFI_PHYSICAL_ADDRESS StartAddress; + EFI_MEMORY_TYPE MemoryType; - if (PcdGetBool (PcdSevEsIsEnabled)) { + if (ConfidentialComputingGuestHas (CCAttrAmdSevEs)) { MemoryType = EfiReservedMemoryType; } else { MemoryType = EfiBootServicesData; @@ -102,7 +107,15 @@ GetWakeupBuffer ( // LagacyBios driver depends on CPU Arch protocol which guarantees below // allocation runs earlier than LegacyBios driver. // - StartAddress = 0x88000; + if (ConfidentialComputingGuestHas (CCAttrAmdSevEs)) { + // + // SEV-ES Wakeup buffer should be under 0x88000 and under any previous one + // + StartAddress = mSevEsDxeWakeupBuffer; + } else { + StartAddress = 0x88000; + } + Status = gBS->AllocatePages ( AllocateMaxAddress, MemoryType, @@ -111,13 +124,22 @@ GetWakeupBuffer ( ); ASSERT_EFI_ERROR (Status); if (EFI_ERROR (Status)) { - StartAddress = (EFI_PHYSICAL_ADDRESS) -1; + StartAddress = (EFI_PHYSICAL_ADDRESS)-1; + } else if (ConfidentialComputingGuestHas (CCAttrAmdSevEs)) { + // + // Next SEV-ES wakeup buffer allocation must be below this allocation + // + mSevEsDxeWakeupBuffer = StartAddress; } - DEBUG ((DEBUG_INFO, "WakeupBufferStart = %x, WakeupBufferSize = %x\n", - (UINTN) StartAddress, WakeupBufferSize)); + DEBUG (( + DEBUG_INFO, + "WakeupBufferStart = %x, WakeupBufferSize = %x\n", + (UINTN)StartAddress, + WakeupBufferSize + )); - return (UINTN) StartAddress; + return (UINTN)StartAddress; } /** @@ -134,19 +156,19 @@ GetWakeupBuffer ( **/ UINTN GetModeTransitionBuffer ( - IN UINTN BufferSize + IN UINTN BufferSize ) { - EFI_STATUS Status; - EFI_PHYSICAL_ADDRESS StartAddress; + EFI_STATUS Status; + EFI_PHYSICAL_ADDRESS StartAddress; StartAddress = BASE_4GB - 1; - Status = gBS->AllocatePages ( - AllocateMaxAddress, - EfiBootServicesCode, - EFI_SIZE_TO_PAGES (BufferSize), - &StartAddress - ); + Status = gBS->AllocatePages ( + AllocateMaxAddress, + EfiBootServicesCode, + EFI_SIZE_TO_PAGES (BufferSize), + &StartAddress + ); if (EFI_ERROR (Status)) { StartAddress = 0; } @@ -171,32 +193,33 @@ GetSevEsAPMemory ( EFI_PHYSICAL_ADDRESS StartAddress; MSR_SEV_ES_GHCB_REGISTER Msr; GHCB *Ghcb; + BOOLEAN InterruptState; // // Allocate 1 page for AP jump table page // StartAddress = BASE_4GB - 1; - Status = gBS->AllocatePages ( - AllocateMaxAddress, - EfiReservedMemoryType, - 1, - &StartAddress - ); + Status = gBS->AllocatePages ( + AllocateMaxAddress, + EfiReservedMemoryType, + 1, + &StartAddress + ); ASSERT_EFI_ERROR (Status); - DEBUG ((DEBUG_INFO, "Dxe: SevEsAPMemory = %lx\n", (UINTN) StartAddress)); + DEBUG ((DEBUG_INFO, "Dxe: SevEsAPMemory = %lx\n", (UINTN)StartAddress)); // // Save the SevEsAPMemory as the AP jump table. // Msr.GhcbPhysicalAddress = AsmReadMsr64 (MSR_SEV_ES_GHCB); - Ghcb = Msr.Ghcb; + Ghcb = Msr.Ghcb; - VmgInit (Ghcb); - VmgExit (Ghcb, SVM_EXIT_AP_JUMP_TABLE, 0, (UINT64) (UINTN) StartAddress); - VmgDone (Ghcb); + VmgInit (Ghcb, &InterruptState); + VmgExit (Ghcb, SVM_EXIT_AP_JUMP_TABLE, 0, (UINT64)(UINTN)StartAddress); + VmgDone (Ghcb, InterruptState); - return (UINTN) StartAddress; + return (UINTN)StartAddress; } /** @@ -208,9 +231,9 @@ CheckAndUpdateApsStatus ( VOID ) { - UINTN ProcessorNumber; - EFI_STATUS Status; - CPU_MP_DATA *CpuMpData; + UINTN ProcessorNumber; + EFI_STATUS Status; + CPU_MP_DATA *CpuMpData; CpuMpData = GetCpuMpData (); @@ -218,13 +241,12 @@ CheckAndUpdateApsStatus ( // First, check whether pending StartupAllAPs() exists. // if (CpuMpData->WaitEvent != NULL) { - Status = CheckAllAPs (); // // If all APs finish for StartupAllAPs(), signal the WaitEvent for it. // if (Status != EFI_NOT_READY) { - Status = gBS->SignalEvent (CpuMpData->WaitEvent); + Status = gBS->SignalEvent (CpuMpData->WaitEvent); CpuMpData->WaitEvent = NULL; } } @@ -233,7 +255,6 @@ CheckAndUpdateApsStatus ( // Second, check whether pending StartupThisAPs() callings exist. // for (ProcessorNumber = 0; ProcessorNumber < CpuMpData->CpuCount; ProcessorNumber++) { - if (CpuMpData->CpuData[ProcessorNumber].WaitEvent == NULL) { continue; } @@ -242,7 +263,7 @@ CheckAndUpdateApsStatus ( if (Status != EFI_NOT_READY) { gBS->SignalEvent (CpuMpData->CpuData[ProcessorNumber].WaitEvent); - CpuMpData->CpuData[ProcessorNumber].WaitEvent = NULL; + CpuMpData->CpuData[ProcessorNumber].WaitEvent = NULL; } } } @@ -261,8 +282,8 @@ CheckAndUpdateApsStatus ( VOID EFIAPI CheckApsStatus ( - IN EFI_EVENT Event, - IN VOID *Context + IN EFI_EVENT Event, + IN VOID *Context ) { // @@ -289,18 +310,20 @@ GetProtectedMode16CS ( UINTN GdtEntryCount; UINT16 Index; - Index = (UINT16) -1; + Index = (UINT16)-1; AsmReadGdtr (&GdtrDesc); GdtEntryCount = (GdtrDesc.Limit + 1) / sizeof (IA32_SEGMENT_DESCRIPTOR); - GdtEntry = (IA32_SEGMENT_DESCRIPTOR *) GdtrDesc.Base; + GdtEntry = (IA32_SEGMENT_DESCRIPTOR *)GdtrDesc.Base; for (Index = 0; Index < GdtEntryCount; Index++) { if (GdtEntry->Bits.L == 0) { - if (GdtEntry->Bits.Type > 8 && GdtEntry->Bits.DB == 0) { + if ((GdtEntry->Bits.Type > 8) && (GdtEntry->Bits.DB == 0)) { break; } } + GdtEntry++; } + ASSERT (Index != GdtEntryCount); return Index * 8; } @@ -322,15 +345,17 @@ GetProtectedModeCS ( AsmReadGdtr (&GdtrDesc); GdtEntryCount = (GdtrDesc.Limit + 1) / sizeof (IA32_SEGMENT_DESCRIPTOR); - GdtEntry = (IA32_SEGMENT_DESCRIPTOR *) GdtrDesc.Base; + GdtEntry = (IA32_SEGMENT_DESCRIPTOR *)GdtrDesc.Base; for (Index = 0; Index < GdtEntryCount; Index++) { if (GdtEntry->Bits.L == 0) { - if (GdtEntry->Bits.Type > 8 && GdtEntry->Bits.DB == 1) { + if ((GdtEntry->Bits.Type > 8) && (GdtEntry->Bits.DB == 1)) { break; } } + GdtEntry++; } + ASSERT (Index != GdtEntryCount); return Index * 8; } @@ -346,11 +371,11 @@ RelocateApLoop ( IN OUT VOID *Buffer ) { - CPU_MP_DATA *CpuMpData; - BOOLEAN MwaitSupport; - ASM_RELOCATE_AP_LOOP AsmRelocateApLoopFunc; - UINTN ProcessorNumber; - UINTN StackStart; + CPU_MP_DATA *CpuMpData; + BOOLEAN MwaitSupport; + ASM_RELOCATE_AP_LOOP AsmRelocateApLoopFunc; + UINTN ProcessorNumber; + UINTN StackStart; MpInitLibWhoAmI (&ProcessorNumber); CpuMpData = GetCpuMpData (); @@ -360,13 +385,14 @@ RelocateApLoop ( } else { StackStart = mReservedTopOfApStack; } - AsmRelocateApLoopFunc = (ASM_RELOCATE_AP_LOOP) (UINTN) mReservedApLoopFunc; + + AsmRelocateApLoopFunc = (ASM_RELOCATE_AP_LOOP)(UINTN)mReservedApLoopFunc; AsmRelocateApLoopFunc ( MwaitSupport, CpuMpData->ApTargetCState, CpuMpData->PmCodeSegment, StackStart - ProcessorNumber * AP_SAFE_STACK_SIZE, - (UINTN) &mNumberToFinish, + (UINTN)&mNumberToFinish, CpuMpData->Pm16CodeSegment, CpuMpData->SevEsAPBuffer, CpuMpData->WakeupBuffer @@ -388,32 +414,32 @@ RelocateApLoop ( VOID EFIAPI MpInitChangeApLoopCallback ( - IN EFI_EVENT Event, - IN VOID *Context + IN EFI_EVENT Event, + IN VOID *Context ) { - CPU_MP_DATA *CpuMpData; + CPU_MP_DATA *CpuMpData; - CpuMpData = GetCpuMpData (); - CpuMpData->PmCodeSegment = GetProtectedModeCS (); + CpuMpData = GetCpuMpData (); + CpuMpData->PmCodeSegment = GetProtectedModeCS (); CpuMpData->Pm16CodeSegment = GetProtectedMode16CS (); - CpuMpData->ApLoopMode = PcdGet8 (PcdCpuApLoopMode); - mNumberToFinish = CpuMpData->CpuCount - 1; + CpuMpData->ApLoopMode = PcdGet8 (PcdCpuApLoopMode); + mNumberToFinish = CpuMpData->CpuCount - 1; WakeUpAP (CpuMpData, TRUE, 0, RelocateApLoop, NULL, TRUE); while (mNumberToFinish > 0) { CpuPause (); } - if (CpuMpData->SevEsIsEnabled && (CpuMpData->WakeupBuffer != (UINTN) -1)) { + if (CpuMpData->SevEsIsEnabled && (CpuMpData->WakeupBuffer != (UINTN)-1)) { // // There are APs present. Re-use reserved memory area below 1MB from // WakeupBuffer as the area to be used for transitioning to 16-bit mode // in support of booting of the AP by an OS. // CopyMem ( - (VOID *) CpuMpData->WakeupBuffer, - (VOID *) (CpuMpData->AddressMap.RendezvousFunnelAddress + - CpuMpData->AddressMap.SwitchToRealPM16ModeOffset), + (VOID *)CpuMpData->WakeupBuffer, + (VOID *)(CpuMpData->AddressMap.RendezvousFunnelAddress + + CpuMpData->AddressMap.SwitchToRealPM16ModeOffset), CpuMpData->AddressMap.SwitchToRealPM16ModeSize ); } @@ -428,16 +454,16 @@ MpInitChangeApLoopCallback ( **/ VOID InitMpGlobalData ( - IN CPU_MP_DATA *CpuMpData + IN CPU_MP_DATA *CpuMpData ) { - EFI_STATUS Status; - EFI_PHYSICAL_ADDRESS Address; - UINTN ApSafeBufferSize; - UINTN Index; - EFI_GCD_MEMORY_SPACE_DESCRIPTOR MemDesc; - UINTN StackBase; - CPU_INFO_IN_HOB *CpuInfoInHob; + EFI_STATUS Status; + EFI_PHYSICAL_ADDRESS Address; + UINTN ApSafeBufferSize; + UINTN Index; + EFI_GCD_MEMORY_SPACE_DESCRIPTOR MemDesc; + UINTN StackBase; + CPU_INFO_IN_HOB *CpuInfoInHob; SaveCpuMpData (CpuMpData); @@ -467,7 +493,7 @@ InitMpGlobalData ( // CpuInfoInHob = (CPU_INFO_IN_HOB *)(UINTN)CpuMpData->CpuInfoInHob; for (Index = 0; Index < CpuMpData->CpuCount; ++Index) { - if (CpuInfoInHob != NULL && CpuInfoInHob[Index].ApTopOfStack != 0) { + if ((CpuInfoInHob != NULL) && (CpuInfoInHob[Index].ApTopOfStack != 0)) { StackBase = (UINTN)CpuInfoInHob[Index].ApTopOfStack - CpuMpData->CpuApStackSize; } else { StackBase = CpuMpData->Buffer + Index * CpuMpData->CpuApStackSize; @@ -483,8 +509,12 @@ InitMpGlobalData ( ); ASSERT_EFI_ERROR (Status); - DEBUG ((DEBUG_INFO, "Stack Guard set at %lx [cpu%lu]!\n", - (UINT64)StackBase, (UINT64)Index)); + DEBUG (( + DEBUG_INFO, + "Stack Guard set at %lx [cpu%lu]!\n", + (UINT64)StackBase, + (UINT64)Index + )); } } @@ -496,9 +526,11 @@ InitMpGlobalData ( // Allocating it in advance since memory services are not available in // Exit Boot Services callback function. // - ApSafeBufferSize = EFI_PAGES_TO_SIZE (EFI_SIZE_TO_PAGES ( - CpuMpData->AddressMap.RelocateApLoopFuncSize - )); + ApSafeBufferSize = EFI_PAGES_TO_SIZE ( + EFI_SIZE_TO_PAGES ( + CpuMpData->AddressMap.RelocateApLoopFuncSize + ) + ); Address = BASE_4GB - 1; Status = gBS->AllocatePages ( AllocateMaxAddress, @@ -508,7 +540,7 @@ InitMpGlobalData ( ); ASSERT_EFI_ERROR (Status); - mReservedApLoopFunc = (VOID *) (UINTN) Address; + mReservedApLoopFunc = (VOID *)(UINTN)Address; ASSERT (mReservedApLoopFunc != NULL); // @@ -527,9 +559,11 @@ InitMpGlobalData ( ); } - ApSafeBufferSize = EFI_PAGES_TO_SIZE (EFI_SIZE_TO_PAGES ( - CpuMpData->CpuCount * AP_SAFE_STACK_SIZE - )); + ApSafeBufferSize = EFI_PAGES_TO_SIZE ( + EFI_SIZE_TO_PAGES ( + CpuMpData->CpuCount * AP_SAFE_STACK_SIZE + ) + ); Address = BASE_4GB - 1; Status = gBS->AllocatePages ( AllocateMaxAddress, @@ -539,7 +573,7 @@ InitMpGlobalData ( ); ASSERT_EFI_ERROR (Status); - mReservedTopOfApStack = (UINTN) Address + ApSafeBufferSize; + mReservedTopOfApStack = (UINTN)Address + ApSafeBufferSize; ASSERT ((mReservedTopOfApStack & (UINTN)(CPU_STACK_ALIGNMENT - 1)) == 0); CopyMem ( mReservedApLoopFunc, @@ -666,15 +700,15 @@ InitMpGlobalData ( EFI_STATUS EFIAPI MpInitLibStartupAllAPs ( - IN EFI_AP_PROCEDURE Procedure, - IN BOOLEAN SingleThread, - IN EFI_EVENT WaitEvent OPTIONAL, - IN UINTN TimeoutInMicroseconds, - IN VOID *ProcedureArgument OPTIONAL, - OUT UINTN **FailedCpuList OPTIONAL + IN EFI_AP_PROCEDURE Procedure, + IN BOOLEAN SingleThread, + IN EFI_EVENT WaitEvent OPTIONAL, + IN UINTN TimeoutInMicroseconds, + IN VOID *ProcedureArgument OPTIONAL, + OUT UINTN **FailedCpuList OPTIONAL ) { - EFI_STATUS Status; + EFI_STATUS Status; // // Temporarily stop checkAllApsStatus for avoid resource dead-lock. @@ -773,15 +807,15 @@ MpInitLibStartupAllAPs ( EFI_STATUS EFIAPI MpInitLibStartupThisAP ( - IN EFI_AP_PROCEDURE Procedure, - IN UINTN ProcessorNumber, - IN EFI_EVENT WaitEvent OPTIONAL, - IN UINTN TimeoutInMicroseconds, - IN VOID *ProcedureArgument OPTIONAL, - OUT BOOLEAN *Finished OPTIONAL + IN EFI_AP_PROCEDURE Procedure, + IN UINTN ProcessorNumber, + IN EFI_EVENT WaitEvent OPTIONAL, + IN UINTN TimeoutInMicroseconds, + IN VOID *ProcedureArgument OPTIONAL, + OUT BOOLEAN *Finished OPTIONAL ) { - EFI_STATUS Status; + EFI_STATUS Status; // // temporarily stop checkAllApsStatus for avoid resource dead-lock. @@ -831,19 +865,19 @@ MpInitLibStartupThisAP ( EFI_STATUS EFIAPI MpInitLibSwitchBSP ( - IN UINTN ProcessorNumber, - IN BOOLEAN EnableOldBSP + IN UINTN ProcessorNumber, + IN BOOLEAN EnableOldBSP ) { - EFI_STATUS Status; - EFI_TIMER_ARCH_PROTOCOL *Timer; - UINT64 TimerPeriod; + EFI_STATUS Status; + EFI_TIMER_ARCH_PROTOCOL *Timer; + UINT64 TimerPeriod; TimerPeriod = 0; // // Locate Timer Arch Protocol // - Status = gBS->LocateProtocol (&gEfiTimerArchProtocolGuid, NULL, (VOID **) &Timer); + Status = gBS->LocateProtocol (&gEfiTimerArchProtocolGuid, NULL, (VOID **)&Timer); if (EFI_ERROR (Status)) { Timer = NULL; } @@ -904,13 +938,13 @@ MpInitLibSwitchBSP ( EFI_STATUS EFIAPI MpInitLibEnableDisableAP ( - IN UINTN ProcessorNumber, - IN BOOLEAN EnableAP, - IN UINT32 *HealthFlag OPTIONAL + IN UINTN ProcessorNumber, + IN BOOLEAN EnableAP, + IN UINT32 *HealthFlag OPTIONAL ) { - EFI_STATUS Status; - BOOLEAN TempStopCheckState; + EFI_STATUS Status; + BOOLEAN TempStopCheckState; TempStopCheckState = FALSE; // @@ -943,7 +977,7 @@ MpInitLibEnableDisableAP ( **/ EFI_STATUS PlatformShadowMicrocode ( - IN OUT CPU_MP_DATA *CpuMpData + IN OUT CPU_MP_DATA *CpuMpData ) { //