Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

S3 cleanup #5606

Merged
merged 18 commits into from
Jun 4, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions MdeModulePkg/Include/Guid/AcpiS3Context.h
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/** @file
Definitions for data structures used in S3 resume.

Copyright (c) 2011 - 2023, Intel Corporation. All rights reserved.<BR>
Copyright (c) 2011 - 2024, Intel Corporation. All rights reserved.<BR>

SPDX-License-Identifier: BSD-2-Clause-Patent

Expand Down Expand Up @@ -30,7 +30,6 @@ typedef struct {
EFI_PHYSICAL_ADDRESS ReturnContext1;
EFI_PHYSICAL_ADDRESS ReturnContext2;
EFI_PHYSICAL_ADDRESS ReturnStackPointer;
EFI_PHYSICAL_ADDRESS MpService2Ppi;
EFI_PHYSICAL_ADDRESS Smst;
} SMM_S3_RESUME_STATE;

Expand Down
5 changes: 4 additions & 1 deletion MdeModulePkg/MdeModulePkg.dec
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
# and libraries instances, which are used for those modules.
#
# Copyright (c) 2019, NVIDIA CORPORATION. All rights reserved.
# Copyright (c) 2007 - 2021, Intel Corporation. All rights reserved.<BR>
# Copyright (c) 2007 - 2024, Intel Corporation. All rights reserved.<BR>
# Copyright (c) 2016, Linaro Ltd. All rights reserved.<BR>
# (C) Copyright 2016 - 2019 Hewlett Packard Enterprise Development LP<BR>
# Copyright (c) 2017, AMD Incorporated. All rights reserved.<BR>
Expand Down Expand Up @@ -465,6 +465,9 @@
gEdk2JedecSfdpSpiDxeDriverGuid = { 0xBE71701E, 0xB63C, 0x4574, { 0x9C, 0x5C, 0x36, 0x29, 0xE8, 0xEA, 0xC4, 0x14 }}
gEdk2JedecSfdpSpiSmmDriverGuid = { 0x95A1E915, 0x195C, 0x477C, { 0x92, 0x6F, 0x7E, 0x24, 0x67, 0xC1, 0xB3, 0x1F }}

## This GUID will be used to save MTRR_SETTINGS at EndOfDxe by LockBox and restore at S3 boot PEI phase for s3 usage.
gEdkiiS3MtrrSettingGuid = { 0xd77baa84, 0xb332, 0x4463, { 0x9f, 0x1d, 0xce, 0x81, 0x00, 0xfe, 0x7f, 0x35 }}

[Ppis]
## Include/Ppi/FirmwareVolumeShadowPpi.h
gEdkiiPeiFirmwareVolumeShadowPpiGuid = { 0x7dfe756c, 0xed8d, 0x4d77, {0x9e, 0xc4, 0x39, 0x9a, 0x8a, 0x81, 0x51, 0x16 } }
Expand Down
13 changes: 12 additions & 1 deletion OvmfPkg/CpuS3DataDxe/CpuS3Data.c
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ number of CPUs reported by the MP Services Protocol, so this module does not
support hot plug CPUs. This module can be copied into a CPU specific package
and customized if these additional features are required.

Copyright (c) 2013 - 2021, Intel Corporation. All rights reserved.<BR>
Copyright (c) 2013 - 2024, Intel Corporation. All rights reserved.<BR>
Copyright (c) 2015 - 2020, Red Hat, Inc.

SPDX-License-Identifier: BSD-2-Clause-Patent
Expand All @@ -26,6 +26,7 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
#include <Library/MemoryAllocationLib.h>
#include <Library/MtrrLib.h>
#include <Library/UefiBootServicesTableLib.h>
#include <Library/LockBoxLib.h>

#include <Protocol/MpService.h>
#include <Guid/EventGroup.h>
Expand Down Expand Up @@ -130,6 +131,16 @@ CpuS3DataOnEndOfDxe (
DEBUG ((DEBUG_VERBOSE, "%a\n", __func__));
MtrrGetAllMtrrs (&AcpiCpuDataEx->MtrrTable);

//
// Save MTRR in lockbox
//
Status = SaveLockBox (
&gEdkiiS3MtrrSettingGuid,
&AcpiCpuDataEx->MtrrTable,
sizeof (MTRR_SETTINGS)
);
ASSERT_EFI_ERROR (Status);

//
// Close event, so it will not be invoked again.
//
Expand Down
4 changes: 3 additions & 1 deletion OvmfPkg/CpuS3DataDxe/CpuS3DataDxe.inf
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
# support hot plug CPUs. This module can be copied into a CPU specific package
# and customized if these additional features are required.
#
# Copyright (c) 2013-2016, Intel Corporation. All rights reserved.<BR>
# Copyright (c) 2013-2024, Intel Corporation. All rights reserved.<BR>
# Copyright (c) 2015-2020, Red Hat, Inc.
#
# SPDX-License-Identifier: BSD-2-Clause-Patent
Expand Down Expand Up @@ -46,9 +46,11 @@
MtrrLib
UefiBootServicesTableLib
UefiDriverEntryPoint
LockBoxLib

[Guids]
gEfiEndOfDxeEventGroupGuid ## CONSUMES ## Event
gEdkiiS3MtrrSettingGuid

[Protocols]
gEfiMpServiceProtocolGuid ## CONSUMES
Expand Down
13 changes: 12 additions & 1 deletion UefiCpuPkg/CpuS3DataDxe/CpuS3Data.c
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ number of CPUs reported by the MP Services Protocol, so this module does not
support hot plug CPUs. This module can be copied into a CPU specific package
and customized if these additional features are required.

Copyright (c) 2013 - 2021, Intel Corporation. All rights reserved.<BR>
Copyright (c) 2013 - 2024, Intel Corporation. All rights reserved.<BR>
Copyright (c) 2015, Red Hat, Inc.

SPDX-License-Identifier: BSD-2-Clause-Patent
Expand All @@ -26,6 +26,7 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
#include <Library/DebugLib.h>
#include <Library/MtrrLib.h>
#include <Library/MemoryAllocationLib.h>
#include <Library/LockBoxLib.h>

#include <Protocol/MpService.h>
#include <Guid/EventGroup.h>
Expand Down Expand Up @@ -130,6 +131,16 @@ CpuS3DataOnEndOfDxe (
DEBUG ((DEBUG_VERBOSE, "%a\n", __func__));
MtrrGetAllMtrrs (&AcpiCpuDataEx->MtrrTable);

//
// Save MTRR in lockbox
//
Status = SaveLockBox (
&gEdkiiS3MtrrSettingGuid,
&AcpiCpuDataEx->MtrrTable,
sizeof (MTRR_SETTINGS)
);
ASSERT_EFI_ERROR (Status);

//
// Close event, so it will not be invoked again.
//
Expand Down
4 changes: 3 additions & 1 deletion UefiCpuPkg/CpuS3DataDxe/CpuS3DataDxe.inf
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
# support hot plug CPUs. This module can be copied into a CPU specific package
# and customized if these additional features are required.
#
# Copyright (c) 2013-2016, Intel Corporation. All rights reserved.<BR>
# Copyright (c) 2013-2024, Intel Corporation. All rights reserved.<BR>
# Copyright (c) 2015, Red Hat, Inc.
#
# SPDX-License-Identifier: BSD-2-Clause-Patent
Expand Down Expand Up @@ -46,9 +46,11 @@
BaseLib
MtrrLib
MemoryAllocationLib
LockBoxLib

[Guids]
gEfiEndOfDxeEventGroupGuid ## CONSUMES ## Event
gEdkiiS3MtrrSettingGuid

[Protocols]
gEfiMpServiceProtocolGuid ## CONSUMES
Expand Down
183 changes: 50 additions & 133 deletions UefiCpuPkg/Library/MpInitLib/DxeMpLib.c
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/** @file
MP initialize support functions for DXE phase.

Copyright (c) 2016 - 2023, Intel Corporation. All rights reserved.<BR>
Copyright (c) 2016 - 2024, Intel Corporation. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent

**/
Expand All @@ -20,15 +20,11 @@

#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;
RELOCATE_AP_LOOP_ENTRY mReservedApLoop;
UINTN mReservedTopOfApStack;
volatile UINT32 mNumberToFinish = 0;
UINTN mApPageTable;
CPU_MP_DATA *mCpuMpData = NULL;
EFI_EVENT mCheckAllApsEvent = NULL;
EFI_EVENT mMpInitExitBootServicesEvent = NULL;
EFI_EVENT mLegacyBootEvent = NULL;
volatile BOOLEAN mStopCheckAllApsStatus = TRUE;

//
// Begin wakeup buffer allocation below 0x88000
Expand Down Expand Up @@ -369,57 +365,58 @@ GetProtectedModeCS (
}

/**
Do sync on APs.
Allocate buffer for ApLoopCode.

@param[in, out] Buffer Pointer to private data buffer.
@param[in] Pages Number of pages to allocate.
@param[in, out] Address Pointer to the allocated buffer.
**/
VOID
EFIAPI
RelocateApLoop (
IN OUT VOID *Buffer
AllocateApLoopCodeBuffer (
IN UINTN Pages,
IN OUT EFI_PHYSICAL_ADDRESS *Address
)
{
CPU_MP_DATA *CpuMpData;
BOOLEAN MwaitSupport;
UINTN ProcessorNumber;
UINTN StackStart;
EFI_STATUS Status;

MpInitLibWhoAmI (&ProcessorNumber);
CpuMpData = GetCpuMpData ();
MwaitSupport = IsMwaitSupport ();
if (CpuMpData->UseSevEsAPMethod) {
//
// 64-bit AMD processors with SEV-ES
//
StackStart = CpuMpData->SevEsAPResetStackStart;
mReservedApLoop.AmdSevEntry (
MwaitSupport,
CpuMpData->ApTargetCState,
CpuMpData->PmCodeSegment,
StackStart - ProcessorNumber * AP_SAFE_STACK_SIZE,
(UINTN)&mNumberToFinish,
CpuMpData->Pm16CodeSegment,
CpuMpData->SevEsAPBuffer,
CpuMpData->WakeupBuffer
);
} else {
//
// Intel processors (32-bit or 64-bit), 32-bit AMD processors, or 64-bit AMD processors without SEV-ES
//
StackStart = mReservedTopOfApStack;
mReservedApLoop.GenericEntry (
MwaitSupport,
CpuMpData->ApTargetCState,
StackStart - ProcessorNumber * AP_SAFE_STACK_SIZE,
(UINTN)&mNumberToFinish,
mApPageTable
);
}
Status = gBS->AllocatePages (
AllocateMaxAddress,
EfiReservedMemoryType,
Pages,
Address
);
ASSERT_EFI_ERROR (Status);
}

/**
Remove Nx protection for the range specific by BaseAddress and Length.

The PEI implementation uses CpuPageTableLib to change the attribute.
The DXE implementation uses gDS to change the attribute.

@param[in] BaseAddress BaseAddress of the range.
@param[in] Length Length of the range.
**/
VOID
RemoveNxprotection (
IN EFI_PHYSICAL_ADDRESS BaseAddress,
IN UINTN Length
)
{
EFI_STATUS Status;
EFI_GCD_MEMORY_SPACE_DESCRIPTOR MemDesc;

//
// It should never reach here
// TODO: Check EFI_MEMORY_XP bit set or not once it's available in DXE GCD
// service.
//
ASSERT (FALSE);
Status = gDS->GetMemorySpaceDescriptor (BaseAddress, &MemDesc);
if (!EFI_ERROR (Status)) {
gDS->SetMemorySpaceAttributes (
BaseAddress,
Length,
MemDesc.Attributes & (~EFI_MEMORY_XP)
);
}
}

/**
Expand Down Expand Up @@ -477,16 +474,10 @@ InitMpGlobalData (
)
{
EFI_STATUS Status;
EFI_PHYSICAL_ADDRESS Address;
UINTN Index;
EFI_GCD_MEMORY_SPACE_DESCRIPTOR MemDesc;
UINTN StackBase;
CPU_INFO_IN_HOB *CpuInfoInHob;
MP_ASSEMBLY_ADDRESS_MAP *AddressMap;
UINT8 *ApLoopFunc;
UINTN ApLoopFuncSize;
UINTN StackPages;
UINTN FuncPages;

SaveCpuMpData (CpuMpData);

Expand Down Expand Up @@ -541,81 +532,7 @@ InitMpGlobalData (
}
}

AddressMap = &CpuMpData->AddressMap;
if (CpuMpData->UseSevEsAPMethod) {
//
// 64-bit AMD processors with SEV-ES
//
Address = BASE_4GB - 1;
ApLoopFunc = AddressMap->RelocateApLoopFuncAddressAmdSev;
ApLoopFuncSize = AddressMap->RelocateApLoopFuncSizeAmdSev;
} else {
//
// Intel processors (32-bit or 64-bit), 32-bit AMD processors, or 64-bit AMD processors without SEV-ES
//
Address = MAX_ADDRESS;
ApLoopFunc = AddressMap->RelocateApLoopFuncAddressGeneric;
ApLoopFuncSize = AddressMap->RelocateApLoopFuncSizeGeneric;
}

//
// Avoid APs access invalid buffer data which allocated by BootServices,
// so we will allocate reserved data for AP loop code. We also need to
// allocate this buffer below 4GB due to APs may be transferred to 32bit
// protected mode on long mode DXE.
// Allocating it in advance since memory services are not available in
// Exit Boot Services callback function.
//
// +------------+ (TopOfApStack)
// | Stack * N |
// +------------+ (stack base, 4k aligned)
// | Padding |
// +------------+
// | Ap Loop |
// +------------+ ((low address, 4k-aligned)
//

StackPages = EFI_SIZE_TO_PAGES (CpuMpData->CpuCount * AP_SAFE_STACK_SIZE);
FuncPages = EFI_SIZE_TO_PAGES (ApLoopFuncSize);

Status = gBS->AllocatePages (
AllocateMaxAddress,
EfiReservedMemoryType,
StackPages + FuncPages,
&Address
);
ASSERT_EFI_ERROR (Status);

//
// Make sure that the buffer memory is executable if NX protection is enabled
// for EfiReservedMemoryType.
//
// TODO: Check EFI_MEMORY_XP bit set or not once it's available in DXE GCD
// service.
//
Status = gDS->GetMemorySpaceDescriptor (Address, &MemDesc);
if (!EFI_ERROR (Status)) {
gDS->SetMemorySpaceAttributes (
Address,
EFI_PAGES_TO_SIZE (FuncPages),
MemDesc.Attributes & (~EFI_MEMORY_XP)
);
}

mReservedTopOfApStack = (UINTN)Address + EFI_PAGES_TO_SIZE (StackPages+FuncPages);
ASSERT ((mReservedTopOfApStack & (UINTN)(CPU_STACK_ALIGNMENT - 1)) == 0);
mReservedApLoop.Data = (VOID *)(UINTN)Address;
ASSERT (mReservedApLoop.Data != NULL);
CopyMem (mReservedApLoop.Data, ApLoopFunc, ApLoopFuncSize);
if (!CpuMpData->UseSevEsAPMethod) {
//
// processors without SEV-ES
//
mApPageTable = CreatePageTable (
(UINTN)Address,
EFI_PAGES_TO_SIZE (StackPages+FuncPages)
);
}
PrepareApLoopCode (CpuMpData);

Status = gBS->CreateEvent (
EVT_TIMER | EVT_NOTIFY_SIGNAL,
Expand Down
6 changes: 5 additions & 1 deletion UefiCpuPkg/Library/MpInitLib/Ia32/MpFuncs.nasm
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
;------------------------------------------------------------------------------ ;
; Copyright (c) 2015 - 2023, Intel Corporation. All rights reserved.<BR>
; Copyright (c) 2015 - 2024, Intel Corporation. All rights reserved.<BR>
; SPDX-License-Identifier: BSD-2-Clause-Patent
;
; Module Name:
Expand Down Expand Up @@ -225,6 +225,10 @@ RendezvousFunnelProcEnd:
; specific to SEV-ES support and are not applicable on IA32.
;-------------------------------------------------------------------------------------
AsmRelocateApLoopGenericStart:
mov eax, cr0
btr eax, 31 ; Clear CR0.PG
mov cr0, eax ; Disable paging since the page table might be unavailiable

mov eax, esp
mov esp, [eax + 12] ; TopOfApStack
push dword [eax] ; push return address for stack trace
Expand Down
Loading
Loading