mirror of https://github.com/acidanthera/audk.git
Add EDKII_VARIABLE_LOCK_PROTOCOL and the implementation in MdeModulePkg variable drivers.
Add code in BdsDxe driver to call the protocol to mark the read-only variables defined in the UEFI Spec. Signed-off-by: Ruiyu Ni <ruiyu.ni@intel.com> Reviewed-by: Guo Dong <guo.dong@intel.com> Reviewed-by: Star Zeng <star.zeng@intel.com> git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@14372 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
parent
efffd9c17e
commit
ff8438477f
|
@ -1,7 +1,7 @@
|
||||||
/** @file
|
/** @file
|
||||||
Head file for BDS Architectural Protocol implementation
|
Head file for BDS Architectural Protocol implementation
|
||||||
|
|
||||||
Copyright (c) 2004 - 2012, Intel Corporation. All rights reserved.<BR>
|
Copyright (c) 2004 - 2013, Intel Corporation. All rights reserved.<BR>
|
||||||
This program and the accompanying materials
|
This program and the accompanying materials
|
||||||
are licensed and made available under the terms and conditions of the BSD License
|
are licensed and made available under the terms and conditions of the BSD License
|
||||||
which accompanies this distribution. The full text of the license may be found at
|
which accompanies this distribution. The full text of the license may be found at
|
||||||
|
@ -47,6 +47,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||||
#include <Protocol/SimpleTextInEx.h>
|
#include <Protocol/SimpleTextInEx.h>
|
||||||
#include <Protocol/DriverHealth.h>
|
#include <Protocol/DriverHealth.h>
|
||||||
#include <Protocol/BootLogo.h>
|
#include <Protocol/BootLogo.h>
|
||||||
|
#include <Protocol/VariableLock.h>
|
||||||
|
|
||||||
#include <Library/UefiDriverEntryPoint.h>
|
#include <Library/UefiDriverEntryPoint.h>
|
||||||
#include <Library/PrintLib.h>
|
#include <Library/PrintLib.h>
|
||||||
|
|
|
@ -14,7 +14,7 @@
|
||||||
# BDSDxe also maintain the UI for "Boot Manager, Boot Maintaince Manager, Device Manager" which
|
# BDSDxe also maintain the UI for "Boot Manager, Boot Maintaince Manager, Device Manager" which
|
||||||
# is used for user to configure boot option or maintain hardware device.
|
# is used for user to configure boot option or maintain hardware device.
|
||||||
#
|
#
|
||||||
# Copyright (c) 2008 - 2012, Intel Corporation. All rights reserved.<BR>
|
# Copyright (c) 2008 - 2013, Intel Corporation. All rights reserved.<BR>
|
||||||
# This program and the accompanying materials
|
# This program and the accompanying materials
|
||||||
# are licensed and made available under the terms and conditions of the BSD License
|
# are licensed and made available under the terms and conditions of the BSD License
|
||||||
# which accompanies this distribution. The full text of the license may be found at
|
# which accompanies this distribution. The full text of the license may be found at
|
||||||
|
@ -160,6 +160,7 @@
|
||||||
gEfiDriverHealthProtocolGuid ## PROTOCOL SOMETIMES_CONSUMES
|
gEfiDriverHealthProtocolGuid ## PROTOCOL SOMETIMES_CONSUMES
|
||||||
gEfiPciIoProtocolGuid ## PROTOCOL CONSUMES
|
gEfiPciIoProtocolGuid ## PROTOCOL CONSUMES
|
||||||
gEfiBootLogoProtocolGuid ## PROTOCOL SOMETIMES_CONSUMES
|
gEfiBootLogoProtocolGuid ## PROTOCOL SOMETIMES_CONSUMES
|
||||||
|
gEdkiiVariableLockProtocolGuid ## PROTOCOL CONSUMES
|
||||||
|
|
||||||
[FeaturePcd]
|
[FeaturePcd]
|
||||||
gEfiMdePkgTokenSpaceGuid.PcdUefiVariableDefaultLangDeprecate
|
gEfiMdePkgTokenSpaceGuid.PcdUefiVariableDefaultLangDeprecate
|
||||||
|
|
|
@ -38,6 +38,17 @@ EFI_BDS_ARCH_PROTOCOL gBds = {
|
||||||
|
|
||||||
UINT16 *mBootNext = NULL;
|
UINT16 *mBootNext = NULL;
|
||||||
|
|
||||||
|
///
|
||||||
|
/// The read-only variables defined in UEFI Spec.
|
||||||
|
///
|
||||||
|
CHAR16 *mReadOnlyVariables[] = {
|
||||||
|
L"PlatformLangCodes",
|
||||||
|
L"LangCodes",
|
||||||
|
L"BootOptionSupport",
|
||||||
|
L"HwErrRecSupport",
|
||||||
|
L"OsIndicationsSupported"
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
||||||
Install Boot Device Selection Protocol
|
Install Boot Device Selection Protocol
|
||||||
|
@ -459,6 +470,8 @@ BdsEntry (
|
||||||
CHAR16 *FirmwareVendor;
|
CHAR16 *FirmwareVendor;
|
||||||
EFI_STATUS Status;
|
EFI_STATUS Status;
|
||||||
UINT16 BootTimeOut;
|
UINT16 BootTimeOut;
|
||||||
|
UINTN Index;
|
||||||
|
EDKII_VARIABLE_LOCK_PROTOCOL *VariableLock;
|
||||||
|
|
||||||
//
|
//
|
||||||
// Insert the performance probe
|
// Insert the performance probe
|
||||||
|
@ -496,6 +509,18 @@ BdsEntry (
|
||||||
//
|
//
|
||||||
BdsFormalizeEfiGlobalVariable();
|
BdsFormalizeEfiGlobalVariable();
|
||||||
|
|
||||||
|
//
|
||||||
|
// Mark the read-only variables if the Variable Lock protocol exists
|
||||||
|
//
|
||||||
|
Status = gBS->LocateProtocol (&gEdkiiVariableLockProtocolGuid, NULL, (VOID **) &VariableLock);
|
||||||
|
DEBUG ((EFI_D_INFO, "[BdsDxe] Locate Variable Lock protocol - %r\n", Status));
|
||||||
|
if (!EFI_ERROR (Status)) {
|
||||||
|
for (Index = 0; Index < sizeof (mReadOnlyVariables) / sizeof (mReadOnlyVariables[0]); Index++) {
|
||||||
|
Status = VariableLock->RequestToLock (VariableLock, mReadOnlyVariables[Index], &gEfiGlobalVariableGuid);
|
||||||
|
ASSERT_EFI_ERROR (Status);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// Report Status Code to indicate connecting drivers will happen
|
// Report Status Code to indicate connecting drivers will happen
|
||||||
//
|
//
|
||||||
|
@ -504,12 +529,6 @@ BdsEntry (
|
||||||
(EFI_SOFTWARE_DXE_BS_DRIVER | EFI_SW_DXE_BS_PC_BEGIN_CONNECTING_DRIVERS)
|
(EFI_SOFTWARE_DXE_BS_DRIVER | EFI_SW_DXE_BS_PC_BEGIN_CONNECTING_DRIVERS)
|
||||||
);
|
);
|
||||||
|
|
||||||
//
|
|
||||||
// Do the platform init, can be customized by OEM/IBV
|
|
||||||
//
|
|
||||||
PERF_START (NULL, "PlatformBds", "BDS", 0);
|
|
||||||
PlatformBdsInit ();
|
|
||||||
|
|
||||||
InitializeHwErrRecSupport();
|
InitializeHwErrRecSupport();
|
||||||
|
|
||||||
//
|
//
|
||||||
|
@ -539,6 +558,12 @@ BdsEntry (
|
||||||
InitializeLanguage (TRUE);
|
InitializeLanguage (TRUE);
|
||||||
InitializeFrontPage (TRUE);
|
InitializeFrontPage (TRUE);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Do the platform init, can be customized by OEM/IBV
|
||||||
|
//
|
||||||
|
PERF_START (NULL, "PlatformBds", "BDS", 0);
|
||||||
|
PlatformBdsInit ();
|
||||||
|
|
||||||
//
|
//
|
||||||
// Set up the device list based on EFI 1.1 variables
|
// Set up the device list based on EFI 1.1 variables
|
||||||
// process Driver#### and Load the driver's in the
|
// process Driver#### and Load the driver's in the
|
||||||
|
|
|
@ -60,6 +60,10 @@ typedef struct {
|
||||||
// is gEfiSmmVariableProtocolGuid.
|
// is gEfiSmmVariableProtocolGuid.
|
||||||
//
|
//
|
||||||
#define SMM_VARIABLE_FUNCTION_GET_STATISTICS 7
|
#define SMM_VARIABLE_FUNCTION_GET_STATISTICS 7
|
||||||
|
//
|
||||||
|
// The payload for this function is SMM_VARIABLE_COMMUNICATE_LOCK_VARIABLE
|
||||||
|
//
|
||||||
|
#define SMM_VARIABLE_FUNCTION_LOCK_VARIABLE 8
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Size of SMM communicate header, without including the payload.
|
/// Size of SMM communicate header, without including the payload.
|
||||||
|
@ -101,4 +105,6 @@ typedef struct {
|
||||||
UINT32 Attributes;
|
UINT32 Attributes;
|
||||||
} SMM_VARIABLE_COMMUNICATE_QUERY_VARIABLE_INFO;
|
} SMM_VARIABLE_COMMUNICATE_QUERY_VARIABLE_INFO;
|
||||||
|
|
||||||
|
typedef SMM_VARIABLE_COMMUNICATE_GET_NEXT_VARIABLE_NAME SMM_VARIABLE_COMMUNICATE_LOCK_VARIABLE;
|
||||||
|
|
||||||
#endif // _SMM_VARIABLE_COMMON_H_
|
#endif // _SMM_VARIABLE_COMMON_H_
|
|
@ -0,0 +1,63 @@
|
||||||
|
/** @file
|
||||||
|
Variable Lock Protocol is related to EDK II-specific implementation of variables
|
||||||
|
and intended for use as a means to mark a variable read-only after the event
|
||||||
|
EFI_END_OF_DXE_EVENT_GUID is signaled.
|
||||||
|
|
||||||
|
Copyright (c) 2013, Intel Corporation. All rights reserved.<BR>
|
||||||
|
This program and the accompanying materials
|
||||||
|
are licensed and made available under the terms and conditions of the BSD License
|
||||||
|
which accompanies this distribution. The full text of the license may be found at
|
||||||
|
http://opensource.org/licenses/bsd-license.php
|
||||||
|
|
||||||
|
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||||
|
|
||||||
|
**/
|
||||||
|
|
||||||
|
#ifndef __VARIABLE_LOCK_H__
|
||||||
|
#define __VARIABLE_LOCK_H__
|
||||||
|
|
||||||
|
#define EDKII_VARIABLE_LOCK_PROTOCOL_GUID \
|
||||||
|
{ \
|
||||||
|
0xcd3d0a05, 0x9e24, 0x437c, { 0xa8, 0x91, 0x1e, 0xe0, 0x53, 0xdb, 0x76, 0x38 } \
|
||||||
|
}
|
||||||
|
|
||||||
|
typedef struct _EDKII_VARIABLE_LOCK_PROTOCOL EDKII_VARIABLE_LOCK_PROTOCOL;
|
||||||
|
|
||||||
|
/**
|
||||||
|
Mark a variable that will become read-only after leaving the DXE phase of execution.
|
||||||
|
Write request coming from SMM environment through EFI_SMM_VARIABLE_PROTOCOL is allowed.
|
||||||
|
|
||||||
|
@param[in] This The EDKII_VARIABLE_LOCK_PROTOCOL instance.
|
||||||
|
@param[in] VariableName A pointer to the variable name that will be made read-only subsequently.
|
||||||
|
@param[in] VendorGuid A pointer to the vendor GUID that will be made read-only subsequently.
|
||||||
|
|
||||||
|
@retval EFI_SUCCESS The variable specified by the VariableName and the VendorGuid was marked
|
||||||
|
as pending to be read-only.
|
||||||
|
@retval EFI_INVALID_PARAMETER VariableName or VendorGuid is NULL.
|
||||||
|
Or VariableName is an empty string.
|
||||||
|
@retval EFI_ACCESS_DENIED EFI_END_OF_DXE_EVENT_GROUP_GUID or EFI_EVENT_GROUP_READY_TO_BOOT has
|
||||||
|
already been signaled.
|
||||||
|
@retval EFI_OUT_OF_RESOURCES There is not enough resource to hold the lock request.
|
||||||
|
**/
|
||||||
|
typedef
|
||||||
|
EFI_STATUS
|
||||||
|
(EFIAPI * EDKII_VARIABLE_LOCK_PROTOCOL_REQUEST_TO_LOCK) (
|
||||||
|
IN CONST EDKII_VARIABLE_LOCK_PROTOCOL *This,
|
||||||
|
IN CHAR16 *VariableName,
|
||||||
|
IN EFI_GUID *VendorGuid
|
||||||
|
);
|
||||||
|
|
||||||
|
///
|
||||||
|
/// Variable Lock Protocol is related to EDK II-specific implementation of variables
|
||||||
|
/// and intended for use as a means to mark a variable read-only after the event
|
||||||
|
/// EFI_END_OF_DXE_EVENT_GUID is signaled.
|
||||||
|
///
|
||||||
|
struct _EDKII_VARIABLE_LOCK_PROTOCOL {
|
||||||
|
EDKII_VARIABLE_LOCK_PROTOCOL_REQUEST_TO_LOCK RequestToLock;
|
||||||
|
};
|
||||||
|
|
||||||
|
extern EFI_GUID gEdkiiVariableLockProtocolGuid;
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
|
@ -326,6 +326,10 @@
|
||||||
# Include/Protocol/SmmVariableProtocol.h
|
# Include/Protocol/SmmVariableProtocol.h
|
||||||
gEfiSmmVariableProtocolGuid = { 0xed32d533, 0x99e6, 0x4209, { 0x9c, 0xc0, 0x2d, 0x72, 0xcd, 0xd9, 0x98, 0xa7 }}
|
gEfiSmmVariableProtocolGuid = { 0xed32d533, 0x99e6, 0x4209, { 0x9c, 0xc0, 0x2d, 0x72, 0xcd, 0xd9, 0x98, 0xa7 }}
|
||||||
|
|
||||||
|
## This protocol is intended for use as a means to mark a variable read-only after the event EFI_END_OF_DXE_EVENT_GUID is signaled.
|
||||||
|
# Include/Protocol/VariableLock.h
|
||||||
|
gEdkiiVariableLockProtocolGuid = { 0xcd3d0a05, 0x9e24, 0x437c, { 0xa8, 0x91, 0x1e, 0xe0, 0x53, 0xdb, 0x76, 0x38 }}
|
||||||
|
|
||||||
## This protocol is similar with DXE FVB protocol and used in the UEFI SMM evvironment.
|
## This protocol is similar with DXE FVB protocol and used in the UEFI SMM evvironment.
|
||||||
# Include/Protocol/SmmFirmwareVolumeBlock.h
|
# Include/Protocol/SmmFirmwareVolumeBlock.h
|
||||||
gEfiSmmFirmwareVolumeBlockProtocolGuid = { 0xd326d041, 0xbd31, 0x4c01, { 0xb5, 0xa8, 0x62, 0x8b, 0xe8, 0x7f, 0x6, 0x53 }}
|
gEfiSmmFirmwareVolumeBlockProtocolGuid = { 0xd326d041, 0xbd31, 0x4c01, { 0xb5, 0xa8, 0x62, 0x8b, 0xe8, 0x7f, 0x6, 0x53 }}
|
||||||
|
|
|
@ -21,12 +21,28 @@ VARIABLE_MODULE_GLOBAL *mVariableModuleGlobal;
|
||||||
///
|
///
|
||||||
/// Define a memory cache that improves the search performance for a variable.
|
/// Define a memory cache that improves the search performance for a variable.
|
||||||
///
|
///
|
||||||
VARIABLE_STORE_HEADER *mNvVariableCache = NULL;
|
VARIABLE_STORE_HEADER *mNvVariableCache = NULL;
|
||||||
|
|
||||||
///
|
///
|
||||||
/// The memory entry used for variable statistics data.
|
/// The memory entry used for variable statistics data.
|
||||||
///
|
///
|
||||||
VARIABLE_INFO_ENTRY *gVariableInfo = NULL;
|
VARIABLE_INFO_ENTRY *gVariableInfo = NULL;
|
||||||
|
|
||||||
|
///
|
||||||
|
/// The list to store the variables which cannot be set after the EFI_END_OF_DXE_EVENT_GROUP_GUID
|
||||||
|
/// or EVT_GROUP_READY_TO_BOOT event.
|
||||||
|
///
|
||||||
|
LIST_ENTRY mLockedVariableList = INITIALIZE_LIST_HEAD_VARIABLE (mLockedVariableList);
|
||||||
|
|
||||||
|
///
|
||||||
|
/// The flag to indicate whether the platform has left the DXE phase of execution.
|
||||||
|
///
|
||||||
|
BOOLEAN mEndOfDxe = FALSE;
|
||||||
|
|
||||||
|
///
|
||||||
|
/// The flag to indicate whether the variable storage locking is enabled.
|
||||||
|
///
|
||||||
|
BOOLEAN mEnableLocking = TRUE;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1918,6 +1934,58 @@ IsHwErrRecVariable (
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Mark a variable that will become read-only after leaving the DXE phase of execution.
|
||||||
|
|
||||||
|
@param[in] This The VARIABLE_LOCK_PROTOCOL instance.
|
||||||
|
@param[in] VariableName A pointer to the variable name that will be made read-only subsequently.
|
||||||
|
@param[in] VendorGuid A pointer to the vendor GUID that will be made read-only subsequently.
|
||||||
|
|
||||||
|
@retval EFI_SUCCESS The variable specified by the VariableName and the VendorGuid was marked
|
||||||
|
as pending to be read-only.
|
||||||
|
@retval EFI_INVALID_PARAMETER VariableName or VendorGuid is NULL.
|
||||||
|
Or VariableName is an empty string.
|
||||||
|
@retval EFI_ACCESS_DENIED EFI_END_OF_DXE_EVENT_GROUP_GUID or EFI_EVENT_GROUP_READY_TO_BOOT has
|
||||||
|
already been signaled.
|
||||||
|
@retval EFI_OUT_OF_RESOURCES There is not enough resource to hold the lock request.
|
||||||
|
**/
|
||||||
|
EFI_STATUS
|
||||||
|
EFIAPI
|
||||||
|
VariableLockRequestToLock (
|
||||||
|
IN CONST EDKII_VARIABLE_LOCK_PROTOCOL *This,
|
||||||
|
IN CHAR16 *VariableName,
|
||||||
|
IN EFI_GUID *VendorGuid
|
||||||
|
)
|
||||||
|
{
|
||||||
|
VARIABLE_ENTRY *Entry;
|
||||||
|
|
||||||
|
if (VariableName == NULL || VariableName[0] == 0 || VendorGuid == NULL) {
|
||||||
|
return EFI_INVALID_PARAMETER;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mEndOfDxe) {
|
||||||
|
return EFI_ACCESS_DENIED;
|
||||||
|
}
|
||||||
|
|
||||||
|
Entry = AllocateRuntimePool (sizeof (*Entry) + StrSize (VariableName));
|
||||||
|
if (Entry == NULL) {
|
||||||
|
return EFI_OUT_OF_RESOURCES;
|
||||||
|
}
|
||||||
|
|
||||||
|
DEBUG ((EFI_D_INFO, "[Variable] Lock: %g:%s\n", VendorGuid, VariableName));
|
||||||
|
|
||||||
|
AcquireLockOnlyAtBootTime(&mVariableModuleGlobal->VariableGlobal.VariableServicesLock);
|
||||||
|
|
||||||
|
Entry->Name = (CHAR16 *) (Entry + 1);
|
||||||
|
StrCpy (Entry->Name, VariableName);
|
||||||
|
CopyGuid (&Entry->Guid, VendorGuid);
|
||||||
|
InsertTailList (&mLockedVariableList, &Entry->Link);
|
||||||
|
|
||||||
|
ReleaseLockOnlyAtBootTime (&mVariableModuleGlobal->VariableGlobal.VariableServicesLock);
|
||||||
|
|
||||||
|
return EFI_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
||||||
This code finds variable in storage blocks (Volatile or Non-Volatile).
|
This code finds variable in storage blocks (Volatile or Non-Volatile).
|
||||||
|
@ -2192,6 +2260,8 @@ VariableServiceSetVariable (
|
||||||
EFI_STATUS Status;
|
EFI_STATUS Status;
|
||||||
VARIABLE_HEADER *NextVariable;
|
VARIABLE_HEADER *NextVariable;
|
||||||
EFI_PHYSICAL_ADDRESS Point;
|
EFI_PHYSICAL_ADDRESS Point;
|
||||||
|
LIST_ENTRY *Link;
|
||||||
|
VARIABLE_ENTRY *Entry;
|
||||||
|
|
||||||
//
|
//
|
||||||
// Check input parameters.
|
// Check input parameters.
|
||||||
|
@ -2247,16 +2317,6 @@ VariableServiceSetVariable (
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (AtRuntime ()) {
|
|
||||||
//
|
|
||||||
// HwErrRecSupport Global Variable identifies the level of hardware error record persistence
|
|
||||||
// support implemented by the platform. This variable is only modified by firmware and is read-only to the OS.
|
|
||||||
//
|
|
||||||
if (CompareGuid (VendorGuid, &gEfiGlobalVariableGuid) && (StrCmp (VariableName, L"HwErrRecSupport") == 0)) {
|
|
||||||
return EFI_WRITE_PROTECTED;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
AcquireLockOnlyAtBootTime(&mVariableModuleGlobal->VariableGlobal.VariableServicesLock);
|
AcquireLockOnlyAtBootTime(&mVariableModuleGlobal->VariableGlobal.VariableServicesLock);
|
||||||
|
|
||||||
//
|
//
|
||||||
|
@ -2275,13 +2335,31 @@ VariableServiceSetVariable (
|
||||||
mVariableModuleGlobal->NonVolatileLastVariableOffset = (UINTN) NextVariable - (UINTN) Point;
|
mVariableModuleGlobal->NonVolatileLastVariableOffset = (UINTN) NextVariable - (UINTN) Point;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (mEndOfDxe && mEnableLocking) {
|
||||||
|
//
|
||||||
|
// Treat the variables listed in the forbidden variable list as read-only after leaving DXE phase.
|
||||||
|
//
|
||||||
|
for ( Link = GetFirstNode (&mLockedVariableList)
|
||||||
|
; !IsNull (&mLockedVariableList, Link)
|
||||||
|
; Link = GetNextNode (&mLockedVariableList, Link)
|
||||||
|
) {
|
||||||
|
Entry = BASE_CR (Link, VARIABLE_ENTRY, Link);
|
||||||
|
if (CompareGuid (&Entry->Guid, VendorGuid) && (StrCmp (Entry->Name, VariableName) == 0)) {
|
||||||
|
Status = EFI_WRITE_PROTECTED;
|
||||||
|
DEBUG ((EFI_D_INFO, "[Variable]: Changing readonly variable after leaving DXE phase - %g:%s\n", VendorGuid, VariableName));
|
||||||
|
goto Done;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// Check whether the input variable is already existed.
|
// Check whether the input variable is already existed.
|
||||||
//
|
//
|
||||||
Status = FindVariable (VariableName, VendorGuid, &Variable, &mVariableModuleGlobal->VariableGlobal, TRUE);
|
Status = FindVariable (VariableName, VendorGuid, &Variable, &mVariableModuleGlobal->VariableGlobal, TRUE);
|
||||||
if (!EFI_ERROR (Status)) {
|
if (!EFI_ERROR (Status)) {
|
||||||
if (((Variable.CurrPtr->Attributes & EFI_VARIABLE_RUNTIME_ACCESS) == 0) && AtRuntime ()) {
|
if (((Variable.CurrPtr->Attributes & EFI_VARIABLE_RUNTIME_ACCESS) == 0) && AtRuntime ()) {
|
||||||
return EFI_WRITE_PROTECTED;
|
Status = EFI_WRITE_PROTECTED;
|
||||||
|
goto Done;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2292,6 +2370,7 @@ VariableServiceSetVariable (
|
||||||
|
|
||||||
Status = UpdateVariable (VariableName, VendorGuid, Data, DataSize, Attributes, &Variable);
|
Status = UpdateVariable (VariableName, VendorGuid, Data, DataSize, Attributes, &Variable);
|
||||||
|
|
||||||
|
Done:
|
||||||
InterlockedDecrement (&mVariableModuleGlobal->VariableGlobal.ReentrantState);
|
InterlockedDecrement (&mVariableModuleGlobal->VariableGlobal.ReentrantState);
|
||||||
ReleaseLockOnlyAtBootTime (&mVariableModuleGlobal->VariableGlobal.VariableServicesLock);
|
ReleaseLockOnlyAtBootTime (&mVariableModuleGlobal->VariableGlobal.VariableServicesLock);
|
||||||
|
|
||||||
|
|
|
@ -22,6 +22,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||||
#include <Protocol/FaultTolerantWrite.h>
|
#include <Protocol/FaultTolerantWrite.h>
|
||||||
#include <Protocol/FirmwareVolumeBlock.h>
|
#include <Protocol/FirmwareVolumeBlock.h>
|
||||||
#include <Protocol/Variable.h>
|
#include <Protocol/Variable.h>
|
||||||
|
#include <Protocol/VariableLock.h>
|
||||||
#include <Library/PcdLib.h>
|
#include <Library/PcdLib.h>
|
||||||
#include <Library/HobLib.h>
|
#include <Library/HobLib.h>
|
||||||
#include <Library/UefiDriverEntryPoint.h>
|
#include <Library/UefiDriverEntryPoint.h>
|
||||||
|
@ -97,6 +98,12 @@ typedef struct {
|
||||||
VOID *Data;
|
VOID *Data;
|
||||||
} VARIABLE_CACHE_ENTRY;
|
} VARIABLE_CACHE_ENTRY;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
EFI_GUID Guid;
|
||||||
|
CHAR16 *Name;
|
||||||
|
LIST_ENTRY Link;
|
||||||
|
} VARIABLE_ENTRY;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Flush the HOB variable to flash.
|
Flush the HOB variable to flash.
|
||||||
|
|
||||||
|
@ -457,6 +464,29 @@ VariableServiceQueryVariableInfo (
|
||||||
OUT UINT64 *MaximumVariableSize
|
OUT UINT64 *MaximumVariableSize
|
||||||
);
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
Mark a variable that will become read-only after leaving the DXE phase of execution.
|
||||||
|
|
||||||
|
@param[in] This The VARIABLE_LOCK_PROTOCOL instance.
|
||||||
|
@param[in] VariableName A pointer to the variable name that will be made read-only subsequently.
|
||||||
|
@param[in] VendorGuid A pointer to the vendor GUID that will be made read-only subsequently.
|
||||||
|
|
||||||
|
@retval EFI_SUCCESS The variable specified by the VariableName and the VendorGuid was marked
|
||||||
|
as pending to be read-only.
|
||||||
|
@retval EFI_INVALID_PARAMETER VariableName or VendorGuid is NULL.
|
||||||
|
Or VariableName is an empty string.
|
||||||
|
@retval EFI_ACCESS_DENIED EFI_END_OF_DXE_EVENT_GROUP_GUID or EFI_EVENT_GROUP_READY_TO_BOOT has
|
||||||
|
already been signaled.
|
||||||
|
@retval EFI_OUT_OF_RESOURCES There is not enough resource to hold the lock request.
|
||||||
|
**/
|
||||||
|
EFI_STATUS
|
||||||
|
EFIAPI
|
||||||
|
VariableLockRequestToLock (
|
||||||
|
IN CONST EDKII_VARIABLE_LOCK_PROTOCOL *This,
|
||||||
|
IN CHAR16 *VariableName,
|
||||||
|
IN EFI_GUID *VendorGuid
|
||||||
|
);
|
||||||
|
|
||||||
extern VARIABLE_MODULE_GLOBAL *mVariableModuleGlobal;
|
extern VARIABLE_MODULE_GLOBAL *mVariableModuleGlobal;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
Implement all four UEFI Runtime Variable services for the nonvolatile
|
Implement all four UEFI Runtime Variable services for the nonvolatile
|
||||||
and volatile storage space and install variable architecture protocol.
|
and volatile storage space and install variable architecture protocol.
|
||||||
|
|
||||||
Copyright (c) 2006 - 2012, Intel Corporation. All rights reserved.<BR>
|
Copyright (c) 2006 - 2013, Intel Corporation. All rights reserved.<BR>
|
||||||
This program and the accompanying materials
|
This program and the accompanying materials
|
||||||
are licensed and made available under the terms and conditions of the BSD License
|
are licensed and made available under the terms and conditions of the BSD License
|
||||||
which accompanies this distribution. The full text of the license may be found at
|
which accompanies this distribution. The full text of the license may be found at
|
||||||
|
@ -21,6 +21,9 @@ extern VARIABLE_INFO_ENTRY *gVariableInfo;
|
||||||
EFI_HANDLE mHandle = NULL;
|
EFI_HANDLE mHandle = NULL;
|
||||||
EFI_EVENT mVirtualAddressChangeEvent = NULL;
|
EFI_EVENT mVirtualAddressChangeEvent = NULL;
|
||||||
EFI_EVENT mFtwRegistration = NULL;
|
EFI_EVENT mFtwRegistration = NULL;
|
||||||
|
extern BOOLEAN mEndOfDxe;
|
||||||
|
extern BOOLEAN mEnableLocking;
|
||||||
|
EDKII_VARIABLE_LOCK_PROTOCOL mVariableLock = { VariableLockRequestToLock };
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Return TRUE if ExitBootServices () has been called.
|
Return TRUE if ExitBootServices () has been called.
|
||||||
|
@ -255,12 +258,34 @@ OnReadyToBoot (
|
||||||
VOID *Context
|
VOID *Context
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
|
//
|
||||||
|
// Set the End Of DXE bit in case the EFI_END_OF_DXE_EVENT_GROUP_GUID event is not signaled.
|
||||||
|
//
|
||||||
|
mEndOfDxe = TRUE;
|
||||||
ReclaimForOS ();
|
ReclaimForOS ();
|
||||||
if (FeaturePcdGet (PcdVariableCollectStatistics)) {
|
if (FeaturePcdGet (PcdVariableCollectStatistics)) {
|
||||||
gBS->InstallConfigurationTable (&gEfiVariableGuid, gVariableInfo);
|
gBS->InstallConfigurationTable (&gEfiVariableGuid, gVariableInfo);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Notification function of EFI_END_OF_DXE_EVENT_GROUP_GUID event group.
|
||||||
|
|
||||||
|
This is a notification function registered on EFI_END_OF_DXE_EVENT_GROUP_GUID event group.
|
||||||
|
|
||||||
|
@param Event Event whose notification function is being invoked.
|
||||||
|
@param Context Pointer to the notification function's context.
|
||||||
|
|
||||||
|
**/
|
||||||
|
VOID
|
||||||
|
EFIAPI
|
||||||
|
OnEndOfDxe (
|
||||||
|
EFI_EVENT Event,
|
||||||
|
VOID *Context
|
||||||
|
)
|
||||||
|
{
|
||||||
|
mEndOfDxe = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Fault Tolerant Write protocol notification event handler.
|
Fault Tolerant Write protocol notification event handler.
|
||||||
|
@ -376,10 +401,19 @@ VariableServiceInitialize (
|
||||||
{
|
{
|
||||||
EFI_STATUS Status;
|
EFI_STATUS Status;
|
||||||
EFI_EVENT ReadyToBootEvent;
|
EFI_EVENT ReadyToBootEvent;
|
||||||
|
EFI_EVENT EndOfDxeEvent;
|
||||||
|
|
||||||
Status = VariableCommonInitialize ();
|
Status = VariableCommonInitialize ();
|
||||||
ASSERT_EFI_ERROR (Status);
|
ASSERT_EFI_ERROR (Status);
|
||||||
|
|
||||||
|
Status = gBS->InstallMultipleProtocolInterfaces (
|
||||||
|
&mHandle,
|
||||||
|
&gEdkiiVariableLockProtocolGuid,
|
||||||
|
&mVariableLock,
|
||||||
|
NULL
|
||||||
|
);
|
||||||
|
ASSERT_EFI_ERROR (Status);
|
||||||
|
|
||||||
SystemTable->RuntimeServices->GetVariable = VariableServiceGetVariable;
|
SystemTable->RuntimeServices->GetVariable = VariableServiceGetVariable;
|
||||||
SystemTable->RuntimeServices->GetNextVariableName = VariableServiceGetNextVariableName;
|
SystemTable->RuntimeServices->GetNextVariableName = VariableServiceGetNextVariableName;
|
||||||
SystemTable->RuntimeServices->SetVariable = VariableServiceSetVariable;
|
SystemTable->RuntimeServices->SetVariable = VariableServiceSetVariable;
|
||||||
|
@ -426,6 +460,20 @@ VariableServiceInitialize (
|
||||||
NULL,
|
NULL,
|
||||||
&ReadyToBootEvent
|
&ReadyToBootEvent
|
||||||
);
|
);
|
||||||
|
ASSERT_EFI_ERROR (Status);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Register the event handling function to set the End Of DXE flag.
|
||||||
|
//
|
||||||
|
Status = gBS->CreateEventEx (
|
||||||
|
EVT_NOTIFY_SIGNAL,
|
||||||
|
TPL_NOTIFY,
|
||||||
|
OnEndOfDxe,
|
||||||
|
NULL,
|
||||||
|
&gEfiEndOfDxeEventGroupGuid,
|
||||||
|
&EndOfDxeEvent
|
||||||
|
);
|
||||||
|
ASSERT_EFI_ERROR (Status);
|
||||||
|
|
||||||
return EFI_SUCCESS;
|
return EFI_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
# Component description file for Variable module.
|
# Component description file for Variable module.
|
||||||
#
|
#
|
||||||
# This module installs three EFI_RUNTIME_SERVICES: SetVariable, GetVariable, GetNextVariableName.
|
# This module installs three EFI_RUNTIME_SERVICES: SetVariable, GetVariable, GetNextVariableName.
|
||||||
# Copyright (c) 2006 - 2012, Intel Corporation. All rights reserved.<BR>
|
# Copyright (c) 2006 - 2013, Intel Corporation. All rights reserved.<BR>
|
||||||
#
|
#
|
||||||
# This program and the accompanying materials
|
# This program and the accompanying materials
|
||||||
# are licensed and made available under the terms and conditions of the BSD License
|
# are licensed and made available under the terms and conditions of the BSD License
|
||||||
|
@ -59,13 +59,15 @@
|
||||||
gEfiVariableWriteArchProtocolGuid ## ALWAYS_PRODUCES
|
gEfiVariableWriteArchProtocolGuid ## ALWAYS_PRODUCES
|
||||||
gEfiVariableArchProtocolGuid ## ALWAYS_PRODUCES
|
gEfiVariableArchProtocolGuid ## ALWAYS_PRODUCES
|
||||||
gEfiFaultTolerantWriteProtocolGuid ## SOMETIMES_CONSUMES
|
gEfiFaultTolerantWriteProtocolGuid ## SOMETIMES_CONSUMES
|
||||||
|
gEdkiiVariableLockProtocolGuid ## ALWAYS_PRODUCES
|
||||||
|
|
||||||
[Guids]
|
[Guids]
|
||||||
gEfiVariableGuid ## PRODUCES ## Configuration Table Guid
|
gEfiVariableGuid ## PRODUCES ## Configuration Table Guid
|
||||||
gEfiGlobalVariableGuid ## PRODUCES ## Variable Guid
|
gEfiGlobalVariableGuid ## PRODUCES ## Variable Guid
|
||||||
gEfiEventVirtualAddressChangeGuid ## PRODUCES ## Event
|
gEfiEventVirtualAddressChangeGuid ## CONSUMES ## Event
|
||||||
gEfiSystemNvDataFvGuid ## CONSUMES
|
gEfiSystemNvDataFvGuid ## CONSUMES
|
||||||
gEfiHardwareErrorVariableGuid ## SOMETIMES_CONSUMES
|
gEfiHardwareErrorVariableGuid ## SOMETIMES_CONSUMES
|
||||||
|
gEfiEndOfDxeEventGroupGuid ## CONSUMES ## Event
|
||||||
|
|
||||||
[Pcd]
|
[Pcd]
|
||||||
gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableSize
|
gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableSize
|
||||||
|
|
|
@ -29,6 +29,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||||
#include <Protocol/SmmFirmwareVolumeBlock.h>
|
#include <Protocol/SmmFirmwareVolumeBlock.h>
|
||||||
#include <Protocol/SmmFaultTolerantWrite.h>
|
#include <Protocol/SmmFaultTolerantWrite.h>
|
||||||
#include <Protocol/SmmAccess2.h>
|
#include <Protocol/SmmAccess2.h>
|
||||||
|
#include <Protocol/SmmEndOfDxe.h>
|
||||||
|
|
||||||
#include <Library/SmmServicesTableLib.h>
|
#include <Library/SmmServicesTableLib.h>
|
||||||
|
|
||||||
|
@ -46,15 +47,61 @@ BOOLEAN mAtRuntime = F
|
||||||
EFI_GUID mZeroGuid = {0, 0, 0, {0, 0, 0, 0, 0, 0, 0, 0}};
|
EFI_GUID mZeroGuid = {0, 0, 0, {0, 0, 0, 0, 0, 0, 0, 0}};
|
||||||
UINT8 *mVariableBufferPayload = NULL;
|
UINT8 *mVariableBufferPayload = NULL;
|
||||||
UINTN mVariableBufferPayloadSize;
|
UINTN mVariableBufferPayloadSize;
|
||||||
|
extern BOOLEAN mEndOfDxe;
|
||||||
|
extern BOOLEAN mEnableLocking;
|
||||||
|
|
||||||
|
/**
|
||||||
|
|
||||||
|
This code sets variable in storage blocks (Volatile or Non-Volatile).
|
||||||
|
|
||||||
|
@param VariableName Name of Variable to be found.
|
||||||
|
@param VendorGuid Variable vendor GUID.
|
||||||
|
@param Attributes Attribute value of the variable found
|
||||||
|
@param DataSize Size of Data found. If size is less than the
|
||||||
|
data, this value contains the required size.
|
||||||
|
@param Data Data pointer.
|
||||||
|
|
||||||
|
@return EFI_INVALID_PARAMETER Invalid parameter.
|
||||||
|
@return EFI_SUCCESS Set successfully.
|
||||||
|
@return EFI_OUT_OF_RESOURCES Resource not enough to set variable.
|
||||||
|
@return EFI_NOT_FOUND Not found.
|
||||||
|
@return EFI_WRITE_PROTECTED Variable is read-only.
|
||||||
|
|
||||||
|
**/
|
||||||
|
EFI_STATUS
|
||||||
|
EFIAPI
|
||||||
|
SmmVariableSetVariable (
|
||||||
|
IN CHAR16 *VariableName,
|
||||||
|
IN EFI_GUID *VendorGuid,
|
||||||
|
IN UINT32 Attributes,
|
||||||
|
IN UINTN DataSize,
|
||||||
|
IN VOID *Data
|
||||||
|
)
|
||||||
|
{
|
||||||
|
EFI_STATUS Status;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Disable write protection when the calling SetVariable() through EFI_SMM_VARIABLE_PROTOCOL.
|
||||||
|
//
|
||||||
|
mEnableLocking = FALSE;
|
||||||
|
Status = VariableServiceSetVariable (
|
||||||
|
VariableName,
|
||||||
|
VendorGuid,
|
||||||
|
Attributes,
|
||||||
|
DataSize,
|
||||||
|
Data
|
||||||
|
);
|
||||||
|
mEnableLocking = TRUE;
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
EFI_SMM_VARIABLE_PROTOCOL gSmmVariable = {
|
EFI_SMM_VARIABLE_PROTOCOL gSmmVariable = {
|
||||||
VariableServiceGetVariable,
|
VariableServiceGetVariable,
|
||||||
VariableServiceGetNextVariableName,
|
VariableServiceGetNextVariableName,
|
||||||
VariableServiceSetVariable,
|
SmmVariableSetVariable,
|
||||||
VariableServiceQueryVariableInfo
|
VariableServiceQueryVariableInfo
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Return TRUE if ExitBootServices () has been called.
|
Return TRUE if ExitBootServices () has been called.
|
||||||
|
|
||||||
|
@ -450,6 +497,7 @@ SmmVariableHandler (
|
||||||
SMM_VARIABLE_COMMUNICATE_GET_NEXT_VARIABLE_NAME *GetNextVariableName;
|
SMM_VARIABLE_COMMUNICATE_GET_NEXT_VARIABLE_NAME *GetNextVariableName;
|
||||||
SMM_VARIABLE_COMMUNICATE_QUERY_VARIABLE_INFO *QueryVariableInfo;
|
SMM_VARIABLE_COMMUNICATE_QUERY_VARIABLE_INFO *QueryVariableInfo;
|
||||||
VARIABLE_INFO_ENTRY *VariableInfo;
|
VARIABLE_INFO_ENTRY *VariableInfo;
|
||||||
|
SMM_VARIABLE_COMMUNICATE_LOCK_VARIABLE *VariableToLock;
|
||||||
UINTN InfoSize;
|
UINTN InfoSize;
|
||||||
UINTN NameBufferSize;
|
UINTN NameBufferSize;
|
||||||
UINTN CommBufferPayloadSize;
|
UINTN CommBufferPayloadSize;
|
||||||
|
@ -635,6 +683,7 @@ SmmVariableHandler (
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SMM_VARIABLE_FUNCTION_READY_TO_BOOT:
|
case SMM_VARIABLE_FUNCTION_READY_TO_BOOT:
|
||||||
|
mEndOfDxe = TRUE;
|
||||||
if (AtRuntime()) {
|
if (AtRuntime()) {
|
||||||
Status = EFI_UNSUPPORTED;
|
Status = EFI_UNSUPPORTED;
|
||||||
break;
|
break;
|
||||||
|
@ -667,6 +716,51 @@ SmmVariableHandler (
|
||||||
*CommBufferSize = InfoSize + SMM_VARIABLE_COMMUNICATE_HEADER_SIZE;
|
*CommBufferSize = InfoSize + SMM_VARIABLE_COMMUNICATE_HEADER_SIZE;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case SMM_VARIABLE_FUNCTION_LOCK_VARIABLE:
|
||||||
|
if (CommBufferPayloadSize < OFFSET_OF(SMM_VARIABLE_COMMUNICATE_LOCK_VARIABLE, Name)) {
|
||||||
|
DEBUG ((EFI_D_ERROR, "RequestToLock: SMM communication buffer size invalid!\n"));
|
||||||
|
return EFI_SUCCESS;
|
||||||
|
}
|
||||||
|
//
|
||||||
|
// Copy the input communicate buffer payload to pre-allocated SMM variable buffer payload.
|
||||||
|
//
|
||||||
|
CopyMem (mVariableBufferPayload, SmmVariableFunctionHeader->Data, CommBufferPayloadSize);
|
||||||
|
VariableToLock = (SMM_VARIABLE_COMMUNICATE_LOCK_VARIABLE *) mVariableBufferPayload;
|
||||||
|
|
||||||
|
if (VariableToLock->NameSize > MAX_ADDRESS - OFFSET_OF (SMM_VARIABLE_COMMUNICATE_LOCK_VARIABLE, Name)) {
|
||||||
|
//
|
||||||
|
// Prevent InfoSize overflow happen
|
||||||
|
//
|
||||||
|
Status = EFI_ACCESS_DENIED;
|
||||||
|
goto EXIT;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (VariableToLock->NameSize < sizeof (CHAR16) || VariableToLock->Name[VariableToLock->NameSize/sizeof (CHAR16) - 1] != L'\0') {
|
||||||
|
//
|
||||||
|
// Make sure VariableName is A Null-terminated string.
|
||||||
|
//
|
||||||
|
Status = EFI_ACCESS_DENIED;
|
||||||
|
goto EXIT;
|
||||||
|
}
|
||||||
|
|
||||||
|
InfoSize = OFFSET_OF (SMM_VARIABLE_COMMUNICATE_LOCK_VARIABLE, Name) + VariableToLock->NameSize;
|
||||||
|
|
||||||
|
//
|
||||||
|
// SMRAM range check already covered before
|
||||||
|
//
|
||||||
|
if (InfoSize > CommBufferPayloadSize) {
|
||||||
|
DEBUG ((EFI_D_ERROR, "Data size exceed communication buffer size limit!\n"));
|
||||||
|
Status = EFI_ACCESS_DENIED;
|
||||||
|
goto EXIT;
|
||||||
|
}
|
||||||
|
|
||||||
|
Status = VariableLockRequestToLock (
|
||||||
|
NULL,
|
||||||
|
VariableToLock->Name,
|
||||||
|
&VariableToLock->Guid
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
Status = EFI_UNSUPPORTED;
|
Status = EFI_UNSUPPORTED;
|
||||||
}
|
}
|
||||||
|
@ -678,6 +772,28 @@ EXIT:
|
||||||
return EFI_SUCCESS;
|
return EFI_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
SMM END_OF_DXE protocol notification event handler.
|
||||||
|
|
||||||
|
@param Protocol Points to the protocol's unique identifier
|
||||||
|
@param Interface Points to the interface instance
|
||||||
|
@param Handle The handle on which the interface was installed
|
||||||
|
|
||||||
|
@retval EFI_SUCCESS SmmEndOfDxeCallback runs successfully
|
||||||
|
|
||||||
|
**/
|
||||||
|
EFI_STATUS
|
||||||
|
EFIAPI
|
||||||
|
SmmEndOfDxeCallback (
|
||||||
|
IN CONST EFI_GUID *Protocol,
|
||||||
|
IN VOID *Interface,
|
||||||
|
IN EFI_HANDLE Handle
|
||||||
|
)
|
||||||
|
{
|
||||||
|
DEBUG ((EFI_D_INFO, "[Variable]END_OF_DXE is signaled\n"));
|
||||||
|
mEndOfDxe = TRUE;
|
||||||
|
return EFI_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
SMM Fault Tolerant Write protocol notification event handler.
|
SMM Fault Tolerant Write protocol notification event handler.
|
||||||
|
@ -774,6 +890,7 @@ VariableServiceInitialize (
|
||||||
VOID *SmmFtwRegistration;
|
VOID *SmmFtwRegistration;
|
||||||
EFI_SMM_ACCESS2_PROTOCOL *SmmAccess;
|
EFI_SMM_ACCESS2_PROTOCOL *SmmAccess;
|
||||||
UINTN Size;
|
UINTN Size;
|
||||||
|
VOID *SmmEndOfDxeRegistration;
|
||||||
|
|
||||||
//
|
//
|
||||||
// Variable initialize.
|
// Variable initialize.
|
||||||
|
@ -843,6 +960,16 @@ VariableServiceInitialize (
|
||||||
);
|
);
|
||||||
ASSERT_EFI_ERROR (Status);
|
ASSERT_EFI_ERROR (Status);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Register EFI_SMM_END_OF_DXE_PROTOCOL_GUID notify function.
|
||||||
|
//
|
||||||
|
Status = gSmst->SmmRegisterProtocolNotify (
|
||||||
|
&gEfiSmmEndOfDxeProtocolGuid,
|
||||||
|
SmmEndOfDxeCallback,
|
||||||
|
&SmmEndOfDxeRegistration
|
||||||
|
);
|
||||||
|
ASSERT_EFI_ERROR (Status);
|
||||||
|
|
||||||
//
|
//
|
||||||
// Register FtwNotificationEvent () notify function.
|
// Register FtwNotificationEvent () notify function.
|
||||||
//
|
//
|
||||||
|
|
|
@ -14,7 +14,7 @@
|
||||||
# This external input must be validated carefully to avoid security issue like
|
# This external input must be validated carefully to avoid security issue like
|
||||||
# buffer overflow, integer overflow.
|
# buffer overflow, integer overflow.
|
||||||
#
|
#
|
||||||
# Copyright (c) 2010 - 2012, Intel Corporation. All rights reserved.<BR>
|
# Copyright (c) 2010 - 2013, Intel Corporation. All rights reserved.<BR>
|
||||||
# This program and the accompanying materials
|
# This program and the accompanying materials
|
||||||
# are licensed and made available under the terms and conditions of the BSD License
|
# are licensed and made available under the terms and conditions of the BSD License
|
||||||
# which accompanies this distribution. The full text of the license may be found at
|
# which accompanies this distribution. The full text of the license may be found at
|
||||||
|
@ -69,6 +69,7 @@
|
||||||
gEfiSmmVariableProtocolGuid ## ALWAYS_PRODUCES
|
gEfiSmmVariableProtocolGuid ## ALWAYS_PRODUCES
|
||||||
gEfiSmmFaultTolerantWriteProtocolGuid ## SOMETIMES_CONSUMES
|
gEfiSmmFaultTolerantWriteProtocolGuid ## SOMETIMES_CONSUMES
|
||||||
gEfiSmmAccess2ProtocolGuid ## ALWAYS_CONSUMES
|
gEfiSmmAccess2ProtocolGuid ## ALWAYS_CONSUMES
|
||||||
|
gEfiSmmEndOfDxeProtocolGuid ## ALWAYS_CONSUMES
|
||||||
|
|
||||||
[Guids]
|
[Guids]
|
||||||
gEfiVariableGuid ## PRODUCES ## Configuration Table Guid
|
gEfiVariableGuid ## PRODUCES ## Configuration Table Guid
|
||||||
|
|
|
@ -19,6 +19,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||||
#include <Protocol/Variable.h>
|
#include <Protocol/Variable.h>
|
||||||
#include <Protocol/SmmCommunication.h>
|
#include <Protocol/SmmCommunication.h>
|
||||||
#include <Protocol/SmmVariable.h>
|
#include <Protocol/SmmVariable.h>
|
||||||
|
#include <Protocol/VariableLock.h>
|
||||||
|
|
||||||
#include <Library/UefiBootServicesTableLib.h>
|
#include <Library/UefiBootServicesTableLib.h>
|
||||||
#include <Library/UefiRuntimeServicesTableLib.h>
|
#include <Library/UefiRuntimeServicesTableLib.h>
|
||||||
|
@ -44,6 +45,7 @@ UINT8 *mVariableBufferPhysical = NULL;
|
||||||
UINTN mVariableBufferSize;
|
UINTN mVariableBufferSize;
|
||||||
UINTN mVariableBufferPayloadSize;
|
UINTN mVariableBufferPayloadSize;
|
||||||
EFI_LOCK mVariableServicesLock;
|
EFI_LOCK mVariableServicesLock;
|
||||||
|
EDKII_VARIABLE_LOCK_PROTOCOL mVariableLock;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Acquires lock only at boot time. Simply returns at runtime.
|
Acquires lock only at boot time. Simply returns at runtime.
|
||||||
|
@ -160,6 +162,63 @@ SendCommunicateBuffer (
|
||||||
return SmmVariableFunctionHeader->ReturnStatus;
|
return SmmVariableFunctionHeader->ReturnStatus;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Mark a variable that will become read-only after leaving the DXE phase of execution.
|
||||||
|
|
||||||
|
@param[in] This The VARIABLE_LOCK_PROTOCOL instance.
|
||||||
|
@param[in] VariableName A pointer to the variable name that will be made read-only subsequently.
|
||||||
|
@param[in] VendorGuid A pointer to the vendor GUID that will be made read-only subsequently.
|
||||||
|
|
||||||
|
@retval EFI_SUCCESS The variable specified by the VariableName and the VendorGuid was marked
|
||||||
|
as pending to be read-only.
|
||||||
|
@retval EFI_INVALID_PARAMETER VariableName or VendorGuid is NULL.
|
||||||
|
Or VariableName is an empty string.
|
||||||
|
@retval EFI_ACCESS_DENIED EFI_END_OF_DXE_EVENT_GROUP_GUID or EFI_EVENT_GROUP_READY_TO_BOOT has
|
||||||
|
already been signaled.
|
||||||
|
@retval EFI_OUT_OF_RESOURCES There is not enough resource to hold the lock request.
|
||||||
|
**/
|
||||||
|
EFI_STATUS
|
||||||
|
EFIAPI
|
||||||
|
VariableLockRequestToLock (
|
||||||
|
IN CONST EDKII_VARIABLE_LOCK_PROTOCOL *This,
|
||||||
|
IN CHAR16 *VariableName,
|
||||||
|
IN EFI_GUID *VendorGuid
|
||||||
|
)
|
||||||
|
{
|
||||||
|
EFI_STATUS Status;
|
||||||
|
UINTN PayloadSize;
|
||||||
|
SMM_VARIABLE_COMMUNICATE_LOCK_VARIABLE *VariableToLock;
|
||||||
|
|
||||||
|
if (VariableName == NULL || VariableName[0] == 0 || VendorGuid == NULL) {
|
||||||
|
return EFI_INVALID_PARAMETER;
|
||||||
|
}
|
||||||
|
|
||||||
|
AcquireLockOnlyAtBootTime(&mVariableServicesLock);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Init the communicate buffer. The buffer data size is:
|
||||||
|
// SMM_COMMUNICATE_HEADER_SIZE + SMM_VARIABLE_COMMUNICATE_HEADER_SIZE + PayloadSize.
|
||||||
|
//
|
||||||
|
PayloadSize = OFFSET_OF (SMM_VARIABLE_COMMUNICATE_LOCK_VARIABLE, Name) + StrSize (VariableName);
|
||||||
|
Status = InitCommunicateBuffer ((VOID **) &VariableToLock, PayloadSize, SMM_VARIABLE_FUNCTION_LOCK_VARIABLE);
|
||||||
|
if (EFI_ERROR (Status)) {
|
||||||
|
goto Done;
|
||||||
|
}
|
||||||
|
ASSERT (VariableToLock != NULL);
|
||||||
|
|
||||||
|
CopyGuid (&VariableToLock->Guid, VendorGuid);
|
||||||
|
VariableToLock->NameSize = StrSize (VariableName);
|
||||||
|
CopyMem (VariableToLock->Name, VariableName, VariableToLock->NameSize);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Send data to SMM.
|
||||||
|
//
|
||||||
|
Status = SendCommunicateBuffer (PayloadSize);
|
||||||
|
|
||||||
|
Done:
|
||||||
|
ReleaseLockOnlyAtBootTime (&mVariableServicesLock);
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
This code finds variable in storage blocks (Volatile or Non-Volatile).
|
This code finds variable in storage blocks (Volatile or Non-Volatile).
|
||||||
|
@ -722,6 +781,7 @@ VariableSmmRuntimeInitialize (
|
||||||
IN EFI_SYSTEM_TABLE *SystemTable
|
IN EFI_SYSTEM_TABLE *SystemTable
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
|
EFI_STATUS Status;
|
||||||
VOID *SmmVariableRegistration;
|
VOID *SmmVariableRegistration;
|
||||||
VOID *SmmVariableWriteRegistration;
|
VOID *SmmVariableWriteRegistration;
|
||||||
EFI_EVENT OnReadyToBootEvent;
|
EFI_EVENT OnReadyToBootEvent;
|
||||||
|
@ -729,6 +789,15 @@ VariableSmmRuntimeInitialize (
|
||||||
|
|
||||||
EfiInitializeLock (&mVariableServicesLock, TPL_NOTIFY);
|
EfiInitializeLock (&mVariableServicesLock, TPL_NOTIFY);
|
||||||
|
|
||||||
|
mVariableLock.RequestToLock = VariableLockRequestToLock;
|
||||||
|
Status = gBS->InstallMultipleProtocolInterfaces (
|
||||||
|
&mHandle,
|
||||||
|
&gEdkiiVariableLockProtocolGuid,
|
||||||
|
&mVariableLock,
|
||||||
|
NULL
|
||||||
|
);
|
||||||
|
ASSERT_EFI_ERROR (Status);
|
||||||
|
|
||||||
//
|
//
|
||||||
// Smm variable service is ready
|
// Smm variable service is ready
|
||||||
//
|
//
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
# This module is the Runtime DXE part correspond to SMM variable module. It
|
# This module is the Runtime DXE part correspond to SMM variable module. It
|
||||||
# installs variable arch protocol and variable write arch protocol and works
|
# installs variable arch protocol and variable write arch protocol and works
|
||||||
# with SMM variable module together.
|
# with SMM variable module together.
|
||||||
# Copyright (c) 2010 - 2011, Intel Corporation. All rights reserved.<BR>
|
# Copyright (c) 2010 - 2013, Intel Corporation. All rights reserved.<BR>
|
||||||
#
|
#
|
||||||
# This program and the accompanying materials
|
# This program and the accompanying materials
|
||||||
# are licensed and made available under the terms and conditions of the BSD License
|
# are licensed and made available under the terms and conditions of the BSD License
|
||||||
|
@ -54,6 +54,7 @@
|
||||||
gEfiVariableArchProtocolGuid ## ALWAYS_PRODUCES
|
gEfiVariableArchProtocolGuid ## ALWAYS_PRODUCES
|
||||||
gEfiSmmCommunicationProtocolGuid
|
gEfiSmmCommunicationProtocolGuid
|
||||||
gEfiSmmVariableProtocolGuid
|
gEfiSmmVariableProtocolGuid
|
||||||
|
gEdkiiVariableLockProtocolGuid ## ALWAYS_PRODUCES
|
||||||
|
|
||||||
[Guids]
|
[Guids]
|
||||||
gEfiEventVirtualAddressChangeGuid ## PRODUCES ## Event
|
gEfiEventVirtualAddressChangeGuid ## PRODUCES ## Event
|
||||||
|
|
Loading…
Reference in New Issue