MdeModulePkg/DxeCapsuleLibFmp: Check BootService Status to Use ESRT Cache

- In c36414b131dfd0a1ca51f10f87a18955bc110ff2 change, it was introduced
  the ReadyToBoot event check to prevent the boot service got called
  in runtime to cause the issue.

- In this patch introduced the ExitBootService event to replace it.
  It would be better to base on the BootService status to decide
  the source of ESRT table.

- Based on the BootService availability to decide,
  - Exit    : Use cache ESRT table in IF-condition
  - Not Exit: Use boot service to locate protocol in ELSE-condition

Co-authored-by: Dakota Chiang <dakota.chiang@intel.com>
Signed-off-by: Jason1 Lin <jason1.lin@intel.com>
This commit is contained in:
Jason1 Lin 2024-08-28 17:36:11 +08:00 committed by mergify[bot]
parent dadd8c7a95
commit 03c8ec6ce2
3 changed files with 23 additions and 31 deletions

View File

@ -10,7 +10,7 @@
ValidateFmpCapsule(), and DisplayCapsuleImage() receives untrusted input and
performs basic validation.
Copyright (c) 2016 - 2019, Intel Corporation. All rights reserved.<BR>
Copyright (c) 2016 - 2024, Intel Corporation. All rights reserved.<BR>
Copyright (c) 2024, Ampere Computing LLC. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
@ -49,7 +49,7 @@ EFI_EVENT mDxeCapsuleLibEndOfDxeEvent = NULL;
EDKII_FIRMWARE_MANAGEMENT_PROGRESS_PROTOCOL *mFmpProgress = NULL;
BOOLEAN mDxeCapsuleLibReadyToBootEvent = FALSE;
BOOLEAN mDxeCapsuleLibIsExitBootService = FALSE;
/**
Initialize capsule related variables.
@ -1396,25 +1396,17 @@ IsNestedFmpCapsule (
EFI_SYSTEM_RESOURCE_ENTRY Entry;
EsrtGuidFound = FALSE;
if (mEsrtTable != NULL) {
EsrtEntry = (EFI_SYSTEM_RESOURCE_ENTRY *)(mEsrtTable + 1);
for (Index = 0; Index < mEsrtTable->FwResourceCount; Index++, EsrtEntry++) {
if (CompareGuid (&EsrtEntry->FwClass, &CapsuleHeader->CapsuleGuid)) {
EsrtGuidFound = TRUE;
break;
if (mDxeCapsuleLibIsExitBootService) {
if (mEsrtTable != NULL) {
EsrtEntry = (EFI_SYSTEM_RESOURCE_ENTRY *)(mEsrtTable + 1);
for (Index = 0; Index < mEsrtTable->FwResourceCount; Index++, EsrtEntry++) {
if (CompareGuid (&EsrtEntry->FwClass, &CapsuleHeader->CapsuleGuid)) {
EsrtGuidFound = TRUE;
break;
}
}
}
} else {
if (mDxeCapsuleLibReadyToBootEvent) {
//
// The ESRT table (mEsrtTable) in the Configuration Table would be located
// at the ReadyToBoot event if it exists. Hence, it should return here to
// avoid a crash due to calling gBS->LocateProtocol () at runtime in case
// there is no ERST table installed.
//
return FALSE;
}
//
// Check ESRT protocol
//

View File

@ -22,10 +22,10 @@
#include <Library/MemoryAllocationLib.h>
extern EFI_SYSTEM_RESOURCE_TABLE *mEsrtTable;
extern BOOLEAN mDxeCapsuleLibIsExitBootService;
EFI_EVENT mDxeRuntimeCapsuleLibVirtualAddressChangeEvent = NULL;
EFI_EVENT mDxeRuntimeCapsuleLibSystemResourceTableEvent = NULL;
EFI_EVENT mDxeRuntimeCapsuleLibReadyToBootEvent = NULL;
extern BOOLEAN mDxeCapsuleLibReadyToBootEvent;
EFI_EVENT mDxeRuntimeCapsuleLibExitBootServiceEvent = NULL;
/**
Convert EsrtTable physical address to virtual address.
@ -107,7 +107,7 @@ DxeCapsuleLibSystemResourceTableInstallEventNotify (
}
/**
Notify function for event group EFI_EVENT_GROUP_READY_TO_BOOT.
Notify function for event of exit boot service.
@param[in] Event The Event that is being processed.
@param[in] Context The Event Context.
@ -116,12 +116,12 @@ DxeCapsuleLibSystemResourceTableInstallEventNotify (
STATIC
VOID
EFIAPI
DxeCapsuleLibReadyToBootEventNotify (
DxeCapsuleLibExitBootServiceEventNotify (
IN EFI_EVENT Event,
IN VOID *Context
)
{
mDxeCapsuleLibReadyToBootEvent = TRUE;
mDxeCapsuleLibIsExitBootService = TRUE;
}
/**
@ -168,15 +168,15 @@ DxeRuntimeCapsuleLibConstructor (
ASSERT_EFI_ERROR (Status);
//
// Register notify function to indicate the event is signaled at ReadyToBoot.
// Register notify function to indicate the event is signaled at ExitBootService.
//
Status = gBS->CreateEventEx (
EVT_NOTIFY_SIGNAL,
TPL_CALLBACK,
DxeCapsuleLibReadyToBootEventNotify,
DxeCapsuleLibExitBootServiceEventNotify,
NULL,
&gEfiEventReadyToBootGuid,
&mDxeRuntimeCapsuleLibReadyToBootEvent
&gEfiEventExitBootServicesGuid,
&mDxeRuntimeCapsuleLibExitBootServiceEvent
);
ASSERT_EFI_ERROR (Status);
@ -213,9 +213,9 @@ DxeRuntimeCapsuleLibDestructor (
ASSERT_EFI_ERROR (Status);
//
// Close the ReadyToBoot event.
// Close the ExitBootService event.
//
Status = gBS->CloseEvent (mDxeRuntimeCapsuleLibReadyToBootEvent);
Status = gBS->CloseEvent (mDxeRuntimeCapsuleLibExitBootServiceEvent);
ASSERT_EFI_ERROR (Status);
return EFI_SUCCESS;

View File

@ -3,7 +3,7 @@
#
# Capsule library instance for DXE_RUNTIME_DRIVER module types.
#
# Copyright (c) 2016 - 2019, Intel Corporation. All rights reserved.<BR>
# Copyright (c) 2016 - 2024, Intel Corporation. All rights reserved.<BR>
# SPDX-License-Identifier: BSD-2-Clause-Patent
#
##
@ -66,7 +66,7 @@
gEfiCapsuleReportGuid
gEfiCapsuleVendorGuid ## SOMETIMES_CONSUMES ## Variable:L"CapsuleUpdateData"
gEfiEndOfDxeEventGroupGuid ## CONSUMES ## Event
gEfiEventReadyToBootGuid ## CONSUMES ## Event
gEfiEventExitBootServicesGuid ## CONSUMES ## Event
gEfiEventVirtualAddressChangeGuid ## CONSUMES ## Event
gEdkiiCapsuleOnDiskNameGuid ## SOMETIMES_CONSUMES ## GUID