From nobody Sat Apr 20 15:26:50 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) client-ip=66.175.222.108; envelope-from=bounce+27952+73758+1787277+3901457@groups.io; helo=mail02.groups.io; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) smtp.mailfrom=bounce+27952+73758+1787277+3901457@groups.io; dmarc=fail(p=none dis=none) header.from=intel.com ARC-Seal: i=1; a=rsa-sha256; t=1617764804; cv=none; d=zohomail.com; s=zohoarc; b=M2SpFfw6eCBHlAB2CK/FrpSWSiJKtS6vwODDoS1+yW0hh2uTfkFEKki3K2lLRO2jNyAAQ7RAOZSAPoYG2Ri0nh7cknbinkHXez27LXBabIa26K5TVJdPLj5eNeqq6Y1EehnB5kny898o8sn5UbDsIRAUzGOqQb9Wq5bIbIdTfGM= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1617764804; h=Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Id:List-Help:List-Unsubscribe:MIME-Version:Message-ID:Reply-To:References:Sender:Subject:To; bh=FX24ya4NWyb+Tm9/DJJPJiqHmxcESlPF2qogxkJNJgI=; b=N6310fIMSofK5ouKwwZSpe6k0MhLxkL7aFKm0Ms4itKiQHiixUmt8iIMMWGDp3fS3b7+zydBGkzEI/PvY8vBP9QQe6/5zuHndUar3xVxqb313dw3lQk1TZH+R6CnOEI9iFVZEwpfdiaqQ3D7YzefJIm/4mo+c1nIEa3Hg7wskKY= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) smtp.mailfrom=bounce+27952+73758+1787277+3901457@groups.io; dmarc=fail header.from= (p=none dis=none) header.from= Received: from mail02.groups.io (mail02.groups.io [66.175.222.108]) by mx.zohomail.com with SMTPS id 1617764804724776.0693170932253; Tue, 6 Apr 2021 20:06:44 -0700 (PDT) Return-Path: X-Received: by 127.0.0.2 with SMTP id LXU9YY1788612xEDPHexk3A5; Tue, 06 Apr 2021 20:06:44 -0700 X-Received: from mga07.intel.com (mga07.intel.com [134.134.136.100]) by mx.groups.io with SMTP id smtpd.web10.2006.1617764802929453428 for ; Tue, 06 Apr 2021 20:06:43 -0700 IronPort-SDR: QBdodLU8RRbucLRwdfa1CfnV8D5qD4oLuhVWmfW28zawxFxOV1+UzB/jxZ8RxIuuOAB0LoyEtr QXXeWinKK/sQ== X-IronPort-AV: E=McAfee;i="6000,8403,9946"; a="257193869" X-IronPort-AV: E=Sophos;i="5.82,201,1613462400"; d="scan'208";a="257193869" X-Received: from fmsmga002.fm.intel.com ([10.253.24.26]) by orsmga105.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 06 Apr 2021 20:06:41 -0700 IronPort-SDR: a7TAPZ6X2hTHiTwmgwNQUcPVSI85QUuU5LCVEt9uaqoX+eGGzz8INwx6lw2Ih3cSRFutAdv1o9 G0ALjYiIF3qA== X-IronPort-AV: E=Sophos;i="5.82,201,1613462400"; d="scan'208";a="448896651" X-Received: from nldesimo-desk1.amr.corp.intel.com ([10.209.7.29]) by fmsmga002-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 06 Apr 2021 20:06:38 -0700 From: "Nate DeSimone" To: devel@edk2.groups.io Cc: Chasel Chiu , Liming Gao , Eric Dong , Michael Kubacki , Isaac Oram Subject: [edk2-devel] [edk2-platforms] [PATCH v4 2/4] MinPlatformPkg: Add VariableWriteLib Date: Tue, 6 Apr 2021 20:04:24 -0700 Message-Id: <20210407030426.8075-3-nathaniel.l.desimone@intel.com> In-Reply-To: <20210407030426.8075-1-nathaniel.l.desimone@intel.com> References: <20210407030426.8075-1-nathaniel.l.desimone@intel.com> MIME-Version: 1.0 Precedence: Bulk List-Unsubscribe: List-Subscribe: List-Help: Sender: devel@edk2.groups.io List-Id: Mailing-List: list devel@edk2.groups.io; contact devel+owner@edk2.groups.io Reply-To: devel@edk2.groups.io,nathaniel.l.desimone@intel.com X-Gm-Message-State: HdCMbhC3XDGvxfQsQmu1N8B0x1787277AA= Content-Transfer-Encoding: quoted-printable DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=groups.io; q=dns/txt; s=20140610; t=1617764804; bh=4rBwWS8SGiZ5GgcvgbCcCXmcX+VM3dYxv6Arbbz6YjY=; h=Cc:Date:From:Reply-To:Subject:To; b=ooAHK7bYELz8/u3Fxssy/wXfiQtJ8ErMvipcM6ZpZEiHif2y72mJrDo8B8bSi8LzCRE 4WsztzETRh/8Qb7+CFVEnWXeCOYgbmPb5osS7mBHMe1DK4Jt9jhFycRLBDl1ijHvH4xJ0 ghvhWYfi4Xs9//g8Tg8aCYBh2aG3HuhPZh0= X-ZohoMail-DKIM: pass (identity @groups.io) Content-Type: text/plain; charset="utf-8" VariableWriteLib is a phase agnostic library for writing to UEFI Variables. This library provides the MinSetVariable(), MinQueryVariableInfo(), MinIsVariableRequestToLockSupported(), and MinVariableRequestToLock() APIs which are usable in DXE and SMM. Cc: Chasel Chiu Cc: Liming Gao Cc: Eric Dong Cc: Michael Kubacki Cc: Isaac Oram Signed-off-by: Nate DeSimone Reviewed-by: Isaac Oram --- .../MinPlatformPkg/Include/Dsc/CoreDxeLib.dsc | 2 + .../Include/Library/VariableWriteLib.h | 138 +++++++++ .../DxeRuntimeVariableWriteLib.c | 265 ++++++++++++++++++ .../DxeRuntimeVariableWriteLib.inf | 49 ++++ .../SmmVariableWriteCommon.c | 171 +++++++++++ .../StandaloneMmVariableWriteLib.inf | 45 +++ .../StandaloneMmVariableWriteLibConstructor.c | 51 ++++ .../TraditionalMmVariableWriteLib.inf | 44 +++ ...TraditionalMmVariableWriteLibConstructor.c | 51 ++++ .../Intel/MinPlatformPkg/MinPlatformPkg.dsc | 1 + 10 files changed, 817 insertions(+) create mode 100644 Platform/Intel/MinPlatformPkg/Include/Library/VariableW= riteLib.h create mode 100644 Platform/Intel/MinPlatformPkg/Library/DxeRuntimeVariabl= eWriteLib/DxeRuntimeVariableWriteLib.c create mode 100644 Platform/Intel/MinPlatformPkg/Library/DxeRuntimeVariabl= eWriteLib/DxeRuntimeVariableWriteLib.inf create mode 100644 Platform/Intel/MinPlatformPkg/Library/SmmVariableWriteL= ib/SmmVariableWriteCommon.c create mode 100644 Platform/Intel/MinPlatformPkg/Library/SmmVariableWriteL= ib/StandaloneMmVariableWriteLib.inf create mode 100644 Platform/Intel/MinPlatformPkg/Library/SmmVariableWriteL= ib/StandaloneMmVariableWriteLibConstructor.c create mode 100644 Platform/Intel/MinPlatformPkg/Library/SmmVariableWriteL= ib/TraditionalMmVariableWriteLib.inf create mode 100644 Platform/Intel/MinPlatformPkg/Library/SmmVariableWriteL= ib/TraditionalMmVariableWriteLibConstructor.c diff --git a/Platform/Intel/MinPlatformPkg/Include/Dsc/CoreDxeLib.dsc b/Pla= tform/Intel/MinPlatformPkg/Include/Dsc/CoreDxeLib.dsc index 0db1250ab7..57847e6a4d 100644 --- a/Platform/Intel/MinPlatformPkg/Include/Dsc/CoreDxeLib.dsc +++ b/Platform/Intel/MinPlatformPkg/Include/Dsc/CoreDxeLib.dsc @@ -48,6 +48,7 @@ =20 [LibraryClasses.common.DXE_CORE, LibraryClasses.common.DXE_DRIVER, Library= Classes.common.DXE_RUNTIME_DRIVER, LibraryClasses.common.UEFI_DRIVER, Libra= ryClasses.common.UEFI_APPLICATION] VariableReadLib|MinPlatformPkg/Library/DxeRuntimeVariableReadLib/DxeRunt= imeVariableReadLib.inf + VariableWriteLib|MinPlatformPkg/Library/DxeRuntimeVariableWriteLib/DxeRu= ntimeVariableWriteLib.inf =20 [LibraryClasses.common.DXE_CORE] HobLib|MdePkg/Library/DxeCoreHobLib/DxeCoreHobLib.inf @@ -93,6 +94,7 @@ Tcg2PhysicalPresenceLib|SecurityPkg/Library/SmmTcg2PhysicalPresenceLib/S= mmTcg2PhysicalPresenceLib.inf BaseCryptLib|CryptoPkg/Library/BaseCryptLib/SmmCryptLib.inf VariableReadLib|MinPlatformPkg/Library/SmmVariableReadLib/TraditionalMmV= ariableReadLib.inf + VariableWriteLib|MinPlatformPkg/Library/SmmVariableWriteLib/TraditionalM= mVariableWriteLib.inf =20 [LibraryClasses.common.SMM_CORE] PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf diff --git a/Platform/Intel/MinPlatformPkg/Include/Library/VariableWriteLib= .h b/Platform/Intel/MinPlatformPkg/Include/Library/VariableWriteLib.h new file mode 100644 index 0000000000..fab87f2e48 --- /dev/null +++ b/Platform/Intel/MinPlatformPkg/Include/Library/VariableWriteLib.h @@ -0,0 +1,138 @@ +/** @file + Variable Write Lib + + This library provides phase agnostic access to the UEFI Variable Service= s. + This is done by implementing a wrapper on top of the phase specific mech= anism + for writing to UEFI variables. For example, the DXE implementation acces= ses + the UEFI Runtime Services Table, and the SMM implementation uses + EFI_SMM_VARIABLE_PROTOCOL. + + Using this library allows code to be written in a generic manner that ca= n be + used in DXE or SMM without modification. + + Copyright (c) 2021, Intel Corporation. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef _VARIABLE_WRITE_LIB_H_ +#define _VARIABLE_WRITE_LIB_H_ + +#include + +/** + Sets the value of a variable. + + @param[in] VariableName A Null-terminated string that is the name= of the vendor's variable. + Each VariableName is unique for each Vend= orGuid. VariableName must + contain 1 or more characters. If Variable= Name is an empty string, + then EFI_INVALID_PARAMETER is returned. + @param[in] VendorGuid A unique identifier for the vendor. + @param[in] Attributes Attributes bitmask to set for the variabl= e. + @param[in] DataSize The size in bytes of the Data buffer. Unl= ess the EFI_VARIABLE_APPEND_WRITE or + EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRI= TE_ACCESS attribute is set, a size of zero + causes the variable to be deleted. When t= he EFI_VARIABLE_APPEND_WRITE attribute is + set, then a SetVariable() call with a Dat= aSize of zero will not cause any change to + the variable value (the timestamp associa= ted with the variable may be updated however + even if no new data value is provided,see= the description of the + EFI_VARIABLE_AUTHENTICATION_2 descriptor = below. In this case the DataSize will not + be zero since the EFI_VARIABLE_AUTHENTICA= TION_2 descriptor will be populated). + @param[in] Data The contents for the variable. + + @retval EFI_SUCCESS The firmware has successfully stored the = variable and its data as + defined by the Attributes. + @retval EFI_INVALID_PARAMETER An invalid combination of attribute bits,= name, and GUID was supplied, or the + DataSize exceeds the maximum allowed. + @retval EFI_INVALID_PARAMETER VariableName is an empty string. + @retval EFI_OUT_OF_RESOURCES Not enough storage is available to hold t= he variable and its data. + @retval EFI_DEVICE_ERROR The variable could not be retrieved due t= o a hardware error. + @retval EFI_WRITE_PROTECTED The variable in question is read-only. + @retval EFI_WRITE_PROTECTED The variable in question cannot be delete= d. + @retval EFI_SECURITY_VIOLATION The variable could not be written due to = EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACESS being set, + but the AuthInfo does NOT pass the valida= tion check carried out by the firmware. + @retval EFI_UNSUPPORTED This function is not implemented by this = instance of the LibraryClass + + @retval EFI_NOT_FOUND The variable trying to be updated or dele= ted was not found. + +**/ +EFI_STATUS +EFIAPI +VarLibSetVariable ( + IN CHAR16 *VariableName, + IN EFI_GUID *VendorGuid, + IN UINT32 Attributes, + IN UINTN DataSize, + IN VOID *Data + ); + +/** + Returns information about the EFI variables. + + @param[in] Attributes Attributes bitmask to specify = the type of variables on + which to return information. + @param[out] MaximumVariableStorageSize On output the maximum size of = the storage space + available for the EFI variable= s associated with the + attributes specified. + @param[out] RemainingVariableStorageSize Returns the remaining size of = the storage space + available for the EFI variable= s associated with the + attributes specified. + @param[out] MaximumVariableSize Returns the maximum size of th= e individual EFI + variables associated with the = attributes specified. + + @retval EFI_SUCCESS Valid answer returned. + @retval EFI_INVALID_PARAMETER An invalid combination of attribute= bits was supplied + @retval EFI_UNSUPPORTED The attribute is not supported on t= his platform, and the + MaximumVariableStorageSize, + RemainingVariableStorageSize, Maxim= umVariableSize + are undefined. +**/ +EFI_STATUS +EFIAPI +VarLibQueryVariableInfo ( + IN UINT32 Attributes, + OUT UINT64 *MaximumVariableStorageSize, + OUT UINT64 *RemainingVariableStorageSize, + OUT UINT64 *MaximumVariableSize + ); + +/** + Indicates if the VarLibVariableRequestToLock() API is supported by the c= urrent + VariableWriteLib implementation. At time of writting, this API is not + available in SMM or after ExitBootServices. + + @retval TRUE The VarLibVariableRequestToLock() API is s= upported + @retval FALSE The VarLibVariableRequestToLock() API is n= ot supported + +**/ +BOOLEAN +EFIAPI +VarLibIsVariableRequestToLockSupported ( + VOID + ); + +/** + Mark a variable that will become read-only after leaving the DXE phase o= f execution. + Write request coming from SMM environment through EFI_SMM_VARIABLE_PROTO= COL is allowed. + + @param[in] This The EDKII_VARIABLE_LOCK_PROTOCOL instance. + @param[in] VariableName A pointer to the variable name that will be mad= e 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_EVE= NT_GROUP_READY_TO_BOOT has + already been signaled. + @retval EFI_OUT_OF_RESOURCES There is not enough resource to hold the l= ock request. + @retval EFI_UNSUPPORTED This function is not implemented by this i= nstance of the LibraryClass + +**/ +EFI_STATUS +EFIAPI +VarLibVariableRequestToLock ( + IN CHAR16 *VariableName, + IN EFI_GUID *VendorGuid + ); + +#endif // _VARIABLE_WRITE_LIB_H_ diff --git a/Platform/Intel/MinPlatformPkg/Library/DxeRuntimeVariableWriteL= ib/DxeRuntimeVariableWriteLib.c b/Platform/Intel/MinPlatformPkg/Library/Dxe= RuntimeVariableWriteLib/DxeRuntimeVariableWriteLib.c new file mode 100644 index 0000000000..9ed59f8827 --- /dev/null +++ b/Platform/Intel/MinPlatformPkg/Library/DxeRuntimeVariableWriteLib/DxeR= untimeVariableWriteLib.c @@ -0,0 +1,265 @@ +/** @file + DXE Variable Write Lib + + This library provides phase agnostic access to the UEFI Variable Service= s. + This is done by implementing a wrapper on top of the phase specific mech= anism + for writing to UEFI variables. For example, the DXE implementation acces= ses + the UEFI Runtime Services Table, and the SMM implementation uses + EFI_SMM_VARIABLE_PROTOCOL. + + Using this library allows code to be written in a generic manner that ca= n be + used in DXE or SMM without modification. + + Copyright (c) 2021, Intel Corporation. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include + +#include +#include + +#include +#include +#include +#include + +STATIC EDKII_VARIABLE_LOCK_PROTOCOL *mVariableWriteLibVariableLock =3D NU= LL; + +/** + Sets the value of a variable. + + @param[in] VariableName A Null-terminated string that is the name= of the vendor's variable. + Each VariableName is unique for each Vend= orGuid. VariableName must + contain 1 or more characters. If Variable= Name is an empty string, + then EFI_INVALID_PARAMETER is returned. + @param[in] VendorGuid A unique identifier for the vendor. + @param[in] Attributes Attributes bitmask to set for the variabl= e. + @param[in] DataSize The size in bytes of the Data buffer. Unl= ess the EFI_VARIABLE_APPEND_WRITE or + EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRI= TE_ACCESS attribute is set, a size of zero + causes the variable to be deleted. When t= he EFI_VARIABLE_APPEND_WRITE attribute is + set, then a SetVariable() call with a Dat= aSize of zero will not cause any change to + the variable value (the timestamp associa= ted with the variable may be updated however + even if no new data value is provided,see= the description of the + EFI_VARIABLE_AUTHENTICATION_2 descriptor = below. In this case the DataSize will not + be zero since the EFI_VARIABLE_AUTHENTICA= TION_2 descriptor will be populated). + @param[in] Data The contents for the variable. + + @retval EFI_SUCCESS The firmware has successfully stored the = variable and its data as + defined by the Attributes. + @retval EFI_INVALID_PARAMETER An invalid combination of attribute bits,= name, and GUID was supplied, or the + DataSize exceeds the maximum allowed. + @retval EFI_INVALID_PARAMETER VariableName is an empty string. + @retval EFI_OUT_OF_RESOURCES Not enough storage is available to hold t= he variable and its data. + @retval EFI_DEVICE_ERROR The variable could not be retrieved due t= o a hardware error. + @retval EFI_WRITE_PROTECTED The variable in question is read-only. + @retval EFI_WRITE_PROTECTED The variable in question cannot be delete= d. + @retval EFI_SECURITY_VIOLATION The variable could not be written due to = EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACESS being set, + but the AuthInfo does NOT pass the valida= tion check carried out by the firmware. + @retval EFI_UNSUPPORTED This function is not implemented by this = instance of the LibraryClass + + @retval EFI_NOT_FOUND The variable trying to be updated or dele= ted was not found. + +**/ +EFI_STATUS +EFIAPI +VarLibSetVariable ( + IN CHAR16 *VariableName, + IN EFI_GUID *VendorGuid, + IN UINT32 Attributes, + IN UINTN DataSize, + IN VOID *Data + ) +{ + EFI_STATUS Status =3D EFI_UNSUPPORTED; + + if (gRT !=3D NULL) { + Status =3D gRT->SetVariable ( + VariableName, + VendorGuid, + Attributes, + DataSize, + Data + ); + } + return Status; +} + +/** + Returns information about the EFI variables. + + @param[in] Attributes Attributes bitmask to specify = the type of variables on + which to return information. + @param[out] MaximumVariableStorageSize On output the maximum size of = the storage space + available for the EFI variable= s associated with the + attributes specified. + @param[out] RemainingVariableStorageSize Returns the remaining size of = the storage space + available for the EFI variable= s associated with the + attributes specified. + @param[out] MaximumVariableSize Returns the maximum size of th= e individual EFI + variables associated with the = attributes specified. + + @retval EFI_SUCCESS Valid answer returned. + @retval EFI_INVALID_PARAMETER An invalid combination of attribute= bits was supplied + @retval EFI_UNSUPPORTED The attribute is not supported on t= his platform, and the + MaximumVariableStorageSize, + RemainingVariableStorageSize, Maxim= umVariableSize + are undefined. +**/ +EFI_STATUS +EFIAPI +VarLibQueryVariableInfo ( + IN UINT32 Attributes, + OUT UINT64 *MaximumVariableStorageSize, + OUT UINT64 *RemainingVariableStorageSize, + OUT UINT64 *MaximumVariableSize + ) +{ + EFI_STATUS Status =3D EFI_UNSUPPORTED; + + if (gRT !=3D NULL) { + Status =3D gRT->QueryVariableInfo ( + Attributes, + MaximumVariableStorageSize, + RemainingVariableStorageSize, + MaximumVariableSize + ); + } + return Status; +} + +/** + Indicates if the VarLibVariableRequestToLock() API is supported by the c= urrent + VariableWriteLib implementation. At time of writting, this API is not + available in SMM or after ExitBootServices. + + @retval TRUE The VarLibVariableRequestToLock() API is s= upported + @retval FALSE The VarLibVariableRequestToLock() API is n= ot supported + +**/ +BOOLEAN +EFIAPI +VarLibIsVariableRequestToLockSupported ( + VOID + ) +{ + if (mVariableWriteLibVariableLock !=3D NULL) { + return TRUE; + } else { + return FALSE; + } +} + +/** + Mark a variable that will become read-only after leaving the DXE phase o= f execution. + Write request coming from SMM environment through EFI_SMM_VARIABLE_PROTO= COL is allowed. + + @param[in] This The EDKII_VARIABLE_LOCK_PROTOCOL instance. + @param[in] VariableName A pointer to the variable name that will be mad= e 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_EVE= NT_GROUP_READY_TO_BOOT has + already been signaled. + @retval EFI_OUT_OF_RESOURCES There is not enough resource to hold the l= ock request. + @retval EFI_UNSUPPORTED This function is not implemented by this i= nstance of the LibraryClass + +**/ +EFI_STATUS +EFIAPI +VarLibVariableRequestToLock ( + IN CHAR16 *VariableName, + IN EFI_GUID *VendorGuid + ) +{ + EFI_STATUS Status =3D EFI_UNSUPPORTED; + + if (mVariableWriteLibVariableLock !=3D NULL) { + Status =3D mVariableWriteLibVariableLock->RequestToLock ( + mVariableWriteLibVariableLoc= k, + VariableName, + VendorGuid + ); + } + return Status; +} + +/** + Exit Boot Services Event notification handler. + + @param[in] Event Event whose notification function is being invoked. + @param[in] Context Pointer to the notification function's context. + +**/ +VOID +EFIAPI +DxeRuntimeVariableWriteLibOnExitBootServices ( + IN EFI_EVENT Event, + IN VOID *Context + ) +{ + mVariableWriteLibVariableLock =3D NULL; +} + +/** + The constructor function acquires the Variable Lock Protocol + + @param ImageHandle The firmware allocated handle for the EFI image. + @param SystemTable A pointer to the EFI System Table. + + @retval EFI_SUCCESS The constructor was successful. + @retval EFI_NOT_FOUND gEdkiiVariableLockProtocolGuid Protocol + interface not found, which technically sho= uld + not be possible since this protocol is in = the + LibraryClass DEPEX + @retval EFI_OUT_OF_RESOURCES Unable to create new events + +**/ +EFI_STATUS +EFIAPI +DxeRuntimeVariableWriteLibConstructor ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + EFI_STATUS Status; + EFI_EVENT ExitBootServiceEvent; + EFI_EVENT LegacyBootEvent; + + // + // Locate VariableLockProtocol. + // + Status =3D gBS->LocateProtocol (&gEdkiiVariableLockProtocolGuid, NULL, (= VOID **)&mVariableWriteLibVariableLock); + ASSERT_EFI_ERROR (Status); + + // + // Register the event to inform SMM variable that it is at runtime. + // + Status =3D gBS->CreateEventEx ( + EVT_NOTIFY_SIGNAL, + TPL_NOTIFY, + DxeRuntimeVariableWriteLibOnExitBootServices, + NULL, + &gEfiEventExitBootServicesGuid, + &ExitBootServiceEvent + ); + ASSERT_EFI_ERROR (Status); + + // + // Register the event to inform SMM variable that it is at runtime for l= egacy boot. + // Reuse OnExitBootServices() here. + // + Status =3D EfiCreateEventLegacyBootEx ( + TPL_NOTIFY, + DxeRuntimeVariableWriteLibOnExitBootServices, + NULL, + &LegacyBootEvent + ); + ASSERT_EFI_ERROR (Status); + + return Status; +} diff --git a/Platform/Intel/MinPlatformPkg/Library/DxeRuntimeVariableWriteL= ib/DxeRuntimeVariableWriteLib.inf b/Platform/Intel/MinPlatformPkg/Library/D= xeRuntimeVariableWriteLib/DxeRuntimeVariableWriteLib.inf new file mode 100644 index 0000000000..704a8ac7cc --- /dev/null +++ b/Platform/Intel/MinPlatformPkg/Library/DxeRuntimeVariableWriteLib/DxeR= untimeVariableWriteLib.inf @@ -0,0 +1,49 @@ +## @file +# Component description file for DXE Variable Write Lib +# +# This library provides phase agnostic access to the UEFI Variable Service= s. +# This is done by implementing a wrapper on top of the phase specific mech= anism +# for writing to UEFI variables. For example, the DXE implementation acces= ses +# the UEFI Runtime Services Table, and the SMM implementation uses +# EFI_SMM_VARIABLE_PROTOCOL. +# +# Using this library allows code to be written in a generic manner that ca= n be +# used in DXE or SMM without modification. +# +# Copyright (c) 2021, Intel Corporation. All rights reserved.
+# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +[Defines] + INF_VERSION =3D 0x00010005 + BASE_NAME =3D DxeRuntimeVariableWriteLib + FILE_GUID =3D 9681E383-5FD4-47A4-B4F8-6651EE603E4E + VERSION_STRING =3D 1.0 + MODULE_TYPE =3D DXE_RUNTIME_DRIVER + LIBRARY_CLASS =3D VariableWriteLib|DXE_CORE DXE_DRIVER = DXE_RUNTIME_DRIVER UEFI_APPLICATION UEFI_DRIVER + CONSTRUCTOR =3D DxeRuntimeVariableWriteLibConstructor + +[Packages] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + +[Sources] + DxeRuntimeVariableWriteLib.c + +[LibraryClasses] + DebugLib + UefiLib + UefiBootServicesTableLib + UefiRuntimeServicesTableLib + +[Guids] + gEfiEventExitBootServicesGuid ## CONSUMES ## Event + +[Protocols] + gEfiVariableWriteArchProtocolGuid ## CONSUMES + gEdkiiVariableLockProtocolGuid ## CONSUMES + +[Depex] + gEfiVariableWriteArchProtocolGuid AND gEdkiiVariableLockProtocolGuid diff --git a/Platform/Intel/MinPlatformPkg/Library/SmmVariableWriteLib/SmmV= ariableWriteCommon.c b/Platform/Intel/MinPlatformPkg/Library/SmmVariableWri= teLib/SmmVariableWriteCommon.c new file mode 100644 index 0000000000..50ebb544b8 --- /dev/null +++ b/Platform/Intel/MinPlatformPkg/Library/SmmVariableWriteLib/SmmVariable= WriteCommon.c @@ -0,0 +1,171 @@ +/** @file + SMM Variable Write Lib + + This library provides phase agnostic access to the UEFI Variable Service= s. + This is done by implementing a wrapper on top of the phase specific mech= anism + for writing to UEFI variables. + + This is the common implementation pieces that are shared between + traditional SMM and standalone MM. + + Copyright (c) 2021, Intel Corporation. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include + +#include + +EFI_SMM_VARIABLE_PROTOCOL *mVariableWriteLibSmmVariable =3D NULL; + +/** + Sets the value of a variable. + + @param[in] VariableName A Null-terminated string that is the name= of the vendor's variable. + Each VariableName is unique for each Vend= orGuid. VariableName must + contain 1 or more characters. If Variable= Name is an empty string, + then EFI_INVALID_PARAMETER is returned. + @param[in] VendorGuid A unique identifier for the vendor. + @param[in] Attributes Attributes bitmask to set for the variabl= e. + @param[in] DataSize The size in bytes of the Data buffer. Unl= ess the EFI_VARIABLE_APPEND_WRITE or + EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRI= TE_ACCESS attribute is set, a size of zero + causes the variable to be deleted. When t= he EFI_VARIABLE_APPEND_WRITE attribute is + set, then a SetVariable() call with a Dat= aSize of zero will not cause any change to + the variable value (the timestamp associa= ted with the variable may be updated however + even if no new data value is provided,see= the description of the + EFI_VARIABLE_AUTHENTICATION_2 descriptor = below. In this case the DataSize will not + be zero since the EFI_VARIABLE_AUTHENTICA= TION_2 descriptor will be populated). + @param[in] Data The contents for the variable. + + @retval EFI_SUCCESS The firmware has successfully stored the = variable and its data as + defined by the Attributes. + @retval EFI_INVALID_PARAMETER An invalid combination of attribute bits,= name, and GUID was supplied, or the + DataSize exceeds the maximum allowed. + @retval EFI_INVALID_PARAMETER VariableName is an empty string. + @retval EFI_OUT_OF_RESOURCES Not enough storage is available to hold t= he variable and its data. + @retval EFI_DEVICE_ERROR The variable could not be retrieved due t= o a hardware error. + @retval EFI_WRITE_PROTECTED The variable in question is read-only. + @retval EFI_WRITE_PROTECTED The variable in question cannot be delete= d. + @retval EFI_SECURITY_VIOLATION The variable could not be written due to = EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACESS being set, + but the AuthInfo does NOT pass the valida= tion check carried out by the firmware. + @retval EFI_UNSUPPORTED This function is not implemented by this = instance of the LibraryClass + + @retval EFI_NOT_FOUND The variable trying to be updated or dele= ted was not found. + +**/ +EFI_STATUS +EFIAPI +VarLibSetVariable ( + IN CHAR16 *VariableName, + IN EFI_GUID *VendorGuid, + IN UINT32 Attributes, + IN UINTN DataSize, + IN VOID *Data + ) +{ + EFI_STATUS Status =3D EFI_UNSUPPORTED; + + if (mVariableWriteLibSmmVariable !=3D NULL) { + Status =3D mVariableWriteLibSmmVariable->SmmSetVariable ( + VariableName, + VendorGuid, + Attributes, + DataSize, + Data + ); + } + return Status; +} + +/** + Returns information about the EFI variables. + + @param[in] Attributes Attributes bitmask to specify = the type of variables on + which to return information. + @param[out] MaximumVariableStorageSize On output the maximum size of = the storage space + available for the EFI variable= s associated with the + attributes specified. + @param[out] RemainingVariableStorageSize Returns the remaining size of = the storage space + available for the EFI variable= s associated with the + attributes specified. + @param[out] MaximumVariableSize Returns the maximum size of th= e individual EFI + variables associated with the = attributes specified. + + @retval EFI_SUCCESS Valid answer returned. + @retval EFI_INVALID_PARAMETER An invalid combination of attribute= bits was supplied + @retval EFI_UNSUPPORTED The attribute is not supported on t= his platform, and the + MaximumVariableStorageSize, + RemainingVariableStorageSize, Maxim= umVariableSize + are undefined. +**/ +EFI_STATUS +EFIAPI +VarLibQueryVariableInfo ( + IN UINT32 Attributes, + OUT UINT64 *MaximumVariableStorageSize, + OUT UINT64 *RemainingVariableStorageSize, + OUT UINT64 *MaximumVariableSize + ) +{ + EFI_STATUS Status =3D EFI_UNSUPPORTED; + + if (mVariableWriteLibSmmVariable !=3D NULL) { + Status =3D mVariableWriteLibSmmVariable->SmmQueryVariableInfo ( + Attributes, + MaximumVariableStorageSize, + RemainingVariableStorageSize, + MaximumVariableSize + ); + } + return Status; +} + +/** + Indicates if the VarLibVariableRequestToLock() API is supported by the c= urrent + VariableWriteLib implementation. At time of writting, this API is not + available in SMM or after ExitBootServices. + + @retval TRUE The VarLibVariableRequestToLock() API is s= upported + @retval FALSE The VarLibVariableRequestToLock() API is n= ot supported + +**/ +BOOLEAN +EFIAPI +VarLibIsVariableRequestToLockSupported ( + VOID + ) +{ + return FALSE; +} + +/** + Mark a variable that will become read-only after leaving the DXE phase o= f execution. + Write request coming from SMM environment through EFI_SMM_VARIABLE_PROTO= COL is allowed. + + @param[in] This The EDKII_VARIABLE_LOCK_PROTOCOL instance. + @param[in] VariableName A pointer to the variable name that will be mad= e 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_EVE= NT_GROUP_READY_TO_BOOT has + already been signaled. + @retval EFI_OUT_OF_RESOURCES There is not enough resource to hold the l= ock request. + @retval EFI_UNSUPPORTED This function is not implemented by this i= nstance of the LibraryClass + +**/ +EFI_STATUS +EFIAPI +VarLibVariableRequestToLock ( + IN CHAR16 *VariableName, + IN EFI_GUID *VendorGuid + ) +{ + // + // Variable lock protocol is not accessible from SMM + // + return EFI_UNSUPPORTED; +} diff --git a/Platform/Intel/MinPlatformPkg/Library/SmmVariableWriteLib/Stan= daloneMmVariableWriteLib.inf b/Platform/Intel/MinPlatformPkg/Library/SmmVar= iableWriteLib/StandaloneMmVariableWriteLib.inf new file mode 100644 index 0000000000..0d1c63a297 --- /dev/null +++ b/Platform/Intel/MinPlatformPkg/Library/SmmVariableWriteLib/StandaloneM= mVariableWriteLib.inf @@ -0,0 +1,45 @@ +## @file +# Component description file for Standalone MM Variable Write Lib +# +# This library provides phase agnostic access to the UEFI Variable Service= s. +# This is done by implementing a wrapper on top of the phase specific mech= anism +# for writing to UEFI variables. For example, the DXE implementation acces= ses +# the UEFI Runtime Services Table, and the SMM implementation uses +# EFI_SMM_VARIABLE_PROTOCOL. +# +# Using this library allows code to be written in a generic manner that ca= n be +# used in DXE or SMM without modification. +# +# Copyright (c) 2021, Intel Corporation. All rights reserved.
+# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +[Defines] + INF_VERSION =3D 0x0001001B + BASE_NAME =3D StandaloneMmVariableWriteLib + FILE_GUID =3D 62A023A6-DEBA-4407-A617-18963090DAFD + VERSION_STRING =3D 1.0 + MODULE_TYPE =3D MM_STANDALONE + PI_SPECIFICATION_VERSION =3D 0x00010032 + LIBRARY_CLASS =3D VariableWriteLib|MM_STANDALONE MM_COR= E_STANDALONE + CONSTRUCTOR =3D StandaloneMmVariableWriteLibConstruct= or + +[Packages] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + +[Sources] + SmmVariableWriteCommon.c + StandaloneMmVariableWriteLibConstructor.c + +[LibraryClasses] + DebugLib + MmServicesTableLib + +[Protocols] + gEfiSmmVariableProtocolGuid ## CONSUMES + +[Depex] + gEfiSmmVariableProtocolGuid diff --git a/Platform/Intel/MinPlatformPkg/Library/SmmVariableWriteLib/Stan= daloneMmVariableWriteLibConstructor.c b/Platform/Intel/MinPlatformPkg/Libra= ry/SmmVariableWriteLib/StandaloneMmVariableWriteLibConstructor.c new file mode 100644 index 0000000000..d39418abd2 --- /dev/null +++ b/Platform/Intel/MinPlatformPkg/Library/SmmVariableWriteLib/StandaloneM= mVariableWriteLibConstructor.c @@ -0,0 +1,51 @@ +/** @file + Standalone MM Variable Write Lib + + This library provides phase agnostic access to the UEFI Variable Service= s. + This is done by implementing a wrapper on top of the phase specific mech= anism + for reading from UEFI variables. + + This is the standalone MM specific LibraryClass constructor. + + Copyright (c) 2021, Intel Corporation. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include + +#include + +#include +#include + +extern EFI_SMM_VARIABLE_PROTOCOL *mVariableWriteLibSmmVariable; + +/** + The constructor function acquires the EFI SMM Variable Services + + @param ImageHandle The firmware allocated handle for the EFI image. + @param SystemTable A pointer to the MM System Table. + + @retval EFI_SUCCESS The constructor always returns RETURN_SUCCESS. + @retval EFI_NOT_FOUND gEfiSmmVariableProtocolGuid Protocol interface n= ot + found, which technically should not be possible = since + this protocol is in the LibraryClass DEPEX + +**/ +EFI_STATUS +EFIAPI +StandaloneMmVariableWriteLibConstructor ( + IN EFI_HANDLE ImageHandle, + IN EFI_MM_SYSTEM_TABLE *SystemTable + ) +{ + EFI_STATUS Status; + + // + // Locate SmmVariableProtocol. + // + Status =3D gMmst->MmLocateProtocol (&gEfiSmmVariableProtocolGuid, NULL, = (VOID **) &mVariableWriteLibSmmVariable); + ASSERT_EFI_ERROR (Status); + return Status; +} diff --git a/Platform/Intel/MinPlatformPkg/Library/SmmVariableWriteLib/Trad= itionalMmVariableWriteLib.inf b/Platform/Intel/MinPlatformPkg/Library/SmmVa= riableWriteLib/TraditionalMmVariableWriteLib.inf new file mode 100644 index 0000000000..5d833b7e0f --- /dev/null +++ b/Platform/Intel/MinPlatformPkg/Library/SmmVariableWriteLib/Traditional= MmVariableWriteLib.inf @@ -0,0 +1,44 @@ +## @file +# Component description file for Traditional MM Variable Write Lib +# +# This library provides phase agnostic access to the UEFI Variable Service= s. +# This is done by implementing a wrapper on top of the phase specific mech= anism +# for writing to UEFI variables. For example, the DXE implementation acces= ses +# the UEFI Runtime Services Table, and the SMM implementation uses +# EFI_SMM_VARIABLE_PROTOCOL. +# +# Using this library allows code to be written in a generic manner that ca= n be +# used in DXE or SMM without modification. +# +# Copyright (c) 2021, Intel Corporation. All rights reserved.
+# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +[Defines] + INF_VERSION =3D 0x00010005 + BASE_NAME =3D TraditionalMmVariableWriteLib + FILE_GUID =3D 8C385E9B-C260-466C-91D2-43D839712680 + VERSION_STRING =3D 1.0 + MODULE_TYPE =3D DXE_SMM_DRIVER + LIBRARY_CLASS =3D VariableWriteLib|DXE_SMM_DRIVER SMM_C= ORE + CONSTRUCTOR =3D TraditionalMmVariableWriteLibConstruc= tor + +[Packages] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + +[Sources] + SmmVariableWriteCommon.c + TraditionalMmVariableWriteLibConstructor.c + +[LibraryClasses] + DebugLib + SmmServicesTableLib + +[Protocols] + gEfiSmmVariableProtocolGuid ## CONSUMES + +[Depex] + gEfiSmmVariableProtocolGuid diff --git a/Platform/Intel/MinPlatformPkg/Library/SmmVariableWriteLib/Trad= itionalMmVariableWriteLibConstructor.c b/Platform/Intel/MinPlatformPkg/Libr= ary/SmmVariableWriteLib/TraditionalMmVariableWriteLibConstructor.c new file mode 100644 index 0000000000..d142527e17 --- /dev/null +++ b/Platform/Intel/MinPlatformPkg/Library/SmmVariableWriteLib/Traditional= MmVariableWriteLibConstructor.c @@ -0,0 +1,51 @@ +/** @file + Traditional MM Variable Write Lib + + This library provides phase agnostic access to the UEFI Variable Service= s. + This is done by implementing a wrapper on top of the phase specific mech= anism + for reading from UEFI variables. + + This is the traditional SMM specific LibraryClass constructor. + + Copyright (c) 2021, Intel Corporation. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include + +#include + +#include +#include + +extern EFI_SMM_VARIABLE_PROTOCOL *mVariableWriteLibSmmVariable; + +/** + The constructor function acquires the EFI SMM Variable Services + + @param ImageHandle The firmware allocated handle for the EFI image. + @param SystemTable A pointer to the EFI System Table. + + @retval EFI_SUCCESS The constructor always returns RETURN_SUCCESS. + @retval EFI_NOT_FOUND gEfiSmmVariableProtocolGuid Protocol interface n= ot + found, which technically should not be possible = since + this protocol is in the LibraryClass DEPEX + +**/ +EFI_STATUS +EFIAPI +TraditionalMmVariableWriteLibConstructor ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + EFI_STATUS Status; + + // + // Locate SmmVariableProtocol. + // + Status =3D gSmst->SmmLocateProtocol (&gEfiSmmVariableProtocolGuid, NULL,= (VOID **) &mVariableWriteLibSmmVariable); + ASSERT_EFI_ERROR (Status); + return Status; +} diff --git a/Platform/Intel/MinPlatformPkg/MinPlatformPkg.dsc b/Platform/In= tel/MinPlatformPkg/MinPlatformPkg.dsc index 18b5c6f5b1..e968ec4cb2 100644 --- a/Platform/Intel/MinPlatformPkg/MinPlatformPkg.dsc +++ b/Platform/Intel/MinPlatformPkg/MinPlatformPkg.dsc @@ -121,6 +121,7 @@ SpiFlashCommonLib|MinPlatformPkg/Flash/Library/SpiFlashCommonLibNull/Spi= FlashCommonLibNull.inf StandaloneMmDriverEntryPoint|MdePkg/Library/StandaloneMmDriverEntryPoint= /StandaloneMmDriverEntryPoint.inf VariableReadLib|MinPlatformPkg/Library/SmmVariableReadLib/StandaloneMmVa= riableReadLib.inf + VariableWriteLib|MinPlatformPkg/Library/SmmVariableWriteLib/StandaloneMm= VariableWriteLib.inf =20 ##########################################################################= ######################### # --=20 2.27.0.windows.1 -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#73758): https://edk2.groups.io/g/devel/message/73758 Mute This Topic: https://groups.io/mt/81907530/1787277 Group Owner: devel+owner@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [importer@patchew.org] -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-