From: Jeff Fan Date: Wed, 24 Aug 2016 14:42:32 +0000 (+0800) Subject: UefiCpuPkg/MpInitLib: Don't allocate reset vector in Exit Boot Service X-Git-Tag: edk2-stable201903~5934 X-Git-Url: https://git.proxmox.com/?p=mirror_edk2.git;a=commitdiff_plain;h=3ed4e502b5f23fbcef235b3a9d025c60c217272b UefiCpuPkg/MpInitLib: Don't allocate reset vector in Exit Boot Service In Exit Boot Services callback function, we cannot use allocate memory services because it may change the memory map that has been gotten by OS. This fix is not to allocate reset vector buffer after SaveRestoreFlag is set to TRUE in MpInitExitBootServicesCallback(). Instead AllocateResetVector() will use the previous allocated buffer address and save the contents before copying reset vector code. At the same time, FreeResetVector() will restore original contents after if SaveRestoreFlag is TRUE. Cc: Michael Kinney Cc: Feng Tian Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Jeff Fan Reviewed-by: Feng Tian --- diff --git a/UefiCpuPkg/Library/MpInitLib/DxeMpLib.c b/UefiCpuPkg/Library/MpInitLib/DxeMpLib.c index e459ebc5eb..50b5b270fe 100644 --- a/UefiCpuPkg/Library/MpInitLib/DxeMpLib.c +++ b/UefiCpuPkg/Library/MpInitLib/DxeMpLib.c @@ -66,29 +66,33 @@ AllocateResetVector ( UINTN ApResetVectorSize; EFI_PHYSICAL_ADDRESS StartAddress; - ApResetVectorSize = CpuMpData->AddressMap.RendezvousFunnelSize + - sizeof (MP_CPU_EXCHANGE_INFO); - - StartAddress = BASE_1MB; - Status = gBS->AllocatePages ( - AllocateMaxAddress, - EfiACPIMemoryNVS, - EFI_SIZE_TO_PAGES (ApResetVectorSize), - &StartAddress - ); - ASSERT_EFI_ERROR (Status); - - CpuMpData->WakeupBuffer = (UINTN) StartAddress; - CpuMpData->MpCpuExchangeInfo = (MP_CPU_EXCHANGE_INFO *) (UINTN) + if (CpuMpData->SaveRestoreFlag) { + BackupAndPrepareWakeupBuffer (CpuMpData); + } else { + ApResetVectorSize = CpuMpData->AddressMap.RendezvousFunnelSize + + sizeof (MP_CPU_EXCHANGE_INFO); + + StartAddress = BASE_1MB; + Status = gBS->AllocatePages ( + AllocateMaxAddress, + EfiACPIMemoryNVS, + EFI_SIZE_TO_PAGES (ApResetVectorSize), + &StartAddress + ); + ASSERT_EFI_ERROR (Status); + + CpuMpData->WakeupBuffer = (UINTN) StartAddress; + CpuMpData->MpCpuExchangeInfo = (MP_CPU_EXCHANGE_INFO *) (UINTN) (CpuMpData->WakeupBuffer + CpuMpData->AddressMap.RendezvousFunnelSize); - // - // copy AP reset code in it - // - CopyMem ( - (VOID *) CpuMpData->WakeupBuffer, - (VOID *) CpuMpData->AddressMap.RendezvousFunnelAddress, - CpuMpData->AddressMap.RendezvousFunnelSize - ); + // + // copy AP reset code in it + // + CopyMem ( + (VOID *) CpuMpData->WakeupBuffer, + (VOID *) CpuMpData->AddressMap.RendezvousFunnelAddress, + CpuMpData->AddressMap.RendezvousFunnelSize + ); + } } /** @@ -103,13 +107,18 @@ FreeResetVector ( { EFI_STATUS Status; UINTN ApResetVectorSize; - ApResetVectorSize = CpuMpData->AddressMap.RendezvousFunnelSize + - sizeof (MP_CPU_EXCHANGE_INFO); - Status = gBS->FreePages( - (EFI_PHYSICAL_ADDRESS)CpuMpData->WakeupBuffer, - EFI_SIZE_TO_PAGES (ApResetVectorSize) - ); - ASSERT_EFI_ERROR (Status); + + if (CpuMpData->SaveRestoreFlag) { + RestoreWakeupBuffer (CpuMpData); + } else { + ApResetVectorSize = CpuMpData->AddressMap.RendezvousFunnelSize + + sizeof (MP_CPU_EXCHANGE_INFO); + Status = gBS->FreePages( + (EFI_PHYSICAL_ADDRESS)CpuMpData->WakeupBuffer, + EFI_SIZE_TO_PAGES (ApResetVectorSize) + ); + ASSERT_EFI_ERROR (Status); + } } /** @@ -260,6 +269,7 @@ MpInitExitBootServicesCallback ( CPU_MP_DATA *CpuMpData; CpuMpData = GetCpuMpData (); + CpuMpData->SaveRestoreFlag = TRUE; CpuMpData->PmCodeSegment = GetProtectedModeCS (); CpuMpData->ApLoopMode = PcdGet8 (PcdCpuApLoopMode); WakeUpAP (CpuMpData, TRUE, 0, RelocateApLoop, mReservedApLoopFunc);