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 <michael.d.kinney@intel.com>
Cc: Feng Tian <feng.tian@intel.com>
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Jeff Fan <jeff.fan@intel.com>
Reviewed-by: Feng Tian <feng.tian@intel.com>
This commit is contained in:
Jeff Fan 2016-08-24 22:42:32 +08:00
parent 42c37b3b33
commit 3ed4e502b5
1 changed files with 37 additions and 27 deletions

View File

@ -66,29 +66,33 @@ AllocateResetVector (
UINTN ApResetVectorSize; UINTN ApResetVectorSize;
EFI_PHYSICAL_ADDRESS StartAddress; EFI_PHYSICAL_ADDRESS StartAddress;
ApResetVectorSize = CpuMpData->AddressMap.RendezvousFunnelSize + if (CpuMpData->SaveRestoreFlag) {
sizeof (MP_CPU_EXCHANGE_INFO); BackupAndPrepareWakeupBuffer (CpuMpData);
} else {
ApResetVectorSize = CpuMpData->AddressMap.RendezvousFunnelSize +
sizeof (MP_CPU_EXCHANGE_INFO);
StartAddress = BASE_1MB; StartAddress = BASE_1MB;
Status = gBS->AllocatePages ( Status = gBS->AllocatePages (
AllocateMaxAddress, AllocateMaxAddress,
EfiACPIMemoryNVS, EfiACPIMemoryNVS,
EFI_SIZE_TO_PAGES (ApResetVectorSize), EFI_SIZE_TO_PAGES (ApResetVectorSize),
&StartAddress &StartAddress
); );
ASSERT_EFI_ERROR (Status); ASSERT_EFI_ERROR (Status);
CpuMpData->WakeupBuffer = (UINTN) StartAddress; CpuMpData->WakeupBuffer = (UINTN) StartAddress;
CpuMpData->MpCpuExchangeInfo = (MP_CPU_EXCHANGE_INFO *) (UINTN) CpuMpData->MpCpuExchangeInfo = (MP_CPU_EXCHANGE_INFO *) (UINTN)
(CpuMpData->WakeupBuffer + CpuMpData->AddressMap.RendezvousFunnelSize); (CpuMpData->WakeupBuffer + CpuMpData->AddressMap.RendezvousFunnelSize);
// //
// copy AP reset code in it // copy AP reset code in it
// //
CopyMem ( CopyMem (
(VOID *) CpuMpData->WakeupBuffer, (VOID *) CpuMpData->WakeupBuffer,
(VOID *) CpuMpData->AddressMap.RendezvousFunnelAddress, (VOID *) CpuMpData->AddressMap.RendezvousFunnelAddress,
CpuMpData->AddressMap.RendezvousFunnelSize CpuMpData->AddressMap.RendezvousFunnelSize
); );
}
} }
/** /**
@ -103,13 +107,18 @@ FreeResetVector (
{ {
EFI_STATUS Status; EFI_STATUS Status;
UINTN ApResetVectorSize; UINTN ApResetVectorSize;
ApResetVectorSize = CpuMpData->AddressMap.RendezvousFunnelSize +
sizeof (MP_CPU_EXCHANGE_INFO); if (CpuMpData->SaveRestoreFlag) {
Status = gBS->FreePages( RestoreWakeupBuffer (CpuMpData);
(EFI_PHYSICAL_ADDRESS)CpuMpData->WakeupBuffer, } else {
EFI_SIZE_TO_PAGES (ApResetVectorSize) ApResetVectorSize = CpuMpData->AddressMap.RendezvousFunnelSize +
); sizeof (MP_CPU_EXCHANGE_INFO);
ASSERT_EFI_ERROR (Status); 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; CPU_MP_DATA *CpuMpData;
CpuMpData = GetCpuMpData (); CpuMpData = GetCpuMpData ();
CpuMpData->SaveRestoreFlag = TRUE;
CpuMpData->PmCodeSegment = GetProtectedModeCS (); CpuMpData->PmCodeSegment = GetProtectedModeCS ();
CpuMpData->ApLoopMode = PcdGet8 (PcdCpuApLoopMode); CpuMpData->ApLoopMode = PcdGet8 (PcdCpuApLoopMode);
WakeUpAP (CpuMpData, TRUE, 0, RelocateApLoop, mReservedApLoopFunc); WakeUpAP (CpuMpData, TRUE, 0, RelocateApLoop, mReservedApLoopFunc);