Date   

Build fails with VS2012

Rebecca Cran
 

I'm setting up a new Jenkins server to do Bhyve builds and run on platforms that aren't currently tested with the GitHub/Azure system.

Since VS2012 appears to be a supported toolchain, I tried building OvmfPkgX64 with it (I'm also planning on testing VS2013, VS2015, VS2017 and VS2019), but it fails with:


Building ... c:\users\administrator\src\edk2\NetworkPkg\Library\DxeUdpIoLib\DxeUdpIoLib.inf [X64]
c:\users\administrator\src\edk2\UefiCpuPkg\Library\MpInitLib\MpLib.c(1268) : error C2220: warning treated as error - no 'object' file generated
c:\users\administrator\src\edk2\UefiCpuPkg\Library\MpInitLib\MpLib.c(1268) : warning C4306: 'type cast' : conversion from 'int' to 'SEV_ES_AP_JMP_FAR *' of greater size

I know the GitHub/Azure system only tests with VS2017 and VS2019: are there plans to drop the older VS versions, or should they still work?
And would it be considered useful to _check_ that they still work, or should they be considered unsupported?

--
Rebecca Cran


[Patch 1/1] BaseTools: Fix DSC override of Guided tool

Michael D Kinney
 

REF: https://bugzilla.tianocore.org/show_bug.cgi?id=3359

If the DSC file provides an override of a Guided tool path
and/or Guided tool GUID value, then make sure the one from the
DSC file is used if it is higher priority than the Guided tool
in the tools_def.txt file. This makes the Guided tool used by
GenFds match the tool listed GuidedSectionTools.txt.

Cc: Bob Feng <bob.c.feng@...>
Cc: Liming Gao <gaoliming@...>
Cc: Yuwei Chen <yuwei.chen@...>
Signed-off-by: Michael D Kinney <michael.d.kinney@...>
---
.../Source/Python/AutoGen/PlatformAutoGen.py | 7 +-
.../Python/GenFds/GenFdsGlobalVariable.py | 228 ++++++++++++------
BaseTools/Source/Python/build/build.py | 52 ++--
3 files changed, 190 insertions(+), 97 deletions(-)

diff --git a/BaseTools/Source/Python/AutoGen/PlatformAutoGen.py b/BaseTools/Source/Python/AutoGen/PlatformAutoGen.py
index 832c0da86bb7..592d4824a4b3 100644
--- a/BaseTools/Source/Python/AutoGen/PlatformAutoGen.py
+++ b/BaseTools/Source/Python/AutoGen/PlatformAutoGen.py
@@ -918,14 +918,13 @@ class PlatformAutoGen(AutoGen):
if Tool in self._BuildOptionWithToolDef(RetVal) and Attr in self._BuildOptionWithToolDef(RetVal)[Tool]:
# check if override is indicated
if self._BuildOptionWithToolDef(RetVal)[Tool][Attr].startswith('='):
- Value = self._BuildOptionWithToolDef(RetVal)[Tool][Attr][1:]
+ Value = self._BuildOptionWithToolDef(RetVal)[Tool][Attr][1:].strip()
else:
- if Attr != 'PATH':
+ # Do not append PATH or GUID
+ if Attr != 'PATH' and Attr != 'GUID':
Value += " " + self._BuildOptionWithToolDef(RetVal)[Tool][Attr]
else:
Value = self._BuildOptionWithToolDef(RetVal)[Tool][Attr]
- Def = '_'.join([self.BuildTarget, self.ToolChain, self.Arch, Tool, Attr])
- self.Workspace.ToolDef.ToolsDefTxtDictionary[Def] = Value
if Attr == "PATH":
# Don't put MAKE definition in the file
if Tool != "MAKE":
diff --git a/BaseTools/Source/Python/GenFds/GenFdsGlobalVariable.py b/BaseTools/Source/Python/GenFds/GenFdsGlobalVariable.py
index c31fc24870d5..25f9d54874d3 100644
--- a/BaseTools/Source/Python/GenFds/GenFdsGlobalVariable.py
+++ b/BaseTools/Source/Python/GenFds/GenFdsGlobalVariable.py
@@ -32,6 +32,7 @@ from Common.LongFilePathSupport import OpenLongFilePath as open
from Common.MultipleWorkspace import MultipleWorkspace as mws
import Common.GlobalData as GlobalData
from Common.BuildToolError import *
+from AutoGen.AutoGen import CalculatePriorityValue

## Global variables
#
@@ -850,6 +851,10 @@ class GenFdsGlobalVariable:
# @param NameGuid The Guid name
#
def FindExtendTool(KeyStringList, CurrentArchList, NameGuid):
+ if GenFdsGlobalVariable.GuidToolDefinition:
+ if NameGuid in GenFdsGlobalVariable.GuidToolDefinition:
+ return GenFdsGlobalVariable.GuidToolDefinition[NameGuid]
+
ToolDefObj = ToolDefDict((os.path.join(os.getenv("WORKSPACE"), "Conf")))
ToolDef = ToolDefObj.ToolDef
ToolDb = ToolDef.ToolsDefTxtDatabase
@@ -864,86 +869,159 @@ def FindExtendTool(KeyStringList, CurrentArchList, NameGuid):
if Target + '_' + ToolChain + '_' + Arch not in KeyStringList:
KeyStringList.append(Target + '_' + ToolChain + '_' + Arch)

- if GenFdsGlobalVariable.GuidToolDefinition:
- if NameGuid in GenFdsGlobalVariable.GuidToolDefinition:
- return GenFdsGlobalVariable.GuidToolDefinition[NameGuid]
-
- ToolDefinition = ToolDef.ToolsDefTxtDictionary
ToolPathTmp = None
ToolOption = None
- ToolPathKey = None
- ToolOptionKey = None
- KeyList = None
- for tool_def in ToolDefinition.items():
- KeyList = tool_def[0].split('_')
- if len(KeyList) < 5:
- continue
- if KeyList[4] != DataType.TAB_GUID:
- continue
- if NameGuid.lower() != tool_def[1].lower():
- continue
- Key = KeyList[0] + \
- '_' + \
- KeyList[1] + \
- '_' + \
- KeyList[2]
+ for Arch in CurrentArchList:
+ MatchItem = None
+ MatchPathItem = None
+ MatchOptionsItem = None
for KeyString in KeyStringList:
KeyStringBuildTarget, KeyStringToolChain, KeyStringArch = KeyString.split('_')
- if KeyList[0] == DataType.TAB_STAR:
- KeyList[0] = KeyStringBuildTarget
- if KeyList[1] == DataType.TAB_STAR:
- KeyList[1] = KeyStringToolChain
- if KeyList[2] == DataType.TAB_STAR:
- KeyList[2] = KeyStringArch
- if KeyList[0] == KeyStringBuildTarget and KeyList[1] == KeyStringToolChain and KeyList[2] == KeyStringArch:
- ToolPathKey = Key + '_' + KeyList[3] + '_PATH'
- ToolOptionKey = Key + '_' + KeyList[3] + '_FLAGS'
- ToolPath = ToolDefinition.get(ToolPathKey)
- ToolOption = ToolDefinition.get(ToolOptionKey)
- if ToolPathTmp is None:
- ToolPathTmp = ToolPath
- else:
- if ToolPathTmp != ToolPath:
- EdkLogger.error("GenFds", GENFDS_ERROR, "Don't know which tool to use, %s or %s ?" % (ToolPathTmp, ToolPath))
+ if KeyStringArch != Arch:
+ continue
+ for Item in ToolDef.ToolsDefTxtDictionary:
+ if len(Item.split('_')) < 5:
+ continue
+ ItemTarget, ItemToolChain, ItemArch, ItemTool, ItemAttr = Item.split('_')
+ if ItemTarget == DataType.TAB_STAR:
+ ItemTarget = KeyStringBuildTarget
+ if ItemToolChain == DataType.TAB_STAR:
+ ItemToolChain = KeyStringToolChain
+ if ItemArch == DataType.TAB_STAR:
+ ItemArch = KeyStringArch
+ if ItemTarget != KeyStringBuildTarget:
+ continue
+ if ItemToolChain != KeyStringToolChain:
+ continue
+ if ItemArch != KeyStringArch:
+ continue
+ if ItemAttr != DataType.TAB_GUID:
+ # Not GUID attribute
+ continue
+ if ToolDef.ToolsDefTxtDictionary[Item].lower() != NameGuid.lower():
+ # No GUID value match
+ continue
+ if MatchItem:
+ if MatchItem.split('_')[3] == ItemTool:
+ # Tool name is the same
+ continue
+ if CalculatePriorityValue(MatchItem) > CalculatePriorityValue(Item):
+ # Current MatchItem is higher priority than new match item
+ continue
+ MatchItem = Item
+ if not MatchItem:
+ continue
+ ToolName = MatchItem.split('_')[3]
+ for Item in ToolDef.ToolsDefTxtDictionary:
+ if len(Item.split('_')) < 5:
+ continue
+ ItemTarget, ItemToolChain, ItemArch, ItemTool, ItemAttr = Item.split('_')
+ if ItemTarget == DataType.TAB_STAR:
+ ItemTarget = KeyStringBuildTarget
+ if ItemToolChain == DataType.TAB_STAR:
+ ItemToolChain = KeyStringToolChain
+ if ItemArch == DataType.TAB_STAR:
+ ItemArch = KeyStringArch
+ if ItemTarget != KeyStringBuildTarget:
+ continue
+ if ItemToolChain != KeyStringToolChain:
+ continue
+ if ItemArch != KeyStringArch:
+ continue
+ if ItemTool != ToolName:
+ continue
+ if ItemAttr == 'PATH':
+ if MatchPathItem:
+ if CalculatePriorityValue(MatchPathItem) <= CalculatePriorityValue(Item):
+ MatchPathItem = Item
+ else:
+ MatchPathItem = Item
+ if ItemAttr == 'FLAGS':
+ if MatchOptionsItem:
+ if CalculatePriorityValue(MatchOptionsItem) <= CalculatePriorityValue(Item):
+ MatchOptionsItem = Item
+ else:
+ MatchOptionsItem = Item
+ if MatchPathItem:
+ ToolPathTmp = ToolDef.ToolsDefTxtDictionary[MatchPathItem]
+ if MatchOptionsItem:
+ ToolOption = ToolDef.ToolsDefTxtDictionary[MatchOptionsItem]

- BuildOption = {}
for Arch in CurrentArchList:
- Platform = GenFdsGlobalVariable.WorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, Arch, GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag]
- # key is (ToolChainFamily, ToolChain, CodeBase)
- for item in Platform.BuildOptions:
- if '_PATH' in item[1] or '_FLAGS' in item[1] or '_GUID' in item[1]:
- if not item[0] or (item[0] and GenFdsGlobalVariable.ToolChainFamily== item[0]):
- if item[1] not in BuildOption:
- BuildOption[item[1]] = Platform.BuildOptions[item]
- if BuildOption:
- ToolList = [DataType.TAB_TOD_DEFINES_TARGET, DataType.TAB_TOD_DEFINES_TOOL_CHAIN_TAG, DataType.TAB_TOD_DEFINES_TARGET_ARCH]
- for Index in range(2, -1, -1):
- for Key in list(BuildOption.keys()):
- List = Key.split('_')
- if List[Index] == DataType.TAB_STAR:
- for String in ToolDb[ToolList[Index]]:
- if String in [Arch, GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag]:
- List[Index] = String
- NewKey = '%s_%s_%s_%s_%s' % tuple(List)
- if NewKey not in BuildOption:
- BuildOption[NewKey] = BuildOption[Key]
- continue
- del BuildOption[Key]
- elif List[Index] not in ToolDb[ToolList[Index]]:
- del BuildOption[Key]
- if BuildOption:
- if not KeyList:
- for Op in BuildOption:
- if NameGuid == BuildOption[Op]:
- KeyList = Op.split('_')
- Key = KeyList[0] + '_' + KeyList[1] +'_' + KeyList[2]
- if Key in KeyStringList and KeyList[4] == DataType.TAB_GUID:
- ToolPathKey = Key + '_' + KeyList[3] + '_PATH'
- ToolOptionKey = Key + '_' + KeyList[3] + '_FLAGS'
- if ToolPathKey in BuildOption:
- ToolPathTmp = BuildOption[ToolPathKey]
- if ToolOptionKey in BuildOption:
- ToolOption = BuildOption[ToolOptionKey]
-
+ MatchItem = None
+ MatchPathItem = None
+ MatchOptionsItem = None
+ for KeyString in KeyStringList:
+ KeyStringBuildTarget, KeyStringToolChain, KeyStringArch = KeyString.split('_')
+ if KeyStringArch != Arch:
+ continue
+ Platform = GenFdsGlobalVariable.WorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, Arch, KeyStringBuildTarget, KeyStringToolChain]
+ for Item in Platform.BuildOptions:
+ if len(Item[1].split('_')) < 5:
+ continue
+ ItemTarget, ItemToolChain, ItemArch, ItemTool, ItemAttr = Item[1].split('_')
+ if ItemTarget == DataType.TAB_STAR:
+ ItemTarget = KeyStringBuildTarget
+ if ItemToolChain == DataType.TAB_STAR:
+ ItemToolChain = KeyStringToolChain
+ if ItemArch == DataType.TAB_STAR:
+ ItemArch = KeyStringArch
+ if ItemTarget != KeyStringBuildTarget:
+ continue
+ if ItemToolChain != KeyStringToolChain:
+ continue
+ if ItemArch != KeyStringArch:
+ continue
+ if ItemAttr != DataType.TAB_GUID:
+ # Not GUID attribute match
+ continue
+ if Platform.BuildOptions[Item].lower() != NameGuid.lower():
+ # No GUID value match
+ continue
+ if MatchItem:
+ if MatchItem[1].split('_')[3] == ItemTool:
+ # Tool name is the same
+ continue
+ if CalculatePriorityValue(MatchItem[1]) > CalculatePriorityValue(Item[1]):
+ # Current MatchItem is higher priority than new match item
+ continue
+ MatchItem = Item
+ if not MatchItem:
+ continue
+ ToolName = MatchItem[1].split('_')[3]
+ for Item in Platform.BuildOptions:
+ if len(Item[1].split('_')) < 5:
+ continue
+ ItemTarget, ItemToolChain, ItemArch, ItemTool, ItemAttr = Item[1].split('_')
+ if ItemTarget == DataType.TAB_STAR:
+ ItemTarget = KeyStringBuildTarget
+ if ItemToolChain == DataType.TAB_STAR:
+ ItemToolChain = KeyStringToolChain
+ if ItemArch == DataType.TAB_STAR:
+ ItemArch = KeyStringArch
+ if ItemTarget != KeyStringBuildTarget:
+ continue
+ if ItemToolChain != KeyStringToolChain:
+ continue
+ if ItemArch != KeyStringArch:
+ continue
+ if ItemTool != ToolName:
+ continue
+ if ItemAttr == 'PATH':
+ if MatchPathItem:
+ if CalculatePriorityValue(MatchPathItem[1]) <= CalculatePriorityValue(Item[1]):
+ MatchPathItem = Item
+ else:
+ MatchPathItem = Item
+ if ItemAttr == 'FLAGS':
+ if MatchOptionsItem:
+ if CalculatePriorityValue(MatchOptionsItem[1]) <= CalculatePriorityValue(Item[1]):
+ MatchOptionsItem = Item
+ else:
+ MatchOptionsItem = Item
+ if MatchPathItem:
+ ToolPathTmp = Platform.BuildOptions[MatchPathItem]
+ if MatchOptionsItem:
+ ToolOption = Platform.BuildOptions[MatchOptionsItem]
GenFdsGlobalVariable.GuidToolDefinition[NameGuid] = (ToolPathTmp, ToolOption)
return ToolPathTmp, ToolOption
diff --git a/BaseTools/Source/Python/build/build.py b/BaseTools/Source/Python/build/build.py
index e5693c0d27a2..037493f0b02a 100755
--- a/BaseTools/Source/Python/build/build.py
+++ b/BaseTools/Source/Python/build/build.py
@@ -62,6 +62,7 @@ from AutoGen.ModuleAutoGenHelper import WorkSpaceInfo, PlatformInfo
from GenFds.FdfParser import FdfParser
from AutoGen.IncludesAutoGen import IncludesAutoGen
from GenFds.GenFds import resetFdsGlobalVariable
+from AutoGen.AutoGen import CalculatePriorityValue

## standard targets of build command
gSupportedTarget = ['all', 'genc', 'genmake', 'modules', 'libraries', 'fds', 'clean', 'cleanall', 'cleanlib', 'run']
@@ -2425,27 +2426,42 @@ class Build():
FvDir = Wa.FvDir
if not os.path.exists(FvDir):
continue
-
for Arch in self.ArchList:
- # Look through the tool definitions for GUIDed tools
+ guidList = []
+ tooldefguidList = []
guidAttribs = []
- for (attrib, value) in self.ToolDef.ToolsDefTxtDictionary.items():
- GuidBuildTarget, GuidToolChain, GuidArch, GuidTool, GuidAttr = attrib.split('_')
- if GuidAttr.upper() == 'GUID':
- if GuidBuildTarget == TAB_STAR:
- GuidBuildTarget = BuildTarget
- if GuidToolChain == TAB_STAR:
- GuidToolChain = ToolChain
- if GuidArch == TAB_STAR:
- GuidArch = Arch
- if GuidBuildTarget == BuildTarget and GuidToolChain == ToolChain and GuidArch == Arch:
- path = '_'.join(attrib.split('_')[:-1]) + '_PATH'
- if path in self.ToolDef.ToolsDefTxtDictionary:
- path = self.ToolDef.ToolsDefTxtDictionary[path]
- path = self.GetRealPathOfTool(path)
- guidAttribs.append((value.lower(), GuidTool, path))
+ for Platform in Wa.AutoGenObjectList:
+ if Platform.BuildTarget != BuildTarget:
+ continue
+ if Platform.ToolChain != ToolChain:
+ continue
+ if Platform.Arch != Arch:
+ continue
+ if hasattr (Platform, 'BuildOption'):
+ for Tool in Platform.BuildOption:
+ if 'GUID' in Platform.BuildOption[Tool]:
+ if 'PATH' in Platform.BuildOption[Tool]:
+ value = Platform.BuildOption[Tool]['GUID']
+ if value in guidList:
+ EdkLogger.error("build", FORMAT_INVALID, "Duplicate GUID value %s used with Tool %s in DSC [BuildOptions]." % (value, Tool))
+ path = Platform.BuildOption[Tool]['PATH']
+ guidList.append(value)
+ guidAttribs.append((value, Tool, path))
+ for Tool in Platform.ToolDefinition:
+ if 'GUID' in Platform.ToolDefinition[Tool]:
+ if 'PATH' in Platform.ToolDefinition[Tool]:
+ value = Platform.ToolDefinition[Tool]['GUID']
+ if value in tooldefguidList:
+ EdkLogger.error("build", FORMAT_INVALID, "Duplicate GUID value %s used with Tool %s in tools_def.txt." % (value, Tool))
+ tooldefguidList.append(value)
+ if value in guidList:
+ # Already added by platform
+ continue
+ path = Platform.ToolDefinition[Tool]['PATH']
+ guidList.append(value)
+ guidAttribs.append((value, Tool, path))
# Sort by GuidTool name
- sorted (guidAttribs, key=lambda x: x[1])
+ guidAttribs = sorted (guidAttribs, key=lambda x: x[1])
# Write out GuidedSecTools.txt
toolsFile = os.path.join(FvDir, 'GuidedSectionTools.txt')
toolsFile = open(toolsFile, 'wt')
--
2.31.1.windows.1


Re: [edk2-test][Patch 1/1] ImageIndex need be corrected to range 1 ~ DescriptorCount.

G Edhaya Chandran
 

Upstreamed by commit : https://github.com/tianocore/edk2-test/commit/da461e14fe86a5f4ee03ab64b412bf5f0bfe08e9


Re: [edk2-test][Patch 1/1] ImageIndex need be corrected to range 1 ~ DescriptorCount.

G Edhaya Chandran
 

Reviewed-by: G Edhaya Chandran<edhaya.chandran@...>


Re: [edk2-sct PATCH] buildzip: Add CapsuleApp.efi to the SCT zip file

G Edhaya Chandran
 

-----Original Message-----
From: devel@edk2.groups.io <devel@edk2.groups.io> On Behalf Of G Edhaya
Chandran via groups.io
Sent: 30 April 2021 21:36
To: Grant Likely <Grant.Likely@...>; devel@edk2.groups.io
Cc: nd <nd@...>; Barton Gao <gaojie@...>
Subject: Re: [edk2-devel] [edk2-sct PATCH] buildzip: Add CapsuleApp.efi to the
SCT zip file

Reviewed-by: G Edhaya Chandran<edhaya.chandran@...>

-----Original Message-----
From: Grant Likely <Grant.Likely@...>
Sent: 27 April 2021 21:46
To: devel@edk2.groups.io
Cc: nd <nd@...>; Grant Likely <Grant.Likely@...>; G Edhaya
Chandran <Edhaya.Chandran@...>; Barton Gao
<gaojie@...>
Subject: [edk2-sct PATCH] buildzip: Add CapsuleApp.efi to the SCT zip
file

CapsuleApp.efi is necessary for testing capsule updates of the firmware.
Add it into the default build.

Cc: G Edhaya Chandran <edhaya.chandran@...>
Cc: Barton Gao <gaojie@...>
Signed-off-by: Grant Likely <grant.likely@...>
---
uefi-sct/SctPkg/buildzip.sh | 7 +++++--
1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/uefi-sct/SctPkg/buildzip.sh b/uefi-sct/SctPkg/buildzip.sh
index
6dfb5aec..cdbe80d7 100755
--- a/uefi-sct/SctPkg/buildzip.sh
+++ b/uefi-sct/SctPkg/buildzip.sh
@@ -39,8 +39,8 @@ NUM_CPUS=$((`getconf _NPROCESSORS_ONLN` + 2))

make -j"$NUM_CPUS" -C edk2/BaseTools/

-# Build the SCT and the shell
-DSC_EXTRA=ShellPkg/ShellPkg.dsc ./SctPkg/build.sh ${TARGET_ARCH} GCC
RELEASE -j"$NUM_CPUS"
+# Build the SCT, CapsuleApp.efi, and the shell
+DSC_EXTRA="ShellPkg/ShellPkg.dsc
MdeModulePkg/MdeModulePkg.dsc" ./SctPkg/build.sh ${TARGET_ARCH} GCC
RELEASE -j"$NUM_CPUS"

# Assemble all the files that need to be in the zip file mkdir -p
${TARGET_ARCH}_SCT/EFI/BOOT @@ -50,6 +50,9 @@ mkdir -p
${TARGET_ARCH}_SCT/SCT cp -r
Build/UefiSct/RELEASE_GCC5/SctPackage${TARGET_ARCH}/${TARGET_ARCH}/
* ${TARGET_ARCH}_SCT/SCT/ cp
Build/UefiSct/RELEASE_GCC5/SctPackage${TARGET_ARCH}/SctStartup.nsh
${TARGET_ARCH}_SCT/Startup.nsh

+mkdir -p ${TARGET_ARCH}_SCT/Mde
+cp Build/MdeModule/RELEASE_GCC5/${TARGET_ARCH}/CapsuleApp.efi
+${TARGET_ARCH}_SCT/Mde
+
# Copy the SCT Parser tool into the repo cp sct_parser/*
${TARGET_ARCH}_SCT/SCT/Sequence/

--
2.20.1




回复: [edk2-devel] [PATCH 00/13] Add GHCBv2 macro and helpers

gaoliming
 

Brijesh:
The changes in MdePkg is good to me. Reviewed-by: Liming Gao
<gaoliming@...>

One minor comment is in Patch2. Its title should be MdePkg/Register/Amd:
xxxx to align other patches.

Thanks
Liming

-----邮件原件-----
发件人: devel@edk2.groups.io <devel@edk2.groups.io> 代表 Brijesh Singh
发送时间: 2021年5月8日 4:38
收件人: devel@edk2.groups.io
抄送: Brijesh Singh <brijesh.singh@...>; James Bottomley
<jejb@...>; Min Xu <min.m.xu@...>; Jiewen Yao
<jiewen.yao@...>; Tom Lendacky <thomas.lendacky@...>;
Jordan Justen <jordan.l.justen@...>; Ard Biesheuvel
<ardb+tianocore@...>; Laszlo Ersek <lersek@...>; Erdem
Aktas <erdemaktas@...>; Michael D Kinney
<michael.d.kinney@...>; Liming Gao <gaoliming@...>;
Zhiguang Liu <zhiguang.liu@...>
主题: [edk2-devel] [PATCH 00/13] Add GHCBv2 macro and helpers

This series is taken from the SNP RFC. This series defines the GHCBv2
macros and NAE events. Additionally, it also introduces a helper to
clear the page encryption mask from the Mmio region.

The series is based on the commit:
f297b7f20010 UnitTestFrameworkPkg: Sample unit test hangs when running
in OVMF/QEMU

Cc: James Bottomley <jejb@...>
Cc: Min Xu <min.m.xu@...>
Cc: Jiewen Yao <jiewen.yao@...>
Cc: Tom Lendacky <thomas.lendacky@...>
Cc: Jordan Justen <jordan.l.justen@...>
Cc: Ard Biesheuvel <ardb+tianocore@...>
Cc: Laszlo Ersek <lersek@...>
Cc: Erdem Aktas <erdemaktas@...>
Cc: Michael D Kinney <michael.d.kinney@...>
Cc: Liming Gao <gaoliming@...>
Cc: Zhiguang Liu <zhiguang.liu@...>

Brijesh Singh (11):
MdePkg/Register/Amd: expand the SEV MSR to include the SNP definition
MdePkg/Amd: add white spaces to retain alignment for future expansion
MdePkg/Register/Amd: define GHCB macros for hypervisor feature
detection
MdePkg/Register/Amd: define GHCB macro for Register GPA structure
MdePkg/Register/Amd: define GHCB macro for the Page State Change
MdePkg/BaseLib: add support for PVALIDATE instruction
OvmfPkg/BaseMemEncryptSevLib: introduce
MemEncryptSevClearMmioPageEncMask()
OvmfPkg/AmdSevDxe: use MemEncryptSevClearMmioPageEncMask() to
clear
EncMask
OvmfPkg/QemuFlashFvbServicesRuntimeDxe: use Mmio helper to clear
enc
mask
OvmfPkg/TpmMmioSevDecryptPei: use
MemEncryptSevClearMmioPageEncMask()
OvmfPkg/BaseMemEncryptSevLib: remove Flush parameter

Tom Lendacky (2):
MdePkg/Register/Amd: define GHCB macros for SNP AP creation
MdePkg/BaseLib: add support for RMPADJUST instruction

MdePkg/Library/BaseLib/BaseLib.inf | 2 +
MdePkg/Include/Library/BaseLib.h | 80 ++++++++++++
MdePkg/Include/Register/Amd/Fam17Msr.h | 46 ++++++-
MdePkg/Include/Register/Amd/Ghcb.h | 123
+++++++++++++++++-
OvmfPkg/Include/Library/MemEncryptSevLib.h | 35 +++--
.../BaseMemEncryptSevLib/X64/VirtualMemory.h | 33 +++--
OvmfPkg/AmdSevDxe/AmdSevDxe.c | 13 +-
OvmfPkg/IoMmuDxe/AmdSevIoMmu.c | 6 +-
.../Ia32/MemEncryptSevLib.c | 41 ++++--
.../X64/MemEncryptSevLib.c | 49 +++++--
.../X64/PeiDxeVirtualMemory.c | 63 +++++++--
.../X64/SecVirtualMemory.c | 8 +-
.../SmmCpuFeaturesLib/SmmCpuFeaturesLib.c | 3 +-
OvmfPkg/PlatformPei/AmdSev.c | 3 +-
.../FwBlockServiceDxe.c | 5 +-
.../QemuFlashSmm.c | 5 +-
.../TpmMmioSevDecryptPeim.c | 5 +-
MdePkg/Include/X64/Nasm.inc | 16 +++
MdePkg/Library/BaseLib/X64/Pvalidate.nasm | 42 ++++++
MdePkg/Library/BaseLib/X64/RmpAdjust.nasm | 40 ++++++
20 files changed, 526 insertions(+), 92 deletions(-)
create mode 100644 MdePkg/Library/BaseLib/X64/Pvalidate.nasm
create mode 100644 MdePkg/Library/BaseLib/X64/RmpAdjust.nasm

--
2.17.1





回复: [PATCH v2 1/2] MdePkg/BaseRngLib: Add support for ARMv8.5 RNG instructions

gaoliming
 

Rebecca:

-----邮件原件-----
发件人: Rebecca Cran <rebecca@...>
发送时间: 2021年5月7日 22:23
收件人: devel@edk2.groups.io; Jiewen Yao <jiewen.yao@...>; Jian J
Wang <jian.j.wang@...>; Michael D Kinney
<michael.d.kinney@...>; Liming Gao <gaoliming@...>;
Zhiguang Liu <zhiguang.liu@...>; Ard Biesheuvel
<ardb+tianocore@...>; Sami Mujawar <sami.mujawar@...>
抄送: Rebecca Cran <rebecca@...>
主题: [PATCH v2 1/2] MdePkg/BaseRngLib: Add support for ARMv8.5 RNG
instructions

Make BaseRngLib more generic by moving x86 specific functionality from
BaseRng.c into Rand/RdRand.c, and adding AArch64/Rndr.c, which supports
the optional ARMv8.5 RNG instructions RNDR and RNDRRS that are a part of
FEAT_RNG.

Add support for the optional ARMv8.5 RNDR and RNDRRS instructions that
are a part of FEAT_RNG to BaseLib, and add a function to read the ISAR0
register which indicates whether the CPU supports FEAT_RNG.
No change is in BaseLib. RNDR and RNDRRS instructions are added into
BaseRngLib.

And, BaseRngLib only uses RNDR instruction to get random value.
So, RNDRRS implementation is dead code. It is not required to be added.

Thanks
Liming

Signed-off-by: Rebecca Cran <rebecca@...>
---
MdePkg/MdePkg.dec | 9 +-
MdePkg/MdePkg.dsc | 4 +-
MdePkg/Library/BaseRngLib/BaseRngLib.inf | 23 +++-
MdePkg/Library/BaseRngLib/AArch64/ArmRng.h | 59
+++++++++
MdePkg/Library/BaseRngLib/BaseRngLibInternals.h | 79
+++++++++++
MdePkg/Library/BaseRngLib/AArch64/Rndr.c | 139
++++++++++++++++++++
MdePkg/Library/BaseRngLib/BaseRng.c | 87
++++++------
MdePkg/Library/BaseRngLib/Rand/RdRand.c | 131
++++++++++++++++++
MdePkg/Library/BaseRngLib/AArch64/ArmReadIdIsar0.S | 31 +++++
MdePkg/Library/BaseRngLib/AArch64/ArmReadIdIsar0.asm | 30 +++++
MdePkg/Library/BaseRngLib/AArch64/ArmRng.S | 61
+++++++++
MdePkg/Library/BaseRngLib/AArch64/ArmRng.asm | 64
+++++++++
MdePkg/Library/BaseRngLib/BaseRngLib.uni | 6 +-
13 files changed, 669 insertions(+), 54 deletions(-)

diff --git a/MdePkg/MdePkg.dec b/MdePkg/MdePkg.dec
index 8965e903e093..b49f88d8e18f 100644
--- a/MdePkg/MdePkg.dec
+++ b/MdePkg/MdePkg.dec
@@ -267,6 +267,11 @@ [LibraryClasses]
#
RegisterFilterLib|Include/Library/RegisterFilterLib.h

+[LibraryClasses.IA32, LibraryClasses.X64, LibraryClasses.AARCH64]
+ ## @libraryclass Provides services to generate random number.
+ #
+ RngLib|Include/Library/RngLib.h
+
[LibraryClasses.IA32, LibraryClasses.X64]
## @libraryclass Abstracts both S/W SMI generation and detection.
##
@@ -288,10 +293,6 @@ [LibraryClasses.IA32, LibraryClasses.X64]
#
SmmPeriodicSmiLib|Include/Library/SmmPeriodicSmiLib.h

- ## @libraryclass Provides services to generate random number.
- #
- RngLib|Include/Library/RngLib.h
-
## @libraryclass Provides services to log the SMI handler
registration.
SmiHandlerProfileLib|Include/Library/SmiHandlerProfileLib.h

diff --git a/MdePkg/MdePkg.dsc b/MdePkg/MdePkg.dsc
index d363419006ea..a94959169b2f 100644
--- a/MdePkg/MdePkg.dsc
+++ b/MdePkg/MdePkg.dsc
@@ -145,6 +145,9 @@ [Components.IA32, Components.X64,
Components.ARM, Components.AARCH64]

MdePkg/Test/UnitTest/Library/BaseSafeIntLib/TestBaseSafeIntLibSmm.inf

MdePkg/Test/UnitTest/Library/BaseSafeIntLib/TestBaseSafeIntLibUefiShell.in
f

+[Components.IA32, Components.X64, Components.AARCH64]
+ MdePkg/Library/BaseRngLib/BaseRngLib.inf
+
[Components.IA32, Components.X64]
MdePkg/Library/BaseIoLibIntrinsic/BaseIoLibIntrinsic.inf
MdePkg/Library/BaseIoLibIntrinsic/BaseIoLibIntrinsicSev.inf
@@ -168,7 +171,6 @@ [Components.IA32, Components.X64]
MdePkg/Library/BaseS3StallLib/BaseS3StallLib.inf
MdePkg/Library/SmmMemLib/SmmMemLib.inf
MdePkg/Library/SmmIoLib/SmmIoLib.inf
- MdePkg/Library/BaseRngLib/BaseRngLib.inf
MdePkg/Library/SmmPciExpressLib/SmmPciExpressLib.inf
MdePkg/Library/SmiHandlerProfileLibNull/SmiHandlerProfileLibNull.inf
MdePkg/Library/MmServicesTableLib/MmServicesTableLib.inf
diff --git a/MdePkg/Library/BaseRngLib/BaseRngLib.inf
b/MdePkg/Library/BaseRngLib/BaseRngLib.inf
index 31740751c69c..1fcceb941495 100644
--- a/MdePkg/Library/BaseRngLib/BaseRngLib.inf
+++ b/MdePkg/Library/BaseRngLib/BaseRngLib.inf
@@ -1,9 +1,10 @@
## @file
# Instance of RNG (Random Number Generator) Library.
#
-# BaseRng Library that uses CPU RdRand instruction access to provide
-# high-quality random numbers.
+# BaseRng Library that uses CPU RNG instructions (e.g. RdRand) to
+# provide random numbers.
#
+# Copyright (c) 2021, NUVIA Inc. All rights reserved.<BR>
# Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>
#
# SPDX-License-Identifier: BSD-2-Clause-Patent
@@ -22,11 +23,25 @@ [Defines]
CONSTRUCTOR = BaseRngLibConstructor

#
-# VALID_ARCHITECTURES = IA32 X64
+# VALID_ARCHITECTURES = IA32 X64 AARCH64
#

-[Sources.Ia32, Sources.X64]
+[Sources]
BaseRng.c
+ BaseRngLibInternals.h
+
+[Sources.Ia32, Sources.X64]
+ Rand/RdRand.c
+
+[Sources.AARCH64]
+ AArch64/Rndr.c
+ AArch64/ArmRng.h
+
+ AArch64/ArmReadIdIsar0.S | GCC
+ AArch64/ArmRng.S | GCC
+
+ AArch64/ArmReadIdIsar0.asm | MSFT
+ AArch64/ArmRng.asm | MSFT

[Packages]
MdePkg/MdePkg.dec
diff --git a/MdePkg/Library/BaseRngLib/AArch64/ArmRng.h
b/MdePkg/Library/BaseRngLib/AArch64/ArmRng.h
new file mode 100644
index 000000000000..595bd87ba60c
--- /dev/null
+++ b/MdePkg/Library/BaseRngLib/AArch64/ArmRng.h
@@ -0,0 +1,59 @@
+/** @file
+ Random number generator service that uses the RNDR instruction
+ to provide pseudorandom numbers.
+
+ Copyright (c) 2021, NUVIA Inc. All rights reserved.<BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef ARM_RNG_H_
+#define ARM_RNG_H_
+
+/**
+ Generates a random number using RNDR.
+ Returns TRUE on success; FALSE on failure.
+
+ @param[out] Rand Buffer pointer to store the 64-bit random value.
+
+ @retval TRUE Random number generated successfully.
+ @retval FALSE Failed to generate the random number.
+
+**/
+BOOLEAN
+EFIAPI
+ArmRndr (
+ OUT UINT64 *Rand
+ );
+
+/**
+ Generates a random number using RNDRRS.
+ Returns TRUE on success; FALSE on failure.
+
+ @param[out] Rand Buffer pointer to store the 64-bit random value.
+
+ @retval TRUE Random number generated successfully.
+ @retval FALSE Failed to generate the random number.
+
+**/
+BOOLEAN
+EFIAPI
+ArmRndrrs (
+ OUT UINT64 *Rand
+ );
+
+/**
+ Reads the ID_AA64ISAR0 Register.
+
+ @return The contents of the ID_AA64ISAR0 register.
+
+**/
+UINT64
+EFIAPI
+ArmReadIdIsar0 (
+ VOID
+ );
+
+#endif /* ARM_RNG_H_ */
+
diff --git a/MdePkg/Library/BaseRngLib/BaseRngLibInternals.h
b/MdePkg/Library/BaseRngLib/BaseRngLibInternals.h
new file mode 100644
index 000000000000..338ba6ea5313
--- /dev/null
+++ b/MdePkg/Library/BaseRngLib/BaseRngLibInternals.h
@@ -0,0 +1,79 @@
+/** @file
+
+ Architecture specific interface to RNG functionality.
+
+Copyright (c) 2021, NUVIA Inc. All rights reserved.<BR>
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef BASE_RNGLIB_INTERNALS_H_
+
+/**
+ Generates a 16-bit random number.
+
+ @param[out] Rand Buffer pointer to store the 16-bit random value.
+
+ @retval TRUE Random number generated successfully.
+ @retval FALSE Failed to generate the random number.
+
+**/
+BOOLEAN
+EFIAPI
+ArchGetRandomNumber16 (
+ OUT UINT16 *Rand
+ );
+
+/**
+ Generates a 32-bit random number.
+
+ @param[out] Rand Buffer pointer to store the 32-bit random value.
+
+ @retval TRUE Random number generated successfully.
+ @retval FALSE Failed to generate the random number.
+
+**/
+BOOLEAN
+EFIAPI
+ArchGetRandomNumber32 (
+ OUT UINT32 *Rand
+ );
+
+/**
+ Generates a 64-bit random number.
+
+ @param[out] Rand Buffer pointer to store the 64-bit random value.
+
+ @retval TRUE Random number generated successfully.
+ @retval FALSE Failed to generate the random number.
+
+**/
+BOOLEAN
+EFIAPI
+ArchGetRandomNumber64 (
+ OUT UINT64 *Rand
+ );
+
+/**
+ Checks whether the RNG instruction is supported.
+
+ @retval TRUE RNG instruction is supported.
+ @retval FALSE RNG instruction is not supported.
+
+**/
+BOOLEAN
+EFIAPI
+ArchIsRngSupported (
+ VOID
+ );
+
+#if defined (MDE_CPU_AARCH64)
+
+// RNDR, Random Number
+#define RNDR S3_3_C2_C4_0
+#define RNDRRS S3_3_C2_C4_1
+
+#endif
+
+#endif // BASE_RNGLIB_INTERNALS_H_
diff --git a/MdePkg/Library/BaseRngLib/AArch64/Rndr.c
b/MdePkg/Library/BaseRngLib/AArch64/Rndr.c
new file mode 100644
index 000000000000..d658ad2bea89
--- /dev/null
+++ b/MdePkg/Library/BaseRngLib/AArch64/Rndr.c
@@ -0,0 +1,139 @@
+/** @file
+ Random number generator service that uses the RNDR instruction
+ to provide pseudorandom numbers.
+
+ Copyright (c) 2021, NUVIA Inc. All rights reserved.<BR>
+ Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <Uefi.h>
+#include <Library/BaseLib.h>
+#include <Library/DebugLib.h>
+#include <Library/RngLib.h>
+
+#include "ArmRng.h"
+#include "BaseRngLibInternals.h"
+
+STATIC BOOLEAN mRndrSupported;
+
+//
+// Bit mask used to determine if RNDR instruction is supported.
+//
+#define RNDR_MASK ((UINT64)MAX_UINT16 << 60U)
+
+/**
+ The constructor function checks whether or not RNDR instruction is
supported
+ by the host hardware.
+
+ The constructor function checks whether or not RNDR instruction is
supported.
+ It will ASSERT() if RNDR instruction is not supported.
+ It will always return EFI_SUCCESS.
+
+ @retval EFI_SUCCESS The constructor always returns EFI_SUCCESS.
+
+**/
+EFI_STATUS
+EFIAPI
+BaseRngLibConstructor (
+ VOID
+ )
+{
+ UINT64 Isar0;
+ //
+ // Determine RNDR support by examining bits 63:60 of the ISAR0 register
returned by
+ // MSR. A non-zero value indicates that the processor supports the RNDR
instruction.
+ //
+ Isar0 = ArmReadIdIsar0 ();
+ ASSERT ((Isar0 & RNDR_MASK) != 0);
+
+ mRndrSupported = ((Isar0 & RNDR_MASK) != 0);
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Generates a 16-bit random number.
+
+ @param[out] Rand Buffer pointer to store the 16-bit random value.
+
+ @retval TRUE Random number generated successfully.
+ @retval FALSE Failed to generate the random number.
+
+**/
+BOOLEAN
+EFIAPI
+ArchGetRandomNumber16 (
+ OUT UINT16 *Rand
+ )
+{
+ UINT64 Rand64;
+
+ if (ArchGetRandomNumber64 (&Rand64)) {
+ *Rand = Rand64 & MAX_UINT16;
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+/**
+ Generates a 32-bit random number.
+
+ @param[out] Rand Buffer pointer to store the 32-bit random value.
+
+ @retval TRUE Random number generated successfully.
+ @retval FALSE Failed to generate the random number.
+
+**/
+BOOLEAN
+EFIAPI
+ArchGetRandomNumber32 (
+ OUT UINT32 *Rand
+ )
+{
+ UINT64 Rand64;
+
+ if (ArchGetRandomNumber64 (&Rand64)) {
+ *Rand = Rand64 & MAX_UINT32;
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+/**
+ Generates a 64-bit random number.
+
+ @param[out] Rand Buffer pointer to store the 64-bit random value.
+
+ @retval TRUE Random number generated successfully.
+ @retval FALSE Failed to generate the random number.
+
+**/
+BOOLEAN
+EFIAPI
+ArchGetRandomNumber64 (
+ OUT UINT64 *Rand
+ )
+{
+ return ArmRndr (Rand);
+}
+
+/**
+ Checks whether RNDR and RNDRRS (FEAT_RNG) are supported.
+
+ @retval TRUE RNDR and RNDRRS are supported.
+ @retval FALSE RNDR and RNDRRS are not supported.
+
+**/
+BOOLEAN
+EFIAPI
+ArchIsRngSupported (
+ VOID
+ )
+{
+ return mRndrSupported;
+}
diff --git a/MdePkg/Library/BaseRngLib/BaseRng.c
b/MdePkg/Library/BaseRngLib/BaseRng.c
index 7ad7aec9d38f..5b63d8f7146b 100644
--- a/MdePkg/Library/BaseRngLib/BaseRng.c
+++ b/MdePkg/Library/BaseRngLib/BaseRng.c
@@ -1,8 +1,10 @@
/** @file
- Random number generator services that uses RdRand instruction access
- to provide high-quality random numbers.
+ Random number generator services that uses CPU RNG instructions to
+ provide random numbers.

+Copyright (c) 2021, NUVIA Inc. All rights reserved.<BR>
Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>
+
SPDX-License-Identifier: BSD-2-Clause-Patent

**/
@@ -10,46 +12,15 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
#include <Library/BaseLib.h>
#include <Library/DebugLib.h>

-//
-// Bit mask used to determine if RdRand instruction is supported.
-//
-#define RDRAND_MASK BIT30
+#include "BaseRngLibInternals.h"

//
// Limited retry number when valid random data is returned.
// Uses the recommended value defined in Section 7.3.17 of "Intel 64 and
IA-32
-// Architectures Software Developer's Mannual".
+// Architectures Software Developer's Manual".
//
-#define RDRAND_RETRY_LIMIT 10
+#define GETRANDOM_RETRY_LIMIT 10

-/**
- The constructor function checks whether or not RDRAND instruction is
supported
- by the host hardware.
-
- The constructor function checks whether or not RDRAND instruction is
supported.
- It will ASSERT() if RDRAND instruction is not supported.
- It will always return RETURN_SUCCESS.
-
- @retval RETURN_SUCCESS The constructor always returns
EFI_SUCCESS.
-
-**/
-RETURN_STATUS
-EFIAPI
-BaseRngLibConstructor (
- VOID
- )
-{
- UINT32 RegEcx;
-
- //
- // Determine RDRAND support by examining bit 30 of the ECX register
returned by
- // CPUID. A value of 1 indicates that processor support RDRAND
instruction.
- //
- AsmCpuid (1, 0, 0, &RegEcx, 0);
- ASSERT ((RegEcx & RDRAND_MASK) == RDRAND_MASK);
-
- return RETURN_SUCCESS;
-}

/**
Generates a 16-bit random number.
@@ -72,11 +43,19 @@ GetRandomNumber16 (

ASSERT (Rand != NULL);

+ if (Rand == NULL) {
+ return FALSE;
+ }
+
+ if (!ArchIsRngSupported ()) {
+ return FALSE;
+ }
+
//
// A loop to fetch a 16 bit random value with a retry count limit.
//
- for (Index = 0; Index < RDRAND_RETRY_LIMIT; Index++) {
- if (AsmRdRand16 (Rand)) {
+ for (Index = 0; Index < GETRANDOM_RETRY_LIMIT; Index++) {
+ if (ArchGetRandomNumber16 (Rand)) {
return TRUE;
}
}
@@ -105,11 +84,19 @@ GetRandomNumber32 (

ASSERT (Rand != NULL);

+ if (Rand == NULL) {
+ return FALSE;
+ }
+
+ if (!ArchIsRngSupported ()) {
+ return FALSE;
+ }
+
//
// A loop to fetch a 32 bit random value with a retry count limit.
//
- for (Index = 0; Index < RDRAND_RETRY_LIMIT; Index++) {
- if (AsmRdRand32 (Rand)) {
+ for (Index = 0; Index < GETRANDOM_RETRY_LIMIT; Index++) {
+ if (ArchGetRandomNumber32 (Rand)) {
return TRUE;
}
}
@@ -138,11 +125,19 @@ GetRandomNumber64 (

ASSERT (Rand != NULL);

+ if (Rand == NULL) {
+ return FALSE;
+ }
+
+ if (!ArchIsRngSupported ()) {
+ return FALSE;
+ }
+
//
// A loop to fetch a 64 bit random value with a retry count limit.
//
- for (Index = 0; Index < RDRAND_RETRY_LIMIT; Index++) {
- if (AsmRdRand64 (Rand)) {
+ for (Index = 0; Index < GETRANDOM_RETRY_LIMIT; Index++) {
+ if (ArchGetRandomNumber64 (Rand)) {
return TRUE;
}
}
@@ -169,6 +164,14 @@ GetRandomNumber128 (
{
ASSERT (Rand != NULL);

+ if (Rand == NULL) {
+ return FALSE;
+ }
+
+ if (!ArchIsRngSupported ()) {
+ return FALSE;
+ }
+
//
// Read first 64 bits
//
diff --git a/MdePkg/Library/BaseRngLib/Rand/RdRand.c
b/MdePkg/Library/BaseRngLib/Rand/RdRand.c
new file mode 100644
index 000000000000..09fb875ac3f9
--- /dev/null
+++ b/MdePkg/Library/BaseRngLib/Rand/RdRand.c
@@ -0,0 +1,131 @@
+/** @file
+ Random number generator services that uses RdRand instruction access
+ to provide high-quality random numbers.
+
+Copyright (c) 2021, NUVIA Inc. All rights reserved.<BR>
+Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <Uefi.h>
+#include <Library/BaseLib.h>
+#include <Library/DebugLib.h>
+
+#include "BaseRngLibInternals.h"
+
+//
+// Bit mask used to determine if RdRand instruction is supported.
+//
+#define RDRAND_MASK BIT30
+
+
+STATIC BOOLEAN mRdRandSupported;
+
+/**
+ The constructor function checks whether or not RDRAND instruction is
supported
+ by the host hardware.
+
+ The constructor function checks whether or not RDRAND instruction is
supported.
+ It will ASSERT() if RDRAND instruction is not supported.
+ It will always return EFI_SUCCESS.
+
+ @retval EFI_SUCCESS The constructor always returns EFI_SUCCESS.
+
+**/
+EFI_STATUS
+EFIAPI
+BaseRngLibConstructor (
+ VOID
+ )
+{
+ UINT32 RegEcx;
+
+ //
+ // Determine RDRAND support by examining bit 30 of the ECX register
returned by
+ // CPUID. A value of 1 indicates that processor support RDRAND
instruction.
+ //
+ AsmCpuid (1, 0, 0, &RegEcx, 0);
+ ASSERT ((RegEcx & RDRAND_MASK) == RDRAND_MASK);
+
+ mRdRandSupported = ((RegEcx & RDRAND_MASK) == RDRAND_MASK);
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Generates a 16-bit random number.
+
+ @param[out] Rand Buffer pointer to store the 16-bit random value.
+
+ @retval TRUE Random number generated successfully.
+ @retval FALSE Failed to generate the random number.
+
+**/
+BOOLEAN
+EFIAPI
+ArchGetRandomNumber16 (
+ OUT UINT16 *Rand
+ )
+{
+ return AsmRdRand16 (Rand);
+}
+
+/**
+ Generates a 32-bit random number.
+
+ @param[out] Rand Buffer pointer to store the 32-bit random value.
+
+ @retval TRUE Random number generated successfully.
+ @retval FALSE Failed to generate the random number.
+
+**/
+BOOLEAN
+EFIAPI
+ArchGetRandomNumber32 (
+ OUT UINT32 *Rand
+ )
+{
+ return AsmRdRand32 (Rand);
+}
+
+/**
+ Generates a 64-bit random number.
+
+ @param[out] Rand Buffer pointer to store the 64-bit random value.
+
+ @retval TRUE Random number generated successfully.
+ @retval FALSE Failed to generate the random number.
+
+**/
+BOOLEAN
+EFIAPI
+ArchGetRandomNumber64 (
+ OUT UINT64 *Rand
+ )
+{
+ return AsmRdRand64 (Rand);
+}
+
+/**
+ Checks whether RDRAND is supported.
+
+ @retval TRUE RDRAND is supported.
+ @retval FALSE RDRAND is not supported.
+
+**/
+BOOLEAN
+EFIAPI
+ArchIsRngSupported (
+ VOID
+ )
+{
+ /*
+ Existing software depends on this always returning TRUE, so for
+ now hard-code it.
+
+ return mRdRandSupported;
+ */
+ return TRUE;
+}
diff --git a/MdePkg/Library/BaseRngLib/AArch64/ArmReadIdIsar0.S
b/MdePkg/Library/BaseRngLib/AArch64/ArmReadIdIsar0.S
new file mode 100644
index 000000000000..82a00d362212
--- /dev/null
+++ b/MdePkg/Library/BaseRngLib/AArch64/ArmReadIdIsar0.S
@@ -0,0 +1,31 @@
+#--------------------------------------------------------------------------
----
+#
+# ArmReadIdIsar0() for AArch64
+#
+# Copyright (c) 2021, NUVIA Inc. All rights reserved.<BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+#--------------------------------------------------------------------------
----
+
+.text
+.p2align 2
+GCC_ASM_EXPORT(ArmReadIdIsar0)
+
+#/**
+# Reads the ID_AA64ISAR0 Register.
+#
+# @return The contents of the ID_AA64ISAR0 register.
+#
+#**/
+#UINT64
+#EFIAPI
+#ArmReadIdIsar0 (
+# VOID
+# );
+#
+ASM_PFX(ArmReadIdIsar0):
+ mrs x0, id_aa64isar0_el1 // Read ID_AA64ISAR0 Register
+ ret
+
+
diff --git a/MdePkg/Library/BaseRngLib/AArch64/ArmReadIdIsar0.asm
b/MdePkg/Library/BaseRngLib/AArch64/ArmReadIdIsar0.asm
new file mode 100644
index 000000000000..1d9f9a808c0c
--- /dev/null
+++ b/MdePkg/Library/BaseRngLib/AArch64/ArmReadIdIsar0.asm
@@ -0,0 +1,30 @@
+;--------------------------------------------------------------------------
----
+;
+; ArmReadIdIsar0() for AArch64
+;
+; Copyright (c) 2021, NUVIA Inc. All rights reserved.<BR>
+;
+; SPDX-License-Identifier: BSD-2-Clause-Patent
+;
+;--------------------------------------------------------------------------
----
+
+ EXPORT ArmReadIdIsar0
+ AREA BaseLib_LowLevel, CODE, READONLY
+
+;/**
+; Reads the ID_AA64ISAR0 Register.
+;
+; @return The contents of the ID_AA64ISAR0 register.
+;
+;**/
+;UINT64
+;EFIAPI
+;ArmReadIdIsar0 (
+; VOID
+; );
+;
+ArmReadIdIsar0
+ mrs x0, id_aa64isar0_el1 // Read ID_AA64ISAR0 Register
+ ret
+
+ END
diff --git a/MdePkg/Library/BaseRngLib/AArch64/ArmRng.S
b/MdePkg/Library/BaseRngLib/AArch64/ArmRng.S
new file mode 100644
index 000000000000..4b9898dadc52
--- /dev/null
+++ b/MdePkg/Library/BaseRngLib/AArch64/ArmRng.S
@@ -0,0 +1,61 @@
+#--------------------------------------------------------------------------
----
+#
+# ArmRndr() and ArmRndrrs() for AArch64
+#
+# Copyright (c) 2021, NUVIA Inc. All rights reserved.<BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+#--------------------------------------------------------------------------
----
+
+#include "BaseRngLibInternals.h"
+
+.text
+.p2align 2
+GCC_ASM_EXPORT(ArmRndr)
+GCC_ASM_EXPORT(ArmRndrrs)
+
+#/**
+# Generates a random number using RNDR.
+# Returns TRUE on success; FALSE on failure.
+#
+# @param[out] Rand Buffer pointer to store the 64-bit random
value.
+#
+# @retval TRUE Random number generated successfully.
+# @retval FALSE Failed to generate the random number.
+#
+#**/
+#BOOLEAN
+#EFIAPI
+#ArmRndr (
+# OUT UINT64 *Rand
+# );
+#
+ASM_PFX(ArmRndr):
+ mrs x1, RNDR
+ str x1, [x0]
+ cset x0, ne // RNDR sets NZCV to 0b0100 on failure
+ ret
+
+
+#/**
+# Generates a random number using RNDRRS
+# Returns TRUE on success; FALSE on failure.
+#
+# @param[out] Rand Buffer pointer to store the 64-bit random
value.
+#
+# @retval TRUE Random number generated successfully.
+# @retval FALSE Failed to generate the random number.
+#
+#**/
+#BOOLEAN
+#EFIAPI
+#ArmRndrrs (
+# OUT UINT64 *Rand
+# );
+#
+ASM_PFX(ArmRndrrs):
+ mrs x1, RNDRRS
+ str x1, [x0]
+ cset x0, ne // RNDRRS sets NZCV to 0b0100 on failure
+ ret
diff --git a/MdePkg/Library/BaseRngLib/AArch64/ArmRng.asm
b/MdePkg/Library/BaseRngLib/AArch64/ArmRng.asm
new file mode 100644
index 000000000000..e3feb56adbcf
--- /dev/null
+++ b/MdePkg/Library/BaseRngLib/AArch64/ArmRng.asm
@@ -0,0 +1,64 @@
+;--------------------------------------------------------------------------
----
+;
+; ArmRndr() and ArmRndrrs() for AArch64
+;
+; Copyright (c) 2021, NUVIA Inc. All rights reserved.<BR>
+;
+; SPDX-License-Identifier: BSD-2-Clause-Patent
+;
+;--------------------------------------------------------------------------
----
+
+#include "BaseRngLibInternals.h"
+
+ EXPORT ArmRndr
+ EXPORT ArmRndrrs
+ AREA BaseLib_LowLevel, CODE, READONLY
+
+
+;/**
+; Generates a random number using RNDR.
+; Returns TRUE on success; FALSE on failure.
+;
+; @param[out] Rand Buffer pointer to store the 64-bit random value.
+;
+; @retval TRUE Random number generated successfully.
+; @retval FALSE Failed to generate the random number.
+;
+;**/
+;BOOLEAN
+;EFIAPI
+;ArmRndr (
+; OUT UINT64 *Rand
+; );
+;
+ArmRndr
+ mrs x1, RNDR
+ str x1, [x0]
+ cset x0, ne // RNDR sets NZCV to 0b0100 on failure
+ ret
+
+ END
+
+;/**
+; Generates a random number using RNDRRS.
+; Returns TRUE on success; FALSE on failure.
+;
+; @param[out] Rand Buffer pointer to store the 64-bit random value.
+;
+; @retval TRUE Random number generated successfully.
+; @retval FALSE Failed to generate the random number.
+;
+;**/
+;BOOLEAN
+;EFIAPI
+;ArmRndrrs (
+; OUT UINT64 *Rand
+; );
+;
+ArmRndrrs
+ mrs x1, RNDRRS
+ str x1, [x0]
+ cset x0, ne // RNDRRS sets NZCV to 0b0100 on failure
+ ret
+
+ END
diff --git a/MdePkg/Library/BaseRngLib/BaseRngLib.uni
b/MdePkg/Library/BaseRngLib/BaseRngLib.uni
index f3ed954c5209..de5d4f9dd869 100644
--- a/MdePkg/Library/BaseRngLib/BaseRngLib.uni
+++ b/MdePkg/Library/BaseRngLib/BaseRngLib.uni
@@ -1,8 +1,8 @@
// /** @file
// Instance of RNG (Random Number Generator) Library.
//
-// BaseRng Library that uses CPU RdRand instruction access to provide
-// high-quality random numbers.
+// BaseRng Library that uses CPU RNG instructions to provide
+// random numbers.
//
// Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>
//
@@ -13,5 +13,5 @@

#string STR_MODULE_ABSTRACT #language en-US
"Instance of RNG Library"

-#string STR_MODULE_DESCRIPTION #language en-US "BaseRng
Library that uses CPU RdRand instruction access to provide high-quality
random numbers"
+#string STR_MODULE_DESCRIPTION #language en-US "BaseRng
Library that uses CPU RNG instructions to provide random numbers"

--
2.26.2


回复: [PATCH v2 2/2] SecurityPkg: Add support for RngDxe on AARCH64

gaoliming
 

Rebecca:

-----邮件原件-----
发件人: Rebecca Cran <rebecca@...>
发送时间: 2021年5月7日 22:23
收件人: devel@edk2.groups.io; Jiewen Yao <jiewen.yao@...>; Jian J
Wang <jian.j.wang@...>; Michael D Kinney
<michael.d.kinney@...>; Liming Gao <gaoliming@...>;
Zhiguang Liu <zhiguang.liu@...>; Ard Biesheuvel
<ardb+tianocore@...>; Sami Mujawar <sami.mujawar@...>
抄送: Rebecca Cran <rebecca@...>
主题: [PATCH v2 2/2] SecurityPkg: Add support for RngDxe on AARCH64

AARCH64 support has been added to BaseRngLib via the optional
ARMv8.5 FEAT_RNG.

Refactor RngDxe to support AARCH64, note support for it in the
VALID_ARCHITECTURES line of RngDxe.inf and enable it in SecurityPkg.dsc.

Signed-off-by: Rebecca Cran <rebecca@...>
---
SecurityPkg/SecurityPkg.dec |
2 +
SecurityPkg/SecurityPkg.dsc |
11 +-
SecurityPkg/RandomNumberGenerator/RngDxe/RngDxe.inf |
24 ++-
SecurityPkg/RandomNumberGenerator/RngDxe/{ => Rand}/AesCore.h |
0
SecurityPkg/RandomNumberGenerator/RngDxe/{ => Rand}/RdRand.h |
17 --
SecurityPkg/RandomNumberGenerator/RngDxe/RngDxeInternals.h |
117 ++++++++++++++
SecurityPkg/RandomNumberGenerator/RngDxe/AArch64/RngDxe.c |
127 +++++++++++++++
SecurityPkg/RandomNumberGenerator/RngDxe/{ => Rand}/AesCore.c |
0
SecurityPkg/RandomNumberGenerator/RngDxe/{ => Rand}/RdRand.c |
45 +-----
SecurityPkg/RandomNumberGenerator/RngDxe/Rand/RngDxe.c |
146 +++++++++++++++++
SecurityPkg/RandomNumberGenerator/RngDxe/RngDxe.c |
170 ++++++++------------
11 files changed, 483 insertions(+), 176 deletions(-)

diff --git a/SecurityPkg/SecurityPkg.dec b/SecurityPkg/SecurityPkg.dec
index dfbbb0365a2b..a45104fe3e6c 100644
--- a/SecurityPkg/SecurityPkg.dec
+++ b/SecurityPkg/SecurityPkg.dec
@@ -297,6 +297,8 @@ [PcdsFixedAtBuild, PcdsPatchableInModule]

gEfiSecurityPkgTokenSpaceGuid.PcdStatusCodeFvVerificationPass|0x0303100
A|UINT32|0x00010030

gEfiSecurityPkgTokenSpaceGuid.PcdStatusCodeFvVerificationFail|0x0303100B
|UINT32|0x00010031

+
gEfiSecurityPkgTokenSpaceGuid.PcdCpuRngSupportedAlgorithm|{0}|VOID*|0
x00010032
+
This PCD value is GUID. So, its default value should be GUID (16 bytes)
instead of {0} (1 byte).

Thanks
Liming
[PcdsFixedAtBuild, PcdsPatchableInModule, PcdsDynamic, PcdsDynamicEx]
## Image verification policy for OptionRom. Only following values are
valid:<BR><BR>
# NOTE: Do NOT use 0x5 and 0x2 since it violates the UEFI
specification
and has been removed.<BR>
diff --git a/SecurityPkg/SecurityPkg.dsc b/SecurityPkg/SecurityPkg.dsc
index 12ccd1634941..bd4b810bce61 100644
--- a/SecurityPkg/SecurityPkg.dsc
+++ b/SecurityPkg/SecurityPkg.dsc
@@ -259,6 +259,12 @@ [Components]
[Components.IA32, Components.X64, Components.ARM,
Components.AARCH64]
SecurityPkg/Library/AuthVariableLib/AuthVariableLib.inf

+[Components.IA32, Components.X64, Components.AARCH64]
+ #
+ # Random Number Generator
+ #
+ SecurityPkg/RandomNumberGenerator/RngDxe/RngDxe.inf
+
[Components.IA32, Components.X64]

SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigD
xe.inf

@@ -334,11 +340,6 @@ [Components.IA32, Components.X64]

SecurityPkg/Library/SmmTcg2PhysicalPresenceLib/SmmTcg2PhysicalPresence
Lib.inf

SecurityPkg/Library/SmmTcg2PhysicalPresenceLib/StandaloneMmTcg2Physic
alPresenceLib.inf

- #
- # Random Number Generator
- #
- SecurityPkg/RandomNumberGenerator/RngDxe/RngDxe.inf
-
#
# Opal Password solution
#
diff --git a/SecurityPkg/RandomNumberGenerator/RngDxe/RngDxe.inf
b/SecurityPkg/RandomNumberGenerator/RngDxe/RngDxe.inf
index 99d6f6b35fc2..f3300971993f 100644
--- a/SecurityPkg/RandomNumberGenerator/RngDxe/RngDxe.inf
+++ b/SecurityPkg/RandomNumberGenerator/RngDxe/RngDxe.inf
@@ -26,15 +26,22 @@ [Defines]
#
# The following information is for reference only and not required by the
build tools.
#
-# VALID_ARCHITECTURES = IA32 X64
+# VALID_ARCHITECTURES = IA32 X64 AARCH64
#

[Sources.common]
RngDxe.c
- RdRand.c
- RdRand.h
- AesCore.c
- AesCore.h
+ RngDxeInternals.h
+
+[Sources.IA32, Sources.X64]
+ Rand/RngDxe.c
+ Rand/RdRand.c
+ Rand/RdRand.h
+ Rand/AesCore.c
+ Rand/AesCore.h
+
+[Sources.AARCH64]
+ AArch64/RngDxe.c

[Packages]
MdePkg/MdePkg.dec
@@ -50,12 +57,19 @@ [LibraryClasses]
RngLib

[Guids]
+ gEfiRngAlgorithmSp80090Hash256Guid ## SOMETIMES_PRODUCES
## GUID # Unique ID of the algorithm for RNG
+ gEfiRngAlgorithmSp80090Hmac256Guid ## SOMETIMES_PRODUCES
## GUID # Unique ID of the algorithm for RNG
gEfiRngAlgorithmSp80090Ctr256Guid ## SOMETIMES_PRODUCES
## GUID # Unique ID of the algorithm for RNG
+ gEfiRngAlgorithmX9313DesGuid ## SOMETIMES_PRODUCES
## GUID # Unique ID of the algorithm for RNG
+ gEfiRngAlgorithmX931AesGuid ## SOMETIMES_PRODUCES
## GUID # Unique ID of the algorithm for RNG
gEfiRngAlgorithmRaw ## SOMETIMES_PRODUCES
## GUID # Unique ID of the algorithm for RNG

[Protocols]
gEfiRngProtocolGuid ## PRODUCES

+[Pcd]
+ gEfiSecurityPkgTokenSpaceGuid.PcdCpuRngSupportedAlgorithm ##
CONSUMES
+
[Depex]
TRUE

diff --git a/SecurityPkg/RandomNumberGenerator/RngDxe/AesCore.h
b/SecurityPkg/RandomNumberGenerator/RngDxe/Rand/AesCore.h
similarity index 100%
rename from SecurityPkg/RandomNumberGenerator/RngDxe/AesCore.h
rename to SecurityPkg/RandomNumberGenerator/RngDxe/Rand/AesCore.h
diff --git a/SecurityPkg/RandomNumberGenerator/RngDxe/RdRand.h
b/SecurityPkg/RandomNumberGenerator/RngDxe/Rand/RdRand.h
similarity index 72%
rename from SecurityPkg/RandomNumberGenerator/RngDxe/RdRand.h
rename to SecurityPkg/RandomNumberGenerator/RngDxe/Rand/RdRand.h
index 12ab1f34ec6d..072378e062e7 100644
--- a/SecurityPkg/RandomNumberGenerator/RngDxe/RdRand.h
+++ b/SecurityPkg/RandomNumberGenerator/RngDxe/Rand/RdRand.h
@@ -23,23 +23,6 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
#include <Library/TimerLib.h>
#include <Protocol/Rng.h>

-/**
- Calls RDRAND to fill a buffer of arbitrary size with random bytes.
-
- @param[in] Length Size of the buffer, in bytes, to fill with.
- @param[out] RandBuffer Pointer to the buffer to store the random
result.
-
- @retval EFI_SUCCESS Random bytes generation succeeded.
- @retval EFI_NOT_READY Failed to request random bytes.
-
-**/
-EFI_STATUS
-EFIAPI
-RdRandGetBytes (
- IN UINTN Length,
- OUT UINT8 *RandBuffer
- );
-
/**
Generate high-quality entropy source through RDRAND.

diff --git a/SecurityPkg/RandomNumberGenerator/RngDxe/RngDxeInternals.h
b/SecurityPkg/RandomNumberGenerator/RngDxe/RngDxeInternals.h
new file mode 100644
index 000000000000..2660ed5875e0
--- /dev/null
+++ b/SecurityPkg/RandomNumberGenerator/RngDxe/RngDxeInternals.h
@@ -0,0 +1,117 @@
+/** @file
+ Function prototypes for UEFI Random Number Generator protocol
support.
+
+ Copyright (c) 2021, NUVIA Inc. All rights reserved.<BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef RNGDXE_INTERNALS_H_
+#define RNGDXE_INTERNALS_H_
+
+/**
+ Returns information about the random number generation
implementation.
+
+ @param[in] This A pointer to the
EFI_RNG_PROTOCOL instance.
+ @param[in,out] RNGAlgorithmListSize On input, the size in bytes of
RNGAlgorithmList.
+ On output with a return code
of EFI_SUCCESS, the size
+ in bytes of the data returned
in RNGAlgorithmList. On output
+ with a return code of
EFI_BUFFER_TOO_SMALL,
+ the size of RNGAlgorithmList
required to obtain the list.
+ @param[out] RNGAlgorithmList A caller-allocated memory
buffer filled by the driver
+ with one
EFI_RNG_ALGORITHM element for each supported
+ RNG algorithm. The list must
not change across multiple
+ calls to the same driver. The
first algorithm in the list
+ is the default algorithm for
the driver.
+
+ @retval EFI_SUCCESS The RNG algorithm list was
returned successfully.
+ @retval EFI_UNSUPPORTED The services is not supported
by this driver.
+ @retval EFI_DEVICE_ERROR The list of algorithms could
not be retrieved due to a
+ hardware or firmware error.
+ @retval EFI_INVALID_PARAMETER One or more of the
parameters are incorrect.
+ @retval EFI_BUFFER_TOO_SMALL The buffer RNGAlgorithmList
is too small to hold the result.
+
+**/
+EFI_STATUS
+EFIAPI
+RngGetInfo (
+ IN EFI_RNG_PROTOCOL *This,
+ IN OUT UINTN *RNGAlgorithmListSize,
+ OUT EFI_RNG_ALGORITHM *RNGAlgorithmList
+ );
+
+/**
+ Produces and returns an RNG value using either the default or specified
RNG algorithm.
+
+ @param[in] This A pointer to the
EFI_RNG_PROTOCOL instance.
+ @param[in] RNGAlgorithm A pointer to the
EFI_RNG_ALGORITHM that identifies the RNG
+ algorithm to use. May be
NULL in which case the function will
+ use its default RNG
algorithm.
+ @param[in] RNGValueLength The length in bytes of the
memory buffer pointed to by
+ RNGValue. The driver shall
return exactly this numbers of bytes.
+ @param[out] RNGValue A caller-allocated memory
buffer filled by the driver with the
+ resulting RNG value.
+
+ @retval EFI_SUCCESS The RNG value was returned
successfully.
+ @retval EFI_UNSUPPORTED The algorithm specified by
RNGAlgorithm is not supported by
+ this driver.
+ @retval EFI_DEVICE_ERROR An RNG value could not be
retrieved due to a hardware or
+ firmware error.
+ @retval EFI_NOT_READY There is not enough random
data available to satisfy the length
+ requested by
RNGValueLength.
+ @retval EFI_INVALID_PARAMETER RNGValue is NULL or
RNGValueLength is zero.
+
+**/
+EFI_STATUS
+EFIAPI
+RngGetRNG (
+ IN EFI_RNG_PROTOCOL *This,
+ IN EFI_RNG_ALGORITHM *RNGAlgorithm, OPTIONAL
+ IN UINTN RNGValueLength,
+ OUT UINT8 *RNGValue
+ );
+
+/**
+ Returns information about the random number generation
implementation.
+
+ @param[in,out] RNGAlgorithmListSize On input, the size in bytes of
RNGAlgorithmList.
+ On output with a return code
of EFI_SUCCESS, the size
+ in bytes of the data returned
in RNGAlgorithmList. On output
+ with a return code of
EFI_BUFFER_TOO_SMALL,
+ the size of RNGAlgorithmList
required to obtain the list.
+ @param[out] RNGAlgorithmList A caller-allocated memory
buffer filled by the driver
+ with one
EFI_RNG_ALGORITHM element for each supported
+ RNG algorithm. The list must
not change across multiple
+ calls to the same driver. The
first algorithm in the list
+ is the default algorithm for
the driver.
+
+ @retval EFI_SUCCESS The RNG algorithm list was
returned successfully.
+ @retval EFI_BUFFER_TOO_SMALL The buffer RNGAlgorithmList
is too small to hold the result.
+
+**/
+UINTN
+EFIAPI
+ArchGetSupportedRngAlgorithms (
+ IN OUT UINTN *RNGAlgorithmListSize,
+ OUT EFI_RNG_ALGORITHM *RNGAlgorithmList
+ );
+
+/**
+ Runs CPU RNG instruction to fill a buffer of arbitrary size with random
bytes.
+
+ @param[in] Length Size of the buffer, in bytes, to fill with.
+ @param[out] RandBuffer Pointer to the buffer to store the random
result.
+
+ @retval EFI_SUCCESS Random bytes generation succeeded.
+ @retval EFI_NOT_READY Failed to request random bytes.
+
+**/
+EFI_STATUS
+EFIAPI
+RngGetBytes (
+ IN UINTN Length,
+ OUT UINT8 *RandBuffer
+ );
+
+#endif // RNGDXE_INTERNALS_H_
diff --git
a/SecurityPkg/RandomNumberGenerator/RngDxe/AArch64/RngDxe.c
b/SecurityPkg/RandomNumberGenerator/RngDxe/AArch64/RngDxe.c
new file mode 100644
index 000000000000..2810a9eb94ad
--- /dev/null
+++ b/SecurityPkg/RandomNumberGenerator/RngDxe/AArch64/RngDxe.c
@@ -0,0 +1,127 @@
+/** @file
+ RNG Driver to produce the UEFI Random Number Generator protocol.
+
+ The driver will use the RNDR instruction to produce random numbers.
+
+ RNG Algorithms defined in UEFI 2.4:
+ - EFI_RNG_ALGORITHM_SP800_90_CTR_256_GUID
+ - EFI_RNG_ALGORITHM_RAW - Unsupported
+ - EFI_RNG_ALGORITHM_SP800_90_HMAC_256_GUID
+ - EFI_RNG_ALGORITHM_SP800_90_HASH_256_GUID
+ - EFI_RNG_ALGORITHM_X9_31_3DES_GUID - Unsupported
+ - EFI_RNG_ALGORITHM_X9_31_AES_GUID - Unsupported
+
+ Copyright (c) 2021, NUVIA Inc. All rights reserved.<BR>
+ Copyright (c) 2013 - 2018, Intel Corporation. All rights reserved.<BR>
+ (C) Copyright 2015 Hewlett Packard Enterprise Development LP<BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/TimerLib.h>
+#include <Protocol/Rng.h>
+
+#include "RngDxeInternals.h"
+
+/**
+ Produces and returns an RNG value using either the default or specified
RNG algorithm.
+
+ @param[in] This A pointer to the
EFI_RNG_PROTOCOL instance.
+ @param[in] RNGAlgorithm A pointer to the
EFI_RNG_ALGORITHM that identifies the RNG
+ algorithm to use. May be
NULL in which case the function will
+ use its default RNG
algorithm.
+ @param[in] RNGValueLength The length in bytes of the
memory buffer pointed to by
+ RNGValue. The driver shall
return exactly this numbers of bytes.
+ @param[out] RNGValue A caller-allocated memory
buffer filled by the driver with the
+ resulting RNG value.
+
+ @retval EFI_SUCCESS The RNG value was returned
successfully.
+ @retval EFI_UNSUPPORTED The algorithm specified by
RNGAlgorithm is not supported by
+ this driver.
+ @retval EFI_DEVICE_ERROR An RNG value could not be
retrieved due to a hardware or
+ firmware error.
+ @retval EFI_NOT_READY There is not enough random
data available to satisfy the length
+ requested by
RNGValueLength.
+ @retval EFI_INVALID_PARAMETER RNGValue is NULL or
RNGValueLength is zero.
+
+**/
+EFI_STATUS
+EFIAPI
+RngGetRNG (
+ IN EFI_RNG_PROTOCOL *This,
+ IN EFI_RNG_ALGORITHM *RNGAlgorithm, OPTIONAL
+ IN UINTN RNGValueLength,
+ OUT UINT8 *RNGValue
+ )
+{
+ EFI_STATUS Status;
+
+ if ((RNGValueLength == 0) || (RNGValue == NULL)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (RNGAlgorithm == NULL) {
+ //
+ // Use the default RNG algorithm if RNGAlgorithm is NULL.
+ //
+ RNGAlgorithm = PcdGetPtr (PcdCpuRngSupportedAlgorithm);
+ }
+
+ if (CompareGuid (RNGAlgorithm, PcdGetPtr
(PcdCpuRngSupportedAlgorithm))) {
+ Status = RngGetBytes (RNGValueLength, RNGValue);
+ return Status;
+ }
+
+ //
+ // Other algorithms are unsupported by this driver.
+ //
+ return EFI_UNSUPPORTED;
+}
+
+/**
+ Returns information about the random number generation
implementation.
+
+ @param[in,out] RNGAlgorithmListSize On input, the size in bytes of
RNGAlgorithmList.
+ On output with a return code
of EFI_SUCCESS, the size
+ in bytes of the data returned
in RNGAlgorithmList. On output
+ with a return code of
EFI_BUFFER_TOO_SMALL,
+ the size of RNGAlgorithmList
required to obtain the list.
+ @param[out] RNGAlgorithmList A caller-allocated memory
buffer filled by the driver
+ with one
EFI_RNG_ALGORITHM element for each supported
+ RNG algorithm. The list must
not change across multiple
+ calls to the same driver. The
first algorithm in the list
+ is the default algorithm for
the driver.
+
+ @retval EFI_SUCCESS The RNG algorithm list was
returned successfully.
+ @retval EFI_BUFFER_TOO_SMALL The buffer RNGAlgorithmList
is too small to hold the result.
+
+**/
+UINTN
+EFIAPI
+ArchGetSupportedRngAlgorithms (
+ IN OUT UINTN *RNGAlgorithmListSize,
+ OUT EFI_RNG_ALGORITHM *RNGAlgorithmList
+ )
+{
+ UINTN RequiredSize;
+ EFI_RNG_ALGORITHM *CpuRngSupportedAlgorithm;
+
+ RequiredSize = sizeof (EFI_RNG_ALGORITHM);
+
+ if (*RNGAlgorithmListSize < RequiredSize) {
+ *RNGAlgorithmListSize = RequiredSize;
+ return EFI_BUFFER_TOO_SMALL;
+ }
+
+ CpuRngSupportedAlgorithm = PcdGetPtr (PcdCpuRngSupportedAlgorithm);
+
+ CopyMem(&RNGAlgorithmList[0], CpuRngSupportedAlgorithm, sizeof
(EFI_RNG_ALGORITHM));
+
+ *RNGAlgorithmListSize = RequiredSize;
+ return EFI_SUCCESS;
+}
+
diff --git a/SecurityPkg/RandomNumberGenerator/RngDxe/AesCore.c
b/SecurityPkg/RandomNumberGenerator/RngDxe/Rand/AesCore.c
similarity index 100%
rename from SecurityPkg/RandomNumberGenerator/RngDxe/AesCore.c
rename to SecurityPkg/RandomNumberGenerator/RngDxe/Rand/AesCore.c
diff --git a/SecurityPkg/RandomNumberGenerator/RngDxe/RdRand.c
b/SecurityPkg/RandomNumberGenerator/RngDxe/Rand/RdRand.c
similarity index 71%
rename from SecurityPkg/RandomNumberGenerator/RngDxe/RdRand.c
rename to SecurityPkg/RandomNumberGenerator/RngDxe/Rand/RdRand.c
index e7dd5ab18111..83025a47d43d 100644
--- a/SecurityPkg/RandomNumberGenerator/RngDxe/RdRand.c
+++ b/SecurityPkg/RandomNumberGenerator/RngDxe/Rand/RdRand.c
@@ -8,48 +8,9 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
**/
#include <Library/RngLib.h>

-#include "RdRand.h"
#include "AesCore.h"
-
-/**
- Calls RDRAND to fill a buffer of arbitrary size with random bytes.
-
- @param[in] Length Size of the buffer, in bytes, to fill with.
- @param[out] RandBuffer Pointer to the buffer to store the random
result.
-
- @retval EFI_SUCCESS Random bytes generation succeeded.
- @retval EFI_NOT_READY Failed to request random bytes.
-
-**/
-EFI_STATUS
-EFIAPI
-RdRandGetBytes (
- IN UINTN Length,
- OUT UINT8 *RandBuffer
- )
-{
- BOOLEAN IsRandom;
- UINT64 TempRand[2];
-
- while (Length > 0) {
- IsRandom = GetRandomNumber128 (TempRand);
- if (!IsRandom) {
- return EFI_NOT_READY;
- }
- if (Length >= sizeof (TempRand)) {
- WriteUnaligned64 ((UINT64*)RandBuffer, TempRand[0]);
- RandBuffer += sizeof (UINT64);
- WriteUnaligned64 ((UINT64*)RandBuffer, TempRand[1]);
- RandBuffer += sizeof (UINT64);
- Length -= sizeof (TempRand);
- } else {
- CopyMem (RandBuffer, TempRand, Length);
- Length = 0;
- }
- }
-
- return EFI_SUCCESS;
-}
+#include "RdRand.h"
+#include "RngDxeInternals.h"

/**
Creates a 128bit random value that is fully forward and backward
prediction resistant,
@@ -92,7 +53,7 @@ RdRandGetSeed128 (
//
for (Index = 0; Index < 32; Index++) {
MicroSecondDelay (10);
- Status = RdRandGetBytes (16, RandByte);
+ Status = RngGetBytes (16, RandByte);
if (EFI_ERROR (Status)) {
return Status;
}
diff --git a/SecurityPkg/RandomNumberGenerator/RngDxe/Rand/RngDxe.c
b/SecurityPkg/RandomNumberGenerator/RngDxe/Rand/RngDxe.c
new file mode 100644
index 000000000000..6b628a9f8bc6
--- /dev/null
+++ b/SecurityPkg/RandomNumberGenerator/RngDxe/Rand/RngDxe.c
@@ -0,0 +1,146 @@
+/** @file
+ RNG Driver to produce the UEFI Random Number Generator protocol.
+
+ The driver will use the new RDRAND instruction to produce high-quality,
high-performance
+ entropy and random number.
+
+ RNG Algorithms defined in UEFI 2.4:
+ - EFI_RNG_ALGORITHM_SP800_90_CTR_256_GUID - Supported
+ (RDRAND implements a hardware NIST SP800-90 AES-CTR-256 based
DRBG)
+ - EFI_RNG_ALGORITHM_RAW - Supported
+ (Structuring RDRAND invocation can be guaranteed as high-quality
entropy source)
+ - EFI_RNG_ALGORITHM_SP800_90_HMAC_256_GUID - Unsupported
+ - EFI_RNG_ALGORITHM_SP800_90_HASH_256_GUID - Unsupported
+ - EFI_RNG_ALGORITHM_X9_31_3DES_GUID - Unsupported
+ - EFI_RNG_ALGORITHM_X9_31_AES_GUID - Unsupported
+
+ Copyright (c) 2013 - 2018, Intel Corporation. All rights reserved.<BR>
+ (C) Copyright 2015 Hewlett Packard Enterprise Development LP<BR>
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include "RdRand.h"
+#include "RngDxeInternals.h"
+
+/**
+ Produces and returns an RNG value using either the default or specified
RNG algorithm.
+
+ @param[in] This A pointer to the
EFI_RNG_PROTOCOL instance.
+ @param[in] RNGAlgorithm A pointer to the
EFI_RNG_ALGORITHM that identifies the RNG
+ algorithm to use. May be
NULL in which case the function will
+ use its default RNG
algorithm.
+ @param[in] RNGValueLength The length in bytes of the
memory buffer pointed to by
+ RNGValue. The driver shall
return exactly this numbers of bytes.
+ @param[out] RNGValue A caller-allocated memory
buffer filled by the driver with the
+ resulting RNG value.
+
+ @retval EFI_SUCCESS The RNG value was returned
successfully.
+ @retval EFI_UNSUPPORTED The algorithm specified by
RNGAlgorithm is not supported by
+ this driver.
+ @retval EFI_DEVICE_ERROR An RNG value could not be
retrieved due to a hardware or
+ firmware error.
+ @retval EFI_NOT_READY There is not enough random
data available to satisfy the length
+ requested by
RNGValueLength.
+ @retval EFI_INVALID_PARAMETER RNGValue is NULL or
RNGValueLength is zero.
+
+**/
+EFI_STATUS
+EFIAPI
+RngGetRNG (
+ IN EFI_RNG_PROTOCOL *This,
+ IN EFI_RNG_ALGORITHM *RNGAlgorithm, OPTIONAL
+ IN UINTN RNGValueLength,
+ OUT UINT8 *RNGValue
+ )
+{
+ EFI_STATUS Status;
+
+ if ((RNGValueLength == 0) || (RNGValue == NULL)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ Status = EFI_UNSUPPORTED;
+ if (RNGAlgorithm == NULL) {
+ //
+ // Use the default RNG algorithm if RNGAlgorithm is NULL.
+ //
+ RNGAlgorithm = &gEfiRngAlgorithmSp80090Ctr256Guid;
+ }
+
+ //
+ // NIST SP800-90-AES-CTR-256 supported by RDRAND
+ //
+ if (CompareGuid (RNGAlgorithm, &gEfiRngAlgorithmSp80090Ctr256Guid))
{
+ Status = RngGetBytes (RNGValueLength, RNGValue);
+ return Status;
+ }
+
+ //
+ // The "raw" algorithm is intended to provide entropy directly
+ //
+ if (CompareGuid (RNGAlgorithm, &gEfiRngAlgorithmRaw)) {
+ //
+ // When a DRBG is used on the output of a entropy source,
+ // its security level must be at least 256 bits according to UEFI
Spec.
+ //
+ if (RNGValueLength < 32) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ Status = RdRandGenerateEntropy (RNGValueLength, RNGValue);
+ return Status;
+ }
+
+ //
+ // Other algorithms were unsupported by this driver.
+ //
+ return Status;
+}
+
+/**
+ Returns information about the random number generation
implementation.
+
+ @param[in,out] RNGAlgorithmListSize On input, the size in bytes of
RNGAlgorithmList.
+ On output with a return code
of EFI_SUCCESS, the size
+ in bytes of the data returned
in RNGAlgorithmList. On output
+ with a return code of
EFI_BUFFER_TOO_SMALL,
+ the size of RNGAlgorithmList
required to obtain the list.
+ @param[out] RNGAlgorithmList A caller-allocated memory
buffer filled by the driver
+ with one
EFI_RNG_ALGORITHM element for each supported
+ RNG algorithm. The list must
not change across multiple
+ calls to the same driver. The
first algorithm in the list
+ is the default algorithm for
the driver.
+
+ @retval EFI_SUCCESS The RNG algorithm list was
returned successfully.
+ @retval EFI_BUFFER_TOO_SMALL The buffer RNGAlgorithmList
is too small to hold the result.
+
+**/
+UINTN
+EFIAPI
+ArchGetSupportedRngAlgorithms (
+ IN OUT UINTN *RNGAlgorithmListSize,
+ OUT EFI_RNG_ALGORITHM *RNGAlgorithmList
+ )
+{
+ UINTN RequiredSize;
+ EFI_RNG_ALGORITHM *CpuRngSupportedAlgorithm;
+
+ RequiredSize = 2 * sizeof (EFI_RNG_ALGORITHM);
+
+ if (*RNGAlgorithmListSize < RequiredSize) {
+ *RNGAlgorithmListSize = RequiredSize;
+ return EFI_BUFFER_TOO_SMALL;
+ }
+
+ CpuRngSupportedAlgorithm = PcdGetPtr (PcdCpuRngSupportedAlgorithm);
+
+ CopyMem(&RNGAlgorithmList[0], CpuRngSupportedAlgorithm, sizeof
(EFI_RNG_ALGORITHM));
+
+ // x86 platforms also support EFI_RNG_ALGORITHM_RAW via RDSEED
+ CopyMem(&RNGAlgorithmList[1], &gEfiRngAlgorithmRaw, sizeof
(EFI_RNG_ALGORITHM));
+
+ *RNGAlgorithmListSize = RequiredSize;
+ return EFI_SUCCESS;
+}
+
diff --git a/SecurityPkg/RandomNumberGenerator/RngDxe/RngDxe.c
b/SecurityPkg/RandomNumberGenerator/RngDxe/RngDxe.c
index 13d3dbd0bfbe..b959c70536ea 100644
--- a/SecurityPkg/RandomNumberGenerator/RngDxe/RngDxe.c
+++ b/SecurityPkg/RandomNumberGenerator/RngDxe/RngDxe.c
@@ -1,34 +1,32 @@
/** @file
RNG Driver to produce the UEFI Random Number Generator protocol.

- The driver will use the new RDRAND instruction to produce high-quality,
high-performance
- entropy and random number.
+ The driver uses CPU RNG instructions to produce high-quality,
+ high-performance entropy and random number.

RNG Algorithms defined in UEFI 2.4:
- - EFI_RNG_ALGORITHM_SP800_90_CTR_256_GUID - Supported
- (RDRAND implements a hardware NIST SP800-90 AES-CTR-256 based
DRBG)
- - EFI_RNG_ALGORITHM_RAW - Supported
- (Structuring RDRAND invocation can be guaranteed as high-quality
entropy source)
- - EFI_RNG_ALGORITHM_SP800_90_HMAC_256_GUID - Unsupported
- - EFI_RNG_ALGORITHM_SP800_90_HASH_256_GUID - Unsupported
- - EFI_RNG_ALGORITHM_X9_31_3DES_GUID - Unsupported
- - EFI_RNG_ALGORITHM_X9_31_AES_GUID - Unsupported
+ - EFI_RNG_ALGORITHM_SP800_90_CTR_256_GUID
+ - EFI_RNG_ALGORITHM_RAW
+ - EFI_RNG_ALGORITHM_SP800_90_HMAC_256_GUID
+ - EFI_RNG_ALGORITHM_SP800_90_HASH_256_GUID
+ - EFI_RNG_ALGORITHM_X9_31_3DES_GUID
+ - EFI_RNG_ALGORITHM_X9_31_AES_GUID

Copyright (c) 2013 - 2018, Intel Corporation. All rights reserved.<BR>
(C) Copyright 2015 Hewlett Packard Enterprise Development LP<BR>
+
SPDX-License-Identifier: BSD-2-Clause-Patent

**/

-#include "RdRand.h"
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/RngLib.h>
+#include <Library/TimerLib.h>
+#include <Protocol/Rng.h>

-//
-// Supported RNG Algorithms list by this driver.
-//
-EFI_RNG_ALGORITHM mSupportedRngAlgorithms[] = {
- EFI_RNG_ALGORITHM_SP800_90_CTR_256_GUID,
- EFI_RNG_ALGORITHM_RAW
-};
+#include "RngDxeInternals.h"

/**
Returns information about the random number generation
implementation.
@@ -62,106 +60,23 @@ RngGetInfo (
)
{
EFI_STATUS Status;
- UINTN RequiredSize;

if ((This == NULL) || (RNGAlgorithmListSize == NULL)) {
return EFI_INVALID_PARAMETER;
}

- RequiredSize = sizeof (mSupportedRngAlgorithms);
- if (*RNGAlgorithmListSize < RequiredSize) {
- Status = EFI_BUFFER_TOO_SMALL;
+ //
+ // Return algorithm list supported by driver.
+ //
+ if (RNGAlgorithmList != NULL) {
+ Status = ArchGetSupportedRngAlgorithms (RNGAlgorithmListSize,
RNGAlgorithmList);
} else {
- //
- // Return algorithm list supported by driver.
- //
- if (RNGAlgorithmList != NULL) {
- CopyMem (RNGAlgorithmList, mSupportedRngAlgorithms,
RequiredSize);
- Status = EFI_SUCCESS;
- } else {
- Status = EFI_INVALID_PARAMETER;
- }
+ Status = EFI_INVALID_PARAMETER;
}
- *RNGAlgorithmListSize = RequiredSize;

return Status;
}

-/**
- Produces and returns an RNG value using either the default or specified
RNG algorithm.
-
- @param[in] This A pointer to the
EFI_RNG_PROTOCOL instance.
- @param[in] RNGAlgorithm A pointer to the
EFI_RNG_ALGORITHM that identifies the RNG
- algorithm to use. May be
NULL in which case the function will
- use its default RNG
algorithm.
- @param[in] RNGValueLength The length in bytes of the
memory buffer pointed to by
- RNGValue. The driver shall
return exactly this numbers of bytes.
- @param[out] RNGValue A caller-allocated memory
buffer filled by the driver with the
- resulting RNG value.
-
- @retval EFI_SUCCESS The RNG value was returned
successfully.
- @retval EFI_UNSUPPORTED The algorithm specified by
RNGAlgorithm is not supported by
- this driver.
- @retval EFI_DEVICE_ERROR An RNG value could not be
retrieved due to a hardware or
- firmware error.
- @retval EFI_NOT_READY There is not enough random
data available to satisfy the length
- requested by
RNGValueLength.
- @retval EFI_INVALID_PARAMETER RNGValue is NULL or
RNGValueLength is zero.
-
-**/
-EFI_STATUS
-EFIAPI
-RngGetRNG (
- IN EFI_RNG_PROTOCOL *This,
- IN EFI_RNG_ALGORITHM *RNGAlgorithm, OPTIONAL
- IN UINTN RNGValueLength,
- OUT UINT8 *RNGValue
- )
-{
- EFI_STATUS Status;
-
- if ((RNGValueLength == 0) || (RNGValue == NULL)) {
- return EFI_INVALID_PARAMETER;
- }
-
- Status = EFI_UNSUPPORTED;
- if (RNGAlgorithm == NULL) {
- //
- // Use the default RNG algorithm if RNGAlgorithm is NULL.
- //
- RNGAlgorithm = &gEfiRngAlgorithmSp80090Ctr256Guid;
- }
-
- //
- // NIST SP800-90-AES-CTR-256 supported by RDRAND
- //
- if (CompareGuid (RNGAlgorithm, &gEfiRngAlgorithmSp80090Ctr256Guid)) {
- Status = RdRandGetBytes (RNGValueLength, RNGValue);
- return Status;
- }
-
- //
- // The "raw" algorithm is intended to provide entropy directly
- //
- if (CompareGuid (RNGAlgorithm, &gEfiRngAlgorithmRaw)) {
- //
- // When a DRBG is used on the output of a entropy source,
- // its security level must be at least 256 bits according to UEFI
Spec.
- //
- if (RNGValueLength < 32) {
- return EFI_INVALID_PARAMETER;
- }
-
- Status = RdRandGenerateEntropy (RNGValueLength, RNGValue);
- return Status;
- }
-
- //
- // Other algorithms were unsupported by this driver.
- //
- return Status;
-}
-
//
// The Random Number Generator (RNG) protocol
//
@@ -204,3 +119,44 @@ RngDriverEntry (

return Status;
}
+
+
+/**
+ Calls RDRAND to fill a buffer of arbitrary size with random bytes.
+
+ @param[in] Length Size of the buffer, in bytes, to fill with.
+ @param[out] RandBuffer Pointer to the buffer to store the random
result.
+
+ @retval EFI_SUCCESS Random bytes generation succeeded.
+ @retval EFI_NOT_READY Failed to request random bytes.
+
+**/
+EFI_STATUS
+EFIAPI
+RngGetBytes (
+ IN UINTN Length,
+ OUT UINT8 *RandBuffer
+ )
+{
+ BOOLEAN IsRandom;
+ UINT64 TempRand[2];
+
+ while (Length > 0) {
+ IsRandom = GetRandomNumber128 (TempRand);
+ if (!IsRandom) {
+ return EFI_NOT_READY;
+ }
+ if (Length >= sizeof (TempRand)) {
+ WriteUnaligned64 ((UINT64*)RandBuffer, TempRand[0]);
+ RandBuffer += sizeof (UINT64);
+ WriteUnaligned64 ((UINT64*)RandBuffer, TempRand[1]);
+ RandBuffer += sizeof (UINT64);
+ Length -= sizeof (TempRand);
+ } else {
+ CopyMem (RandBuffer, TempRand, Length);
+ Length = 0;
+ }
+ }
+
+ return EFI_SUCCESS;
+}
--
2.26.2


TianoCore Meeting Minutes - May 2021

Soumya Guptha
 

Revised minutes:

TianoCore Community Meeting

May 6, 2021

EVENTS:
UEFI Plugfest (update from Dick Wilkins):
We are planning a plug fest during the week of April 4th during 2022 in Hillsboro, Oregon.

Google Summer of Code (update from Nate Desimone)
* Google has reviewed the project submissions and will communicate the decisions to those applicants on the accepted projects on May 17th.
* Projects will begin from Jun 7 till Aug 16th.
* Community Action: We encourage entire community to be involved, for getting your input/comments and supporting our mentors. The community can get involved in activities such as code reviews etc.. we need support from maintainers, reviewers. Be responsive on the mailing list. you can respond to students when they post questions on the mailing list.


Stable Tag updates:

o Up to date information: https://github.com/tianocore/tianocore.github.io/wiki/EDK-II-Release-Planning

o Feature planning freeze scheduled for 5/10/2021


Stewards Meeting Download (Mike Kinney)

* Limited attendance this month.

o We are seeing an increase in EDK2 CI failure/coverage issues. Azure moved to Ubuntu 20 and we are still on Ubuntu 18. There are some gaps (such as emulator package) that we are addressing. There is a specific failure on emulator package that we need to disable temporarily. Ubuntu GCC IA32 EmulatorPkg - 32-bit X11 dependency conflicts. May need to consider adding text console support.

o Action: Mike Kinney will submit an RFC

* Bugzilla 988 (https://bugzilla.tianocore.org/show_bug.cgi?id=988) - performance issues in handles database.

o DXE core implementation and performance issues on large number of handles.

o Question to the Community: Can we drop EFI 1.02 driver compatibility support from DXE core?

Removing the compatibility will help the performance issues, but not fully resolve them. Risk is extremely low for support. Simple change in DXE core. Base tools still have support for building EDK1 style modules. Action: Mike to start an RFC on this topic.



Opens:
Dick Wilkins - MSFT maintains the list of revoked code signatures for UEFI code modules and loaders for the UEFI Forum and produces binary files that contain revoked signatures for use by secure boot. MSFT has approved the latest update of revoked signatures list for general testing. They are posted at https://uefi.org/revocationlistfile. These files should only be used for testing at this time. Use of these files my cause systems to not boot and should not be used in shipping products without appropriate planning and testing.


Regards,
Soumya

Soumya Guptha
Firmware Ecosystem Enabling Manager, Intel Corporation


TianoCore Meeting Minutes - May 2021

Soumya Guptha
 

TianoCore Community Meeting

May 6, 2021

 

 

EVENTS:

UEFI Plugfest (update from Dick Wilkins):

We are planning a plug fest during the week of April 4th during 2022 in Hillsboro, Oregon.

 

Google Summer of Code (update from Nate Desimone)

  • Google has accepted all of our projects. Google will make that announcement.
  • Google will communicate the decisions to those applicants on the accepted projects on May 17th.
  • Projects will begin from Jun 7 till Aug 16th.
  • Community Action: We encourage entire community to be involved, for getting your input/comments and supporting our mentors. The community can involved in activities such as code reviews etc.. we need support from maintainers, reviewers. Be responsive on the mailing list. you can respond to students when they post questions on the mailing list.

 

Stable Tag updates:

o   Up to date information: https://github.com/tianocore/tianocore.github.io/wiki/EDK-II-Release-Planning

o   Feature planning freeze scheduled for 5/10/2021

 

 

Stewards Meeting Download (Mike Kinney)

·       Limited attendance this month.

o   We are seeing an increase in EDK2 CI failure/coverage issues. Azure moved to Ubuntu 20 and we are still on Ubuntu 18. There are some gaps (such as emulator package) that we are addressing. There is a specific failure on emulator package that we need to disable temporarily. Ubuntu GCC IA32 EmulatorPkg – 32-bit X11 dependency conflicts. May need to consider adding text console support.

o   Action: Mike Kinney will submit an RFC

·       Bugzilla 988 (https://bugzilla.tianocore.org/show_bug.cgi?id=988) – performance issues in handles database.

o   DXE core implementation and performance issues on large number of handles.

o   Question to the Community: Can we drop EFI 1.02 driver compatibility support from DXE core?

Removing the compatibility will help the performance issues, but not fully resolve them. Risk is extremely low for support. Simple change in DXE core. Base tools still have support for building EDK1 style modules. Action: Mike to start an RFC on this topic.

 

 

Opens:

Dick Wilkins - MSFT maintains the list of revoked code signatures for UEFI code modules and loaders for the UEFI Forum and produces

binary files that contain revoked signatures for use by secure boot.  MSFT has approved the latest update of revoked

signatures list for general testing. They are posted at https://uefi.org/revocationlistfile. These files should only be used for

testing at this time. Use of these files my cause systems to not boot and should not be used in shipping products without

appropriate planning and testing.

 

 

Regards,

Soumya

 

Soumya Guptha
Firmware Ecosystem Enabling Manager, Intel Corporation


 


[PATCH 13/13] OvmfPkg/BaseMemEncryptSevLib: remove Flush parameter

Brijesh Singh
 

BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=3275

The Flush parameter is used to provide a hint whether the specified range
is Mmio address. Now that we have a dedicated helper to clear the
memory encryption mask for the Mmio address range, its safe to remove the
Flush parameter from MemEncryptSev{Set,Clear}PageEncMask().

Cc: James Bottomley <jejb@...>
Cc: Min Xu <min.m.xu@...>
Cc: Jiewen Yao <jiewen.yao@...>
Cc: Tom Lendacky <thomas.lendacky@...>
Cc: Jordan Justen <jordan.l.justen@...>
Cc: Ard Biesheuvel <ardb+tianocore@...>
Cc: Laszlo Ersek <lersek@...>
Cc: Erdem Aktas <erdemaktas@...>
Signed-off-by: Brijesh Singh <brijesh.singh@...>
---
OvmfPkg/Include/Library/MemEncryptSevLib.h | 10 ++----
.../BaseMemEncryptSevLib/X64/VirtualMemory.h | 10 ++----
OvmfPkg/AmdSevDxe/AmdSevDxe.c | 3 +-
OvmfPkg/IoMmuDxe/AmdSevIoMmu.c | 6 ++--
.../Ia32/MemEncryptSevLib.c | 10 ++----
.../X64/MemEncryptSevLib.c | 16 +++-------
.../X64/PeiDxeVirtualMemory.c | 32 +++++++++++--------
.../X64/SecVirtualMemory.c | 8 ++---
.../SmmCpuFeaturesLib/SmmCpuFeaturesLib.c | 3 +-
OvmfPkg/PlatformPei/AmdSev.c | 3 +-
10 files changed, 35 insertions(+), 66 deletions(-)

diff --git a/OvmfPkg/Include/Library/MemEncryptSevLib.h b/OvmfPkg/Include/Library/MemEncryptSevLib.h
index b91490d5d44d..76d06c206c8b 100644
--- a/OvmfPkg/Include/Library/MemEncryptSevLib.h
+++ b/OvmfPkg/Include/Library/MemEncryptSevLib.h
@@ -100,8 +100,6 @@ MemEncryptSevIsEnabled (
address of a memory region.
@param[in] NumPages The number of pages from start memory
region.
- @param[in] Flush Flush the caches before clearing the bit
- (mostly TRUE except MMIO addresses)

@retval RETURN_SUCCESS The attributes were cleared for the
memory region.
@@ -114,8 +112,7 @@ EFIAPI
MemEncryptSevClearPageEncMask (
IN PHYSICAL_ADDRESS Cr3BaseAddress,
IN PHYSICAL_ADDRESS BaseAddress,
- IN UINTN NumPages,
- IN BOOLEAN Flush
+ IN UINTN NumPages
);

/**
@@ -128,8 +125,6 @@ MemEncryptSevClearPageEncMask (
address of a memory region.
@param[in] NumPages The number of pages from start memory
region.
- @param[in] Flush Flush the caches before setting the bit
- (mostly TRUE except MMIO addresses)

@retval RETURN_SUCCESS The attributes were set for the memory
region.
@@ -142,8 +137,7 @@ EFIAPI
MemEncryptSevSetPageEncMask (
IN PHYSICAL_ADDRESS Cr3BaseAddress,
IN PHYSICAL_ADDRESS BaseAddress,
- IN UINTN NumPages,
- IN BOOLEAN Flush
+ IN UINTN NumPages
);


diff --git a/OvmfPkg/Library/BaseMemEncryptSevLib/X64/VirtualMemory.h b/OvmfPkg/Library/BaseMemEncryptSevLib/X64/VirtualMemory.h
index 8dc39e647b90..21bbbd1c4f9c 100644
--- a/OvmfPkg/Library/BaseMemEncryptSevLib/X64/VirtualMemory.h
+++ b/OvmfPkg/Library/BaseMemEncryptSevLib/X64/VirtualMemory.h
@@ -58,8 +58,6 @@ InternalGetMemEncryptionAddressMask (
@param[in] PhysicalAddress The physical address that is the start
address of a memory region.
@param[in] Length The length of memory region
- @param[in] Flush Flush the caches before applying the
- encryption mask

@retval RETURN_SUCCESS The attributes were cleared for the
memory region.
@@ -72,8 +70,7 @@ EFIAPI
InternalMemEncryptSevSetMemoryDecrypted (
IN PHYSICAL_ADDRESS Cr3BaseAddress,
IN PHYSICAL_ADDRESS PhysicalAddress,
- IN UINTN Length,
- IN BOOLEAN Flush
+ IN UINTN Length
);

/**
@@ -85,8 +82,6 @@ InternalMemEncryptSevSetMemoryDecrypted (
@param[in] PhysicalAddress The physical address that is the start
address of a memory region.
@param[in] Length The length of memory region
- @param[in] Flush Flush the caches before applying the
- encryption mask

@retval RETURN_SUCCESS The attributes were set for the memory
region.
@@ -99,8 +94,7 @@ EFIAPI
InternalMemEncryptSevSetMemoryEncrypted (
IN PHYSICAL_ADDRESS Cr3BaseAddress,
IN PHYSICAL_ADDRESS PhysicalAddress,
- IN UINTN Length,
- IN BOOLEAN Flush
+ IN UINTN Length
);

/**
diff --git a/OvmfPkg/AmdSevDxe/AmdSevDxe.c b/OvmfPkg/AmdSevDxe/AmdSevDxe.c
index 80831b81facf..41e4b291d070 100644
--- a/OvmfPkg/AmdSevDxe/AmdSevDxe.c
+++ b/OvmfPkg/AmdSevDxe/AmdSevDxe.c
@@ -120,8 +120,7 @@ AmdSevDxeEntryPoint (
Status = MemEncryptSevClearPageEncMask (
0, // Cr3BaseAddress -- use current CR3
MapPagesBase, // BaseAddress
- MapPagesCount, // NumPages
- TRUE // Flush
+ MapPagesCount // NumPages
);
if (EFI_ERROR (Status)) {
DEBUG ((DEBUG_ERROR, "%a: MemEncryptSevClearPageEncMask(): %r\n",
diff --git a/OvmfPkg/IoMmuDxe/AmdSevIoMmu.c b/OvmfPkg/IoMmuDxe/AmdSevIoMmu.c
index 49ffa2448811..b30628078f73 100644
--- a/OvmfPkg/IoMmuDxe/AmdSevIoMmu.c
+++ b/OvmfPkg/IoMmuDxe/AmdSevIoMmu.c
@@ -252,8 +252,7 @@ IoMmuMap (
Status = MemEncryptSevClearPageEncMask (
0,
MapInfo->PlainTextAddress,
- MapInfo->NumberOfPages,
- TRUE
+ MapInfo->NumberOfPages
);
ASSERT_EFI_ERROR (Status);
if (EFI_ERROR (Status)) {
@@ -407,8 +406,7 @@ IoMmuUnmapWorker (
Status = MemEncryptSevSetPageEncMask (
0,
MapInfo->PlainTextAddress,
- MapInfo->NumberOfPages,
- TRUE
+ MapInfo->NumberOfPages
);
ASSERT_EFI_ERROR (Status);
if (EFI_ERROR (Status)) {
diff --git a/OvmfPkg/Library/BaseMemEncryptSevLib/Ia32/MemEncryptSevLib.c b/OvmfPkg/Library/BaseMemEncryptSevLib/Ia32/MemEncryptSevLib.c
index 169d3118e44f..be260e0d1014 100644
--- a/OvmfPkg/Library/BaseMemEncryptSevLib/Ia32/MemEncryptSevLib.c
+++ b/OvmfPkg/Library/BaseMemEncryptSevLib/Ia32/MemEncryptSevLib.c
@@ -25,8 +25,6 @@
address of a memory region.
@param[in] NumPages The number of pages from start memory
region.
- @param[in] Flush Flush the caches before clearing the bit
- (mostly TRUE except MMIO addresses)

@retval RETURN_SUCCESS The attributes were cleared for the
memory region.
@@ -39,8 +37,7 @@ EFIAPI
MemEncryptSevClearPageEncMask (
IN PHYSICAL_ADDRESS Cr3BaseAddress,
IN PHYSICAL_ADDRESS BaseAddress,
- IN UINTN NumPages,
- IN BOOLEAN Flush
+ IN UINTN NumPages
)
{
//
@@ -59,8 +56,6 @@ MemEncryptSevClearPageEncMask (
address of a memory region.
@param[in] NumPages The number of pages from start memory
region.
- @param[in] Flush Flush the caches before setting the bit
- (mostly TRUE except MMIO addresses)

@retval RETURN_SUCCESS The attributes were set for the memory
region.
@@ -73,8 +68,7 @@ EFIAPI
MemEncryptSevSetPageEncMask (
IN PHYSICAL_ADDRESS Cr3BaseAddress,
IN PHYSICAL_ADDRESS BaseAddress,
- IN UINTN NumPages,
- IN BOOLEAN Flush
+ IN UINTN NumPages
)
{
//
diff --git a/OvmfPkg/Library/BaseMemEncryptSevLib/X64/MemEncryptSevLib.c b/OvmfPkg/Library/BaseMemEncryptSevLib/X64/MemEncryptSevLib.c
index a2bf698bcde7..a57e8fd37fa7 100644
--- a/OvmfPkg/Library/BaseMemEncryptSevLib/X64/MemEncryptSevLib.c
+++ b/OvmfPkg/Library/BaseMemEncryptSevLib/X64/MemEncryptSevLib.c
@@ -27,8 +27,6 @@
address of a memory region.
@param[in] NumPages The number of pages from start memory
region.
- @param[in] Flush Flush the caches before clearing the bit
- (mostly TRUE except MMIO addresses)

@retval RETURN_SUCCESS The attributes were cleared for the
memory region.
@@ -41,15 +39,13 @@ EFIAPI
MemEncryptSevClearPageEncMask (
IN PHYSICAL_ADDRESS Cr3BaseAddress,
IN PHYSICAL_ADDRESS BaseAddress,
- IN UINTN NumPages,
- IN BOOLEAN Flush
+ IN UINTN NumPages
)
{
return InternalMemEncryptSevSetMemoryDecrypted (
Cr3BaseAddress,
BaseAddress,
- EFI_PAGES_TO_SIZE (NumPages),
- Flush
+ EFI_PAGES_TO_SIZE (NumPages)
);
}

@@ -63,8 +59,6 @@ MemEncryptSevClearPageEncMask (
address of a memory region.
@param[in] NumPages The number of pages from start memory
region.
- @param[in] Flush Flush the caches before setting the bit
- (mostly TRUE except MMIO addresses)

@retval RETURN_SUCCESS The attributes were set for the memory
region.
@@ -77,15 +71,13 @@ EFIAPI
MemEncryptSevSetPageEncMask (
IN PHYSICAL_ADDRESS Cr3BaseAddress,
IN PHYSICAL_ADDRESS BaseAddress,
- IN UINTN NumPages,
- IN BOOLEAN Flush
+ IN UINTN NumPages
)
{
return InternalMemEncryptSevSetMemoryEncrypted (
Cr3BaseAddress,
BaseAddress,
- EFI_PAGES_TO_SIZE (NumPages),
- Flush
+ EFI_PAGES_TO_SIZE (NumPages)
);
}

diff --git a/OvmfPkg/Library/BaseMemEncryptSevLib/X64/PeiDxeVirtualMemory.c b/OvmfPkg/Library/BaseMemEncryptSevLib/X64/PeiDxeVirtualMemory.c
index a18d336a8789..ad1021bd3e43 100644
--- a/OvmfPkg/Library/BaseMemEncryptSevLib/X64/PeiDxeVirtualMemory.c
+++ b/OvmfPkg/Library/BaseMemEncryptSevLib/X64/PeiDxeVirtualMemory.c
@@ -555,8 +555,7 @@ EnableReadOnlyPageWriteProtect (
address of a memory region.
@param[in] Length The length of memory region
@param[in] Mode Set or Clear mode
- @param[in] CacheFlush Flush the caches before applying the
- encryption mask
+ @param[in] Mmio The physical address range is Mmio.

@retval RETURN_SUCCESS The attributes were cleared for the
memory region.
@@ -572,7 +571,7 @@ SetMemoryEncDec (
IN PHYSICAL_ADDRESS PhysicalAddress,
IN UINTN Length,
IN MAP_RANGE_MODE Mode,
- IN BOOLEAN CacheFlush
+ IN BOOLEAN Mmio
)
{
PAGE_MAP_AND_DIRECTORY_POINTER *PageMapLevel4Entry;
@@ -585,12 +584,23 @@ SetMemoryEncDec (
UINT64 AddressEncMask;
BOOLEAN IsWpEnabled;
RETURN_STATUS Status;
+ BOOLEAN CacheFlush;

//
// Set PageMapLevel4Entry to suppress incorrect compiler/analyzer warnings.
//
PageMapLevel4Entry = NULL;

+ //
+ // The cache need to flushed for the non-Mmio address range.
+ //
+ if (Mmio == TRUE) {
+ CacheFlush = FALSE;
+ } else {
+ CacheFlush = TRUE;
+ }
+
+ //
DEBUG ((
DEBUG_VERBOSE,
"%a:%a: Cr3Base=0x%Lx Physical=0x%Lx Length=0x%Lx Mode=%a CacheFlush=%u\n",
@@ -828,8 +838,6 @@ SetMemoryEncDec (
@param[in] PhysicalAddress The physical address that is the start
address of a memory region.
@param[in] Length The length of memory region
- @param[in] Flush Flush the caches before applying the
- encryption mask

@retval RETURN_SUCCESS The attributes were cleared for the
memory region.
@@ -842,8 +850,7 @@ EFIAPI
InternalMemEncryptSevSetMemoryDecrypted (
IN PHYSICAL_ADDRESS Cr3BaseAddress,
IN PHYSICAL_ADDRESS PhysicalAddress,
- IN UINTN Length,
- IN BOOLEAN Flush
+ IN UINTN Length
)
{

@@ -852,7 +859,7 @@ InternalMemEncryptSevSetMemoryDecrypted (
PhysicalAddress,
Length,
ClearCBit,
- Flush
+ FALSE
);
}

@@ -865,8 +872,6 @@ InternalMemEncryptSevSetMemoryDecrypted (
@param[in] PhysicalAddress The physical address that is the start
address of a memory region.
@param[in] Length The length of memory region
- @param[in] Flush Flush the caches before applying the
- encryption mask

@retval RETURN_SUCCESS The attributes were set for the memory
region.
@@ -879,8 +884,7 @@ EFIAPI
InternalMemEncryptSevSetMemoryEncrypted (
IN PHYSICAL_ADDRESS Cr3BaseAddress,
IN PHYSICAL_ADDRESS PhysicalAddress,
- IN UINTN Length,
- IN BOOLEAN Flush
+ IN UINTN Length
)
{
return SetMemoryEncDec (
@@ -888,7 +892,7 @@ InternalMemEncryptSevSetMemoryEncrypted (
PhysicalAddress,
Length,
SetCBit,
- Flush
+ FALSE
);
}

@@ -921,6 +925,6 @@ InternalMemEncryptSevClearMmioPageEncMask (
PhysicalAddress,
Length,
ClearCBit,
- FALSE
+ TRUE
);
}
diff --git a/OvmfPkg/Library/BaseMemEncryptSevLib/X64/SecVirtualMemory.c b/OvmfPkg/Library/BaseMemEncryptSevLib/X64/SecVirtualMemory.c
index bca5e3febb1b..24d19d3ca161 100644
--- a/OvmfPkg/Library/BaseMemEncryptSevLib/X64/SecVirtualMemory.c
+++ b/OvmfPkg/Library/BaseMemEncryptSevLib/X64/SecVirtualMemory.c
@@ -42,8 +42,6 @@ InternalGetMemEncryptionAddressMask (
@param[in] PhysicalAddress The physical address that is the start
address of a memory region.
@param[in] Length The length of memory region
- @param[in] Flush Flush the caches before applying the
- encryption mask

@retval RETURN_SUCCESS The attributes were cleared for the
memory region.
@@ -56,8 +54,7 @@ EFIAPI
InternalMemEncryptSevSetMemoryDecrypted (
IN PHYSICAL_ADDRESS Cr3BaseAddress,
IN PHYSICAL_ADDRESS PhysicalAddress,
- IN UINTN Length,
- IN BOOLEAN Flush
+ IN UINTN Length
)
{
//
@@ -89,8 +86,7 @@ EFIAPI
InternalMemEncryptSevSetMemoryEncrypted (
IN PHYSICAL_ADDRESS Cr3BaseAddress,
IN PHYSICAL_ADDRESS PhysicalAddress,
- IN UINTN Length,
- IN BOOLEAN Flush
+ IN UINTN Length
)
{
//
diff --git a/OvmfPkg/Library/SmmCpuFeaturesLib/SmmCpuFeaturesLib.c b/OvmfPkg/Library/SmmCpuFeaturesLib/SmmCpuFeaturesLib.c
index fdf2380974fa..c7cc5b0389c8 100644
--- a/OvmfPkg/Library/SmmCpuFeaturesLib/SmmCpuFeaturesLib.c
+++ b/OvmfPkg/Library/SmmCpuFeaturesLib/SmmCpuFeaturesLib.c
@@ -283,8 +283,7 @@ SmmCpuFeaturesSmmRelocationComplete (
Status = MemEncryptSevSetPageEncMask (
0, // Cr3BaseAddress -- use current CR3
MapPagesBase, // BaseAddress
- MapPagesCount, // NumPages
- TRUE // Flush
+ MapPagesCount // NumPages
);
if (EFI_ERROR (Status)) {
DEBUG ((DEBUG_ERROR, "%a: MemEncryptSevSetPageEncMask(): %r\n",
diff --git a/OvmfPkg/PlatformPei/AmdSev.c b/OvmfPkg/PlatformPei/AmdSev.c
index dddffdebda4b..a8bf610022ba 100644
--- a/OvmfPkg/PlatformPei/AmdSev.c
+++ b/OvmfPkg/PlatformPei/AmdSev.c
@@ -72,8 +72,7 @@ AmdSevEsInitialize (
DecryptStatus = MemEncryptSevClearPageEncMask (
0,
GhcbBasePa + EFI_PAGES_TO_SIZE (PageCount),
- 1,
- TRUE
+ 1
);
ASSERT_RETURN_ERROR (DecryptStatus);
}
--
2.17.1


[PATCH 12/13] OvmfPkg/TpmMmioSevDecryptPei: use MemEncryptSevClearMmioPageEncMask()

Brijesh Singh
 

BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=3275

Use the MemEncryptSevClearMmioPageEncMask() to clear memory encryption mask
for the Mmio address range.

Cc: James Bottomley <jejb@...>
Cc: Min Xu <min.m.xu@...>
Cc: Jiewen Yao <jiewen.yao@...>
Cc: Tom Lendacky <thomas.lendacky@...>
Cc: Jordan Justen <jordan.l.justen@...>
Cc: Ard Biesheuvel <ardb+tianocore@...>
Cc: Laszlo Ersek <lersek@...>
Cc: Erdem Aktas <erdemaktas@...>
Signed-off-by: Brijesh Singh <brijesh.singh@...>
---
OvmfPkg/Tcg/TpmMmioSevDecryptPei/TpmMmioSevDecryptPeim.c | 5 ++---
1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/OvmfPkg/Tcg/TpmMmioSevDecryptPei/TpmMmioSevDecryptPeim.c b/OvmfPkg/Tcg/TpmMmioSevDecryptPei/TpmMmioSevDecryptPeim.c
index df2ad623308d..570c8467a673 100644
--- a/OvmfPkg/Tcg/TpmMmioSevDecryptPei/TpmMmioSevDecryptPeim.c
+++ b/OvmfPkg/Tcg/TpmMmioSevDecryptPei/TpmMmioSevDecryptPeim.c
@@ -62,11 +62,10 @@ TpmMmioSevDecryptPeimEntryPoint (
"%a: mapping TPM MMIO address range unencrypted\n",
__FUNCTION__));

- DecryptStatus = MemEncryptSevClearPageEncMask (
+ DecryptStatus = MemEncryptSevClearMmioPageEncMask (
0,
FixedPcdGet64 (PcdTpmBaseAddress),
- EFI_SIZE_TO_PAGES ((UINTN) 0x5000),
- FALSE
+ EFI_SIZE_TO_PAGES ((UINTN) 0x5000)
);

if (RETURN_ERROR (DecryptStatus)) {
--
2.17.1


[PATCH 11/13] OvmfPkg/QemuFlashFvbServicesRuntimeDxe: use Mmio helper to clear enc mask

Brijesh Singh
 

BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=3275

Use the MemEncryptSevClearMmioPageEncMask() to clear memory encryption mask
for the Mmio address range.

Cc: James Bottomley <jejb@...>
Cc: Min Xu <min.m.xu@...>
Cc: Jiewen Yao <jiewen.yao@...>
Cc: Tom Lendacky <thomas.lendacky@...>
Cc: Jordan Justen <jordan.l.justen@...>
Cc: Ard Biesheuvel <ardb+tianocore@...>
Cc: Laszlo Ersek <lersek@...>
Cc: Erdem Aktas <erdemaktas@...>
Signed-off-by: Brijesh Singh <brijesh.singh@...>
---
OvmfPkg/QemuFlashFvbServicesRuntimeDxe/FwBlockServiceDxe.c | 5 ++---
OvmfPkg/QemuFlashFvbServicesRuntimeDxe/QemuFlashSmm.c | 5 ++---
2 files changed, 4 insertions(+), 6 deletions(-)

diff --git a/OvmfPkg/QemuFlashFvbServicesRuntimeDxe/FwBlockServiceDxe.c b/OvmfPkg/QemuFlashFvbServicesRuntimeDxe/FwBlockServiceDxe.c
index 1f285e008372..ab40087a8408 100644
--- a/OvmfPkg/QemuFlashFvbServicesRuntimeDxe/FwBlockServiceDxe.c
+++ b/OvmfPkg/QemuFlashFvbServicesRuntimeDxe/FwBlockServiceDxe.c
@@ -205,11 +205,10 @@ MarkIoMemoryRangeForRuntimeAccess (
// memory range.
//
if (MemEncryptSevIsEnabled ()) {
- Status = MemEncryptSevClearPageEncMask (
+ Status = MemEncryptSevClearMmioPageEncMask (
0,
BaseAddress,
- EFI_SIZE_TO_PAGES (Length),
- FALSE
+ EFI_SIZE_TO_PAGES (Length)
);
ASSERT_EFI_ERROR (Status);
}
diff --git a/OvmfPkg/QemuFlashFvbServicesRuntimeDxe/QemuFlashSmm.c b/OvmfPkg/QemuFlashFvbServicesRuntimeDxe/QemuFlashSmm.c
index 7eb80bfeffae..ea75b489c7fd 100644
--- a/OvmfPkg/QemuFlashFvbServicesRuntimeDxe/QemuFlashSmm.c
+++ b/OvmfPkg/QemuFlashFvbServicesRuntimeDxe/QemuFlashSmm.c
@@ -38,11 +38,10 @@ QemuFlashBeforeProbe (
// C-bit on flash ranges from SMM page table.
//

- Status = MemEncryptSevClearPageEncMask (
+ Status = MemEncryptSevClearMmioPageEncMask (
0,
BaseAddress,
- EFI_SIZE_TO_PAGES (FdBlockSize * FdBlockCount),
- FALSE
+ EFI_SIZE_TO_PAGES (FdBlockSize * FdBlockCount)
);
ASSERT_EFI_ERROR (Status);
}
--
2.17.1


[PATCH 10/13] OvmfPkg/AmdSevDxe: use MemEncryptSevClearMmioPageEncMask() to clear EncMask

Brijesh Singh
 

BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=3275

Use the MemEncryptSevClearMmioPageEncMask() to clear memory encryption mask
for the Mmio and NonExistent address range.

Cc: James Bottomley <jejb@...>
Cc: Min Xu <min.m.xu@...>
Cc: Jiewen Yao <jiewen.yao@...>
Cc: Tom Lendacky <thomas.lendacky@...>
Cc: Jordan Justen <jordan.l.justen@...>
Cc: Ard Biesheuvel <ardb+tianocore@...>
Cc: Laszlo Ersek <lersek@...>
Cc: Erdem Aktas <erdemaktas@...>
Signed-off-by: Brijesh Singh <brijesh.singh@...>
---
OvmfPkg/AmdSevDxe/AmdSevDxe.c | 10 ++++------
1 file changed, 4 insertions(+), 6 deletions(-)

diff --git a/OvmfPkg/AmdSevDxe/AmdSevDxe.c b/OvmfPkg/AmdSevDxe/AmdSevDxe.c
index 689bfb376d03..80831b81facf 100644
--- a/OvmfPkg/AmdSevDxe/AmdSevDxe.c
+++ b/OvmfPkg/AmdSevDxe/AmdSevDxe.c
@@ -53,11 +53,10 @@ AmdSevDxeEntryPoint (
Desc = &AllDescMap[Index];
if (Desc->GcdMemoryType == EfiGcdMemoryTypeMemoryMappedIo ||
Desc->GcdMemoryType == EfiGcdMemoryTypeNonExistent) {
- Status = MemEncryptSevClearPageEncMask (
+ Status = MemEncryptSevClearMmioPageEncMask (
0,
Desc->BaseAddress,
- EFI_SIZE_TO_PAGES (Desc->Length),
- FALSE
+ EFI_SIZE_TO_PAGES (Desc->Length)
);
ASSERT_EFI_ERROR (Status);
}
@@ -73,11 +72,10 @@ AmdSevDxeEntryPoint (
// the range.
//
if (PcdGet16 (PcdOvmfHostBridgePciDevId) == INTEL_Q35_MCH_DEVICE_ID) {
- Status = MemEncryptSevClearPageEncMask (
+ Status = MemEncryptSevClearMmioPageEncMask (
0,
FixedPcdGet64 (PcdPciExpressBaseAddress),
- EFI_SIZE_TO_PAGES (SIZE_256MB),
- FALSE
+ EFI_SIZE_TO_PAGES (SIZE_256MB)
);

ASSERT_EFI_ERROR (Status);
--
2.17.1


[PATCH 09/13] OvmfPkg/BaseMemEncryptSevLib: introduce MemEncryptSevClearMmioPageEncMask()

Brijesh Singh
 

BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=3275

The MemEncryptSevClearMmioPageEncMask() helper can be used for clearing
the memory encryption mask for the Mmio region.

The MemEncryptSevClearMmioPageEncMask() is a simplifies version of
MemEncryptSevClearPageEncMask() -- it does not flush the caches after
clearing the page encryption mask.

Cc: James Bottomley <jejb@...>
Cc: Min Xu <min.m.xu@...>
Cc: Jiewen Yao <jiewen.yao@...>
Cc: Tom Lendacky <thomas.lendacky@...>
Cc: Jordan Justen <jordan.l.justen@...>
Cc: Ard Biesheuvel <ardb+tianocore@...>
Cc: Laszlo Ersek <lersek@...>
Cc: Erdem Aktas <erdemaktas@...>
Signed-off-by: Brijesh Singh <brijesh.singh@...>
---
OvmfPkg/Include/Library/MemEncryptSevLib.h | 25 ++++++++++++++
.../BaseMemEncryptSevLib/X64/VirtualMemory.h | 23 +++++++++++++
.../Ia32/MemEncryptSevLib.c | 31 +++++++++++++++++
.../X64/MemEncryptSevLib.c | 33 +++++++++++++++++++
.../X64/PeiDxeVirtualMemory.c | 33 +++++++++++++++++++
5 files changed, 145 insertions(+)

diff --git a/OvmfPkg/Include/Library/MemEncryptSevLib.h b/OvmfPkg/Include/Library/MemEncryptSevLib.h
index 99f15a7d1271..b91490d5d44d 100644
--- a/OvmfPkg/Include/Library/MemEncryptSevLib.h
+++ b/OvmfPkg/Include/Library/MemEncryptSevLib.h
@@ -203,4 +203,29 @@ MemEncryptSevGetAddressRangeState (
IN UINTN Length
);

+/**
+ This function clears memory encryption bit for the MMIO region specified by
+ BaseAddress and NumPages.
+
+ @param[in] Cr3BaseAddress Cr3 Base Address (if zero then use
+ current CR3)
+ @param[in] BaseAddress The physical address that is the start
+ address of a MMIO region.
+ @param[in] NumPages The number of pages from start memory
+ region.
+
+ @retval RETURN_SUCCESS The attributes were cleared for the
+ memory region.
+ @retval RETURN_INVALID_PARAMETER Number of pages is zero.
+ @retval RETURN_UNSUPPORTED Clearing the memory encryption attribute
+ is not supported
+**/
+RETURN_STATUS
+EFIAPI
+MemEncryptSevClearMmioPageEncMask (
+ IN PHYSICAL_ADDRESS Cr3BaseAddress,
+ IN PHYSICAL_ADDRESS BaseAddress,
+ IN UINTN NumPages
+ );
+
#endif // _MEM_ENCRYPT_SEV_LIB_H_
diff --git a/OvmfPkg/Library/BaseMemEncryptSevLib/X64/VirtualMemory.h b/OvmfPkg/Library/BaseMemEncryptSevLib/X64/VirtualMemory.h
index fe2a0b2826cd..8dc39e647b90 100644
--- a/OvmfPkg/Library/BaseMemEncryptSevLib/X64/VirtualMemory.h
+++ b/OvmfPkg/Library/BaseMemEncryptSevLib/X64/VirtualMemory.h
@@ -126,4 +126,27 @@ InternalMemEncryptSevGetAddressRangeState (
IN UINTN Length
);

+/**
+ This function clears memory encryption bit for the MMIO region specified by
+ PhysicalAddress and Length.
+
+ @param[in] Cr3BaseAddress Cr3 Base Address (if zero then use
+ current CR3)
+ @param[in] PhysicalAddress The physical address that is the start
+ address of a MMIO region.
+ @param[in] Length The length of memory region
+
+ @retval RETURN_SUCCESS The attributes were cleared for the
+ memory region.
+ @retval RETURN_INVALID_PARAMETER Length is zero.
+ @retval RETURN_UNSUPPORTED Clearing the memory encyrption attribute
+ is not supported
+**/
+RETURN_STATUS
+EFIAPI
+InternalMemEncryptSevClearMmioPageEncMask (
+ IN PHYSICAL_ADDRESS Cr3BaseAddress,
+ IN PHYSICAL_ADDRESS PhysicalAddress,
+ IN UINTN Length
+ );
#endif
diff --git a/OvmfPkg/Library/BaseMemEncryptSevLib/Ia32/MemEncryptSevLib.c b/OvmfPkg/Library/BaseMemEncryptSevLib/Ia32/MemEncryptSevLib.c
index 12a5bf495bd7..169d3118e44f 100644
--- a/OvmfPkg/Library/BaseMemEncryptSevLib/Ia32/MemEncryptSevLib.c
+++ b/OvmfPkg/Library/BaseMemEncryptSevLib/Ia32/MemEncryptSevLib.c
@@ -111,3 +111,34 @@ MemEncryptSevGetAddressRangeState (
//
return MemEncryptSevAddressRangeEncrypted;
}
+
+/**
+ This function clears memory encryption bit for the MMIO region specified by
+ BaseAddress and NumPages.
+
+ @param[in] Cr3BaseAddress Cr3 Base Address (if zero then use
+ current CR3)
+ @param[in] BaseAddress The physical address that is the start
+ address of a MMIO region.
+ @param[in] NumPages The number of pages from start memory
+ region.
+
+ @retval RETURN_SUCCESS The attributes were cleared for the
+ memory region.
+ @retval RETURN_INVALID_PARAMETER Number of pages is zero.
+ @retval RETURN_UNSUPPORTED Clearing the memory encryption attribute
+ is not supported
+**/
+RETURN_STATUS
+EFIAPI
+MemEncryptSevClearMmioPageEncMask (
+ IN PHYSICAL_ADDRESS Cr3BaseAddress,
+ IN PHYSICAL_ADDRESS BaseAddress,
+ IN UINTN NumPages
+ )
+{
+ //
+ // Memory encryption bit is not accessible in 32-bit mode
+ //
+ return RETURN_UNSUPPORTED;
+}
diff --git a/OvmfPkg/Library/BaseMemEncryptSevLib/X64/MemEncryptSevLib.c b/OvmfPkg/Library/BaseMemEncryptSevLib/X64/MemEncryptSevLib.c
index 4fea6a6be0ac..a2bf698bcde7 100644
--- a/OvmfPkg/Library/BaseMemEncryptSevLib/X64/MemEncryptSevLib.c
+++ b/OvmfPkg/Library/BaseMemEncryptSevLib/X64/MemEncryptSevLib.c
@@ -118,3 +118,36 @@ MemEncryptSevGetAddressRangeState (
Length
);
}
+
+/**
+ This function clears memory encryption bit for the mmio region specified by
+ BaseAddress and NumPages.
+
+ @param[in] Cr3BaseAddress Cr3 Base Address (if zero then use
+ current CR3)
+ @param[in] BaseAddress The physical address that is the start
+ address of a mmio region.
+ @param[in] NumPages The number of pages from start memory
+ region.
+
+ @retval RETURN_SUCCESS The attributes were cleared for the
+ memory region.
+ @retval RETURN_INVALID_PARAMETER Number of pages is zero.
+ @retval RETURN_UNSUPPORTED Clearing the memory encryption attribute
+ is not supported
+**/
+RETURN_STATUS
+EFIAPI
+MemEncryptSevClearMmioPageEncMask (
+ IN PHYSICAL_ADDRESS Cr3BaseAddress,
+ IN PHYSICAL_ADDRESS BaseAddress,
+ IN UINTN NumPages
+ )
+{
+ return InternalMemEncryptSevClearMmioPageEncMask (
+ Cr3BaseAddress,
+ BaseAddress,
+ EFI_PAGES_TO_SIZE (NumPages)
+ );
+
+}
diff --git a/OvmfPkg/Library/BaseMemEncryptSevLib/X64/PeiDxeVirtualMemory.c b/OvmfPkg/Library/BaseMemEncryptSevLib/X64/PeiDxeVirtualMemory.c
index d3455e812bd1..a18d336a8789 100644
--- a/OvmfPkg/Library/BaseMemEncryptSevLib/X64/PeiDxeVirtualMemory.c
+++ b/OvmfPkg/Library/BaseMemEncryptSevLib/X64/PeiDxeVirtualMemory.c
@@ -891,3 +891,36 @@ InternalMemEncryptSevSetMemoryEncrypted (
Flush
);
}
+
+/**
+ This function clears memory encryption bit for the MMIO region specified by
+ PhysicalAddress and Length.
+
+ @param[in] Cr3BaseAddress Cr3 Base Address (if zero then use
+ current CR3)
+ @param[in] PhysicalAddress The physical address that is the start
+ address of a MMIO region.
+ @param[in] Length The length of memory region
+
+ @retval RETURN_SUCCESS The attributes were cleared for the
+ memory region.
+ @retval RETURN_INVALID_PARAMETER Length is zero.
+ @retval RETURN_UNSUPPORTED Clearing the memory encyrption attribute
+ is not supported
+**/
+RETURN_STATUS
+EFIAPI
+InternalMemEncryptSevClearMmioPageEncMask (
+ IN PHYSICAL_ADDRESS Cr3BaseAddress,
+ IN PHYSICAL_ADDRESS PhysicalAddress,
+ IN UINTN Length
+ )
+{
+ return SetMemoryEncDec (
+ Cr3BaseAddress,
+ PhysicalAddress,
+ Length,
+ ClearCBit,
+ FALSE
+ );
+}
--
2.17.1


[PATCH 08/13] MdePkg/BaseLib: add support for RMPADJUST instruction

Brijesh Singh
 

From: Tom Lendacky <thomas.lendacky@...>

BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=3275

The RMPADJUST instruction will be used by the SEV-SNP guest to modify the
RMP permissions for a guest page. See AMD APM volume 3 for further
details.

Cc: James Bottomley <jejb@...>
Cc: Min Xu <min.m.xu@...>
Cc: Jiewen Yao <jiewen.yao@...>
Cc: Tom Lendacky <thomas.lendacky@...>
Cc: Jordan Justen <jordan.l.justen@...>
Cc: Ard Biesheuvel <ardb+tianocore@...>
Cc: Laszlo Ersek <lersek@...>
Cc: Erdem Aktas <erdemaktas@...>
Cc: Michael D Kinney <michael.d.kinney@...>
Cc: Liming Gao <gaoliming@...>
Cc: Zhiguang Liu <zhiguang.liu@...>
Signed-off-by: Tom Lendacky <thomas.lendacky@...>
Signed-off-by: Brijesh Singh <brijesh.singh@...>
---
MdePkg/Library/BaseLib/BaseLib.inf | 1 +
MdePkg/Include/Library/BaseLib.h | 36 +++++++++++++++++++-
MdePkg/Include/X64/Nasm.inc | 8 +++++
MdePkg/Library/BaseLib/X64/RmpAdjust.nasm | 40 +++++++++++++++++++++++
4 files changed, 84 insertions(+), 1 deletion(-)
create mode 100644 MdePkg/Library/BaseLib/X64/RmpAdjust.nasm

diff --git a/MdePkg/Library/BaseLib/BaseLib.inf b/MdePkg/Library/BaseLib/BaseLib.inf
index 89a52f72c08a..6ccb8997b7e8 100644
--- a/MdePkg/Library/BaseLib/BaseLib.inf
+++ b/MdePkg/Library/BaseLib/BaseLib.inf
@@ -319,6 +319,7 @@ [Sources.X64]
X64/DisablePaging64.nasm
X64/Pvalidate.nasm
X64/RdRand.nasm
+ X64/RmpAdjust.nasm
X64/XGetBv.nasm
X64/XSetBv.nasm
X64/VmgExit.nasm
diff --git a/MdePkg/Include/Library/BaseLib.h b/MdePkg/Include/Library/BaseLib.h
index f177034af6a1..04e58f995b9a 100644
--- a/MdePkg/Include/Library/BaseLib.h
+++ b/MdePkg/Include/Library/BaseLib.h
@@ -4857,9 +4857,43 @@ AsmPvalidate (
IN BOOLEAN Validate,
IN PHYSICAL_ADDRESS Address
);
+
+//
+// RDX settings for RMPADJUST
+//
+#define RMPADJUST_VMPL_MAX 3
+#define RMPADJUST_VMPL_MASK 0xFF
+#define RMPADJUST_VMPL_SHIFT 0
+#define RMPADJUST_PERMISSION_MASK_MASK 0xFF
+#define RMPADJUST_PERMISSION_MASK_SHIFT 8
+#define RMPADJUST_VMSA_PAGE_BIT BIT16
+
+/**
+ Adjusts the permissions of an SEV-SNP guest page.
+
+ Executes a RMPADJUST instruction with the register state specified by Rax,
+ Rcx and Rdx. Returns Eax. This function is only available x64.
+
+ The instruction is available only when CPUID Fn8000_001F_EAX[SNP]=1.
+
+ @param[in] Rax The value to load into RAX before executing the RMPADJUST
+ instruction.
+ @param[in] Rcx The value to load into RCX before executing the RMPADJUST
+ instruction.
+ @param[in] Rdx The value to load into RDX before executing the RMPADJUST
+ instruction.
+
+ @return Eax
+**/
+UINTN
+EFIAPI
+AsmRmpAdjust (
+ IN UINTN Rax,
+ IN UINTN Rcx,
+ IN UINTN Rdx
+ );
#endif

-
#if defined (MDE_CPU_IA32) || defined (MDE_CPU_X64)
///
/// IA32 and x64 Specific Functions.
diff --git a/MdePkg/Include/X64/Nasm.inc b/MdePkg/Include/X64/Nasm.inc
index 528bb3385609..cfb14edc9449 100644
--- a/MdePkg/Include/X64/Nasm.inc
+++ b/MdePkg/Include/X64/Nasm.inc
@@ -41,6 +41,14 @@
DB 0xF2, 0x0F, 0x01, 0xFF
%endmacro

+;
+; Macro for the RMPADJUST instruction, defined in AMD APM volume 3.
+; NASM feature request URL: https://bugzilla.nasm.us/show_bug.cgi?id=3392754
+;
+%macro RMPADJUST 0
+ DB 0xF3, 0x0F, 0x01, 0xFE
+%endmacro
+
; NASM provides built-in macros STRUC and ENDSTRUC for structure definition.
; For example, to define a structure called mytype containing a longword,
; a word, a byte and a string of bytes, you might code
diff --git a/MdePkg/Library/BaseLib/X64/RmpAdjust.nasm b/MdePkg/Library/BaseLib/X64/RmpAdjust.nasm
new file mode 100644
index 000000000000..f2c295b67c9c
--- /dev/null
+++ b/MdePkg/Library/BaseLib/X64/RmpAdjust.nasm
@@ -0,0 +1,40 @@
+;-----------------------------------------------------------------------------
+;
+; Copyright (c) 2021, Advanced Micro Devices, Inc. All rights reserved.<BR>
+; SPDX-License-Identifier: BSD-2-Clause-Patent
+;
+; Module Name:
+;
+; RmpAdjust.Asm
+;
+; Abstract:
+;
+; AsmRmpAdjust function
+;
+; Notes:
+;
+;-----------------------------------------------------------------------------
+
+%include "Nasm.inc"
+
+ SECTION .text
+
+;-----------------------------------------------------------------------------
+; UINTN
+; EFIAPI
+; AsmRmpAdjust (
+; IN UINTN Rax,
+; IN UINTN Rcx,
+; IN UINTN Rdx
+; )
+;-----------------------------------------------------------------------------
+global ASM_PFX(AsmRmpAdjust)
+ASM_PFX(AsmRmpAdjust):
+ mov rax, rcx ; Input Rax is in RCX by calling convention
+ mov rcx, rdx ; Input Rcx is in RDX by calling convention
+ mov rdx, r8 ; Input Rdx is in R8 by calling convention
+
+ RMPADJUST
+
+ ; RMPADJUST returns the status in the EAX register.
+ ret
--
2.17.1


[PATCH 07/13] MdePkg/BaseLib: add support for PVALIDATE instruction

Brijesh Singh
 

BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=3275

The PVALIDATE instruction validates or rescinds validation of a guest
page RMP entry. Upon completion, a return code is stored in EAX, rFLAGS
bits OF, ZF, AF, PF and SF are set based on this return code. If the
instruction completed succesfully, the rFLAGS bit CF indicates if the
contents of the RMP entry were changed or not.

For more information about the instruction see AMD APM volume 3.

Cc: James Bottomley <jejb@...>
Cc: Min Xu <min.m.xu@...>
Cc: Jiewen Yao <jiewen.yao@...>
Cc: Tom Lendacky <thomas.lendacky@...>
Cc: Jordan Justen <jordan.l.justen@...>
Cc: Ard Biesheuvel <ardb+tianocore@...>
Cc: Laszlo Ersek <lersek@...>
Cc: Erdem Aktas <erdemaktas@...>
Cc: Michael D Kinney <michael.d.kinney@...>
Cc: Liming Gao <gaoliming@...>
Cc: Zhiguang Liu <zhiguang.liu@...>
Signed-off-by: Brijesh Singh <brijesh.singh@...>
---
MdePkg/Library/BaseLib/BaseLib.inf | 1 +
MdePkg/Include/Library/BaseLib.h | 46 +++++++++++++++++++++++
MdePkg/Include/X64/Nasm.inc | 8 ++++
MdePkg/Library/BaseLib/X64/Pvalidate.nasm | 42 +++++++++++++++++++++
4 files changed, 97 insertions(+)
create mode 100644 MdePkg/Library/BaseLib/X64/Pvalidate.nasm

diff --git a/MdePkg/Library/BaseLib/BaseLib.inf b/MdePkg/Library/BaseLib/BaseLib.inf
index b76f3af380ea..89a52f72c08a 100644
--- a/MdePkg/Library/BaseLib/BaseLib.inf
+++ b/MdePkg/Library/BaseLib/BaseLib.inf
@@ -317,6 +317,7 @@ [Sources.X64]
X64/GccInlinePriv.c | GCC
X64/EnableDisableInterrupts.nasm
X64/DisablePaging64.nasm
+ X64/Pvalidate.nasm
X64/RdRand.nasm
X64/XGetBv.nasm
X64/XSetBv.nasm
diff --git a/MdePkg/Include/Library/BaseLib.h b/MdePkg/Include/Library/BaseLib.h
index 7253997a6f8c..f177034af6a1 100644
--- a/MdePkg/Include/Library/BaseLib.h
+++ b/MdePkg/Include/Library/BaseLib.h
@@ -4813,6 +4813,52 @@ SpeculationBarrier (
VOID
);

+#if defined (MDE_CPU_X64)
+//
+// The page size for the PVALIDATE instruction
+//
+typedef enum {
+ PvalidatePageSize4K = 0,
+ PvalidatePageSize2MB,
+} PVALIDATE_PAGE_SIZE;
+
+//
+// PVALIDATE Return Code.
+//
+#define PVALIDATE_RET_SUCCESS 0
+#define PVALIDATE_RET_FAIL_INPUT 1
+#define PVALIDATE_RET_SIZE_MISMATCH 6
+
+//
+// The PVALIDATE instruction did not made any changes to the RMP entry.
+//
+#define PVALIDATE_RET_NO_RMPUPDATE 255
+
+/**
+ Execute a PVALIDATE instruction to validate or rescinds validation of a guest
+ page's RMP entry.
+
+ The instruction is available only when CPUID Fn8000_001F_EAX[SNP]=1.
+
+ The function is available on X64.
+
+ @param[in] PageSize The page size to use.
+ @param[in] Validate Validate or rescinds.
+ @param[in] Address The guest virtual address to validate.
+
+ @retval The return value from the PVALIDATE instruction, and
+ PVALIDATE_RET_NO_RMPUPDATE when there was no change in
+ the RMP entry.
+**/
+UINTN
+EFIAPI
+AsmPvalidate (
+ IN PVALIDATE_PAGE_SIZE PageSize,
+ IN BOOLEAN Validate,
+ IN PHYSICAL_ADDRESS Address
+ );
+#endif
+

#if defined (MDE_CPU_IA32) || defined (MDE_CPU_X64)
///
diff --git a/MdePkg/Include/X64/Nasm.inc b/MdePkg/Include/X64/Nasm.inc
index 527f71e9eb4d..528bb3385609 100644
--- a/MdePkg/Include/X64/Nasm.inc
+++ b/MdePkg/Include/X64/Nasm.inc
@@ -33,6 +33,14 @@
DB 0xF3, 0x48, 0x0F, 0xAE, 0xE8
%endmacro

+;
+; Macro for the PVALIDATE instruction, defined in AMD APM volume 3.
+; NASM feature request URL: https://bugzilla.nasm.us/show_bug.cgi?id=3392753
+;
+%macro PVALIDATE 0
+ DB 0xF2, 0x0F, 0x01, 0xFF
+%endmacro
+
; NASM provides built-in macros STRUC and ENDSTRUC for structure definition.
; For example, to define a structure called mytype containing a longword,
; a word, a byte and a string of bytes, you might code
diff --git a/MdePkg/Library/BaseLib/X64/Pvalidate.nasm b/MdePkg/Library/BaseLib/X64/Pvalidate.nasm
new file mode 100644
index 000000000000..b20dac7e6831
--- /dev/null
+++ b/MdePkg/Library/BaseLib/X64/Pvalidate.nasm
@@ -0,0 +1,42 @@
+;-----------------------------------------------------------------------------
+;
+; Copyright (c) 2021, AMD. All rights reserved.<BR>
+; SPDX-License-Identifier: BSD-2-Clause-Patent
+;
+;-----------------------------------------------------------------------------
+
+%include "Nasm.inc"
+
+ SECTION .text
+
+;-----------------------------------------------------------------------------
+; UINTN
+; EFIAPI
+; AsmPvalidate (
+; IN UINT32 RmpPageSize
+; IN UINT32 Validate,
+; IN PHYSICAL_ADDRESS Address
+; )
+;-----------------------------------------------------------------------------
+global ASM_PFX(AsmPvalidate)
+ASM_PFX(AsmPvalidate):
+ mov rax, r8
+
+ PVALIDATE
+
+ ; Save the carry flag.
+ setb dl
+
+ ; The PVALIDATE instruction returns the status in rax register.
+ cmp rax, 0
+ jne PvalidateExit
+
+ ; Check the carry flag to determine if RMP entry was updated.
+ cmp dl, 0
+ jz PvalidateExit
+
+ ; Return the PVALIDATE_RET_NO_RMPUPDATE.
+ mov rax, 255
+
+PvalidateExit:
+ ret
--
2.17.1


[PATCH 06/13] MdePkg/Register/Amd: define GHCB macros for SNP AP creation

Brijesh Singh
 

From: Tom Lendacky <thomas.lendacky@...>

BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=3275

Version 2 of GHCB introduces NAE for creating AP when SEV-SNP is
enabled in the guest VM. See the GHCB spec section for additional
details.

While at it, define the VMSA state save area that are required for
creating the AP. The save area format is defined in AMD APM volume
2 (Table B-4).

Cc: James Bottomley <jejb@...>
Cc: Min Xu <min.m.xu@...>
Cc: Jiewen Yao <jiewen.yao@...>
Cc: Tom Lendacky <thomas.lendacky@...>
Cc: Jordan Justen <jordan.l.justen@...>
Cc: Ard Biesheuvel <ardb+tianocore@...>
Cc: Laszlo Ersek <lersek@...>
Cc: Erdem Aktas <erdemaktas@...>
Cc: Michael D Kinney <michael.d.kinney@...>
Cc: Liming Gao <gaoliming@...>
Cc: Zhiguang Liu <zhiguang.liu@...>
Signed-off-by: Tom Lendacky <thomas.lendacky@...>
Signed-off-by: Brijesh Singh <brijesh.singh@...>
---
MdePkg/Include/Register/Amd/Ghcb.h | 70 ++++++++++++++++++++++++++++++
1 file changed, 70 insertions(+)

diff --git a/MdePkg/Include/Register/Amd/Ghcb.h b/MdePkg/Include/Register/Amd/Ghcb.h
index a15b4b7e2760..956cefbc003c 100644
--- a/MdePkg/Include/Register/Amd/Ghcb.h
+++ b/MdePkg/Include/Register/Amd/Ghcb.h
@@ -55,6 +55,7 @@
#define SVM_EXIT_AP_RESET_HOLD 0x80000004ULL
#define SVM_EXIT_AP_JUMP_TABLE 0x80000005ULL
#define SVM_EXIT_SNP_PAGE_STATE_CHANGE 0x80000010ULL
+#define SVM_EXIT_SNP_AP_CREATION 0x80000013ULL
#define SVM_EXIT_HYPERVISOR_FEATURES 0x8000FFFDULL
#define SVM_EXIT_UNSUPPORTED 0x8000FFFFULL

@@ -83,6 +84,12 @@
#define IOIO_SEG_ES 0
#define IOIO_SEG_DS (BIT11 | BIT10)

+//
+// AP Creation Information
+//
+#define SVM_VMGEXIT_SNP_AP_CREATE_ON_INIT 0
+#define SVM_VMGEXIT_SNP_AP_CREATE 1
+#define SVM_VMGEXIT_SNP_AP_DESTROY 2

typedef PACKED struct {
UINT8 Reserved1[203];
@@ -195,4 +202,67 @@ typedef struct {
SNP_PAGE_STATE_ENTRY Entry[SNP_PAGE_STATE_MAX_ENTRY];
} SNP_PAGE_STATE_CHANGE_INFO;

+//
+// SEV-ES save area mapping structures used for SEV-SNP AP Creation.
+// Only the fields required to be set to a non-zero value are defined.
+//
+#pragma pack(1)
+typedef struct {
+ UINT16 Selector;
+ UINT16 Attributes;
+ UINT32 Limit;
+ UINT64 Base;
+} SEV_ES_SEGMENT_REGISTER;
+#pragma pack()
+
+#define SEV_ES_RESET_CS_ATTRIBUTES (BIT7 | BIT4 | BIT3 | BIT1)
+#define SEV_ES_RESET_DS_ATTRIBUTES (BIT7 | BIT4 | BIT1)
+#define SEV_ES_RESET_ES_ATTRIBUTES SEV_ES_RESET_DS_ATTRIBUTES
+#define SEV_ES_RESET_FS_ATTRIBUTES SEV_ES_RESET_DS_ATTRIBUTES
+#define SEV_ES_RESET_GS_ATTRIBUTES SEV_ES_RESET_DS_ATTRIBUTES
+#define SEV_ES_RESET_SS_ATTRIBUTES SEV_ES_RESET_DS_ATTRIBUTES
+
+#define SEV_ES_RESET_GDTR_ATTRIBUTES 0
+#define SEV_ES_RESET_LDTR_ATTRIBUTES (BIT7 | 2)
+#define SEV_ES_RESET_IDTR_ATTRIBUTES 0
+#define SEV_ES_RESET_TR_ATTRIBUTES (BIT7 | 3)
+
+#pragma pack(1)
+typedef struct {
+ SEV_ES_SEGMENT_REGISTER Es;
+ SEV_ES_SEGMENT_REGISTER Cs;
+ SEV_ES_SEGMENT_REGISTER Ss;
+ SEV_ES_SEGMENT_REGISTER Ds;
+ SEV_ES_SEGMENT_REGISTER Fs;
+ SEV_ES_SEGMENT_REGISTER Gs;
+ SEV_ES_SEGMENT_REGISTER Gdtr;
+ SEV_ES_SEGMENT_REGISTER Ldtr;
+ SEV_ES_SEGMENT_REGISTER Idtr;
+ SEV_ES_SEGMENT_REGISTER Tr;
+ UINT8 Reserved1[42];
+ UINT8 Vmpl;
+ UINT8 Reserved2[5];
+ UINT64 Efer;
+ UINT8 Reserved3[112];
+ UINT64 Cr4;
+ UINT8 Reserved4[8];
+ UINT64 Cr0;
+ UINT64 Dr7;
+ UINT64 Dr6;
+ UINT64 Rflags;
+ UINT64 Rip;
+ UINT8 Reserved5[232];
+ UINT64 GPat;
+ UINT8 Reserved6[320];
+ UINT64 SevFeatures;
+ UINT8 Reserved7[48];
+ UINT64 XCr0;
+ UINT8 Reserved8[24];
+ UINT32 Mxcsr;
+ UINT64 X87Ftw;
+ UINT64 Reserved9[8];
+ UINT64 X87Fcw;
+} SEV_ES_SAVE_AREA;
+#pragma pack()
+
#endif
--
2.17.1


[PATCH 05/13] MdePkg/Register/Amd: define GHCB macro for the Page State Change

Brijesh Singh
 

BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=3275

The Page State Change NAE exit will be used by the SEV-SNP guest to
request a page state change using the GHCB protocol. See the GHCB
spec section 4.1.6 and 2.3.1 for more detail on the structure
definitions.

Cc: James Bottomley <jejb@...>
Cc: Min Xu <min.m.xu@...>
Cc: Jiewen Yao <jiewen.yao@...>
Cc: Tom Lendacky <thomas.lendacky@...>
Cc: Jordan Justen <jordan.l.justen@...>
Cc: Ard Biesheuvel <ardb+tianocore@...>
Cc: Laszlo Ersek <lersek@...>
Cc: Erdem Aktas <erdemaktas@...>
Cc: Michael D Kinney <michael.d.kinney@...>
Cc: Liming Gao <gaoliming@...>
Cc: Zhiguang Liu <zhiguang.liu@...>
Signed-off-by: Brijesh Singh <brijesh.singh@...>
---
MdePkg/Include/Register/Amd/Fam17Msr.h | 15 ++++++++++++
MdePkg/Include/Register/Amd/Ghcb.h | 33 ++++++++++++++++++++++++++
2 files changed, 48 insertions(+)

diff --git a/MdePkg/Include/Register/Amd/Fam17Msr.h b/MdePkg/Include/Register/Amd/Fam17Msr.h
index 542e4cdf4782..62014854d9b7 100644
--- a/MdePkg/Include/Register/Amd/Fam17Msr.h
+++ b/MdePkg/Include/Register/Amd/Fam17Msr.h
@@ -58,6 +58,19 @@ typedef union {
UINT64 GuestFrameNumber:52;
} GhcbGpaRegister;

+ struct {
+ UINT64 Function:12;
+ UINT64 GuestFrameNumber:40;
+ UINT64 Operation:4;
+ UINT64 Reserved:8;
+ } SnpPageStateChangeRequest;
+
+ struct {
+ UINT32 Function:12;
+ UINT32 Reserved:20;
+ UINT32 ErrorCode;
+ } SnpPageStateChangeResponse;
+
VOID *Ghcb;

UINT64 GhcbPhysicalAddress;
@@ -69,6 +82,8 @@ typedef union {
#define GHCB_INFO_CPUID_RESPONSE 5
#define GHCB_INFO_GHCB_GPA_REGISTER_REQUEST 18
#define GHCB_INFO_GHCB_GPA_REGISTER_RESPONSE 19
+#define GHCB_INFO_SNP_PAGE_STATE_CHANGE_REQUEST 20
+#define GHCB_INFO_SNP_PAGE_STATE_CHANGE_RESPONSE 21
#define GHCB_HYPERVISOR_FEATURES_REQUEST 128
#define GHCB_HYPERVISOR_FEATURES_RESPONSE 129
#define GHCB_INFO_TERMINATE_REQUEST 256
diff --git a/MdePkg/Include/Register/Amd/Ghcb.h b/MdePkg/Include/Register/Amd/Ghcb.h
index 326b11479779..a15b4b7e2760 100644
--- a/MdePkg/Include/Register/Amd/Ghcb.h
+++ b/MdePkg/Include/Register/Amd/Ghcb.h
@@ -54,6 +54,7 @@
#define SVM_EXIT_NMI_COMPLETE 0x80000003ULL
#define SVM_EXIT_AP_RESET_HOLD 0x80000004ULL
#define SVM_EXIT_AP_JUMP_TABLE 0x80000005ULL
+#define SVM_EXIT_SNP_PAGE_STATE_CHANGE 0x80000010ULL
#define SVM_EXIT_HYPERVISOR_FEATURES 0x8000FFFDULL
#define SVM_EXIT_UNSUPPORTED 0x8000FFFFULL

@@ -162,4 +163,36 @@ typedef union {
#define GHCB_HV_FEATURES_SNP_AP_CREATE (GHCB_HV_FEATURES_SNP | BIT1)
#define GHCB_HV_FEATURES_SNP_RESTRICTED_INJECTION (GHCB_HV_FEATURES_SNP_AP_CREATE | BIT2)
#define GHCB_HV_FEATURES_SNP_RESTRICTED_INJECTION_TIMER (GHCB_HV_FEATURES_SNP_RESTRICTED_INJECTION | BIT3)
+
+//
+// SNP Page State Change.
+//
+// Note that the PSMASH and UNSMASH operations are not supported when using the MSR protocol.
+//
+#define SNP_PAGE_STATE_PRIVATE 1
+#define SNP_PAGE_STATE_SHARED 2
+#define SNP_PAGE_STATE_PSMASH 3
+#define SNP_PAGE_STATE_UNSMASH 4
+
+typedef struct {
+ UINT64 CurrentPage:12;
+ UINT64 GuestFrameNumber:40;
+ UINT64 Operation:4;
+ UINT64 PageSize:1;
+ UINT64 Reserved: 7;
+} SNP_PAGE_STATE_ENTRY;
+
+typedef struct {
+ UINT16 CurrentEntry;
+ UINT16 EndEntry;
+ UINT32 Reserved;
+} SNP_PAGE_STATE_HEADER;
+
+#define SNP_PAGE_STATE_MAX_ENTRY 253
+
+typedef struct {
+ SNP_PAGE_STATE_HEADER Header;
+ SNP_PAGE_STATE_ENTRY Entry[SNP_PAGE_STATE_MAX_ENTRY];
+} SNP_PAGE_STATE_CHANGE_INFO;
+
#endif
--
2.17.1


[PATCH 04/13] MdePkg/Register/Amd: define GHCB macro for Register GPA structure

Brijesh Singh
 

BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=3275

An SEV-SNP guest is required to perform the GHCB GPA registration. See
the GHCB specification for further details.

Cc: James Bottomley <jejb@...>
Cc: Min Xu <min.m.xu@...>
Cc: Jiewen Yao <jiewen.yao@...>
Cc: Tom Lendacky <thomas.lendacky@...>
Cc: Jordan Justen <jordan.l.justen@...>
Cc: Ard Biesheuvel <ardb+tianocore@...>
Cc: Laszlo Ersek <lersek@...>
Cc: Erdem Aktas <erdemaktas@...>
Cc: Michael D Kinney <michael.d.kinney@...>
Cc: Liming Gao <gaoliming@...>
Cc: Zhiguang Liu <zhiguang.liu@...>
Reviewed-by: Laszlo Ersek <lersek@...>
Signed-off-by: Brijesh Singh <brijesh.singh@...>
---
MdePkg/Include/Register/Amd/Fam17Msr.h | 7 +++++++
1 file changed, 7 insertions(+)

diff --git a/MdePkg/Include/Register/Amd/Fam17Msr.h b/MdePkg/Include/Register/Amd/Fam17Msr.h
index cdb8f588ccf8..542e4cdf4782 100644
--- a/MdePkg/Include/Register/Amd/Fam17Msr.h
+++ b/MdePkg/Include/Register/Amd/Fam17Msr.h
@@ -53,6 +53,11 @@ typedef union {
UINT64 Features:52;
} GhcbHypervisorFeatures;

+ struct {
+ UINT64 Function:12;
+ UINT64 GuestFrameNumber:52;
+ } GhcbGpaRegister;
+
VOID *Ghcb;

UINT64 GhcbPhysicalAddress;
@@ -62,6 +67,8 @@ typedef union {
#define GHCB_INFO_SEV_INFO_GET 2
#define GHCB_INFO_CPUID_REQUEST 4
#define GHCB_INFO_CPUID_RESPONSE 5
+#define GHCB_INFO_GHCB_GPA_REGISTER_REQUEST 18
+#define GHCB_INFO_GHCB_GPA_REGISTER_RESPONSE 19
#define GHCB_HYPERVISOR_FEATURES_REQUEST 128
#define GHCB_HYPERVISOR_FEATURES_RESPONSE 129
#define GHCB_INFO_TERMINATE_REQUEST 256
--
2.17.1

17541 - 17560 of 92312