public inbox for devel@edk2.groups.io
 help / color / mirror / Atom feed
* [PATCH v2 0/6] SEV Encrypted Boot for Ovmf
@ 2020-11-20 18:45 James Bottomley
  2020-11-20 18:45 ` [PATCH v2 1/6] OvmfPkg/Amdsev: Base commit to build encrypted boot specific OVMF James Bottomley
                   ` (5 more replies)
  0 siblings, 6 replies; 37+ messages in thread
From: James Bottomley @ 2020-11-20 18:45 UTC (permalink / raw)
  To: devel
  Cc: dovmurik, Dov.Murik1, ashish.kalra, brijesh.singh, tobin,
	david.kaplan, jon.grimm, thomas.lendacky, jejb, frankeh,
	Dr . David Alan Gilbert, Laszlo Ersek

v2:

- Strip more out of AmdSev image (networking, secure boot, smm)
- give sev reset block a generic table guid and use it for boot secret area
- separate secret patches and make grub script more robust
- Add copyrights and fix formatting issues

v1:

Ref: https://bugzilla.tianocore.org/show_bug.cgi?id=3077

This patch series is modelled on the structure of the Bhyve patches
for Ovmf, since it does somewhat similar things.  This patch series
creates a separate build for an AmdSev OVMF.fd that does nothing
except combine with grub and boot straight through the internal grub
to try to mount an encrypted volume.

Concept: SEV Secure Encrypted Images
====================================

The SEV patches in Linux and OVMF allow for the booting of SEV VMs in
an encrypted state, but don't really show how this could be done with
an encrypted image.  Since the key used to decrypt the image must be
maintained within the SEV encryption envelope, encrypted QCOW is not
an option because the key would then have to be known to QEMU which is
outside the encryption envelope.  The proposal here is that an
encrypted image should be a QCOW image consisting of two partitions,
the normal unencrypted EFI partition (Identifying it as an OVMF
bootable image) and a luks encrypted root partition.  The kernel would
be inside the encrypted root in the /boot directory.  The secret
injected securely through QEMU is extracted by OVMF and passed to grub
which uses it to mount the encrypted root and boot the kernel
normally.  The creator of the secret bundle must be satisfied with the
SEV attestation before the secret is constructed.  Unfortunately, the
SEV attestation can only be on the first QEMU firmware volume and
nothing else, so this patch series builds grub itself into a firmware
volume and places it inside OVMF so that the entire boot system can be
attested.  In a normal OVMF KVM system, the variable store is on the
second flash volume (which is read/write).  Unfortunately, this
mutable configuration provided by the variables is outside the
attestation envelope and can significantly alter the boot path,
possibly leading to secret leak, so encrypted image boot should only
be done with the OVMF.fd that combines both the code and variables.
the OVMF.fd is constructed so that it becomes impossible to interrupt
the boot sequence after attestation and the system will either boot
the image or fail. The boot sequence runs the grub.efi embedded in the
OVMF firmware volume so the encrypted image owner knows their own
version of grub is the only one that will boot before injecting the
secret.  Note this boot path actually ignores the unencrypted EFI
partition.  However, as part of this design, the encrypted image may be
booted by a standard OVMF KVM boot and in that case, the user will
have to type the encryption password.  This standard boot will be
insecure but it might be used by the constructor of the encrypted
images on their own private laptop, for instance.  The standard boot
path will use the unencrypted EFI partition.

Patches Required Outside of OVMF
================================

There is a patch set to grub which allows it to extract the SEV secret
area from the configuration table and use the secret as a password to
do a luks crypto mount of root (this is the sevsecret grub module).

There is also a patch to qemu which allows it to search through the
OVMF.fd and find the SEV secret area which is now described inside the
Reset Vector using the existing SEV_ES reset block.  This area is the
place QEMU will inject the encrypted SEV secret bundle.

Security of the System
======================

Since Grub is now part of the attested OVMF.fd bundle, the VM owner
knows absolutely that it will proceed straight to partition decryption
inside the attested code and boot the kernel off the encrypted
partition.  Even if a different QCOW image is substituted, the boot
will fail without revealing the secret because the system is designed
to fail hard in that case and because the secret is always contained
within the encrypted envelope it should be impossible for the cloud
operator to obtain it even if they can pause the boot and examine the
machine memory.

Putting it All Together
=======================

This is somewhat hard.  You must first understand how to boot a QEMU
system so as to have the VM pause after firmware loading (-S option)
and use the qmp port to request an attestation.  Only if the
attestation corresponds to the expected sha256sum of OVMF.fd should
the secret bundle be constructed and injected using qmp.  The tools
for constructing the secret bundle are in

https://github.com/AMDESE/sev-tool/

James

---

James Bottomley (6):
  OvmfPkg/Amdsev: Base commit to build encrypted boot specific OVMF
  OvmfPkg/AmdSev: add Grub Firmware Volume Package
  OvmfPkg: convert ES Reset Block structure to be guided
  OvmfPkg: create a SEV secret area in the AmdSev memfd
  OvmfPkg/AmdSev: assign and protect the Sev Secret area
  OvmfPkg/AmdSev: Expose the Sev Secret area using a configuration table

 OvmfPkg/OvmfPkg.dec                           |    8 +
 OvmfPkg/AmdSev/AmdSevX64.dsc                  |  878 ++++++++++
 OvmfPkg/AmdSev/AmdSevX64.fdf                  |  467 ++++++
 OvmfPkg/AmdSev/Grub/Grub.inf                  |   37 +
 OvmfPkg/AmdSev/SecretDxe/SecretDxe.inf        |   37 +
 OvmfPkg/AmdSev/SecretPei/SecretPei.inf        |   39 +
 .../PlatformBootManagerLibGrub.inf            |   79 +
 OvmfPkg/ResetVector/ResetVector.inf           |    4 +
 OvmfPkg/Include/Guid/SevLaunchSecret.h        |   28 +
 .../PlatformBootManagerLibGrub/BdsPlatform.h  |  175 ++
 OvmfPkg/AmdSev/SecretDxe/SecretDxe.c          |   25 +
 OvmfPkg/AmdSev/SecretPei/SecretPei.c          |   25 +
 .../PlatformBootManagerLibGrub/BdsPlatform.c  | 1483 +++++++++++++++++
 .../PlatformBootManagerLibGrub/PlatformData.c |  213 +++
 OvmfPkg/AmdSev/Grub/.gitignore                |    1 +
 OvmfPkg/AmdSev/Grub/grub.cfg                  |   46 +
 OvmfPkg/AmdSev/Grub/grub.sh                   |   92 +
 OvmfPkg/ResetVector/Ia16/ResetVectorVtf0.asm  |   63 +-
 OvmfPkg/ResetVector/ResetVector.nasmb         |    2 +
 19 files changed, 3691 insertions(+), 11 deletions(-)
 create mode 100644 OvmfPkg/AmdSev/AmdSevX64.dsc
 create mode 100644 OvmfPkg/AmdSev/AmdSevX64.fdf
 create mode 100644 OvmfPkg/AmdSev/Grub/Grub.inf
 create mode 100644 OvmfPkg/AmdSev/SecretDxe/SecretDxe.inf
 create mode 100644 OvmfPkg/AmdSev/SecretPei/SecretPei.inf
 create mode 100644 OvmfPkg/Library/PlatformBootManagerLibGrub/PlatformBootManagerLibGrub.inf
 create mode 100644 OvmfPkg/Include/Guid/SevLaunchSecret.h
 create mode 100644 OvmfPkg/Library/PlatformBootManagerLibGrub/BdsPlatform.h
 create mode 100644 OvmfPkg/AmdSev/SecretDxe/SecretDxe.c
 create mode 100644 OvmfPkg/AmdSev/SecretPei/SecretPei.c
 create mode 100644 OvmfPkg/Library/PlatformBootManagerLibGrub/BdsPlatform.c
 create mode 100644 OvmfPkg/Library/PlatformBootManagerLibGrub/PlatformData.c
 create mode 100644 OvmfPkg/AmdSev/Grub/.gitignore
 create mode 100644 OvmfPkg/AmdSev/Grub/grub.cfg
 create mode 100644 OvmfPkg/AmdSev/Grub/grub.sh

-- 
2.26.2


^ permalink raw reply	[flat|nested] 37+ messages in thread

* [PATCH v2 1/6] OvmfPkg/Amdsev: Base commit to build encrypted boot specific OVMF
  2020-11-20 18:45 [PATCH v2 0/6] SEV Encrypted Boot for Ovmf James Bottomley
@ 2020-11-20 18:45 ` James Bottomley
  2020-11-23 18:01   ` Laszlo Ersek
  2020-11-20 18:45 ` [PATCH v2 2/6] OvmfPkg/AmdSev: add Grub Firmware Volume Package James Bottomley
                   ` (4 subsequent siblings)
  5 siblings, 1 reply; 37+ messages in thread
From: James Bottomley @ 2020-11-20 18:45 UTC (permalink / raw)
  To: devel
  Cc: dovmurik, Dov.Murik1, ashish.kalra, brijesh.singh, tobin,
	david.kaplan, jon.grimm, thomas.lendacky, jejb, frankeh,
	Dr . David Alan Gilbert, Laszlo Ersek

This commit represents the file copied from OvmfPkgX64 with minor
changes to change the build name.

This package will form the basis for adding Sev specific features.
Since everything must go into a single rom file for attestation, the
separated build of code and variables is eliminated.

Ref: https://bugzilla.tianocore.org/show_bug.cgi?id=3077
Signed-off-by: James Bottomley <jejb@linux.ibm.com>

---

v2: remove secure boot, smm and networking
---
 OvmfPkg/AmdSev/AmdSevX64.dsc | 867 +++++++++++++++++++++++++++++++++++
 OvmfPkg/AmdSev/AmdSevX64.fdf | 461 +++++++++++++++++++
 2 files changed, 1328 insertions(+)
 create mode 100644 OvmfPkg/AmdSev/AmdSevX64.dsc
 create mode 100644 OvmfPkg/AmdSev/AmdSevX64.fdf

diff --git a/OvmfPkg/AmdSev/AmdSevX64.dsc b/OvmfPkg/AmdSev/AmdSevX64.dsc
new file mode 100644
index 000000000000..852be757bfbe
--- /dev/null
+++ b/OvmfPkg/AmdSev/AmdSevX64.dsc
@@ -0,0 +1,867 @@
+## @file
+#  EFI/Framework Open Virtual Machine Firmware (OVMF) platform for SEV secure
+#  virtual machine remote attestation and secret injection
+#
+#  Copyright (c) 2020 James Bottomley, IBM Corporation.
+#  Copyright (c) 2006 - 2020, Intel Corporation. All rights reserved.<BR>
+#  (C) Copyright 2016 Hewlett Packard Enterprise Development LP<BR>
+#
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+################################################################################
+#
+# Defines Section - statements that will be processed to create a Makefile.
+#
+################################################################################
+[Defines]
+  PLATFORM_NAME                  = Ovmf
+  PLATFORM_GUID                  = 07ff380c-4760-4823-8f59-ec2cb06fbc16
+  PLATFORM_VERSION               = 0.1
+  DSC_SPECIFICATION              = 0x00010005
+  OUTPUT_DIRECTORY               = Build/AmdSev
+  SUPPORTED_ARCHITECTURES        = X64
+  BUILD_TARGETS                  = NOOPT|DEBUG|RELEASE
+  SKUID_IDENTIFIER               = DEFAULT
+  FLASH_DEFINITION               = OvmfPkg/AmdSev/AmdSevX64.fdf
+
+  #
+  # Defines for default states.  These can be changed on the command line.
+  # -D FLAG=VALUE
+  #
+  DEFINE SOURCE_DEBUG_ENABLE     = FALSE
+  DEFINE TPM_ENABLE              = FALSE
+  DEFINE TPM_CONFIG_ENABLE       = FALSE
+
+  #
+  # Device drivers
+  #
+  DEFINE PVSCSI_ENABLE           = TRUE
+  DEFINE MPT_SCSI_ENABLE         = TRUE
+  DEFINE LSI_SCSI_ENABLE         = FALSE
+
+  #
+  # Flash size selection. Setting FD_SIZE_IN_KB on the command line directly to
+  # one of the supported values, in place of any of the convenience macros, is
+  # permitted.
+  #
+!ifdef $(FD_SIZE_1MB)
+  DEFINE FD_SIZE_IN_KB           = 1024
+!else
+!ifdef $(FD_SIZE_2MB)
+  DEFINE FD_SIZE_IN_KB           = 2048
+!else
+!ifdef $(FD_SIZE_4MB)
+  DEFINE FD_SIZE_IN_KB           = 4096
+!else
+  DEFINE FD_SIZE_IN_KB           = 4096
+!endif
+!endif
+!endif
+
+[BuildOptions]
+  GCC:RELEASE_*_*_CC_FLAGS             = -DMDEPKG_NDEBUG
+  INTEL:RELEASE_*_*_CC_FLAGS           = /D MDEPKG_NDEBUG
+  MSFT:RELEASE_*_*_CC_FLAGS            = /D MDEPKG_NDEBUG
+!if $(TOOL_CHAIN_TAG) != "XCODE5" && $(TOOL_CHAIN_TAG) != "CLANGPDB"
+  GCC:*_*_*_CC_FLAGS                   = -mno-mmx -mno-sse
+!endif
+!if $(SOURCE_DEBUG_ENABLE) == TRUE
+  MSFT:*_*_X64_GENFW_FLAGS  = --keepexceptiontable
+  GCC:*_*_X64_GENFW_FLAGS   = --keepexceptiontable
+  INTEL:*_*_X64_GENFW_FLAGS = --keepexceptiontable
+!endif
+
+  #
+  # Disable deprecated APIs.
+  #
+  MSFT:*_*_*_CC_FLAGS = /D DISABLE_NEW_DEPRECATED_INTERFACES
+  INTEL:*_*_*_CC_FLAGS = /D DISABLE_NEW_DEPRECATED_INTERFACES
+  GCC:*_*_*_CC_FLAGS = -D DISABLE_NEW_DEPRECATED_INTERFACES
+
+[BuildOptions.common.EDKII.DXE_RUNTIME_DRIVER]
+  GCC:*_*_*_DLINK_FLAGS = -z common-page-size=0x1000
+  XCODE:*_*_*_DLINK_FLAGS = -seg1addr 0x1000 -segalign 0x1000
+  XCODE:*_*_*_MTOC_FLAGS = -align 0x1000
+  CLANGPDB:*_*_*_DLINK_FLAGS = /ALIGN:4096
+
+# Force PE/COFF sections to be aligned at 4KB boundaries to support page level
+# protection of DXE_SMM_DRIVER/SMM_CORE modules
+[BuildOptions.common.EDKII.DXE_SMM_DRIVER, BuildOptions.common.EDKII.SMM_CORE]
+  GCC:*_*_*_DLINK_FLAGS = -z common-page-size=0x1000
+  XCODE:*_*_*_DLINK_FLAGS = -seg1addr 0x1000 -segalign 0x1000
+  XCODE:*_*_*_MTOC_FLAGS = -align 0x1000
+  CLANGPDB:*_*_*_DLINK_FLAGS = /ALIGN:4096
+
+################################################################################
+#
+# SKU Identification section - list of all SKU IDs supported by this Platform.
+#
+################################################################################
+[SkuIds]
+  0|DEFAULT
+
+################################################################################
+#
+# Library Class section - list of all Library Classes needed by this Platform.
+#
+################################################################################
+[LibraryClasses]
+  PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf
+  TimerLib|OvmfPkg/Library/AcpiTimerLib/BaseAcpiTimerLib.inf
+  ResetSystemLib|OvmfPkg/Library/ResetSystemLib/BaseResetSystemLib.inf
+  PrintLib|MdePkg/Library/BasePrintLib/BasePrintLib.inf
+  BaseMemoryLib|MdePkg/Library/BaseMemoryLibRepStr/BaseMemoryLibRepStr.inf
+  BaseLib|MdePkg/Library/BaseLib/BaseLib.inf
+  SafeIntLib|MdePkg/Library/BaseSafeIntLib/BaseSafeIntLib.inf
+  BmpSupportLib|MdeModulePkg/Library/BaseBmpSupportLib/BaseBmpSupportLib.inf
+  SynchronizationLib|MdePkg/Library/BaseSynchronizationLib/BaseSynchronizationLib.inf
+  CpuLib|MdePkg/Library/BaseCpuLib/BaseCpuLib.inf
+  PerformanceLib|MdePkg/Library/BasePerformanceLibNull/BasePerformanceLibNull.inf
+  PeCoffLib|MdePkg/Library/BasePeCoffLib/BasePeCoffLib.inf
+  CacheMaintenanceLib|MdePkg/Library/BaseCacheMaintenanceLib/BaseCacheMaintenanceLib.inf
+  UefiDecompressLib|MdePkg/Library/BaseUefiDecompressLib/BaseUefiDecompressLib.inf
+  UefiHiiServicesLib|MdeModulePkg/Library/UefiHiiServicesLib/UefiHiiServicesLib.inf
+  HiiLib|MdeModulePkg/Library/UefiHiiLib/UefiHiiLib.inf
+  SortLib|MdeModulePkg/Library/UefiSortLib/UefiSortLib.inf
+  UefiBootManagerLib|MdeModulePkg/Library/UefiBootManagerLib/UefiBootManagerLib.inf
+  BootLogoLib|MdeModulePkg/Library/BootLogoLib/BootLogoLib.inf
+  FileExplorerLib|MdeModulePkg/Library/FileExplorerLib/FileExplorerLib.inf
+  CapsuleLib|MdeModulePkg/Library/DxeCapsuleLibNull/DxeCapsuleLibNull.inf
+  DxeServicesLib|MdePkg/Library/DxeServicesLib/DxeServicesLib.inf
+  DxeServicesTableLib|MdePkg/Library/DxeServicesTableLib/DxeServicesTableLib.inf
+  PeCoffGetEntryPointLib|MdePkg/Library/BasePeCoffGetEntryPointLib/BasePeCoffGetEntryPointLib.inf
+  PciCf8Lib|MdePkg/Library/BasePciCf8Lib/BasePciCf8Lib.inf
+  PciExpressLib|MdePkg/Library/BasePciExpressLib/BasePciExpressLib.inf
+  PciLib|MdePkg/Library/BasePciLibCf8/BasePciLibCf8.inf
+  PciSegmentLib|MdePkg/Library/BasePciSegmentLibPci/BasePciSegmentLibPci.inf
+  PciCapLib|OvmfPkg/Library/BasePciCapLib/BasePciCapLib.inf
+  PciCapPciSegmentLib|OvmfPkg/Library/BasePciCapPciSegmentLib/BasePciCapPciSegmentLib.inf
+  PciCapPciIoLib|OvmfPkg/Library/UefiPciCapPciIoLib/UefiPciCapPciIoLib.inf
+  IoLib|MdePkg/Library/BaseIoLibIntrinsic/BaseIoLibIntrinsicSev.inf
+  OemHookStatusCodeLib|MdeModulePkg/Library/OemHookStatusCodeLibNull/OemHookStatusCodeLibNull.inf
+  SerialPortLib|PcAtChipsetPkg/Library/SerialIoLib/SerialIoLib.inf
+  MtrrLib|UefiCpuPkg/Library/MtrrLib/MtrrLib.inf
+  UefiLib|MdePkg/Library/UefiLib/UefiLib.inf
+  UefiBootServicesTableLib|MdePkg/Library/UefiBootServicesTableLib/UefiBootServicesTableLib.inf
+  UefiRuntimeServicesTableLib|MdePkg/Library/UefiRuntimeServicesTableLib/UefiRuntimeServicesTableLib.inf
+  UefiDriverEntryPoint|MdePkg/Library/UefiDriverEntryPoint/UefiDriverEntryPoint.inf
+  UefiApplicationEntryPoint|MdePkg/Library/UefiApplicationEntryPoint/UefiApplicationEntryPoint.inf
+  DevicePathLib|MdePkg/Library/UefiDevicePathLibDevicePathProtocol/UefiDevicePathLibDevicePathProtocol.inf
+  NvVarsFileLib|OvmfPkg/Library/NvVarsFileLib/NvVarsFileLib.inf
+  FileHandleLib|MdePkg/Library/UefiFileHandleLib/UefiFileHandleLib.inf
+  UefiCpuLib|UefiCpuPkg/Library/BaseUefiCpuLib/BaseUefiCpuLib.inf
+  SecurityManagementLib|MdeModulePkg/Library/DxeSecurityManagementLib/DxeSecurityManagementLib.inf
+  UefiUsbLib|MdePkg/Library/UefiUsbLib/UefiUsbLib.inf
+  SerializeVariablesLib|OvmfPkg/Library/SerializeVariablesLib/SerializeVariablesLib.inf
+  QemuFwCfgLib|OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgDxeLib.inf
+  QemuFwCfgSimpleParserLib|OvmfPkg/Library/QemuFwCfgSimpleParserLib/QemuFwCfgSimpleParserLib.inf
+  VirtioLib|OvmfPkg/Library/VirtioLib/VirtioLib.inf
+  LoadLinuxLib|OvmfPkg/Library/LoadLinuxLib/LoadLinuxLib.inf
+  MemEncryptSevLib|OvmfPkg/Library/BaseMemEncryptSevLib/BaseMemEncryptSevLib.inf
+  LockBoxLib|OvmfPkg/Library/LockBoxLib/LockBoxBaseLib.inf
+  CustomizedDisplayLib|MdeModulePkg/Library/CustomizedDisplayLib/CustomizedDisplayLib.inf
+  FrameBufferBltLib|MdeModulePkg/Library/FrameBufferBltLib/FrameBufferBltLib.inf
+
+!if $(SOURCE_DEBUG_ENABLE) == TRUE
+  PeCoffExtraActionLib|SourceLevelDebugPkg/Library/PeCoffExtraActionLibDebug/PeCoffExtraActionLibDebug.inf
+  DebugCommunicationLib|SourceLevelDebugPkg/Library/DebugCommunicationLibSerialPort/DebugCommunicationLibSerialPort.inf
+!else
+  PeCoffExtraActionLib|MdePkg/Library/BasePeCoffExtraActionLibNull/BasePeCoffExtraActionLibNull.inf
+  DebugAgentLib|MdeModulePkg/Library/DebugAgentLibNull/DebugAgentLibNull.inf
+!endif
+
+  LocalApicLib|UefiCpuPkg/Library/BaseXApicX2ApicLib/BaseXApicX2ApicLib.inf
+  DebugPrintErrorLevelLib|MdePkg/Library/BaseDebugPrintErrorLevelLib/BaseDebugPrintErrorLevelLib.inf
+
+  IntrinsicLib|CryptoPkg/Library/IntrinsicLib/IntrinsicLib.inf
+  OpensslLib|CryptoPkg/Library/OpensslLib/OpensslLibCrypto.inf
+  RngLib|MdePkg/Library/BaseRngLibTimerLib/BaseRngLibTimerLib.inf
+
+  AuthVariableLib|MdeModulePkg/Library/AuthVariableLibNull/AuthVariableLibNull.inf
+  VarCheckLib|MdeModulePkg/Library/VarCheckLib/VarCheckLib.inf
+
+
+  ShellLib|ShellPkg/Library/UefiShellLib/UefiShellLib.inf
+  ShellCEntryLib|ShellPkg/Library/UefiShellCEntryLib/UefiShellCEntryLib.inf
+  S3BootScriptLib|MdeModulePkg/Library/PiDxeS3BootScriptLib/DxeS3BootScriptLib.inf
+  SmbusLib|MdePkg/Library/BaseSmbusLibNull/BaseSmbusLibNull.inf
+  OrderedCollectionLib|MdePkg/Library/BaseOrderedCollectionRedBlackTreeLib/BaseOrderedCollectionRedBlackTreeLib.inf
+  XenHypercallLib|OvmfPkg/Library/XenHypercallLib/XenHypercallLib.inf
+  XenPlatformLib|OvmfPkg/Library/XenPlatformLib/XenPlatformLib.inf
+
+!if $(TPM_ENABLE) == TRUE
+  Tpm12CommandLib|SecurityPkg/Library/Tpm12CommandLib/Tpm12CommandLib.inf
+  Tpm2CommandLib|SecurityPkg/Library/Tpm2CommandLib/Tpm2CommandLib.inf
+  Tcg2PhysicalPresenceLib|OvmfPkg/Library/Tcg2PhysicalPresenceLibQemu/DxeTcg2PhysicalPresenceLib.inf
+  Tcg2PpVendorLib|SecurityPkg/Library/Tcg2PpVendorLibNull/Tcg2PpVendorLibNull.inf
+  TpmMeasurementLib|SecurityPkg/Library/DxeTpmMeasurementLib/DxeTpmMeasurementLib.inf
+!else
+  Tcg2PhysicalPresenceLib|OvmfPkg/Library/Tcg2PhysicalPresenceLibNull/DxeTcg2PhysicalPresenceLib.inf
+  TpmMeasurementLib|MdeModulePkg/Library/TpmMeasurementLibNull/TpmMeasurementLibNull.inf
+!endif
+
+[LibraryClasses.common]
+  BaseCryptLib|CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf
+  VmgExitLib|OvmfPkg/Library/VmgExitLib/VmgExitLib.inf
+
+[LibraryClasses.common.SEC]
+  TimerLib|OvmfPkg/Library/AcpiTimerLib/BaseRomAcpiTimerLib.inf
+  QemuFwCfgLib|OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgSecLib.inf
+!ifdef $(DEBUG_ON_SERIAL_PORT)
+  DebugLib|MdePkg/Library/BaseDebugLibSerialPort/BaseDebugLibSerialPort.inf
+!else
+  DebugLib|OvmfPkg/Library/PlatformDebugLibIoPort/PlatformRomDebugLibIoPort.inf
+!endif
+  ReportStatusCodeLib|MdeModulePkg/Library/PeiReportStatusCodeLib/PeiReportStatusCodeLib.inf
+  ExtractGuidedSectionLib|MdePkg/Library/BaseExtractGuidedSectionLib/BaseExtractGuidedSectionLib.inf
+!if $(SOURCE_DEBUG_ENABLE) == TRUE
+  DebugAgentLib|SourceLevelDebugPkg/Library/DebugAgent/SecPeiDebugAgentLib.inf
+!endif
+  HobLib|MdePkg/Library/PeiHobLib/PeiHobLib.inf
+  PeiServicesLib|MdePkg/Library/PeiServicesLib/PeiServicesLib.inf
+  PeiServicesTablePointerLib|MdePkg/Library/PeiServicesTablePointerLibIdt/PeiServicesTablePointerLibIdt.inf
+  MemoryAllocationLib|MdePkg/Library/PeiMemoryAllocationLib/PeiMemoryAllocationLib.inf
+!if $(TOOL_CHAIN_TAG) == "XCODE5"
+  CpuExceptionHandlerLib|UefiCpuPkg/Library/CpuExceptionHandlerLib/Xcode5SecPeiCpuExceptionHandlerLib.inf
+!else
+  CpuExceptionHandlerLib|UefiCpuPkg/Library/CpuExceptionHandlerLib/SecPeiCpuExceptionHandlerLib.inf
+!endif
+
+[LibraryClasses.common.PEI_CORE]
+  HobLib|MdePkg/Library/PeiHobLib/PeiHobLib.inf
+  PeiServicesTablePointerLib|MdePkg/Library/PeiServicesTablePointerLibIdt/PeiServicesTablePointerLibIdt.inf
+  PeiServicesLib|MdePkg/Library/PeiServicesLib/PeiServicesLib.inf
+  MemoryAllocationLib|MdePkg/Library/PeiMemoryAllocationLib/PeiMemoryAllocationLib.inf
+  PeiCoreEntryPoint|MdePkg/Library/PeiCoreEntryPoint/PeiCoreEntryPoint.inf
+  ReportStatusCodeLib|MdeModulePkg/Library/PeiReportStatusCodeLib/PeiReportStatusCodeLib.inf
+  OemHookStatusCodeLib|MdeModulePkg/Library/OemHookStatusCodeLibNull/OemHookStatusCodeLibNull.inf
+  PeCoffGetEntryPointLib|MdePkg/Library/BasePeCoffGetEntryPointLib/BasePeCoffGetEntryPointLib.inf
+!ifdef $(DEBUG_ON_SERIAL_PORT)
+  DebugLib|MdePkg/Library/BaseDebugLibSerialPort/BaseDebugLibSerialPort.inf
+!else
+  DebugLib|OvmfPkg/Library/PlatformDebugLibIoPort/PlatformDebugLibIoPort.inf
+!endif
+  PeCoffLib|MdePkg/Library/BasePeCoffLib/BasePeCoffLib.inf
+
+[LibraryClasses.common.PEIM]
+  HobLib|MdePkg/Library/PeiHobLib/PeiHobLib.inf
+  PeiServicesTablePointerLib|MdePkg/Library/PeiServicesTablePointerLibIdt/PeiServicesTablePointerLibIdt.inf
+  PeiServicesLib|MdePkg/Library/PeiServicesLib/PeiServicesLib.inf
+  MemoryAllocationLib|MdePkg/Library/PeiMemoryAllocationLib/PeiMemoryAllocationLib.inf
+  PeimEntryPoint|MdePkg/Library/PeimEntryPoint/PeimEntryPoint.inf
+  ReportStatusCodeLib|MdeModulePkg/Library/PeiReportStatusCodeLib/PeiReportStatusCodeLib.inf
+  OemHookStatusCodeLib|MdeModulePkg/Library/OemHookStatusCodeLibNull/OemHookStatusCodeLibNull.inf
+  PeCoffGetEntryPointLib|MdePkg/Library/BasePeCoffGetEntryPointLib/BasePeCoffGetEntryPointLib.inf
+!ifdef $(DEBUG_ON_SERIAL_PORT)
+  DebugLib|MdePkg/Library/BaseDebugLibSerialPort/BaseDebugLibSerialPort.inf
+!else
+  DebugLib|OvmfPkg/Library/PlatformDebugLibIoPort/PlatformDebugLibIoPort.inf
+!endif
+  PeCoffLib|MdePkg/Library/BasePeCoffLib/BasePeCoffLib.inf
+  ResourcePublicationLib|MdePkg/Library/PeiResourcePublicationLib/PeiResourcePublicationLib.inf
+  ExtractGuidedSectionLib|MdePkg/Library/PeiExtractGuidedSectionLib/PeiExtractGuidedSectionLib.inf
+!if $(SOURCE_DEBUG_ENABLE) == TRUE
+  DebugAgentLib|SourceLevelDebugPkg/Library/DebugAgent/SecPeiDebugAgentLib.inf
+!endif
+  CpuExceptionHandlerLib|UefiCpuPkg/Library/CpuExceptionHandlerLib/PeiCpuExceptionHandlerLib.inf
+  MpInitLib|UefiCpuPkg/Library/MpInitLib/PeiMpInitLib.inf
+  QemuFwCfgS3Lib|OvmfPkg/Library/QemuFwCfgS3Lib/PeiQemuFwCfgS3LibFwCfg.inf
+  PcdLib|MdePkg/Library/PeiPcdLib/PeiPcdLib.inf
+  QemuFwCfgLib|OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgPeiLib.inf
+
+!if $(TPM_ENABLE) == TRUE
+  BaseCryptLib|CryptoPkg/Library/BaseCryptLib/PeiCryptLib.inf
+  Tpm12DeviceLib|SecurityPkg/Library/Tpm12DeviceLibDTpm/Tpm12DeviceLibDTpm.inf
+  Tpm2DeviceLib|SecurityPkg/Library/Tpm2DeviceLibDTpm/Tpm2DeviceLibDTpm.inf
+!endif
+
+[LibraryClasses.common.DXE_CORE]
+  HobLib|MdePkg/Library/DxeCoreHobLib/DxeCoreHobLib.inf
+  DxeCoreEntryPoint|MdePkg/Library/DxeCoreEntryPoint/DxeCoreEntryPoint.inf
+  MemoryAllocationLib|MdeModulePkg/Library/DxeCoreMemoryAllocationLib/DxeCoreMemoryAllocationLib.inf
+  ReportStatusCodeLib|MdeModulePkg/Library/DxeReportStatusCodeLib/DxeReportStatusCodeLib.inf
+!ifdef $(DEBUG_ON_SERIAL_PORT)
+  DebugLib|MdePkg/Library/BaseDebugLibSerialPort/BaseDebugLibSerialPort.inf
+!else
+  DebugLib|OvmfPkg/Library/PlatformDebugLibIoPort/PlatformDebugLibIoPort.inf
+!endif
+  ExtractGuidedSectionLib|MdePkg/Library/DxeExtractGuidedSectionLib/DxeExtractGuidedSectionLib.inf
+!if $(SOURCE_DEBUG_ENABLE) == TRUE
+  DebugAgentLib|SourceLevelDebugPkg/Library/DebugAgent/DxeDebugAgentLib.inf
+!endif
+  CpuExceptionHandlerLib|UefiCpuPkg/Library/CpuExceptionHandlerLib/DxeCpuExceptionHandlerLib.inf
+  PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf
+
+[LibraryClasses.common.DXE_RUNTIME_DRIVER]
+  PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf
+  TimerLib|OvmfPkg/Library/AcpiTimerLib/DxeAcpiTimerLib.inf
+  ResetSystemLib|OvmfPkg/Library/ResetSystemLib/DxeResetSystemLib.inf
+  HobLib|MdePkg/Library/DxeHobLib/DxeHobLib.inf
+  DxeCoreEntryPoint|MdePkg/Library/DxeCoreEntryPoint/DxeCoreEntryPoint.inf
+  MemoryAllocationLib|MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAllocationLib.inf
+  ReportStatusCodeLib|MdeModulePkg/Library/RuntimeDxeReportStatusCodeLib/RuntimeDxeReportStatusCodeLib.inf
+!ifdef $(DEBUG_ON_SERIAL_PORT)
+  DebugLib|MdePkg/Library/BaseDebugLibSerialPort/BaseDebugLibSerialPort.inf
+!else
+  DebugLib|OvmfPkg/Library/PlatformDebugLibIoPort/PlatformDebugLibIoPort.inf
+!endif
+  UefiRuntimeLib|MdePkg/Library/UefiRuntimeLib/UefiRuntimeLib.inf
+  BaseCryptLib|CryptoPkg/Library/BaseCryptLib/RuntimeCryptLib.inf
+  PciLib|OvmfPkg/Library/DxePciLibI440FxQ35/DxePciLibI440FxQ35.inf
+  QemuFwCfgS3Lib|OvmfPkg/Library/QemuFwCfgS3Lib/DxeQemuFwCfgS3LibFwCfg.inf
+
+[LibraryClasses.common.UEFI_DRIVER]
+  PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf
+  TimerLib|OvmfPkg/Library/AcpiTimerLib/DxeAcpiTimerLib.inf
+  ResetSystemLib|OvmfPkg/Library/ResetSystemLib/DxeResetSystemLib.inf
+  HobLib|MdePkg/Library/DxeHobLib/DxeHobLib.inf
+  DxeCoreEntryPoint|MdePkg/Library/DxeCoreEntryPoint/DxeCoreEntryPoint.inf
+  MemoryAllocationLib|MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAllocationLib.inf
+  ReportStatusCodeLib|MdeModulePkg/Library/DxeReportStatusCodeLib/DxeReportStatusCodeLib.inf
+!ifdef $(DEBUG_ON_SERIAL_PORT)
+  DebugLib|MdePkg/Library/BaseDebugLibSerialPort/BaseDebugLibSerialPort.inf
+!else
+  DebugLib|OvmfPkg/Library/PlatformDebugLibIoPort/PlatformDebugLibIoPort.inf
+!endif
+  UefiScsiLib|MdePkg/Library/UefiScsiLib/UefiScsiLib.inf
+  PciLib|OvmfPkg/Library/DxePciLibI440FxQ35/DxePciLibI440FxQ35.inf
+
+[LibraryClasses.common.DXE_DRIVER]
+  PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf
+  TimerLib|OvmfPkg/Library/AcpiTimerLib/DxeAcpiTimerLib.inf
+  ResetSystemLib|OvmfPkg/Library/ResetSystemLib/DxeResetSystemLib.inf
+  HobLib|MdePkg/Library/DxeHobLib/DxeHobLib.inf
+  MemoryAllocationLib|MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAllocationLib.inf
+  ReportStatusCodeLib|MdeModulePkg/Library/DxeReportStatusCodeLib/DxeReportStatusCodeLib.inf
+  UefiScsiLib|MdePkg/Library/UefiScsiLib/UefiScsiLib.inf
+!ifdef $(DEBUG_ON_SERIAL_PORT)
+  DebugLib|MdePkg/Library/BaseDebugLibSerialPort/BaseDebugLibSerialPort.inf
+!else
+  DebugLib|OvmfPkg/Library/PlatformDebugLibIoPort/PlatformDebugLibIoPort.inf
+!endif
+  PlatformBootManagerLib|OvmfPkg/Library/PlatformBootManagerLib/PlatformBootManagerLib.inf
+  PlatformBmPrintScLib|OvmfPkg/Library/PlatformBmPrintScLib/PlatformBmPrintScLib.inf
+  QemuBootOrderLib|OvmfPkg/Library/QemuBootOrderLib/QemuBootOrderLib.inf
+  CpuExceptionHandlerLib|UefiCpuPkg/Library/CpuExceptionHandlerLib/DxeCpuExceptionHandlerLib.inf
+  LockBoxLib|OvmfPkg/Library/LockBoxLib/LockBoxDxeLib.inf
+!if $(SOURCE_DEBUG_ENABLE) == TRUE
+  DebugAgentLib|SourceLevelDebugPkg/Library/DebugAgent/DxeDebugAgentLib.inf
+!endif
+  PciLib|OvmfPkg/Library/DxePciLibI440FxQ35/DxePciLibI440FxQ35.inf
+  MpInitLib|UefiCpuPkg/Library/MpInitLib/DxeMpInitLib.inf
+  QemuFwCfgS3Lib|OvmfPkg/Library/QemuFwCfgS3Lib/DxeQemuFwCfgS3LibFwCfg.inf
+  QemuLoadImageLib|OvmfPkg/Library/X86QemuLoadImageLib/X86QemuLoadImageLib.inf
+!if $(TPM_ENABLE) == TRUE
+  Tpm12DeviceLib|SecurityPkg/Library/Tpm12DeviceLibTcg/Tpm12DeviceLibTcg.inf
+  Tpm2DeviceLib|SecurityPkg/Library/Tpm2DeviceLibTcg2/Tpm2DeviceLibTcg2.inf
+!endif
+
+[LibraryClasses.common.UEFI_APPLICATION]
+  PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf
+  TimerLib|OvmfPkg/Library/AcpiTimerLib/DxeAcpiTimerLib.inf
+  ResetSystemLib|OvmfPkg/Library/ResetSystemLib/DxeResetSystemLib.inf
+  HobLib|MdePkg/Library/DxeHobLib/DxeHobLib.inf
+  MemoryAllocationLib|MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAllocationLib.inf
+  ReportStatusCodeLib|MdeModulePkg/Library/DxeReportStatusCodeLib/DxeReportStatusCodeLib.inf
+!ifdef $(DEBUG_ON_SERIAL_PORT)
+  DebugLib|MdePkg/Library/BaseDebugLibSerialPort/BaseDebugLibSerialPort.inf
+!else
+  DebugLib|OvmfPkg/Library/PlatformDebugLibIoPort/PlatformDebugLibIoPort.inf
+!endif
+  PciLib|OvmfPkg/Library/DxePciLibI440FxQ35/DxePciLibI440FxQ35.inf
+
+[LibraryClasses.common.DXE_SMM_DRIVER]
+  PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf
+  TimerLib|OvmfPkg/Library/AcpiTimerLib/DxeAcpiTimerLib.inf
+  ResetSystemLib|OvmfPkg/Library/ResetSystemLib/DxeResetSystemLib.inf
+  MemoryAllocationLib|MdePkg/Library/SmmMemoryAllocationLib/SmmMemoryAllocationLib.inf
+  ReportStatusCodeLib|MdeModulePkg/Library/DxeReportStatusCodeLib/DxeReportStatusCodeLib.inf
+  HobLib|MdePkg/Library/DxeHobLib/DxeHobLib.inf
+  SmmMemLib|MdePkg/Library/SmmMemLib/SmmMemLib.inf
+  MmServicesTableLib|MdePkg/Library/MmServicesTableLib/MmServicesTableLib.inf
+  SmmServicesTableLib|MdePkg/Library/SmmServicesTableLib/SmmServicesTableLib.inf
+!ifdef $(DEBUG_ON_SERIAL_PORT)
+  DebugLib|MdePkg/Library/BaseDebugLibSerialPort/BaseDebugLibSerialPort.inf
+!else
+  DebugLib|OvmfPkg/Library/PlatformDebugLibIoPort/PlatformDebugLibIoPort.inf
+!endif
+  CpuExceptionHandlerLib|UefiCpuPkg/Library/CpuExceptionHandlerLib/SmmCpuExceptionHandlerLib.inf
+!if $(SOURCE_DEBUG_ENABLE) == TRUE
+  DebugAgentLib|SourceLevelDebugPkg/Library/DebugAgent/SmmDebugAgentLib.inf
+!endif
+  BaseCryptLib|CryptoPkg/Library/BaseCryptLib/SmmCryptLib.inf
+  PciLib|OvmfPkg/Library/DxePciLibI440FxQ35/DxePciLibI440FxQ35.inf
+
+[LibraryClasses.common.SMM_CORE]
+  PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf
+  TimerLib|OvmfPkg/Library/AcpiTimerLib/DxeAcpiTimerLib.inf
+  ResetSystemLib|OvmfPkg/Library/ResetSystemLib/DxeResetSystemLib.inf
+  SmmCorePlatformHookLib|MdeModulePkg/Library/SmmCorePlatformHookLibNull/SmmCorePlatformHookLibNull.inf
+  MemoryAllocationLib|MdeModulePkg/Library/PiSmmCoreMemoryAllocationLib/PiSmmCoreMemoryAllocationLib.inf
+  ReportStatusCodeLib|MdeModulePkg/Library/DxeReportStatusCodeLib/DxeReportStatusCodeLib.inf
+  HobLib|MdePkg/Library/DxeHobLib/DxeHobLib.inf
+  SmmMemLib|MdePkg/Library/SmmMemLib/SmmMemLib.inf
+  SmmServicesTableLib|MdeModulePkg/Library/PiSmmCoreSmmServicesTableLib/PiSmmCoreSmmServicesTableLib.inf
+!ifdef $(DEBUG_ON_SERIAL_PORT)
+  DebugLib|MdePkg/Library/BaseDebugLibSerialPort/BaseDebugLibSerialPort.inf
+!else
+  DebugLib|OvmfPkg/Library/PlatformDebugLibIoPort/PlatformDebugLibIoPort.inf
+!endif
+  PciLib|OvmfPkg/Library/DxePciLibI440FxQ35/DxePciLibI440FxQ35.inf
+
+################################################################################
+#
+# Pcd Section - list of all EDK II PCD Entries defined by this Platform.
+#
+################################################################################
+[PcdsFeatureFlag]
+  gEfiMdeModulePkgTokenSpaceGuid.PcdHiiOsRuntimeSupport|FALSE
+  gEfiMdeModulePkgTokenSpaceGuid.PcdDxeIplSupportUefiDecompress|FALSE
+  gEfiMdeModulePkgTokenSpaceGuid.PcdDxeIplSwitchToLongMode|FALSE
+  gEfiMdeModulePkgTokenSpaceGuid.PcdConOutGopSupport|TRUE
+  gEfiMdeModulePkgTokenSpaceGuid.PcdConOutUgaSupport|FALSE
+  gEfiMdeModulePkgTokenSpaceGuid.PcdInstallAcpiSdtProtocol|TRUE
+!ifdef $(CSM_ENABLE)
+  gUefiOvmfPkgTokenSpaceGuid.PcdCsmEnable|TRUE
+!endif
+
+[PcdsFixedAtBuild]
+  gEfiMdeModulePkgTokenSpaceGuid.PcdStatusCodeMemorySize|1
+  gEfiMdeModulePkgTokenSpaceGuid.PcdResetOnMemoryTypeInformationChange|FALSE
+  gEfiMdePkgTokenSpaceGuid.PcdMaximumGuidedExtractHandler|0x10
+!if ($(FD_SIZE_IN_KB) == 1024) || ($(FD_SIZE_IN_KB) == 2048)
+  gEfiMdeModulePkgTokenSpaceGuid.PcdMaxVariableSize|0x2000
+  gEfiMdeModulePkgTokenSpaceGuid.PcdMaxAuthVariableSize|0x2800
+  # match PcdFlashNvStorageVariableSize purely for convenience
+  gEfiMdeModulePkgTokenSpaceGuid.PcdVariableStoreSize|0xe000
+!endif
+!if $(FD_SIZE_IN_KB) == 4096
+  gEfiMdeModulePkgTokenSpaceGuid.PcdMaxVariableSize|0x8400
+  gEfiMdeModulePkgTokenSpaceGuid.PcdMaxAuthVariableSize|0x8400
+  # match PcdFlashNvStorageVariableSize purely for convenience
+  gEfiMdeModulePkgTokenSpaceGuid.PcdVariableStoreSize|0x40000
+!endif
+  gEfiMdeModulePkgTokenSpaceGuid.PcdVariableStoreSize|0x80000
+  gEfiMdeModulePkgTokenSpaceGuid.PcdMaxVolatileVariableSize|0x40000
+
+  gEfiMdeModulePkgTokenSpaceGuid.PcdVpdBaseAddress|0x0
+  gEfiMdeModulePkgTokenSpaceGuid.PcdStatusCodeUseSerial|FALSE
+  gEfiMdeModulePkgTokenSpaceGuid.PcdStatusCodeUseMemory|TRUE
+
+  gEfiMdePkgTokenSpaceGuid.PcdReportStatusCodePropertyMask|0x07
+
+  # DEBUG_INIT      0x00000001  // Initialization
+  # DEBUG_WARN      0x00000002  // Warnings
+  # DEBUG_LOAD      0x00000004  // Load events
+  # DEBUG_FS        0x00000008  // EFI File system
+  # DEBUG_POOL      0x00000010  // Alloc & Free (pool)
+  # DEBUG_PAGE      0x00000020  // Alloc & Free (page)
+  # DEBUG_INFO      0x00000040  // Informational debug messages
+  # DEBUG_DISPATCH  0x00000080  // PEI/DXE/SMM Dispatchers
+  # DEBUG_VARIABLE  0x00000100  // Variable
+  # DEBUG_BM        0x00000400  // Boot Manager
+  # DEBUG_BLKIO     0x00001000  // BlkIo Driver
+  # DEBUG_NET       0x00004000  // SNP Driver
+  # DEBUG_UNDI      0x00010000  // UNDI Driver
+  # DEBUG_LOADFILE  0x00020000  // LoadFile
+  # DEBUG_EVENT     0x00080000  // Event messages
+  # DEBUG_GCD       0x00100000  // Global Coherency Database changes
+  # DEBUG_CACHE     0x00200000  // Memory range cachability changes
+  # DEBUG_VERBOSE   0x00400000  // Detailed debug messages that may
+  #                             // significantly impact boot performance
+  # DEBUG_ERROR     0x80000000  // Error
+  gEfiMdePkgTokenSpaceGuid.PcdDebugPrintErrorLevel|0x8000004F
+
+!if $(SOURCE_DEBUG_ENABLE) == TRUE
+  gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask|0x17
+!else
+  gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask|0x2F
+!endif
+
+  # This PCD is used to set the base address of the PCI express hierarchy. It
+  # is only consulted when OVMF runs on Q35. In that case it is programmed into
+  # the PCIEXBAR register.
+  #
+  # On Q35 machine types that QEMU intends to support in the long term, QEMU
+  # never lets the RAM below 4 GB exceed 2816 MB.
+  gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseAddress|0xB0000000
+
+!if $(SOURCE_DEBUG_ENABLE) == TRUE
+  gEfiSourceLevelDebugPkgTokenSpaceGuid.PcdDebugLoadImageMethod|0x2
+!endif
+
+  #
+  # The NumberOfPages values below are ad-hoc. They are updated sporadically at
+  # best (please refer to git-blame for past updates). The values capture a set
+  # of BIN hints that made sense at a particular time, for some (now likely
+  # unknown) workloads / boot paths.
+  #
+  gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiACPIMemoryNVS|0x80
+  gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiACPIReclaimMemory|0x10
+  gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiReservedMemoryType|0x80
+  gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiRuntimeServicesCode|0x100
+  gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiRuntimeServicesData|0x100
+
+  # IRQs 5, 9, 10, 11 are level-triggered
+  gUefiOvmfPkgTokenSpaceGuid.Pcd8259LegacyModeEdgeLevel|0x0E20
+
+  # Point to the MdeModulePkg/Application/UiApp/UiApp.inf
+  gEfiMdeModulePkgTokenSpaceGuid.PcdBootManagerMenuFile|{ 0x21, 0xaa, 0x2c, 0x46, 0x14, 0x76, 0x03, 0x45, 0x83, 0x6e, 0x8a, 0xb6, 0xf4, 0x66, 0x23, 0x31 }
+
+################################################################################
+#
+# Pcd Dynamic Section - list of all EDK II PCD Entries defined by this Platform
+#
+################################################################################
+
+[PcdsDynamicDefault]
+  # only set when
+  #   ($(SMM_REQUIRE) == FALSE)
+  gEfiMdeModulePkgTokenSpaceGuid.PcdEmuVariableNvStoreReserved|0
+
+  gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableBase64|0
+  gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingBase|0
+  gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareBase|0
+  gEfiMdeModulePkgTokenSpaceGuid.PcdPciDisableBusEnumeration|FALSE
+  gEfiMdeModulePkgTokenSpaceGuid.PcdVideoHorizontalResolution|800
+  gEfiMdeModulePkgTokenSpaceGuid.PcdVideoVerticalResolution|600
+  gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiS3Enable|FALSE
+  gUefiOvmfPkgTokenSpaceGuid.PcdOvmfHostBridgePciDevId|0
+  gUefiOvmfPkgTokenSpaceGuid.PcdPciIoBase|0x0
+  gUefiOvmfPkgTokenSpaceGuid.PcdPciIoSize|0x0
+  gUefiOvmfPkgTokenSpaceGuid.PcdPciMmio32Base|0x0
+  gUefiOvmfPkgTokenSpaceGuid.PcdPciMmio32Size|0x0
+  gUefiOvmfPkgTokenSpaceGuid.PcdPciMmio64Base|0x0
+!ifdef $(CSM_ENABLE)
+  gUefiOvmfPkgTokenSpaceGuid.PcdPciMmio64Size|0x0
+!else
+  gUefiOvmfPkgTokenSpaceGuid.PcdPciMmio64Size|0x800000000
+!endif
+
+  gEfiMdePkgTokenSpaceGuid.PcdPlatformBootTimeOut|0
+
+  # Set video resolution for text setup.
+  gEfiMdeModulePkgTokenSpaceGuid.PcdSetupVideoHorizontalResolution|640
+  gEfiMdeModulePkgTokenSpaceGuid.PcdSetupVideoVerticalResolution|480
+
+  gEfiMdeModulePkgTokenSpaceGuid.PcdSmbiosVersion|0x0208
+  gEfiMdeModulePkgTokenSpaceGuid.PcdSmbiosDocRev|0x0
+  gUefiOvmfPkgTokenSpaceGuid.PcdQemuSmbiosValidated|FALSE
+
+  # Noexec settings for DXE.
+  gEfiMdeModulePkgTokenSpaceGuid.PcdSetNxForStack|FALSE
+
+  # UefiCpuPkg PCDs related to initial AP bringup and general AP management.
+  gUefiCpuPkgTokenSpaceGuid.PcdCpuMaxLogicalProcessorNumber|64
+  gUefiCpuPkgTokenSpaceGuid.PcdCpuBootLogicalProcessorNumber|0
+
+  # Set memory encryption mask
+  gEfiMdeModulePkgTokenSpaceGuid.PcdPteMemoryEncryptionAddressOrMask|0x0
+
+  # Set SEV-ES defaults
+  gEfiMdeModulePkgTokenSpaceGuid.PcdGhcbBase|0
+  gEfiMdeModulePkgTokenSpaceGuid.PcdGhcbSize|0
+  gUefiCpuPkgTokenSpaceGuid.PcdSevEsIsEnabled|0
+
+  gEfiSecurityPkgTokenSpaceGuid.PcdOptionRomImageVerificationPolicy|0x00
+
+!if $(TPM_ENABLE) == TRUE
+  gEfiSecurityPkgTokenSpaceGuid.PcdTpmInstanceGuid|{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}
+!endif
+
+[PcdsDynamicHii]
+!if $(TPM_ENABLE) == TRUE && $(TPM_CONFIG_ENABLE) == TRUE
+  gEfiSecurityPkgTokenSpaceGuid.PcdTcgPhysicalPresenceInterfaceVer|L"TCG2_VERSION"|gTcg2ConfigFormSetGuid|0x0|"1.3"|NV,BS
+  gEfiSecurityPkgTokenSpaceGuid.PcdTpm2AcpiTableRev|L"TCG2_VERSION"|gTcg2ConfigFormSetGuid|0x8|3|NV,BS
+!endif
+
+################################################################################
+#
+# Components Section - list of all EDK II Modules needed by this Platform.
+#
+################################################################################
+[Components]
+  OvmfPkg/ResetVector/ResetVector.inf
+
+  #
+  # SEC Phase modules
+  #
+  OvmfPkg/Sec/SecMain.inf {
+    <LibraryClasses>
+      NULL|MdeModulePkg/Library/LzmaCustomDecompressLib/LzmaCustomDecompressLib.inf
+  }
+
+  #
+  # PEI Phase modules
+  #
+  MdeModulePkg/Core/Pei/PeiMain.inf
+  MdeModulePkg/Universal/PCD/Pei/Pcd.inf  {
+    <LibraryClasses>
+      PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf
+  }
+  MdeModulePkg/Universal/ReportStatusCodeRouter/Pei/ReportStatusCodeRouterPei.inf {
+    <LibraryClasses>
+      PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf
+  }
+  MdeModulePkg/Universal/StatusCodeHandler/Pei/StatusCodeHandlerPei.inf {
+    <LibraryClasses>
+      PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf
+  }
+  MdeModulePkg/Core/DxeIplPeim/DxeIpl.inf
+
+  OvmfPkg/PlatformPei/PlatformPei.inf
+  UefiCpuPkg/Universal/Acpi/S3Resume2Pei/S3Resume2Pei.inf {
+    <LibraryClasses>
+  }
+  UefiCpuPkg/CpuMpPei/CpuMpPei.inf
+
+!if $(TPM_ENABLE) == TRUE
+  OvmfPkg/Tcg/Tcg2Config/Tcg2ConfigPei.inf
+  SecurityPkg/Tcg/TcgPei/TcgPei.inf
+  SecurityPkg/Tcg/Tcg2Pei/Tcg2Pei.inf {
+    <LibraryClasses>
+      HashLib|SecurityPkg/Library/HashLibBaseCryptoRouter/HashLibBaseCryptoRouterPei.inf
+      NULL|SecurityPkg/Library/HashInstanceLibSha1/HashInstanceLibSha1.inf
+      NULL|SecurityPkg/Library/HashInstanceLibSha256/HashInstanceLibSha256.inf
+      NULL|SecurityPkg/Library/HashInstanceLibSha384/HashInstanceLibSha384.inf
+      NULL|SecurityPkg/Library/HashInstanceLibSha512/HashInstanceLibSha512.inf
+      NULL|SecurityPkg/Library/HashInstanceLibSm3/HashInstanceLibSm3.inf
+  }
+!endif
+
+  #
+  # DXE Phase modules
+  #
+  MdeModulePkg/Core/Dxe/DxeMain.inf {
+    <LibraryClasses>
+      NULL|MdeModulePkg/Library/LzmaCustomDecompressLib/LzmaCustomDecompressLib.inf
+      DevicePathLib|MdePkg/Library/UefiDevicePathLib/UefiDevicePathLib.inf
+  }
+
+  MdeModulePkg/Universal/ReportStatusCodeRouter/RuntimeDxe/ReportStatusCodeRouterRuntimeDxe.inf
+  MdeModulePkg/Universal/StatusCodeHandler/RuntimeDxe/StatusCodeHandlerRuntimeDxe.inf
+  MdeModulePkg/Universal/PCD/Dxe/Pcd.inf  {
+   <LibraryClasses>
+      PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf
+  }
+
+  MdeModulePkg/Core/RuntimeDxe/RuntimeDxe.inf
+
+  MdeModulePkg/Universal/SecurityStubDxe/SecurityStubDxe.inf {
+    <LibraryClasses>
+!if $(TPM_ENABLE) == TRUE
+      NULL|SecurityPkg/Library/DxeTpmMeasureBootLib/DxeTpmMeasureBootLib.inf
+      NULL|SecurityPkg/Library/DxeTpm2MeasureBootLib/DxeTpm2MeasureBootLib.inf
+!endif
+  }
+
+  MdeModulePkg/Universal/EbcDxe/EbcDxe.inf
+  OvmfPkg/8259InterruptControllerDxe/8259.inf
+  UefiCpuPkg/CpuIo2Dxe/CpuIo2Dxe.inf
+  UefiCpuPkg/CpuDxe/CpuDxe.inf
+  OvmfPkg/8254TimerDxe/8254Timer.inf
+  OvmfPkg/IncompatiblePciDeviceSupportDxe/IncompatiblePciDeviceSupport.inf
+  OvmfPkg/PciHotPlugInitDxe/PciHotPlugInit.inf
+  MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciHostBridgeDxe.inf {
+    <LibraryClasses>
+      PciHostBridgeLib|OvmfPkg/Library/PciHostBridgeLib/PciHostBridgeLib.inf
+      NULL|OvmfPkg/Library/PlatformHasIoMmuLib/PlatformHasIoMmuLib.inf
+  }
+  MdeModulePkg/Bus/Pci/PciBusDxe/PciBusDxe.inf {
+    <LibraryClasses>
+      PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf
+  }
+  MdeModulePkg/Universal/ResetSystemRuntimeDxe/ResetSystemRuntimeDxe.inf
+  MdeModulePkg/Universal/Metronome/Metronome.inf
+  PcAtChipsetPkg/PcatRealTimeClockRuntimeDxe/PcatRealTimeClockRuntimeDxe.inf
+  MdeModulePkg/Universal/DriverHealthManagerDxe/DriverHealthManagerDxe.inf
+  MdeModulePkg/Universal/BdsDxe/BdsDxe.inf {
+    <LibraryClasses>
+!ifdef $(CSM_ENABLE)
+      NULL|OvmfPkg/Csm/CsmSupportLib/CsmSupportLib.inf
+      NULL|OvmfPkg/Csm/LegacyBootManagerLib/LegacyBootManagerLib.inf
+!endif
+  }
+  MdeModulePkg/Logo/LogoDxe.inf
+  MdeModulePkg/Application/UiApp/UiApp.inf {
+    <LibraryClasses>
+      NULL|MdeModulePkg/Library/DeviceManagerUiLib/DeviceManagerUiLib.inf
+      NULL|MdeModulePkg/Library/BootManagerUiLib/BootManagerUiLib.inf
+      NULL|MdeModulePkg/Library/BootMaintenanceManagerUiLib/BootMaintenanceManagerUiLib.inf
+!ifdef $(CSM_ENABLE)
+      NULL|OvmfPkg/Csm/LegacyBootManagerLib/LegacyBootManagerLib.inf
+      NULL|OvmfPkg/Csm/LegacyBootMaintUiLib/LegacyBootMaintUiLib.inf
+!endif
+  }
+  OvmfPkg/QemuKernelLoaderFsDxe/QemuKernelLoaderFsDxe.inf
+  OvmfPkg/VirtioPciDeviceDxe/VirtioPciDeviceDxe.inf
+  OvmfPkg/Virtio10Dxe/Virtio10.inf
+  OvmfPkg/VirtioBlkDxe/VirtioBlk.inf
+  OvmfPkg/VirtioScsiDxe/VirtioScsi.inf
+  OvmfPkg/VirtioRngDxe/VirtioRng.inf
+  OvmfPkg/XenIoPciDxe/XenIoPciDxe.inf
+  OvmfPkg/XenBusDxe/XenBusDxe.inf
+  OvmfPkg/XenPvBlkDxe/XenPvBlkDxe.inf
+!if $(PVSCSI_ENABLE) == TRUE
+  OvmfPkg/PvScsiDxe/PvScsiDxe.inf
+!endif
+!if $(MPT_SCSI_ENABLE) == TRUE
+  OvmfPkg/MptScsiDxe/MptScsiDxe.inf
+!endif
+!if $(LSI_SCSI_ENABLE) == TRUE
+  OvmfPkg/LsiScsiDxe/LsiScsiDxe.inf
+!endif
+  MdeModulePkg/Universal/WatchdogTimerDxe/WatchdogTimer.inf
+  MdeModulePkg/Universal/MonotonicCounterRuntimeDxe/MonotonicCounterRuntimeDxe.inf
+  MdeModulePkg/Universal/CapsuleRuntimeDxe/CapsuleRuntimeDxe.inf
+  MdeModulePkg/Universal/Console/ConPlatformDxe/ConPlatformDxe.inf
+  MdeModulePkg/Universal/Console/ConSplitterDxe/ConSplitterDxe.inf
+  MdeModulePkg/Universal/Console/GraphicsConsoleDxe/GraphicsConsoleDxe.inf {
+    <LibraryClasses>
+      PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf
+  }
+  MdeModulePkg/Universal/Console/TerminalDxe/TerminalDxe.inf
+  MdeModulePkg/Universal/DevicePathDxe/DevicePathDxe.inf {
+    <LibraryClasses>
+      DevicePathLib|MdePkg/Library/UefiDevicePathLib/UefiDevicePathLib.inf
+      PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf
+  }
+  MdeModulePkg/Universal/PrintDxe/PrintDxe.inf
+  MdeModulePkg/Universal/Disk/DiskIoDxe/DiskIoDxe.inf
+  MdeModulePkg/Universal/Disk/PartitionDxe/PartitionDxe.inf
+  MdeModulePkg/Universal/Disk/RamDiskDxe/RamDiskDxe.inf
+  MdeModulePkg/Universal/Disk/UnicodeCollation/EnglishDxe/EnglishDxe.inf
+  FatPkg/EnhancedFatDxe/Fat.inf
+  MdeModulePkg/Universal/Disk/UdfDxe/UdfDxe.inf
+  MdeModulePkg/Bus/Scsi/ScsiBusDxe/ScsiBusDxe.inf
+  MdeModulePkg/Bus/Scsi/ScsiDiskDxe/ScsiDiskDxe.inf
+  OvmfPkg/SataControllerDxe/SataControllerDxe.inf
+  MdeModulePkg/Bus/Ata/AtaAtapiPassThru/AtaAtapiPassThru.inf
+  MdeModulePkg/Bus/Ata/AtaBusDxe/AtaBusDxe.inf
+  MdeModulePkg/Bus/Pci/NvmExpressDxe/NvmExpressDxe.inf
+  MdeModulePkg/Universal/HiiDatabaseDxe/HiiDatabaseDxe.inf
+  MdeModulePkg/Universal/SetupBrowserDxe/SetupBrowserDxe.inf
+  MdeModulePkg/Universal/DisplayEngineDxe/DisplayEngineDxe.inf
+  MdeModulePkg/Universal/MemoryTest/NullMemoryTestDxe/NullMemoryTestDxe.inf
+
+!ifndef $(CSM_ENABLE)
+  OvmfPkg/QemuVideoDxe/QemuVideoDxe.inf
+!endif
+  OvmfPkg/QemuRamfbDxe/QemuRamfbDxe.inf
+  OvmfPkg/VirtioGpuDxe/VirtioGpu.inf
+
+  #
+  # ISA Support
+  #
+  OvmfPkg/SioBusDxe/SioBusDxe.inf
+  MdeModulePkg/Bus/Pci/PciSioSerialDxe/PciSioSerialDxe.inf
+  MdeModulePkg/Bus/Isa/Ps2KeyboardDxe/Ps2KeyboardDxe.inf
+
+  #
+  # SMBIOS Support
+  #
+  MdeModulePkg/Universal/SmbiosDxe/SmbiosDxe.inf {
+    <LibraryClasses>
+      NULL|OvmfPkg/Library/SmbiosVersionLib/DetectSmbiosVersionLib.inf
+  }
+  OvmfPkg/SmbiosPlatformDxe/SmbiosPlatformDxe.inf
+
+  #
+  # ACPI Support
+  #
+  MdeModulePkg/Universal/Acpi/AcpiTableDxe/AcpiTableDxe.inf
+  OvmfPkg/AcpiPlatformDxe/AcpiPlatformDxe.inf
+  OvmfPkg/AcpiTables/AcpiTables.inf
+  MdeModulePkg/Universal/Acpi/S3SaveStateDxe/S3SaveStateDxe.inf
+  MdeModulePkg/Universal/Acpi/BootScriptExecutorDxe/BootScriptExecutorDxe.inf
+  MdeModulePkg/Universal/Acpi/BootGraphicsResourceTableDxe/BootGraphicsResourceTableDxe.inf
+
+  OvmfPkg/VirtioNetDxe/VirtioNet.inf
+
+  #
+  # Usb Support
+  #
+  MdeModulePkg/Bus/Pci/UhciDxe/UhciDxe.inf
+  MdeModulePkg/Bus/Pci/EhciDxe/EhciDxe.inf
+  MdeModulePkg/Bus/Pci/XhciDxe/XhciDxe.inf
+  MdeModulePkg/Bus/Usb/UsbBusDxe/UsbBusDxe.inf
+  MdeModulePkg/Bus/Usb/UsbKbDxe/UsbKbDxe.inf
+  MdeModulePkg/Bus/Usb/UsbMassStorageDxe/UsbMassStorageDxe.inf
+
+!ifdef $(CSM_ENABLE)
+  OvmfPkg/Csm/BiosThunk/VideoDxe/VideoDxe.inf {
+    <LibraryClasses>
+      PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf
+  }
+  OvmfPkg/Csm/LegacyBiosDxe/LegacyBiosDxe.inf
+  OvmfPkg/Csm/Csm16/Csm16.inf
+!endif
+
+!if $(TOOL_CHAIN_TAG) != "XCODE5"
+  OvmfPkg/LinuxInitrdDynamicShellCommand/LinuxInitrdDynamicShellCommand.inf {
+    <PcdsFixedAtBuild>
+      gEfiShellPkgTokenSpaceGuid.PcdShellLibAutoInitialize|FALSE
+  }
+!endif
+  ShellPkg/Application/Shell/Shell.inf {
+    <LibraryClasses>
+      ShellCommandLib|ShellPkg/Library/UefiShellCommandLib/UefiShellCommandLib.inf
+      NULL|ShellPkg/Library/UefiShellLevel2CommandsLib/UefiShellLevel2CommandsLib.inf
+      NULL|ShellPkg/Library/UefiShellLevel1CommandsLib/UefiShellLevel1CommandsLib.inf
+      NULL|ShellPkg/Library/UefiShellLevel3CommandsLib/UefiShellLevel3CommandsLib.inf
+      NULL|ShellPkg/Library/UefiShellDriver1CommandsLib/UefiShellDriver1CommandsLib.inf
+      NULL|ShellPkg/Library/UefiShellDebug1CommandsLib/UefiShellDebug1CommandsLib.inf
+      NULL|ShellPkg/Library/UefiShellInstall1CommandsLib/UefiShellInstall1CommandsLib.inf
+      HandleParsingLib|ShellPkg/Library/UefiHandleParsingLib/UefiHandleParsingLib.inf
+      PrintLib|MdePkg/Library/BasePrintLib/BasePrintLib.inf
+      BcfgCommandLib|ShellPkg/Library/UefiShellBcfgCommandLib/UefiShellBcfgCommandLib.inf
+
+    <PcdsFixedAtBuild>
+      gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask|0xFF
+      gEfiShellPkgTokenSpaceGuid.PcdShellLibAutoInitialize|FALSE
+      gEfiMdePkgTokenSpaceGuid.PcdUefiLibMaxPrintBufferSize|8000
+  }
+
+  OvmfPkg/PlatformDxe/Platform.inf
+  OvmfPkg/AmdSevDxe/AmdSevDxe.inf
+  OvmfPkg/IoMmuDxe/IoMmuDxe.inf
+
+  #
+  # Variable driver stack (non-SMM)
+  #
+  OvmfPkg/QemuFlashFvbServicesRuntimeDxe/FvbServicesRuntimeDxe.inf
+  OvmfPkg/EmuVariableFvbRuntimeDxe/Fvb.inf {
+    <LibraryClasses>
+      PlatformFvbLib|OvmfPkg/Library/EmuVariableFvbLib/EmuVariableFvbLib.inf
+  }
+  MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteDxe.inf
+  MdeModulePkg/Universal/Variable/RuntimeDxe/VariableRuntimeDxe.inf {
+    <LibraryClasses>
+      NULL|MdeModulePkg/Library/VarCheckUefiLib/VarCheckUefiLib.inf
+  }
+
+  #
+  # TPM support
+  #
+!if $(TPM_ENABLE) == TRUE
+  SecurityPkg/Tcg/Tcg2Dxe/Tcg2Dxe.inf {
+    <LibraryClasses>
+      Tpm2DeviceLib|SecurityPkg/Library/Tpm2DeviceLibRouter/Tpm2DeviceLibRouterDxe.inf
+      NULL|SecurityPkg/Library/Tpm2DeviceLibDTpm/Tpm2InstanceLibDTpm.inf
+      HashLib|SecurityPkg/Library/HashLibBaseCryptoRouter/HashLibBaseCryptoRouterDxe.inf
+      NULL|SecurityPkg/Library/HashInstanceLibSha1/HashInstanceLibSha1.inf
+      NULL|SecurityPkg/Library/HashInstanceLibSha256/HashInstanceLibSha256.inf
+      NULL|SecurityPkg/Library/HashInstanceLibSha384/HashInstanceLibSha384.inf
+      NULL|SecurityPkg/Library/HashInstanceLibSha512/HashInstanceLibSha512.inf
+      NULL|SecurityPkg/Library/HashInstanceLibSm3/HashInstanceLibSm3.inf
+  }
+!if $(TPM_CONFIG_ENABLE) == TRUE
+  SecurityPkg/Tcg/Tcg2Config/Tcg2ConfigDxe.inf
+!endif
+  SecurityPkg/Tcg/TcgDxe/TcgDxe.inf {
+    <LibraryClasses>
+      Tpm12DeviceLib|SecurityPkg/Library/Tpm12DeviceLibDTpm/Tpm12DeviceLibDTpm.inf
+  }
+!endif
diff --git a/OvmfPkg/AmdSev/AmdSevX64.fdf b/OvmfPkg/AmdSev/AmdSevX64.fdf
new file mode 100644
index 000000000000..4592a4ec067d
--- /dev/null
+++ b/OvmfPkg/AmdSev/AmdSevX64.fdf
@@ -0,0 +1,461 @@
+## @file
+#  Open Virtual Machine Firmware: FDF
+#
+#  Copyright (c) 2006 - 2019, Intel Corporation. All rights reserved.<BR>
+#  (C) Copyright 2016 Hewlett Packard Enterprise Development LP<BR>
+#
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+################################################################################
+
+[Defines]
+!include OvmfPkg/OvmfPkgDefines.fdf.inc
+
+#
+# Build the variable store and the firmware code as one unified flash device
+# image.
+#
+[FD.OVMF]
+BaseAddress   = $(FW_BASE_ADDRESS)
+Size          = $(FW_SIZE)
+ErasePolarity = 1
+BlockSize     = $(BLOCK_SIZE)
+NumBlocks     = $(FW_BLOCKS)
+
+!include OvmfPkg/VarStore.fdf.inc
+
+$(VARS_SIZE)|$(FVMAIN_SIZE)
+FV = FVMAIN_COMPACT
+
+$(SECFV_OFFSET)|$(SECFV_SIZE)
+FV = SECFV
+
+################################################################################
+
+[FD.MEMFD]
+BaseAddress   = $(MEMFD_BASE_ADDRESS)
+Size          = 0xD00000
+ErasePolarity = 1
+BlockSize     = 0x10000
+NumBlocks     = 0xD0
+
+0x000000|0x006000
+gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecPageTablesBase|gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecPageTablesSize
+
+0x006000|0x001000
+gUefiOvmfPkgTokenSpaceGuid.PcdOvmfLockBoxStorageBase|gUefiOvmfPkgTokenSpaceGuid.PcdOvmfLockBoxStorageSize
+
+0x007000|0x001000
+gEfiMdePkgTokenSpaceGuid.PcdGuidedExtractHandlerTableAddress|gUefiOvmfPkgTokenSpaceGuid.PcdGuidedExtractHandlerTableSize
+
+0x008000|0x001000
+gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecGhcbPageTableBase|gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecGhcbPageTableSize
+
+0x009000|0x002000
+gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecGhcbBase|gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecGhcbSize
+
+0x00B000|0x001000
+gUefiCpuPkgTokenSpaceGuid.PcdSevEsWorkAreaBase|gUefiCpuPkgTokenSpaceGuid.PcdSevEsWorkAreaSize
+
+0x010000|0x010000
+gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecPeiTempRamBase|gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecPeiTempRamSize
+
+0x020000|0x0E0000
+gUefiOvmfPkgTokenSpaceGuid.PcdOvmfPeiMemFvBase|gUefiOvmfPkgTokenSpaceGuid.PcdOvmfPeiMemFvSize
+FV = PEIFV
+
+0x100000|0xC00000
+gUefiOvmfPkgTokenSpaceGuid.PcdOvmfDxeMemFvBase|gUefiOvmfPkgTokenSpaceGuid.PcdOvmfDxeMemFvSize
+FV = DXEFV
+
+################################################################################
+
+[FV.SECFV]
+FvNameGuid         = 763BED0D-DE9F-48F5-81F1-3E90E1B1A015
+BlockSize          = 0x1000
+FvAlignment        = 16
+ERASE_POLARITY     = 1
+MEMORY_MAPPED      = TRUE
+STICKY_WRITE       = TRUE
+LOCK_CAP           = TRUE
+LOCK_STATUS        = TRUE
+WRITE_DISABLED_CAP = TRUE
+WRITE_ENABLED_CAP  = TRUE
+WRITE_STATUS       = TRUE
+WRITE_LOCK_CAP     = TRUE
+WRITE_LOCK_STATUS  = TRUE
+READ_DISABLED_CAP  = TRUE
+READ_ENABLED_CAP   = TRUE
+READ_STATUS        = TRUE
+READ_LOCK_CAP      = TRUE
+READ_LOCK_STATUS   = TRUE
+
+#
+# SEC Phase modules
+#
+# The code in this FV handles the initial firmware startup, and
+# decompresses the PEI and DXE FVs which handles the rest of the boot sequence.
+#
+INF  OvmfPkg/Sec/SecMain.inf
+
+INF  RuleOverride=RESET_VECTOR OvmfPkg/ResetVector/ResetVector.inf
+
+################################################################################
+[FV.PEIFV]
+FvNameGuid         = 6938079B-B503-4E3D-9D24-B28337A25806
+BlockSize          = 0x10000
+FvAlignment        = 16
+ERASE_POLARITY     = 1
+MEMORY_MAPPED      = TRUE
+STICKY_WRITE       = TRUE
+LOCK_CAP           = TRUE
+LOCK_STATUS        = TRUE
+WRITE_DISABLED_CAP = TRUE
+WRITE_ENABLED_CAP  = TRUE
+WRITE_STATUS       = TRUE
+WRITE_LOCK_CAP     = TRUE
+WRITE_LOCK_STATUS  = TRUE
+READ_DISABLED_CAP  = TRUE
+READ_ENABLED_CAP   = TRUE
+READ_STATUS        = TRUE
+READ_LOCK_CAP      = TRUE
+READ_LOCK_STATUS   = TRUE
+
+APRIORI PEI {
+  INF  MdeModulePkg/Universal/PCD/Pei/Pcd.inf
+}
+
+#
+#  PEI Phase modules
+#
+INF  MdeModulePkg/Core/Pei/PeiMain.inf
+INF  MdeModulePkg/Universal/PCD/Pei/Pcd.inf
+INF  MdeModulePkg/Universal/ReportStatusCodeRouter/Pei/ReportStatusCodeRouterPei.inf
+INF  MdeModulePkg/Universal/StatusCodeHandler/Pei/StatusCodeHandlerPei.inf
+INF  OvmfPkg/PlatformPei/PlatformPei.inf
+INF  MdeModulePkg/Core/DxeIplPeim/DxeIpl.inf
+INF  UefiCpuPkg/Universal/Acpi/S3Resume2Pei/S3Resume2Pei.inf
+INF  UefiCpuPkg/CpuMpPei/CpuMpPei.inf
+
+!if $(TPM_ENABLE) == TRUE
+INF  OvmfPkg/Tcg/Tcg2Config/Tcg2ConfigPei.inf
+INF  SecurityPkg/Tcg/TcgPei/TcgPei.inf
+INF  SecurityPkg/Tcg/Tcg2Pei/Tcg2Pei.inf
+!endif
+
+################################################################################
+
+[FV.DXEFV]
+FvForceRebase      = FALSE
+FvNameGuid         = 7CB8BDC9-F8EB-4F34-AAEA-3EE4AF6516A1
+BlockSize          = 0x10000
+FvAlignment        = 16
+ERASE_POLARITY     = 1
+MEMORY_MAPPED      = TRUE
+STICKY_WRITE       = TRUE
+LOCK_CAP           = TRUE
+LOCK_STATUS        = TRUE
+WRITE_DISABLED_CAP = TRUE
+WRITE_ENABLED_CAP  = TRUE
+WRITE_STATUS       = TRUE
+WRITE_LOCK_CAP     = TRUE
+WRITE_LOCK_STATUS  = TRUE
+READ_DISABLED_CAP  = TRUE
+READ_ENABLED_CAP   = TRUE
+READ_STATUS        = TRUE
+READ_LOCK_CAP      = TRUE
+READ_LOCK_STATUS   = TRUE
+
+APRIORI DXE {
+  INF  MdeModulePkg/Universal/DevicePathDxe/DevicePathDxe.inf
+  INF  MdeModulePkg/Universal/PCD/Dxe/Pcd.inf
+  INF  OvmfPkg/AmdSevDxe/AmdSevDxe.inf
+  INF  OvmfPkg/QemuFlashFvbServicesRuntimeDxe/FvbServicesRuntimeDxe.inf
+}
+
+#
+# DXE Phase modules
+#
+INF  MdeModulePkg/Core/Dxe/DxeMain.inf
+
+INF  MdeModulePkg/Universal/ReportStatusCodeRouter/RuntimeDxe/ReportStatusCodeRouterRuntimeDxe.inf
+INF  MdeModulePkg/Universal/StatusCodeHandler/RuntimeDxe/StatusCodeHandlerRuntimeDxe.inf
+INF  MdeModulePkg/Universal/PCD/Dxe/Pcd.inf
+
+INF  MdeModulePkg/Core/RuntimeDxe/RuntimeDxe.inf
+INF  MdeModulePkg/Universal/SecurityStubDxe/SecurityStubDxe.inf
+INF  MdeModulePkg/Universal/EbcDxe/EbcDxe.inf
+INF  OvmfPkg/8259InterruptControllerDxe/8259.inf
+INF  UefiCpuPkg/CpuIo2Dxe/CpuIo2Dxe.inf
+INF  UefiCpuPkg/CpuDxe/CpuDxe.inf
+INF  OvmfPkg/8254TimerDxe/8254Timer.inf
+INF  OvmfPkg/IncompatiblePciDeviceSupportDxe/IncompatiblePciDeviceSupport.inf
+INF  OvmfPkg/PciHotPlugInitDxe/PciHotPlugInit.inf
+INF  MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciHostBridgeDxe.inf
+INF  MdeModulePkg/Bus/Pci/PciBusDxe/PciBusDxe.inf
+INF  MdeModulePkg/Universal/ResetSystemRuntimeDxe/ResetSystemRuntimeDxe.inf
+INF  MdeModulePkg/Universal/Metronome/Metronome.inf
+INF  PcAtChipsetPkg/PcatRealTimeClockRuntimeDxe/PcatRealTimeClockRuntimeDxe.inf
+
+INF  OvmfPkg/VirtioPciDeviceDxe/VirtioPciDeviceDxe.inf
+INF  OvmfPkg/Virtio10Dxe/Virtio10.inf
+INF  OvmfPkg/VirtioBlkDxe/VirtioBlk.inf
+INF  OvmfPkg/VirtioScsiDxe/VirtioScsi.inf
+INF  OvmfPkg/VirtioRngDxe/VirtioRng.inf
+INF  OvmfPkg/XenIoPciDxe/XenIoPciDxe.inf
+INF  OvmfPkg/XenBusDxe/XenBusDxe.inf
+INF  OvmfPkg/XenPvBlkDxe/XenPvBlkDxe.inf
+!if $(PVSCSI_ENABLE) == TRUE
+INF  OvmfPkg/PvScsiDxe/PvScsiDxe.inf
+!endif
+!if $(MPT_SCSI_ENABLE) == TRUE
+INF  OvmfPkg/MptScsiDxe/MptScsiDxe.inf
+!endif
+!if $(LSI_SCSI_ENABLE) == TRUE
+INF  OvmfPkg/LsiScsiDxe/LsiScsiDxe.inf
+!endif
+
+INF  MdeModulePkg/Universal/WatchdogTimerDxe/WatchdogTimer.inf
+INF  MdeModulePkg/Universal/MonotonicCounterRuntimeDxe/MonotonicCounterRuntimeDxe.inf
+INF  MdeModulePkg/Universal/CapsuleRuntimeDxe/CapsuleRuntimeDxe.inf
+INF  MdeModulePkg/Universal/Console/ConPlatformDxe/ConPlatformDxe.inf
+INF  MdeModulePkg/Universal/Console/ConSplitterDxe/ConSplitterDxe.inf
+INF  MdeModulePkg/Universal/Console/GraphicsConsoleDxe/GraphicsConsoleDxe.inf
+INF  MdeModulePkg/Universal/Console/TerminalDxe/TerminalDxe.inf
+INF  MdeModulePkg/Universal/DriverHealthManagerDxe/DriverHealthManagerDxe.inf
+INF  MdeModulePkg/Universal/BdsDxe/BdsDxe.inf
+INF  MdeModulePkg/Application/UiApp/UiApp.inf
+INF  OvmfPkg/QemuKernelLoaderFsDxe/QemuKernelLoaderFsDxe.inf
+INF  MdeModulePkg/Universal/DevicePathDxe/DevicePathDxe.inf
+INF  MdeModulePkg/Universal/PrintDxe/PrintDxe.inf
+INF  MdeModulePkg/Universal/Disk/DiskIoDxe/DiskIoDxe.inf
+INF  MdeModulePkg/Universal/Disk/PartitionDxe/PartitionDxe.inf
+INF  MdeModulePkg/Universal/Disk/RamDiskDxe/RamDiskDxe.inf
+INF  MdeModulePkg/Universal/Disk/UnicodeCollation/EnglishDxe/EnglishDxe.inf
+INF  MdeModulePkg/Bus/Scsi/ScsiBusDxe/ScsiBusDxe.inf
+INF  MdeModulePkg/Bus/Scsi/ScsiDiskDxe/ScsiDiskDxe.inf
+INF  OvmfPkg/SataControllerDxe/SataControllerDxe.inf
+INF  MdeModulePkg/Bus/Ata/AtaAtapiPassThru/AtaAtapiPassThru.inf
+INF  MdeModulePkg/Bus/Ata/AtaBusDxe/AtaBusDxe.inf
+INF  MdeModulePkg/Bus/Pci/NvmExpressDxe/NvmExpressDxe.inf
+INF  MdeModulePkg/Universal/HiiDatabaseDxe/HiiDatabaseDxe.inf
+INF  MdeModulePkg/Universal/SetupBrowserDxe/SetupBrowserDxe.inf
+INF  MdeModulePkg/Universal/DisplayEngineDxe/DisplayEngineDxe.inf
+INF  MdeModulePkg/Universal/MemoryTest/NullMemoryTestDxe/NullMemoryTestDxe.inf
+
+INF  OvmfPkg/SioBusDxe/SioBusDxe.inf
+!if $(SOURCE_DEBUG_ENABLE) == FALSE
+INF  MdeModulePkg/Bus/Pci/PciSioSerialDxe/PciSioSerialDxe.inf
+!endif
+INF  MdeModulePkg/Bus/Isa/Ps2KeyboardDxe/Ps2KeyboardDxe.inf
+
+INF  MdeModulePkg/Universal/SmbiosDxe/SmbiosDxe.inf
+INF  OvmfPkg/SmbiosPlatformDxe/SmbiosPlatformDxe.inf
+
+INF  MdeModulePkg/Universal/Acpi/AcpiTableDxe/AcpiTableDxe.inf
+INF  OvmfPkg/AcpiPlatformDxe/AcpiPlatformDxe.inf
+INF  RuleOverride=ACPITABLE OvmfPkg/AcpiTables/AcpiTables.inf
+INF  MdeModulePkg/Universal/Acpi/S3SaveStateDxe/S3SaveStateDxe.inf
+INF  MdeModulePkg/Universal/Acpi/BootScriptExecutorDxe/BootScriptExecutorDxe.inf
+INF  MdeModulePkg/Universal/Acpi/BootGraphicsResourceTableDxe/BootGraphicsResourceTableDxe.inf
+
+INF  FatPkg/EnhancedFatDxe/Fat.inf
+INF  MdeModulePkg/Universal/Disk/UdfDxe/UdfDxe.inf
+
+!if $(TOOL_CHAIN_TAG) != "XCODE5"
+INF  OvmfPkg/LinuxInitrdDynamicShellCommand/LinuxInitrdDynamicShellCommand.inf
+!endif
+INF  ShellPkg/Application/Shell/Shell.inf
+
+INF MdeModulePkg/Logo/LogoDxe.inf
+
+#
+# Usb Support
+#
+INF  MdeModulePkg/Bus/Pci/UhciDxe/UhciDxe.inf
+INF  MdeModulePkg/Bus/Pci/EhciDxe/EhciDxe.inf
+INF  MdeModulePkg/Bus/Pci/XhciDxe/XhciDxe.inf
+INF  MdeModulePkg/Bus/Usb/UsbBusDxe/UsbBusDxe.inf
+INF  MdeModulePkg/Bus/Usb/UsbKbDxe/UsbKbDxe.inf
+INF  MdeModulePkg/Bus/Usb/UsbMassStorageDxe/UsbMassStorageDxe.inf
+
+!ifdef $(CSM_ENABLE)
+INF  OvmfPkg/Csm/BiosThunk/VideoDxe/VideoDxe.inf
+INF  OvmfPkg/Csm/LegacyBiosDxe/LegacyBiosDxe.inf
+INF  RuleOverride=CSM OvmfPkg/Csm/Csm16/Csm16.inf
+!else
+INF  OvmfPkg/QemuVideoDxe/QemuVideoDxe.inf
+!endif
+
+INF  OvmfPkg/QemuRamfbDxe/QemuRamfbDxe.inf
+INF  OvmfPkg/VirtioGpuDxe/VirtioGpu.inf
+INF  OvmfPkg/PlatformDxe/Platform.inf
+INF  OvmfPkg/AmdSevDxe/AmdSevDxe.inf
+INF  OvmfPkg/IoMmuDxe/IoMmuDxe.inf
+
+
+#
+# Variable driver stack (non-SMM)
+#
+INF  OvmfPkg/QemuFlashFvbServicesRuntimeDxe/FvbServicesRuntimeDxe.inf
+INF  OvmfPkg/EmuVariableFvbRuntimeDxe/Fvb.inf
+INF  MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteDxe.inf
+INF  MdeModulePkg/Universal/Variable/RuntimeDxe/VariableRuntimeDxe.inf
+
+#
+# TPM support
+#
+!if $(TPM_ENABLE) == TRUE
+INF  SecurityPkg/Tcg/TcgDxe/TcgDxe.inf
+INF  SecurityPkg/Tcg/Tcg2Dxe/Tcg2Dxe.inf
+!if $(TPM_CONFIG_ENABLE) == TRUE
+INF  SecurityPkg/Tcg/Tcg2Config/Tcg2ConfigDxe.inf
+!endif
+!endif
+
+################################################################################
+
+[FV.FVMAIN_COMPACT]
+FvNameGuid         = 48DB5E17-707C-472D-91CD-1613E7EF51B0
+FvAlignment        = 16
+ERASE_POLARITY     = 1
+MEMORY_MAPPED      = TRUE
+STICKY_WRITE       = TRUE
+LOCK_CAP           = TRUE
+LOCK_STATUS        = TRUE
+WRITE_DISABLED_CAP = TRUE
+WRITE_ENABLED_CAP  = TRUE
+WRITE_STATUS       = TRUE
+WRITE_LOCK_CAP     = TRUE
+WRITE_LOCK_STATUS  = TRUE
+READ_DISABLED_CAP  = TRUE
+READ_ENABLED_CAP   = TRUE
+READ_STATUS        = TRUE
+READ_LOCK_CAP      = TRUE
+READ_LOCK_STATUS   = TRUE
+
+FILE FV_IMAGE = 9E21FD93-9C72-4c15-8C4B-E77F1DB2D792 {
+   SECTION GUIDED EE4E5898-3914-4259-9D6E-DC7BD79403CF PROCESSING_REQUIRED = TRUE {
+     #
+     # These firmware volumes will have files placed in them uncompressed,
+     # and then both firmware volumes will be compressed in a single
+     # compression operation in order to achieve better overall compression.
+     #
+     SECTION FV_IMAGE = PEIFV
+     SECTION FV_IMAGE = DXEFV
+   }
+ }
+
+!include OvmfPkg/FvmainCompactScratchEnd.fdf.inc
+
+################################################################################
+
+[Rule.Common.SEC]
+  FILE SEC = $(NAMED_GUID) {
+    PE32     PE32           $(INF_OUTPUT)/$(MODULE_NAME).efi
+    UI       STRING ="$(MODULE_NAME)" Optional
+    VERSION  STRING ="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER)
+  }
+
+[Rule.Common.PEI_CORE]
+  FILE PEI_CORE = $(NAMED_GUID) {
+    PE32     PE32   Align=Auto    $(INF_OUTPUT)/$(MODULE_NAME).efi
+    UI       STRING ="$(MODULE_NAME)" Optional
+    VERSION  STRING ="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER)
+  }
+
+[Rule.Common.PEIM]
+  FILE PEIM = $(NAMED_GUID) {
+     PEI_DEPEX PEI_DEPEX Optional        $(INF_OUTPUT)/$(MODULE_NAME).depex
+     PE32      PE32   Align=Auto         $(INF_OUTPUT)/$(MODULE_NAME).efi
+     UI       STRING="$(MODULE_NAME)" Optional
+     VERSION  STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER)
+  }
+
+[Rule.Common.DXE_CORE]
+  FILE DXE_CORE = $(NAMED_GUID) {
+    PE32     PE32           $(INF_OUTPUT)/$(MODULE_NAME).efi
+    UI       STRING="$(MODULE_NAME)" Optional
+    VERSION  STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER)
+  }
+
+[Rule.Common.DXE_DRIVER]
+  FILE DRIVER = $(NAMED_GUID) {
+    DXE_DEPEX    DXE_DEPEX Optional      $(INF_OUTPUT)/$(MODULE_NAME).depex
+    PE32     PE32                    $(INF_OUTPUT)/$(MODULE_NAME).efi
+    UI       STRING="$(MODULE_NAME)" Optional
+    VERSION  STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER)
+    RAW ACPI  Optional               |.acpi
+    RAW ASL   Optional               |.aml
+  }
+
+[Rule.Common.DXE_RUNTIME_DRIVER]
+  FILE DRIVER = $(NAMED_GUID) {
+    DXE_DEPEX    DXE_DEPEX Optional      $(INF_OUTPUT)/$(MODULE_NAME).depex
+    PE32     PE32                    $(INF_OUTPUT)/$(MODULE_NAME).efi
+    UI       STRING="$(MODULE_NAME)" Optional
+    VERSION  STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER)
+  }
+
+[Rule.Common.UEFI_DRIVER]
+  FILE DRIVER = $(NAMED_GUID) {
+    DXE_DEPEX    DXE_DEPEX Optional      $(INF_OUTPUT)/$(MODULE_NAME).depex
+    PE32     PE32                    $(INF_OUTPUT)/$(MODULE_NAME).efi
+    UI       STRING="$(MODULE_NAME)" Optional
+    VERSION  STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER)
+  }
+
+[Rule.Common.UEFI_DRIVER.BINARY]
+  FILE DRIVER = $(NAMED_GUID) {
+    DXE_DEPEX DXE_DEPEX Optional      |.depex
+    PE32      PE32                    |.efi
+    UI        STRING="$(MODULE_NAME)" Optional
+    VERSION   STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER)
+  }
+
+[Rule.Common.UEFI_APPLICATION]
+  FILE APPLICATION = $(NAMED_GUID) {
+    PE32     PE32                    $(INF_OUTPUT)/$(MODULE_NAME).efi
+    UI       STRING="$(MODULE_NAME)" Optional
+    VERSION  STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER)
+  }
+
+[Rule.Common.UEFI_APPLICATION.BINARY]
+  FILE APPLICATION = $(NAMED_GUID) {
+    PE32      PE32                    |.efi
+    UI        STRING="$(MODULE_NAME)" Optional
+    VERSION   STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER)
+  }
+
+[Rule.Common.USER_DEFINED.ACPITABLE]
+  FILE FREEFORM = $(NAMED_GUID) {
+    RAW ACPI               |.acpi
+    RAW ASL                |.aml
+  }
+
+[Rule.Common.USER_DEFINED.CSM]
+  FILE FREEFORM = $(NAMED_GUID) {
+    RAW BIN                |.bin
+  }
+
+[Rule.Common.SEC.RESET_VECTOR]
+  FILE RAW = $(NAMED_GUID) {
+    RAW BIN   Align = 16   |.bin
+  }
+
+[Rule.Common.SMM_CORE]
+  FILE SMM_CORE = $(NAMED_GUID) {
+    PE32     PE32           $(INF_OUTPUT)/$(MODULE_NAME).efi
+    UI       STRING="$(MODULE_NAME)" Optional
+    VERSION  STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER)
+  }
+
+[Rule.Common.DXE_SMM_DRIVER]
+  FILE SMM = $(NAMED_GUID) {
+    SMM_DEPEX    SMM_DEPEX Optional      $(INF_OUTPUT)/$(MODULE_NAME).depex
+    PE32     PE32                    $(INF_OUTPUT)/$(MODULE_NAME).efi
+    UI       STRING="$(MODULE_NAME)" Optional
+    VERSION  STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER)
+  }
-- 
2.26.2


^ permalink raw reply related	[flat|nested] 37+ messages in thread

* [PATCH v2 2/6] OvmfPkg/AmdSev: add Grub Firmware Volume Package
  2020-11-20 18:45 [PATCH v2 0/6] SEV Encrypted Boot for Ovmf James Bottomley
  2020-11-20 18:45 ` [PATCH v2 1/6] OvmfPkg/Amdsev: Base commit to build encrypted boot specific OVMF James Bottomley
@ 2020-11-20 18:45 ` James Bottomley
  2020-11-23 21:08   ` Laszlo Ersek
  2020-11-20 18:45 ` [PATCH v2 3/6] OvmfPkg: convert ES Reset Block structure to be guided James Bottomley
                   ` (3 subsequent siblings)
  5 siblings, 1 reply; 37+ messages in thread
From: James Bottomley @ 2020-11-20 18:45 UTC (permalink / raw)
  To: devel
  Cc: dovmurik, Dov.Murik1, ashish.kalra, brijesh.singh, tobin,
	david.kaplan, jon.grimm, thomas.lendacky, jejb, frankeh,
	Dr . David Alan Gilbert, Laszlo Ersek

This is used to package up the grub bootloader into a firmware volume
where it can be executed as a shell like the UEFI Shell.  Grub itself
is built as a minimal entity into a Fv and then added as a boot
option.  By default the UEFI shell isn't built but for debugging
purposes it can be enabled and will then be presented as a boot option
(This should never be allowed for secure boot in an external data
centre but may be useful for local debugging).  Finally all other boot
options except grub and possibly the shell are stripped and the boot
timeout forced to 0 so the system will not enter a setup menu and will
only boot to grub.  This is done by copying the
Library/PlatformBootManagerLib into Library/PlatformBootManagerLibGrub
and then customizing it.

Boot failure is fatal to try to prevent secret theft.

Ref: https://bugzilla.tianocore.org/show_bug.cgi?id=3077
Signed-off-by: James Bottomley <jejb@linux.ibm.com>

---

v2: strip out s3 and qemu boot contacts make grub script robust and
    don't build grub.efi each time
---
 OvmfPkg/OvmfPkg.dec                           |    1 +
 OvmfPkg/AmdSev/AmdSevX64.dsc                  |   21 +-
 OvmfPkg/AmdSev/AmdSevX64.fdf                  |    7 +-
 OvmfPkg/AmdSev/Grub/Grub.inf                  |   37 +
 .../PlatformBootManagerLibGrub.inf            |   79 +
 .../PlatformBootManagerLibGrub/BdsPlatform.h  |  175 ++
 .../PlatformBootManagerLibGrub/BdsPlatform.c  | 1483 +++++++++++++++++
 .../PlatformBootManagerLibGrub/PlatformData.c |  213 +++
 OvmfPkg/AmdSev/Grub/.gitignore                |    1 +
 OvmfPkg/AmdSev/Grub/grub.cfg                  |   46 +
 OvmfPkg/AmdSev/Grub/grub.sh                   |   92 +
 11 files changed, 2146 insertions(+), 9 deletions(-)
 create mode 100644 OvmfPkg/AmdSev/Grub/Grub.inf
 create mode 100644 OvmfPkg/Library/PlatformBootManagerLibGrub/PlatformBootManagerLibGrub.inf
 create mode 100644 OvmfPkg/Library/PlatformBootManagerLibGrub/BdsPlatform.h
 create mode 100644 OvmfPkg/Library/PlatformBootManagerLibGrub/BdsPlatform.c
 create mode 100644 OvmfPkg/Library/PlatformBootManagerLibGrub/PlatformData.c
 create mode 100644 OvmfPkg/AmdSev/Grub/.gitignore
 create mode 100644 OvmfPkg/AmdSev/Grub/grub.cfg
 create mode 100644 OvmfPkg/AmdSev/Grub/grub.sh

diff --git a/OvmfPkg/OvmfPkg.dec b/OvmfPkg/OvmfPkg.dec
index 6abde4fd9351..3fbf7a0ee1a4 100644
--- a/OvmfPkg/OvmfPkg.dec
+++ b/OvmfPkg/OvmfPkg.dec
@@ -116,6 +116,7 @@ [Guids]
   gEfiLegacyDevOrderVariableGuid        = {0xa56074db, 0x65fe, 0x45f7, {0xbd, 0x21, 0x2d, 0x2b, 0xdd, 0x8e, 0x96, 0x52}}
   gLinuxEfiInitrdMediaGuid              = {0x5568e427, 0x68fc, 0x4f3d, {0xac, 0x74, 0xca, 0x55, 0x52, 0x31, 0xcc, 0x68}}
   gQemuKernelLoaderFsMediaGuid          = {0x1428f772, 0xb64a, 0x441e, {0xb8, 0xc3, 0x9e, 0xbd, 0xd7, 0xf8, 0x93, 0xc7}}
+  gGrubFileGuid                         = {0xb5ae312c, 0xbc8a, 0x43b1, {0x9c, 0x62, 0xeb, 0xb8, 0x26, 0xdd, 0x5d, 0x07}}
 
 [Ppis]
   # PPI whose presence in the PPI database signals that the TPM base address
diff --git a/OvmfPkg/AmdSev/AmdSevX64.dsc b/OvmfPkg/AmdSev/AmdSevX64.dsc
index 852be757bfbe..c0b4e1b274fc 100644
--- a/OvmfPkg/AmdSev/AmdSevX64.dsc
+++ b/OvmfPkg/AmdSev/AmdSevX64.dsc
@@ -25,6 +25,7 @@ [Defines]
   BUILD_TARGETS                  = NOOPT|DEBUG|RELEASE
   SKUID_IDENTIFIER               = DEFAULT
   FLASH_DEFINITION               = OvmfPkg/AmdSev/AmdSevX64.fdf
+  PREBUILD                       = sh OvmfPkg/AmdSev/Grub/grub.sh
 
   #
   # Defines for default states.  These can be changed on the command line.
@@ -34,6 +35,11 @@ [Defines]
   DEFINE TPM_ENABLE              = FALSE
   DEFINE TPM_CONFIG_ENABLE       = FALSE
 
+  #
+  # Shell can be useful for debugging but should not be enabled for production
+  #
+  DEFINE BUILD_SHELL             = FALSE
+
   #
   # Device drivers
   #
@@ -149,7 +155,6 @@ [LibraryClasses]
   UefiDriverEntryPoint|MdePkg/Library/UefiDriverEntryPoint/UefiDriverEntryPoint.inf
   UefiApplicationEntryPoint|MdePkg/Library/UefiApplicationEntryPoint/UefiApplicationEntryPoint.inf
   DevicePathLib|MdePkg/Library/UefiDevicePathLibDevicePathProtocol/UefiDevicePathLibDevicePathProtocol.inf
-  NvVarsFileLib|OvmfPkg/Library/NvVarsFileLib/NvVarsFileLib.inf
   FileHandleLib|MdePkg/Library/UefiFileHandleLib/UefiFileHandleLib.inf
   UefiCpuLib|UefiCpuPkg/Library/BaseUefiCpuLib/BaseUefiCpuLib.inf
   SecurityManagementLib|MdeModulePkg/Library/DxeSecurityManagementLib/DxeSecurityManagementLib.inf
@@ -183,9 +188,11 @@ [LibraryClasses]
   VarCheckLib|MdeModulePkg/Library/VarCheckLib/VarCheckLib.inf
 
 
+!if $(BUILD_SHELL) == TRUE
   ShellLib|ShellPkg/Library/UefiShellLib/UefiShellLib.inf
   ShellCEntryLib|ShellPkg/Library/UefiShellCEntryLib/UefiShellCEntryLib.inf
-  S3BootScriptLib|MdeModulePkg/Library/PiDxeS3BootScriptLib/DxeS3BootScriptLib.inf
+!endif
+
   SmbusLib|MdePkg/Library/BaseSmbusLibNull/BaseSmbusLibNull.inf
   OrderedCollectionLib|MdePkg/Library/BaseOrderedCollectionRedBlackTreeLib/BaseOrderedCollectionRedBlackTreeLib.inf
   XenHypercallLib|OvmfPkg/Library/XenHypercallLib/XenHypercallLib.inf
@@ -341,7 +348,7 @@ [LibraryClasses.common.DXE_DRIVER]
 !else
   DebugLib|OvmfPkg/Library/PlatformDebugLibIoPort/PlatformDebugLibIoPort.inf
 !endif
-  PlatformBootManagerLib|OvmfPkg/Library/PlatformBootManagerLib/PlatformBootManagerLib.inf
+  PlatformBootManagerLib|OvmfPkg/Library/PlatformBootManagerLibGrub/PlatformBootManagerLibGrub.inf
   PlatformBmPrintScLib|OvmfPkg/Library/PlatformBmPrintScLib/PlatformBmPrintScLib.inf
   QemuBootOrderLib|OvmfPkg/Library/QemuBootOrderLib/QemuBootOrderLib.inf
   CpuExceptionHandlerLib|UefiCpuPkg/Library/CpuExceptionHandlerLib/DxeCpuExceptionHandlerLib.inf
@@ -510,6 +517,7 @@ [PcdsFixedAtBuild]
   # Point to the MdeModulePkg/Application/UiApp/UiApp.inf
   gEfiMdeModulePkgTokenSpaceGuid.PcdBootManagerMenuFile|{ 0x21, 0xaa, 0x2c, 0x46, 0x14, 0x76, 0x03, 0x45, 0x83, 0x6e, 0x8a, 0xb6, 0xf4, 0x66, 0x23, 0x31 }
 
+  gEfiMdeModulePkgTokenSpaceGuid.PcdConInConnectOnDemand|TRUE
 ################################################################################
 #
 # Pcd Dynamic Section - list of all EDK II PCD Entries defined by this Platform
@@ -774,8 +782,6 @@ [Components]
   MdeModulePkg/Universal/Acpi/AcpiTableDxe/AcpiTableDxe.inf
   OvmfPkg/AcpiPlatformDxe/AcpiPlatformDxe.inf
   OvmfPkg/AcpiTables/AcpiTables.inf
-  MdeModulePkg/Universal/Acpi/S3SaveStateDxe/S3SaveStateDxe.inf
-  MdeModulePkg/Universal/Acpi/BootScriptExecutorDxe/BootScriptExecutorDxe.inf
   MdeModulePkg/Universal/Acpi/BootGraphicsResourceTableDxe/BootGraphicsResourceTableDxe.inf
 
   OvmfPkg/VirtioNetDxe/VirtioNet.inf
@@ -799,12 +805,14 @@ [Components]
   OvmfPkg/Csm/Csm16/Csm16.inf
 !endif
 
-!if $(TOOL_CHAIN_TAG) != "XCODE5"
+!if $(TOOL_CHAIN_TAG) != "XCODE5" && $(BUILD_SHELL) == TRUE
   OvmfPkg/LinuxInitrdDynamicShellCommand/LinuxInitrdDynamicShellCommand.inf {
     <PcdsFixedAtBuild>
       gEfiShellPkgTokenSpaceGuid.PcdShellLibAutoInitialize|FALSE
   }
 !endif
+  OvmfPkg/AmdSev/Grub/Grub.inf
+!if $(BUILD_SHELL) == TRUE
   ShellPkg/Application/Shell/Shell.inf {
     <LibraryClasses>
       ShellCommandLib|ShellPkg/Library/UefiShellCommandLib/UefiShellCommandLib.inf
@@ -823,6 +831,7 @@ [Components]
       gEfiShellPkgTokenSpaceGuid.PcdShellLibAutoInitialize|FALSE
       gEfiMdePkgTokenSpaceGuid.PcdUefiLibMaxPrintBufferSize|8000
   }
+!endif
 
   OvmfPkg/PlatformDxe/Platform.inf
   OvmfPkg/AmdSevDxe/AmdSevDxe.inf
diff --git a/OvmfPkg/AmdSev/AmdSevX64.fdf b/OvmfPkg/AmdSev/AmdSevX64.fdf
index 4592a4ec067d..97f031950abd 100644
--- a/OvmfPkg/AmdSev/AmdSevX64.fdf
+++ b/OvmfPkg/AmdSev/AmdSevX64.fdf
@@ -257,17 +257,18 @@ [FV.DXEFV]
 INF  MdeModulePkg/Universal/Acpi/AcpiTableDxe/AcpiTableDxe.inf
 INF  OvmfPkg/AcpiPlatformDxe/AcpiPlatformDxe.inf
 INF  RuleOverride=ACPITABLE OvmfPkg/AcpiTables/AcpiTables.inf
-INF  MdeModulePkg/Universal/Acpi/S3SaveStateDxe/S3SaveStateDxe.inf
-INF  MdeModulePkg/Universal/Acpi/BootScriptExecutorDxe/BootScriptExecutorDxe.inf
 INF  MdeModulePkg/Universal/Acpi/BootGraphicsResourceTableDxe/BootGraphicsResourceTableDxe.inf
 
 INF  FatPkg/EnhancedFatDxe/Fat.inf
 INF  MdeModulePkg/Universal/Disk/UdfDxe/UdfDxe.inf
 
-!if $(TOOL_CHAIN_TAG) != "XCODE5"
+!if $(TOOL_CHAIN_TAG) != "XCODE5" && $(BUILD_SHELL) == TRUE
 INF  OvmfPkg/LinuxInitrdDynamicShellCommand/LinuxInitrdDynamicShellCommand.inf
 !endif
+INF  OvmfPkg/AmdSev/Grub/Grub.inf
+!if $(BUILD_SHELL) == TRUE
 INF  ShellPkg/Application/Shell/Shell.inf
+!endif
 
 INF MdeModulePkg/Logo/LogoDxe.inf
 
diff --git a/OvmfPkg/AmdSev/Grub/Grub.inf b/OvmfPkg/AmdSev/Grub/Grub.inf
new file mode 100644
index 000000000000..211e7b8b2be6
--- /dev/null
+++ b/OvmfPkg/AmdSev/Grub/Grub.inf
@@ -0,0 +1,37 @@
+##  @file
+#  Create a Firmware Volume based Grub Bootloaded
+#
+#  Copyright (C) 2020 James Bottomley, IBM Corporation.
+#
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x00010006
+  BASE_NAME                      = Grub
+  # This is gGrubFileGuid
+  FILE_GUID                      = b5ae312c-bc8a-43b1-9c62-ebb826dd5d07
+  MODULE_TYPE                    = UEFI_APPLICATION
+  VERSION_STRING                 = 1.0
+  ENTRY_POINT                    = UefiMain
+
+[Packages]
+  OvmfPkg/OvmfPkg.dec
+
+#
+# The following information is for reference only and not required by
+# the build tools.
+#
+#  VALID_ARCHITECTURES           = X64
+#
+
+##
+# Note: The version of grub.efi this picks up can be generated by
+# grub.sh which must be specified as a PREBUILD in the .dsc file or
+# you can simply move a precompiled grub into here and not do the
+# PREBUILD)
+##
+[Binaries]
+   PE32|grub.efi|*
+
diff --git a/OvmfPkg/Library/PlatformBootManagerLibGrub/PlatformBootManagerLibGrub.inf b/OvmfPkg/Library/PlatformBootManagerLibGrub/PlatformBootManagerLibGrub.inf
new file mode 100644
index 000000000000..a997d7586e6a
--- /dev/null
+++ b/OvmfPkg/Library/PlatformBootManagerLibGrub/PlatformBootManagerLibGrub.inf
@@ -0,0 +1,79 @@
+## @file
+#  Platform BDS customizations library.
+#
+#  Copyright (c) 2007 - 2019, Intel Corporation. All rights reserved.<BR>
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = PlatformBootManagerLibGrub
+  FILE_GUID                      = 3a8f8431-f0c9-4c95-8a1d-04445c582d4e
+  MODULE_TYPE                    = DXE_DRIVER
+  VERSION_STRING                 = 1.0
+  LIBRARY_CLASS                  = PlatformBootManagerLib|DXE_DRIVER
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+#  VALID_ARCHITECTURES           = X64
+#
+
+[Sources]
+  BdsPlatform.c
+  PlatformData.c
+  BdsPlatform.h
+
+[Packages]
+  MdePkg/MdePkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+  SourceLevelDebugPkg/SourceLevelDebugPkg.dec
+  OvmfPkg/OvmfPkg.dec
+  SecurityPkg/SecurityPkg.dec
+  ShellPkg/ShellPkg.dec
+
+[LibraryClasses]
+  BaseLib
+  MemoryAllocationLib
+  UefiBootServicesTableLib
+  UefiRuntimeServicesTableLib
+  BaseMemoryLib
+  DebugLib
+  PcdLib
+  UefiBootManagerLib
+  BootLogoLib
+  DevicePathLib
+  PciLib
+  ReportStatusCodeLib
+  UefiLib
+  PlatformBmPrintScLib
+  Tcg2PhysicalPresenceLib
+  XenPlatformLib
+
+[Pcd]
+  gUefiOvmfPkgTokenSpaceGuid.PcdOvmfFlashVariablesEnable
+  gUefiOvmfPkgTokenSpaceGuid.PcdOvmfHostBridgePciDevId
+  gEfiMdePkgTokenSpaceGuid.PcdPlatformBootTimeOut
+  gEfiMdePkgTokenSpaceGuid.PcdUartDefaultBaudRate         ## CONSUMES
+  gEfiMdePkgTokenSpaceGuid.PcdUartDefaultDataBits         ## CONSUMES
+  gEfiMdePkgTokenSpaceGuid.PcdUartDefaultParity           ## CONSUMES
+  gEfiMdePkgTokenSpaceGuid.PcdUartDefaultStopBits         ## CONSUMES
+
+[Pcd.IA32, Pcd.X64]
+  gEfiMdePkgTokenSpaceGuid.PcdFSBClock
+
+[Protocols]
+  gEfiDecompressProtocolGuid
+  gEfiPciRootBridgeIoProtocolGuid
+  gEfiS3SaveStateProtocolGuid                   # PROTOCOL SOMETIMES_CONSUMED
+  gEfiDxeSmmReadyToLockProtocolGuid             # PROTOCOL SOMETIMES_PRODUCED
+  gEfiLoadedImageProtocolGuid                   # PROTOCOL SOMETIMES_PRODUCED
+  gEfiFirmwareVolume2ProtocolGuid               # PROTOCOL SOMETIMES_CONSUMED
+
+[Guids]
+  gEfiEndOfDxeEventGroupGuid
+  gEfiGlobalVariableGuid
+  gRootBridgesConnectedEventGroupGuid
+  gUefiShellFileGuid
+  gGrubFileGuid
diff --git a/OvmfPkg/Library/PlatformBootManagerLibGrub/BdsPlatform.h b/OvmfPkg/Library/PlatformBootManagerLibGrub/BdsPlatform.h
new file mode 100644
index 000000000000..a7fc4dbc3c1f
--- /dev/null
+++ b/OvmfPkg/Library/PlatformBootManagerLibGrub/BdsPlatform.h
@@ -0,0 +1,175 @@
+/** @file
+  Platform BDS customizations include file.
+
+  Copyright (c) 2006 - 2017, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+Module Name:
+
+  BdsPlatform.h
+
+Abstract:
+
+  Head file for BDS Platform specific code
+
+**/
+
+#ifndef _PLATFORM_SPECIFIC_BDS_PLATFORM_H_
+#define _PLATFORM_SPECIFIC_BDS_PLATFORM_H_
+
+
+#include <PiDxe.h>
+
+#include <IndustryStandard/Pci.h>
+#include <IndustryStandard/Acpi.h>
+#include <IndustryStandard/SmBios.h>
+#include <IndustryStandard/PeImage.h>
+#include <IndustryStandard/Virtio095.h>
+
+#include <Library/DebugLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UefiRuntimeServicesTableLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/BaseLib.h>
+#include <Library/PcdLib.h>
+#include <Library/PciLib.h>
+#include <Library/UefiBootManagerLib.h>
+#include <Library/BootLogoLib.h>
+#include <Library/HobLib.h>
+#include <Library/UefiLib.h>
+#include <Library/DxeServicesTableLib.h>
+#include <Library/DevicePathLib.h>
+#include <Library/IoLib.h>
+
+#include <Protocol/Decompress.h>
+#include <Protocol/PciIo.h>
+#include <Protocol/FirmwareVolume2.h>
+#include <Protocol/SimpleFileSystem.h>
+#include <Protocol/PciRootBridgeIo.h>
+#include <Protocol/S3SaveState.h>
+#include <Protocol/DxeSmmReadyToLock.h>
+#include <Protocol/LoadedImage.h>
+
+#include <Guid/Acpi.h>
+#include <Guid/SmBios.h>
+#include <Guid/HobList.h>
+#include <Guid/GlobalVariable.h>
+#include <Guid/EventGroup.h>
+#include <Guid/DebugAgentGuid.h>
+
+#include <OvmfPlatforms.h>
+
+extern EFI_DEVICE_PATH_PROTOCOL   *gPlatformConnectSequence[];
+extern ACPI_HID_DEVICE_PATH       gPnpPs2KeyboardDeviceNode;
+extern ACPI_HID_DEVICE_PATH       gPnp16550ComPortDeviceNode;
+extern UART_DEVICE_PATH           gUartDeviceNode;
+extern VENDOR_DEVICE_PATH         gTerminalTypeDeviceNode;
+
+#define PCI_DEVICE_PATH_NODE(Func, Dev) \
+  { \
+    { \
+      HARDWARE_DEVICE_PATH, \
+      HW_PCI_DP, \
+      { \
+        (UINT8) (sizeof (PCI_DEVICE_PATH)), \
+        (UINT8) ((sizeof (PCI_DEVICE_PATH)) >> 8) \
+      } \
+    }, \
+    (Func), \
+    (Dev) \
+  }
+
+#define PNPID_DEVICE_PATH_NODE(PnpId) \
+  { \
+    { \
+      ACPI_DEVICE_PATH, \
+      ACPI_DP, \
+      { \
+        (UINT8) (sizeof (ACPI_HID_DEVICE_PATH)), \
+        (UINT8) ((sizeof (ACPI_HID_DEVICE_PATH)) >> 8) \
+      }, \
+    }, \
+    EISA_PNP_ID((PnpId)), \
+    0 \
+  }
+
+#define gPciIsaBridge \
+  PCI_DEVICE_PATH_NODE(0, 0x1f)
+
+#define gP2PBridge \
+  PCI_DEVICE_PATH_NODE(0, 0x1e)
+
+#define gPnpPs2Keyboard \
+  PNPID_DEVICE_PATH_NODE(0x0303)
+
+#define gPnp16550ComPort \
+  PNPID_DEVICE_PATH_NODE(0x0501)
+
+#define gUart \
+  { \
+    { \
+      MESSAGING_DEVICE_PATH, \
+      MSG_UART_DP, \
+      { \
+        (UINT8) (sizeof (UART_DEVICE_PATH)), \
+        (UINT8) ((sizeof (UART_DEVICE_PATH)) >> 8) \
+      } \
+    }, \
+    0, \
+    115200, \
+    8, \
+    1, \
+    1 \
+  }
+
+#define gPcAnsiTerminal \
+  { \
+    { \
+      MESSAGING_DEVICE_PATH, \
+      MSG_VENDOR_DP, \
+      { \
+        (UINT8) (sizeof (VENDOR_DEVICE_PATH)), \
+        (UINT8) ((sizeof (VENDOR_DEVICE_PATH)) >> 8) \
+      } \
+    }, \
+    DEVICE_PATH_MESSAGING_PC_ANSI \
+  }
+
+#define gEndEntire \
+  { \
+    END_DEVICE_PATH_TYPE, \
+    END_ENTIRE_DEVICE_PATH_SUBTYPE, \
+    { \
+      END_DEVICE_PATH_LENGTH, \
+      0 \
+    } \
+  }
+
+#define PCI_CLASS_SCC          0x07
+#define PCI_SUBCLASS_SERIAL    0x00
+#define PCI_IF_16550           0x02
+#define IS_PCI_16550SERIAL(_p)           IS_CLASS3 (_p, PCI_CLASS_SCC, PCI_SUBCLASS_SERIAL, PCI_IF_16550)
+#define IS_PCI_ISA_PDECODE(_p)        IS_CLASS3 (_p, PCI_CLASS_BRIDGE, PCI_CLASS_BRIDGE_ISA_PDECODE, 0)
+
+typedef struct {
+  EFI_DEVICE_PATH_PROTOCOL  *DevicePath;
+  UINTN                     ConnectType;
+} PLATFORM_CONSOLE_CONNECT_ENTRY;
+
+#define CONSOLE_OUT BIT0
+#define CONSOLE_IN  BIT1
+#define STD_ERROR   BIT2
+extern PLATFORM_CONSOLE_CONNECT_ENTRY  gPlatformConsole[];
+extern PLATFORM_CONSOLE_CONNECT_ENTRY  gXenPlatformConsole[];
+
+//
+// Platform BDS Functions
+//
+
+VOID
+PlatformInitializeConsole (
+  IN PLATFORM_CONSOLE_CONNECT_ENTRY   *PlatformConsole
+  );
+
+#endif // _PLATFORM_SPECIFIC_BDS_PLATFORM_H_
diff --git a/OvmfPkg/Library/PlatformBootManagerLibGrub/BdsPlatform.c b/OvmfPkg/Library/PlatformBootManagerLibGrub/BdsPlatform.c
new file mode 100644
index 000000000000..4fb2f904a10e
--- /dev/null
+++ b/OvmfPkg/Library/PlatformBootManagerLibGrub/BdsPlatform.c
@@ -0,0 +1,1483 @@
+/** @file
+  Platform BDS customizations.
+
+  Copyright (c) 2004 - 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include "BdsPlatform.h"
+#include <Guid/RootBridgesConnectedEventGroup.h>
+#include <Protocol/FirmwareVolume2.h>
+#include <Library/PlatformBmPrintScLib.h>
+#include <Library/Tcg2PhysicalPresenceLib.h>
+#include <Library/XenPlatformLib.h>
+
+
+//
+// Global data
+//
+
+VOID          *mEfiDevPathNotifyReg;
+EFI_EVENT     mEfiDevPathEvent;
+UINT16        mHostBridgeDevId;
+
+//
+// Table of host IRQs matching PCI IRQs A-D
+// (for configuring PCI Interrupt Line register)
+//
+CONST UINT8 PciHostIrqs[] = {
+  0x0a, 0x0a, 0x0b, 0x0b
+};
+
+//
+// Type definitions
+//
+
+typedef
+EFI_STATUS
+(EFIAPI *PROTOCOL_INSTANCE_CALLBACK)(
+  IN EFI_HANDLE           Handle,
+  IN VOID                 *Instance,
+  IN VOID                 *Context
+  );
+
+/**
+  @param[in]  Handle - Handle of PCI device instance
+  @param[in]  PciIo - PCI IO protocol instance
+  @param[in]  Pci - PCI Header register block
+**/
+typedef
+EFI_STATUS
+(EFIAPI *VISIT_PCI_INSTANCE_CALLBACK)(
+  IN EFI_HANDLE           Handle,
+  IN EFI_PCI_IO_PROTOCOL  *PciIo,
+  IN PCI_TYPE00           *Pci
+  );
+
+
+//
+// Function prototypes
+//
+
+EFI_STATUS
+VisitAllInstancesOfProtocol (
+  IN EFI_GUID                    *Id,
+  IN PROTOCOL_INSTANCE_CALLBACK  CallBackFunction,
+  IN VOID                        *Context
+  );
+
+EFI_STATUS
+VisitAllPciInstancesOfProtocol (
+  IN VISIT_PCI_INSTANCE_CALLBACK CallBackFunction
+  );
+
+VOID
+InstallDevicePathCallback (
+  VOID
+  );
+
+VOID
+PlatformRegisterFvBootOption (
+  EFI_GUID                         *FileGuid,
+  CHAR16                           *Description,
+  UINT32                           Attributes
+  )
+{
+  EFI_STATUS                        Status;
+  INTN                              OptionIndex;
+  EFI_BOOT_MANAGER_LOAD_OPTION      NewOption;
+  EFI_BOOT_MANAGER_LOAD_OPTION      *BootOptions;
+  UINTN                             BootOptionCount;
+  MEDIA_FW_VOL_FILEPATH_DEVICE_PATH FileNode;
+  EFI_LOADED_IMAGE_PROTOCOL         *LoadedImage;
+  EFI_DEVICE_PATH_PROTOCOL          *DevicePath;
+
+  Status = gBS->HandleProtocol (
+                  gImageHandle,
+                  &gEfiLoadedImageProtocolGuid,
+                  (VOID **) &LoadedImage
+                  );
+  ASSERT_EFI_ERROR (Status);
+
+  EfiInitializeFwVolDevicepathNode (&FileNode, FileGuid);
+  DevicePath = DevicePathFromHandle (LoadedImage->DeviceHandle);
+  ASSERT (DevicePath != NULL);
+  DevicePath = AppendDevicePathNode (
+                 DevicePath,
+                 (EFI_DEVICE_PATH_PROTOCOL *) &FileNode
+                 );
+  ASSERT (DevicePath != NULL);
+
+  Status = EfiBootManagerInitializeLoadOption (
+             &NewOption,
+             LoadOptionNumberUnassigned,
+             LoadOptionTypeBoot,
+             Attributes,
+             Description,
+             DevicePath,
+             NULL,
+             0
+             );
+  ASSERT_EFI_ERROR (Status);
+  FreePool (DevicePath);
+
+  BootOptions = EfiBootManagerGetLoadOptions (
+                  &BootOptionCount, LoadOptionTypeBoot
+                  );
+
+  OptionIndex = EfiBootManagerFindLoadOption (
+                  &NewOption, BootOptions, BootOptionCount
+                  );
+
+  if (OptionIndex == -1) {
+    Status = EfiBootManagerAddLoadOptionVariable (&NewOption, MAX_UINTN);
+    ASSERT_EFI_ERROR (Status);
+  }
+  EfiBootManagerFreeLoadOption (&NewOption);
+  EfiBootManagerFreeLoadOptions (BootOptions, BootOptionCount);
+}
+
+/**
+  Remove all MemoryMapped(...)/FvFile(...) and Fv(...)/FvFile(...) boot options
+  whose device paths do not resolve exactly to an FvFile in the system.
+
+  Also strip out every boot option that is not an FvFile, meaning the system
+  can only boot either the Grub or (if built) the shell.
+
+  This removes any boot options that point to binaries built into the firmware
+  and have become stale due to any of the following:
+  - DXEFV's base address or size changed (historical),
+  - DXEFV's FvNameGuid changed,
+  - the FILE_GUID of the pointed-to binary changed,
+  - the referenced binary is no longer built into the firmware.
+
+  EfiBootManagerFindLoadOption() used in PlatformRegisterFvBootOption() only
+  avoids exact duplicates.
+**/
+VOID
+RemoveStaleFvFileOptions (
+  VOID
+  )
+{
+  EFI_BOOT_MANAGER_LOAD_OPTION *BootOptions;
+  UINTN                        BootOptionCount;
+  UINTN                        Index;
+
+  BootOptions = EfiBootManagerGetLoadOptions (&BootOptionCount,
+                  LoadOptionTypeBoot);
+
+  for (Index = 0; Index < BootOptionCount; ++Index) {
+    EFI_DEVICE_PATH_PROTOCOL *Node1, *Node2, *SearchNode;
+    EFI_STATUS               Status;
+    EFI_HANDLE               FvHandle;
+
+    //
+    // If the device path starts with neither MemoryMapped(...) nor Fv(...),
+    // then delete the boot option.
+    //
+    Node1 = BootOptions[Index].FilePath;
+    if (!(DevicePathType (Node1) == HARDWARE_DEVICE_PATH &&
+          DevicePathSubType (Node1) == HW_MEMMAP_DP) &&
+        !(DevicePathType (Node1) == MEDIA_DEVICE_PATH &&
+          DevicePathSubType (Node1) == MEDIA_PIWG_FW_VOL_DP)) {
+      EfiBootManagerDeleteLoadOptionVariable (
+          BootOptions[Index].OptionNumber, LoadOptionTypeBoot);
+      continue;
+    }
+
+    //
+    // If the second device path node is not FvFile(...), then delete the boot
+    // option.
+    //
+    Node2 = NextDevicePathNode (Node1);
+    if (DevicePathType (Node2) != MEDIA_DEVICE_PATH ||
+        DevicePathSubType (Node2) != MEDIA_PIWG_FW_FILE_DP) {
+      EfiBootManagerDeleteLoadOptionVariable (
+        BootOptions[Index].OptionNumber, LoadOptionTypeBoot);
+      continue;
+    }
+
+    //
+    // Locate the Firmware Volume2 protocol instance that is denoted by the
+    // boot option. If this lookup fails (i.e., the boot option references a
+    // firmware volume that doesn't exist), then we'll proceed to delete the
+    // boot option.
+    //
+    SearchNode = Node1;
+    Status = gBS->LocateDevicePath (&gEfiFirmwareVolume2ProtocolGuid,
+                    &SearchNode, &FvHandle);
+
+    if (!EFI_ERROR (Status)) {
+      //
+      // The firmware volume was found; now let's see if it contains the FvFile
+      // identified by GUID.
+      //
+      EFI_FIRMWARE_VOLUME2_PROTOCOL     *FvProtocol;
+      MEDIA_FW_VOL_FILEPATH_DEVICE_PATH *FvFileNode;
+      UINTN                             BufferSize;
+      EFI_FV_FILETYPE                   FoundType;
+      EFI_FV_FILE_ATTRIBUTES            FileAttributes;
+      UINT32                            AuthenticationStatus;
+
+      Status = gBS->HandleProtocol (FvHandle, &gEfiFirmwareVolume2ProtocolGuid,
+                      (VOID **)&FvProtocol);
+      ASSERT_EFI_ERROR (Status);
+
+      FvFileNode = (MEDIA_FW_VOL_FILEPATH_DEVICE_PATH *)Node2;
+      //
+      // Buffer==NULL means we request metadata only: BufferSize, FoundType,
+      // FileAttributes.
+      //
+      Status = FvProtocol->ReadFile (
+                             FvProtocol,
+                             &FvFileNode->FvFileName, // NameGuid
+                             NULL,                    // Buffer
+                             &BufferSize,
+                             &FoundType,
+                             &FileAttributes,
+                             &AuthenticationStatus
+                             );
+      if (!EFI_ERROR (Status)) {
+        //
+        // The FvFile was found. Keep the boot option.
+        //
+        continue;
+      }
+    }
+
+    //
+    // Delete the boot option.
+    //
+    Status = EfiBootManagerDeleteLoadOptionVariable (
+               BootOptions[Index].OptionNumber, LoadOptionTypeBoot);
+    DEBUG_CODE (
+      CHAR16 *DevicePathString;
+
+      DevicePathString = ConvertDevicePathToText(BootOptions[Index].FilePath,
+                           FALSE, FALSE);
+      DEBUG ((
+        EFI_ERROR (Status) ? DEBUG_WARN : DEBUG_VERBOSE,
+        "%a: removing stale Boot#%04x %s: %r\n",
+        __FUNCTION__,
+        (UINT32)BootOptions[Index].OptionNumber,
+        DevicePathString == NULL ? L"<unavailable>" : DevicePathString,
+        Status
+        ));
+      if (DevicePathString != NULL) {
+        FreePool (DevicePathString);
+      }
+      );
+  }
+
+  EfiBootManagerFreeLoadOptions (BootOptions, BootOptionCount);
+}
+
+EFI_STATUS
+EFIAPI
+ConnectRootBridge (
+  IN EFI_HANDLE  RootBridgeHandle,
+  IN VOID        *Instance,
+  IN VOID        *Context
+  );
+
+STATIC
+EFI_STATUS
+EFIAPI
+ConnectVirtioPciRng (
+  IN EFI_HANDLE Handle,
+  IN VOID       *Instance,
+  IN VOID       *Context
+  );
+
+//
+// BDS Platform Functions
+//
+/**
+  Do the platform init, can be customized by OEM/IBV
+
+  Possible things that can be done in PlatformBootManagerBeforeConsole:
+
+  > Update console variable: 1. include hot-plug devices;
+  >                          2. Clear ConIn and add SOL for AMT
+  > Register new Driver#### or Boot####
+  > Register new Key####: e.g.: F12
+  > Signal ReadyToLock event
+  > Authentication action: 1. connect Auth devices;
+  >                        2. Identify auto logon user.
+**/
+VOID
+EFIAPI
+PlatformBootManagerBeforeConsole (
+  VOID
+  )
+{
+  EFI_HANDLE    Handle;
+  EFI_STATUS    Status;
+
+  DEBUG ((DEBUG_INFO, "PlatformBootManagerBeforeConsole\n"));
+  InstallDevicePathCallback ();
+
+  VisitAllInstancesOfProtocol (&gEfiPciRootBridgeIoProtocolGuid,
+    ConnectRootBridge, NULL);
+
+  //
+  // Signal the ACPI platform driver that it can download QEMU ACPI tables.
+  //
+  EfiEventGroupSignal (&gRootBridgesConnectedEventGroupGuid);
+
+  //
+  // We can't signal End-of-Dxe earlier than this. Namely, End-of-Dxe triggers
+  // the preparation of S3 system information. That logic has a hard dependency
+  // on the presence of the FACS ACPI table. Since our ACPI tables are only
+  // installed after PCI enumeration completes, we must not trigger the S3 save
+  // earlier, hence we can't signal End-of-Dxe earlier.
+  //
+  EfiEventGroupSignal (&gEfiEndOfDxeEventGroupGuid);
+
+  //
+  // Prevent further changes to LockBoxes or SMRAM.
+  //
+  Handle = NULL;
+  Status = gBS->InstallProtocolInterface (&Handle,
+                  &gEfiDxeSmmReadyToLockProtocolGuid, EFI_NATIVE_INTERFACE,
+                  NULL);
+  ASSERT_EFI_ERROR (Status);
+
+  //
+  // Dispatch deferred images after EndOfDxe event and ReadyToLock
+  // installation.
+  //
+  EfiBootManagerDispatchDeferredImages ();
+
+  PlatformInitializeConsole (
+    XenDetected() ? gXenPlatformConsole : gPlatformConsole);
+
+  //
+  // Install both VIRTIO_DEVICE_PROTOCOL and (dependent) EFI_RNG_PROTOCOL
+  // instances on Virtio PCI RNG devices.
+  //
+  VisitAllInstancesOfProtocol (&gEfiPciIoProtocolGuid, ConnectVirtioPciRng,
+    NULL);
+}
+
+
+EFI_STATUS
+EFIAPI
+ConnectRootBridge (
+  IN EFI_HANDLE  RootBridgeHandle,
+  IN VOID        *Instance,
+  IN VOID        *Context
+  )
+{
+  EFI_STATUS Status;
+
+  //
+  // Make the PCI bus driver connect the root bridge, non-recursively. This
+  // will produce a number of child handles with PciIo on them.
+  //
+  Status = gBS->ConnectController (
+                  RootBridgeHandle, // ControllerHandle
+                  NULL,             // DriverImageHandle
+                  NULL,             // RemainingDevicePath -- produce all
+                                    //   children
+                  FALSE             // Recursive
+                  );
+  return Status;
+}
+
+
+STATIC
+EFI_STATUS
+EFIAPI
+ConnectVirtioPciRng (
+  IN EFI_HANDLE Handle,
+  IN VOID       *Instance,
+  IN VOID       *Context
+  )
+{
+  EFI_PCI_IO_PROTOCOL *PciIo;
+  EFI_STATUS          Status;
+  UINT16              VendorId;
+  UINT16              DeviceId;
+  UINT8               RevisionId;
+  BOOLEAN             Virtio10;
+  UINT16              SubsystemId;
+
+  PciIo = Instance;
+
+  //
+  // Read and check VendorId.
+  //
+  Status = PciIo->Pci.Read (PciIo, EfiPciIoWidthUint16, PCI_VENDOR_ID_OFFSET,
+                        1, &VendorId);
+  if (EFI_ERROR (Status)) {
+    goto Error;
+  }
+  if (VendorId != VIRTIO_VENDOR_ID) {
+    return EFI_SUCCESS;
+  }
+
+  //
+  // Read DeviceId and RevisionId.
+  //
+  Status = PciIo->Pci.Read (PciIo, EfiPciIoWidthUint16, PCI_DEVICE_ID_OFFSET,
+                        1, &DeviceId);
+  if (EFI_ERROR (Status)) {
+    goto Error;
+  }
+  Status = PciIo->Pci.Read (PciIo, EfiPciIoWidthUint8, PCI_REVISION_ID_OFFSET,
+                        1, &RevisionId);
+  if (EFI_ERROR (Status)) {
+    goto Error;
+  }
+
+  //
+  // From DeviceId and RevisionId, determine whether the device is a
+  // modern-only Virtio 1.0 device. In case of Virtio 1.0, DeviceId can
+  // immediately be restricted to VIRTIO_SUBSYSTEM_ENTROPY_SOURCE, and
+  // SubsystemId will only play a sanity-check role. Otherwise, DeviceId can
+  // only be sanity-checked, and SubsystemId will decide.
+  //
+  if (DeviceId == 0x1040 + VIRTIO_SUBSYSTEM_ENTROPY_SOURCE &&
+      RevisionId >= 0x01) {
+    Virtio10 = TRUE;
+  } else if (DeviceId >= 0x1000 && DeviceId <= 0x103F && RevisionId == 0x00) {
+    Virtio10 = FALSE;
+  } else {
+    return EFI_SUCCESS;
+  }
+
+  //
+  // Read and check SubsystemId as dictated by Virtio10.
+  //
+  Status = PciIo->Pci.Read (PciIo, EfiPciIoWidthUint16,
+                        PCI_SUBSYSTEM_ID_OFFSET, 1, &SubsystemId);
+  if (EFI_ERROR (Status)) {
+    goto Error;
+  }
+  if ((Virtio10 && SubsystemId >= 0x40) ||
+      (!Virtio10 && SubsystemId == VIRTIO_SUBSYSTEM_ENTROPY_SOURCE)) {
+    Status = gBS->ConnectController (
+                    Handle, // ControllerHandle
+                    NULL,   // DriverImageHandle -- connect all drivers
+                    NULL,   // RemainingDevicePath -- produce all child handles
+                    FALSE   // Recursive -- don't follow child handles
+                    );
+    if (EFI_ERROR (Status)) {
+      goto Error;
+    }
+  }
+  return EFI_SUCCESS;
+
+Error:
+  DEBUG ((DEBUG_ERROR, "%a: %r\n", __FUNCTION__, Status));
+  return Status;
+}
+
+
+/**
+  Add IsaKeyboard to ConIn; add IsaSerial to ConOut, ConIn, ErrOut.
+
+  @param[in] DeviceHandle  Handle of the LPC Bridge device.
+
+  @retval EFI_SUCCESS  Console devices on the LPC bridge have been added to
+                       ConOut, ConIn, and ErrOut.
+
+  @return              Error codes, due to EFI_DEVICE_PATH_PROTOCOL missing
+                       from DeviceHandle.
+**/
+EFI_STATUS
+PrepareLpcBridgeDevicePath (
+  IN EFI_HANDLE                DeviceHandle
+  )
+{
+  EFI_STATUS                Status;
+  EFI_DEVICE_PATH_PROTOCOL  *DevicePath;
+  EFI_DEVICE_PATH_PROTOCOL  *TempDevicePath;
+  CHAR16                    *DevPathStr;
+
+  DevicePath = NULL;
+  Status = gBS->HandleProtocol (
+                  DeviceHandle,
+                  &gEfiDevicePathProtocolGuid,
+                  (VOID*)&DevicePath
+                  );
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+  TempDevicePath = DevicePath;
+
+  //
+  // Register Keyboard
+  //
+  DevicePath = AppendDevicePathNode (DevicePath,
+                 (EFI_DEVICE_PATH_PROTOCOL *)&gPnpPs2KeyboardDeviceNode);
+
+  EfiBootManagerUpdateConsoleVariable (ConIn, DevicePath, NULL);
+
+  //
+  // Register COM1
+  //
+  DevicePath = TempDevicePath;
+  gPnp16550ComPortDeviceNode.UID = 0;
+
+  DevicePath = AppendDevicePathNode (DevicePath,
+                 (EFI_DEVICE_PATH_PROTOCOL *)&gPnp16550ComPortDeviceNode);
+  DevicePath = AppendDevicePathNode (DevicePath,
+                 (EFI_DEVICE_PATH_PROTOCOL *)&gUartDeviceNode);
+  DevicePath = AppendDevicePathNode (DevicePath,
+                 (EFI_DEVICE_PATH_PROTOCOL *)&gTerminalTypeDeviceNode);
+
+  //
+  // Print Device Path
+  //
+  DevPathStr = ConvertDevicePathToText (DevicePath, FALSE, FALSE);
+  if (DevPathStr != NULL) {
+    DEBUG((
+      DEBUG_INFO,
+      "BdsPlatform.c+%d: COM%d DevPath: %s\n",
+      __LINE__,
+      gPnp16550ComPortDeviceNode.UID + 1,
+      DevPathStr
+      ));
+    FreePool(DevPathStr);
+  }
+
+  EfiBootManagerUpdateConsoleVariable (ConOut, DevicePath, NULL);
+  EfiBootManagerUpdateConsoleVariable (ConIn, DevicePath, NULL);
+  EfiBootManagerUpdateConsoleVariable (ErrOut, DevicePath, NULL);
+
+  //
+  // Register COM2
+  //
+  DevicePath = TempDevicePath;
+  gPnp16550ComPortDeviceNode.UID = 1;
+
+  DevicePath = AppendDevicePathNode (DevicePath,
+                 (EFI_DEVICE_PATH_PROTOCOL *)&gPnp16550ComPortDeviceNode);
+  DevicePath = AppendDevicePathNode (DevicePath,
+                 (EFI_DEVICE_PATH_PROTOCOL *)&gUartDeviceNode);
+  DevicePath = AppendDevicePathNode (DevicePath,
+                 (EFI_DEVICE_PATH_PROTOCOL *)&gTerminalTypeDeviceNode);
+
+  //
+  // Print Device Path
+  //
+  DevPathStr = ConvertDevicePathToText (DevicePath, FALSE, FALSE);
+  if (DevPathStr != NULL) {
+    DEBUG((
+      DEBUG_INFO,
+      "BdsPlatform.c+%d: COM%d DevPath: %s\n",
+      __LINE__,
+      gPnp16550ComPortDeviceNode.UID + 1,
+      DevPathStr
+      ));
+    FreePool(DevPathStr);
+  }
+
+  EfiBootManagerUpdateConsoleVariable (ConOut, DevicePath, NULL);
+  EfiBootManagerUpdateConsoleVariable (ConIn, DevicePath, NULL);
+  EfiBootManagerUpdateConsoleVariable (ErrOut, DevicePath, NULL);
+
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+GetGopDevicePath (
+   IN  EFI_DEVICE_PATH_PROTOCOL *PciDevicePath,
+   OUT EFI_DEVICE_PATH_PROTOCOL **GopDevicePath
+   )
+{
+  UINTN                           Index;
+  EFI_STATUS                      Status;
+  EFI_HANDLE                      PciDeviceHandle;
+  EFI_DEVICE_PATH_PROTOCOL        *TempDevicePath;
+  EFI_DEVICE_PATH_PROTOCOL        *TempPciDevicePath;
+  UINTN                           GopHandleCount;
+  EFI_HANDLE                      *GopHandleBuffer;
+
+  if (PciDevicePath == NULL || GopDevicePath == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  //
+  // Initialize the GopDevicePath to be PciDevicePath
+  //
+  *GopDevicePath    = PciDevicePath;
+  TempPciDevicePath = PciDevicePath;
+
+  Status = gBS->LocateDevicePath (
+                  &gEfiDevicePathProtocolGuid,
+                  &TempPciDevicePath,
+                  &PciDeviceHandle
+                  );
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  //
+  // Try to connect this handle, so that GOP driver could start on this
+  // device and create child handles with GraphicsOutput Protocol installed
+  // on them, then we get device paths of these child handles and select
+  // them as possible console device.
+  //
+  gBS->ConnectController (PciDeviceHandle, NULL, NULL, FALSE);
+
+  Status = gBS->LocateHandleBuffer (
+                  ByProtocol,
+                  &gEfiGraphicsOutputProtocolGuid,
+                  NULL,
+                  &GopHandleCount,
+                  &GopHandleBuffer
+                  );
+  if (!EFI_ERROR (Status)) {
+    //
+    // Add all the child handles as possible Console Device
+    //
+    for (Index = 0; Index < GopHandleCount; Index++) {
+      Status = gBS->HandleProtocol (GopHandleBuffer[Index],
+                      &gEfiDevicePathProtocolGuid, (VOID*)&TempDevicePath);
+      if (EFI_ERROR (Status)) {
+        continue;
+      }
+      if (CompareMem (
+            PciDevicePath,
+            TempDevicePath,
+            GetDevicePathSize (PciDevicePath) - END_DEVICE_PATH_LENGTH
+            ) == 0) {
+        //
+        // In current implementation, we only enable one of the child handles
+        // as console device, i.e. sotre one of the child handle's device
+        // path to variable "ConOut"
+        // In future, we could select all child handles to be console device
+        //
+
+        *GopDevicePath = TempDevicePath;
+
+        //
+        // Delete the PCI device's path that added by
+        // GetPlugInPciVgaDevicePath(). Add the integrity GOP device path.
+        //
+        EfiBootManagerUpdateConsoleVariable (ConOutDev, NULL, PciDevicePath);
+        EfiBootManagerUpdateConsoleVariable (ConOutDev, TempDevicePath, NULL);
+      }
+    }
+    gBS->FreePool (GopHandleBuffer);
+  }
+
+  return EFI_SUCCESS;
+}
+
+/**
+  Add PCI display to ConOut.
+
+  @param[in] DeviceHandle  Handle of the PCI display device.
+
+  @retval EFI_SUCCESS  The PCI display device has been added to ConOut.
+
+  @return              Error codes, due to EFI_DEVICE_PATH_PROTOCOL missing
+                       from DeviceHandle.
+**/
+EFI_STATUS
+PreparePciDisplayDevicePath (
+  IN EFI_HANDLE                DeviceHandle
+  )
+{
+  EFI_STATUS                Status;
+  EFI_DEVICE_PATH_PROTOCOL  *DevicePath;
+  EFI_DEVICE_PATH_PROTOCOL  *GopDevicePath;
+
+  DevicePath    = NULL;
+  GopDevicePath = NULL;
+  Status = gBS->HandleProtocol (
+                  DeviceHandle,
+                  &gEfiDevicePathProtocolGuid,
+                  (VOID*)&DevicePath
+                  );
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  GetGopDevicePath (DevicePath, &GopDevicePath);
+  DevicePath = GopDevicePath;
+
+  EfiBootManagerUpdateConsoleVariable (ConOut, DevicePath, NULL);
+
+  return EFI_SUCCESS;
+}
+
+/**
+  Add PCI Serial to ConOut, ConIn, ErrOut.
+
+  @param[in] DeviceHandle  Handle of the PCI serial device.
+
+  @retval EFI_SUCCESS  The PCI serial device has been added to ConOut, ConIn,
+                       ErrOut.
+
+  @return              Error codes, due to EFI_DEVICE_PATH_PROTOCOL missing
+                       from DeviceHandle.
+**/
+EFI_STATUS
+PreparePciSerialDevicePath (
+  IN EFI_HANDLE                DeviceHandle
+  )
+{
+  EFI_STATUS                Status;
+  EFI_DEVICE_PATH_PROTOCOL  *DevicePath;
+
+  DevicePath = NULL;
+  Status = gBS->HandleProtocol (
+                  DeviceHandle,
+                  &gEfiDevicePathProtocolGuid,
+                  (VOID*)&DevicePath
+                  );
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  DevicePath = AppendDevicePathNode (DevicePath,
+                 (EFI_DEVICE_PATH_PROTOCOL *)&gUartDeviceNode);
+  DevicePath = AppendDevicePathNode (DevicePath,
+                 (EFI_DEVICE_PATH_PROTOCOL *)&gTerminalTypeDeviceNode);
+
+  EfiBootManagerUpdateConsoleVariable (ConOut, DevicePath, NULL);
+  EfiBootManagerUpdateConsoleVariable (ConIn, DevicePath, NULL);
+  EfiBootManagerUpdateConsoleVariable (ErrOut, DevicePath, NULL);
+
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+VisitAllInstancesOfProtocol (
+  IN EFI_GUID                    *Id,
+  IN PROTOCOL_INSTANCE_CALLBACK  CallBackFunction,
+  IN VOID                        *Context
+  )
+{
+  EFI_STATUS                Status;
+  UINTN                     HandleCount;
+  EFI_HANDLE                *HandleBuffer;
+  UINTN                     Index;
+  VOID                      *Instance;
+
+  //
+  // Start to check all the PciIo to find all possible device
+  //
+  HandleCount = 0;
+  HandleBuffer = NULL;
+  Status = gBS->LocateHandleBuffer (
+                  ByProtocol,
+                  Id,
+                  NULL,
+                  &HandleCount,
+                  &HandleBuffer
+                  );
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  for (Index = 0; Index < HandleCount; Index++) {
+    Status = gBS->HandleProtocol (HandleBuffer[Index], Id, &Instance);
+    if (EFI_ERROR (Status)) {
+      continue;
+    }
+
+    Status = (*CallBackFunction) (
+               HandleBuffer[Index],
+               Instance,
+               Context
+               );
+  }
+
+  gBS->FreePool (HandleBuffer);
+
+  return EFI_SUCCESS;
+}
+
+
+EFI_STATUS
+EFIAPI
+VisitingAPciInstance (
+  IN EFI_HANDLE  Handle,
+  IN VOID        *Instance,
+  IN VOID        *Context
+  )
+{
+  EFI_STATUS                Status;
+  EFI_PCI_IO_PROTOCOL       *PciIo;
+  PCI_TYPE00                Pci;
+
+  PciIo = (EFI_PCI_IO_PROTOCOL*) Instance;
+
+  //
+  // Check for all PCI device
+  //
+  Status = PciIo->Pci.Read (
+                    PciIo,
+                    EfiPciIoWidthUint32,
+                    0,
+                    sizeof (Pci) / sizeof (UINT32),
+                    &Pci
+                    );
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  return (*(VISIT_PCI_INSTANCE_CALLBACK)(UINTN) Context) (
+           Handle,
+           PciIo,
+           &Pci
+           );
+
+}
+
+
+
+EFI_STATUS
+VisitAllPciInstances (
+  IN VISIT_PCI_INSTANCE_CALLBACK CallBackFunction
+  )
+{
+  return VisitAllInstancesOfProtocol (
+           &gEfiPciIoProtocolGuid,
+           VisitingAPciInstance,
+           (VOID*)(UINTN) CallBackFunction
+           );
+}
+
+
+/**
+  Do platform specific PCI Device check and add them to
+  ConOut, ConIn, ErrOut.
+
+  @param[in]  Handle - Handle of PCI device instance
+  @param[in]  PciIo - PCI IO protocol instance
+  @param[in]  Pci - PCI Header register block
+
+  @retval EFI_SUCCESS - PCI Device check and Console variable update
+                        successfully.
+  @retval EFI_STATUS - PCI Device check or Console variable update fail.
+
+**/
+EFI_STATUS
+EFIAPI
+DetectAndPreparePlatformPciDevicePath (
+  IN EFI_HANDLE           Handle,
+  IN EFI_PCI_IO_PROTOCOL  *PciIo,
+  IN PCI_TYPE00           *Pci
+  )
+{
+  EFI_STATUS                Status;
+
+  Status = PciIo->Attributes (
+    PciIo,
+    EfiPciIoAttributeOperationEnable,
+    EFI_PCI_DEVICE_ENABLE,
+    NULL
+    );
+  ASSERT_EFI_ERROR (Status);
+
+  //
+  // Here we decide whether it is LPC Bridge
+  //
+  if ((IS_PCI_LPC (Pci)) ||
+      ((IS_PCI_ISA_PDECODE (Pci)) &&
+       (Pci->Hdr.VendorId == 0x8086) &&
+       (Pci->Hdr.DeviceId == 0x7000)
+      )
+     ) {
+    //
+    // Add IsaKeyboard to ConIn,
+    // add IsaSerial to ConOut, ConIn, ErrOut
+    //
+    DEBUG ((DEBUG_INFO, "Found LPC Bridge device\n"));
+    PrepareLpcBridgeDevicePath (Handle);
+    return EFI_SUCCESS;
+  }
+  //
+  // Here we decide which Serial device to enable in PCI bus
+  //
+  if (IS_PCI_16550SERIAL (Pci)) {
+    //
+    // Add them to ConOut, ConIn, ErrOut.
+    //
+    DEBUG ((DEBUG_INFO, "Found PCI 16550 SERIAL device\n"));
+    PreparePciSerialDevicePath (Handle);
+    return EFI_SUCCESS;
+  }
+
+  //
+  // Here we decide which display device to enable in PCI bus
+  //
+  if (IS_PCI_DISPLAY (Pci)) {
+    //
+    // Add them to ConOut.
+    //
+    DEBUG ((DEBUG_INFO, "Found PCI display device\n"));
+    PreparePciDisplayDevicePath (Handle);
+    return EFI_SUCCESS;
+  }
+
+  return Status;
+}
+
+
+/**
+  Connect the predefined platform default console device.
+
+  Always try to find and enable PCI display devices.
+
+  @param[in] PlatformConsole  Predefined platform default console device array.
+**/
+VOID
+PlatformInitializeConsole (
+  IN PLATFORM_CONSOLE_CONNECT_ENTRY   *PlatformConsole
+  )
+{
+  UINTN                              Index;
+
+  //
+  // Do platform specific PCI Device check and add them to ConOut, ConIn,
+  // ErrOut
+  //
+  VisitAllPciInstances (DetectAndPreparePlatformPciDevicePath);
+
+  //
+  // Have chance to connect the platform default console,
+  // the platform default console is the minimum device group
+  // the platform should support
+  //
+  for (Index = 0; PlatformConsole[Index].DevicePath != NULL; ++Index) {
+    //
+    // Update the console variable with the connect type
+    //
+    if ((PlatformConsole[Index].ConnectType & CONSOLE_IN) == CONSOLE_IN) {
+      EfiBootManagerUpdateConsoleVariable (ConIn,
+        PlatformConsole[Index].DevicePath, NULL);
+    }
+    if ((PlatformConsole[Index].ConnectType & CONSOLE_OUT) == CONSOLE_OUT) {
+      EfiBootManagerUpdateConsoleVariable (ConOut,
+        PlatformConsole[Index].DevicePath, NULL);
+    }
+    if ((PlatformConsole[Index].ConnectType & STD_ERROR) == STD_ERROR) {
+      EfiBootManagerUpdateConsoleVariable (ErrOut,
+        PlatformConsole[Index].DevicePath, NULL);
+    }
+  }
+}
+
+
+/**
+  Configure PCI Interrupt Line register for applicable devices
+  Ported from SeaBIOS, src/fw/pciinit.c, *_pci_slot_get_irq()
+
+  @param[in]  Handle - Handle of PCI device instance
+  @param[in]  PciIo - PCI IO protocol instance
+  @param[in]  PciHdr - PCI Header register block
+
+  @retval EFI_SUCCESS - PCI Interrupt Line register configured successfully.
+
+**/
+EFI_STATUS
+EFIAPI
+SetPciIntLine (
+  IN EFI_HANDLE           Handle,
+  IN EFI_PCI_IO_PROTOCOL  *PciIo,
+  IN PCI_TYPE00           *PciHdr
+  )
+{
+  EFI_DEVICE_PATH_PROTOCOL  *DevPathNode;
+  EFI_DEVICE_PATH_PROTOCOL  *DevPath;
+  UINTN                     RootSlot;
+  UINTN                     Idx;
+  UINT8                     IrqLine;
+  EFI_STATUS                Status;
+  UINT32                    RootBusNumber;
+
+  Status = EFI_SUCCESS;
+
+  if (PciHdr->Device.InterruptPin != 0) {
+
+    DevPathNode = DevicePathFromHandle (Handle);
+    ASSERT (DevPathNode != NULL);
+    DevPath = DevPathNode;
+
+    RootBusNumber = 0;
+    if (DevicePathType (DevPathNode) == ACPI_DEVICE_PATH &&
+        DevicePathSubType (DevPathNode) == ACPI_DP &&
+        ((ACPI_HID_DEVICE_PATH *)DevPathNode)->HID == EISA_PNP_ID(0x0A03)) {
+      RootBusNumber = ((ACPI_HID_DEVICE_PATH *)DevPathNode)->UID;
+    }
+
+    //
+    // Compute index into PciHostIrqs[] table by walking
+    // the device path and adding up all device numbers
+    //
+    Status = EFI_NOT_FOUND;
+    RootSlot = 0;
+    Idx = PciHdr->Device.InterruptPin - 1;
+    while (!IsDevicePathEnd (DevPathNode)) {
+      if (DevicePathType (DevPathNode) == HARDWARE_DEVICE_PATH &&
+          DevicePathSubType (DevPathNode) == HW_PCI_DP) {
+
+        Idx += ((PCI_DEVICE_PATH *)DevPathNode)->Device;
+
+        //
+        // Unlike SeaBIOS, which starts climbing from the leaf device
+        // up toward the root, we traverse the device path starting at
+        // the root moving toward the leaf node.
+        // The slot number of the top-level parent bridge is needed for
+        // Q35 cases with more than 24 slots on the root bus.
+        //
+        if (Status != EFI_SUCCESS) {
+          Status = EFI_SUCCESS;
+          RootSlot = ((PCI_DEVICE_PATH *)DevPathNode)->Device;
+        }
+      }
+
+      DevPathNode = NextDevicePathNode (DevPathNode);
+    }
+    if (EFI_ERROR (Status)) {
+      return Status;
+    }
+    if (RootBusNumber == 0 && RootSlot == 0) {
+      DEBUG((
+        DEBUG_ERROR,
+        "%a: PCI host bridge (00:00.0) should have no interrupts!\n",
+        __FUNCTION__
+        ));
+      ASSERT (FALSE);
+    }
+
+    //
+    // Final PciHostIrqs[] index calculation depends on the platform
+    // and should match SeaBIOS src/fw/pciinit.c *_pci_slot_get_irq()
+    //
+    switch (mHostBridgeDevId) {
+      case INTEL_82441_DEVICE_ID:
+        Idx -= 1;
+        break;
+      case INTEL_Q35_MCH_DEVICE_ID:
+        //
+        // SeaBIOS contains the following comment:
+        // "Slots 0-24 rotate slot:pin mapping similar to piix above, but
+        //  with a different starting index - see q35-acpi-dsdt.dsl.
+        //
+        //  Slots 25-31 all use LNKA mapping (or LNKE, but A:D = E:H)"
+        //
+        if (RootSlot > 24) {
+          //
+          // in this case, subtract back out RootSlot from Idx
+          // (SeaBIOS never adds it to begin with, but that would make our
+          //  device path traversal loop above too awkward)
+          //
+          Idx -= RootSlot;
+        }
+        break;
+      default:
+        ASSERT (FALSE); // should never get here
+    }
+    Idx %= ARRAY_SIZE (PciHostIrqs);
+    IrqLine = PciHostIrqs[Idx];
+
+    DEBUG_CODE_BEGIN ();
+    {
+      CHAR16        *DevPathString;
+      STATIC CHAR16 Fallback[] = L"<failed to convert>";
+      UINTN         Segment, Bus, Device, Function;
+
+      DevPathString = ConvertDevicePathToText (DevPath, FALSE, FALSE);
+      if (DevPathString == NULL) {
+        DevPathString = Fallback;
+      }
+      Status = PciIo->GetLocation (PciIo, &Segment, &Bus, &Device, &Function);
+      ASSERT_EFI_ERROR (Status);
+
+      DEBUG ((DEBUG_VERBOSE, "%a: [%02x:%02x.%x] %s -> 0x%02x\n", __FUNCTION__,
+        (UINT32)Bus, (UINT32)Device, (UINT32)Function, DevPathString,
+        IrqLine));
+
+      if (DevPathString != Fallback) {
+        FreePool (DevPathString);
+      }
+    }
+    DEBUG_CODE_END ();
+
+    //
+    // Set PCI Interrupt Line register for this device to PciHostIrqs[Idx]
+    //
+    Status = PciIo->Pci.Write (
+               PciIo,
+               EfiPciIoWidthUint8,
+               PCI_INT_LINE_OFFSET,
+               1,
+               &IrqLine
+               );
+  }
+
+  return Status;
+}
+
+
+VOID
+PciAcpiInitialization (
+  )
+{
+  UINTN  Pmba;
+
+  //
+  // Query Host Bridge DID to determine platform type
+  //
+  mHostBridgeDevId = PcdGet16 (PcdOvmfHostBridgePciDevId);
+  switch (mHostBridgeDevId) {
+    case INTEL_82441_DEVICE_ID:
+      Pmba = POWER_MGMT_REGISTER_PIIX4 (PIIX4_PMBA);
+      //
+      // 00:01.0 ISA Bridge (PIIX4) LNK routing targets
+      //
+      PciWrite8 (PCI_LIB_ADDRESS (0, 1, 0, 0x60), 0x0b); // A
+      PciWrite8 (PCI_LIB_ADDRESS (0, 1, 0, 0x61), 0x0b); // B
+      PciWrite8 (PCI_LIB_ADDRESS (0, 1, 0, 0x62), 0x0a); // C
+      PciWrite8 (PCI_LIB_ADDRESS (0, 1, 0, 0x63), 0x0a); // D
+      break;
+    case INTEL_Q35_MCH_DEVICE_ID:
+      Pmba = POWER_MGMT_REGISTER_Q35 (ICH9_PMBASE);
+      //
+      // 00:1f.0 LPC Bridge (Q35) LNK routing targets
+      //
+      PciWrite8 (PCI_LIB_ADDRESS (0, 0x1f, 0, 0x60), 0x0a); // A
+      PciWrite8 (PCI_LIB_ADDRESS (0, 0x1f, 0, 0x61), 0x0a); // B
+      PciWrite8 (PCI_LIB_ADDRESS (0, 0x1f, 0, 0x62), 0x0b); // C
+      PciWrite8 (PCI_LIB_ADDRESS (0, 0x1f, 0, 0x63), 0x0b); // D
+      PciWrite8 (PCI_LIB_ADDRESS (0, 0x1f, 0, 0x68), 0x0a); // E
+      PciWrite8 (PCI_LIB_ADDRESS (0, 0x1f, 0, 0x69), 0x0a); // F
+      PciWrite8 (PCI_LIB_ADDRESS (0, 0x1f, 0, 0x6a), 0x0b); // G
+      PciWrite8 (PCI_LIB_ADDRESS (0, 0x1f, 0, 0x6b), 0x0b); // H
+      break;
+    default:
+      if (XenDetected ()) {
+        //
+        // There is no PCI bus in this case.
+        //
+        return;
+      }
+      DEBUG ((DEBUG_ERROR, "%a: Unknown Host Bridge Device ID: 0x%04x\n",
+        __FUNCTION__, mHostBridgeDevId));
+      ASSERT (FALSE);
+      return;
+  }
+
+  //
+  // Initialize PCI_INTERRUPT_LINE for applicable present PCI devices
+  //
+  VisitAllPciInstances (SetPciIntLine);
+
+  //
+  // Set ACPI SCI_EN bit in PMCNTRL
+  //
+  IoOr16 ((PciRead32 (Pmba) & ~BIT0) + 4, BIT0);
+}
+
+EFI_STATUS
+EFIAPI
+ConnectRecursivelyIfPciMassStorage (
+  IN EFI_HANDLE           Handle,
+  IN EFI_PCI_IO_PROTOCOL  *Instance,
+  IN PCI_TYPE00           *PciHeader
+  )
+{
+  EFI_STATUS                Status;
+  EFI_DEVICE_PATH_PROTOCOL  *DevicePath;
+  CHAR16                    *DevPathStr;
+
+  //
+  // Recognize PCI Mass Storage, and Xen PCI devices
+  //
+  if (IS_CLASS1 (PciHeader, PCI_CLASS_MASS_STORAGE) ||
+      (XenDetected() && IS_CLASS2 (PciHeader, 0xFF, 0x80))) {
+    DevicePath = NULL;
+    Status = gBS->HandleProtocol (
+                    Handle,
+                    &gEfiDevicePathProtocolGuid,
+                    (VOID*)&DevicePath
+                    );
+    if (EFI_ERROR (Status)) {
+      return Status;
+    }
+
+    //
+    // Print Device Path
+    //
+    DevPathStr = ConvertDevicePathToText (DevicePath, FALSE, FALSE);
+    if (DevPathStr != NULL) {
+      DEBUG((
+        DEBUG_INFO,
+        "Found %s device: %s\n",
+        (IS_CLASS1 (PciHeader, PCI_CLASS_MASS_STORAGE) ?
+         L"Mass Storage" :
+         L"Xen"
+         ),
+        DevPathStr
+        ));
+      FreePool(DevPathStr);
+    }
+
+    Status = gBS->ConnectController (Handle, NULL, NULL, TRUE);
+    if (EFI_ERROR (Status)) {
+      return Status;
+    }
+
+  }
+
+  return EFI_SUCCESS;
+}
+
+
+/**
+  Connect with predefined platform connect sequence.
+
+  The OEM/IBV can customize with their own connect sequence.
+**/
+VOID
+PlatformBdsConnectSequence (
+  VOID
+  )
+{
+  UINTN         Index;
+
+  DEBUG ((DEBUG_INFO, "PlatformBdsConnectSequence\n"));
+
+  Index = 0;
+
+  //
+  // Here we can get the customized platform connect sequence
+  // Notes: we can connect with new variable which record the
+  // last time boots connect device path sequence
+  //
+  while (gPlatformConnectSequence[Index] != NULL) {
+    //
+    // Build the platform boot option
+    //
+    EfiBootManagerConnectDevicePath (gPlatformConnectSequence[Index], NULL);
+    Index++;
+  }
+  EfiBootManagerConnectAll ();
+}
+
+/**
+  Do the platform specific action after the console is ready
+
+  Possible things that can be done in PlatformBootManagerAfterConsole:
+
+  > Console post action:
+    > Dynamically switch output mode from 100x31 to 80x25 for certain senarino
+    > Signal console ready platform customized event
+  > Run diagnostics like memory testing
+  > Connect certain devices
+  > Dispatch aditional option roms
+  > Special boot: e.g.: USB boot, enter UI
+**/
+VOID
+EFIAPI
+PlatformBootManagerAfterConsole (
+  VOID
+  )
+{
+  EFI_BOOT_MODE                      BootMode;
+
+  DEBUG ((DEBUG_INFO, "PlatformBootManagerAfterConsole\n"));
+
+  //
+  // Get current Boot Mode
+  //
+  BootMode = GetBootModeHob ();
+  DEBUG ((DEBUG_INFO, "Boot Mode:%x\n", BootMode));
+
+  //
+  // Go the different platform policy with different boot mode
+  // Notes: this part code can be change with the table policy
+  //
+  ASSERT (BootMode == BOOT_WITH_FULL_CONFIGURATION);
+
+  //
+  // Logo show
+  //
+  BootLogoEnableLogo ();
+
+  //
+  // Set PCI Interrupt Line registers and ACPI SCI_EN
+  //
+  PciAcpiInitialization ();
+
+  //
+  // Process TPM PPI request
+  //
+  Tcg2PhysicalPresenceLibProcessRequest (NULL);
+
+  //
+  // Perform some platform specific connect sequence
+  //
+  PlatformBdsConnectSequence ();
+
+  EfiBootManagerRefreshAllBootOption ();
+
+  //
+  // Register UEFI Shell (Will be removed if the Shell isn't built
+  // which is the default)
+  //
+  PlatformRegisterFvBootOption (
+    &gUefiShellFileGuid, L"EFI Internal Shell", LOAD_OPTION_ACTIVE
+    );
+
+  //
+  // Register Grub
+  //
+  PlatformRegisterFvBootOption (
+    &gGrubFileGuid, L"Grub Bootloader", LOAD_OPTION_ACTIVE
+    );
+
+  RemoveStaleFvFileOptions ();
+
+  PlatformBmPrintScRegisterHandler ();
+}
+
+/**
+  This notification function is invoked when an instance of the
+  EFI_DEVICE_PATH_PROTOCOL is produced.
+
+  @param  Event                 The event that occurred
+  @param  Context               For EFI compatibility.  Not used.
+
+**/
+VOID
+EFIAPI
+NotifyDevPath (
+  IN  EFI_EVENT Event,
+  IN  VOID      *Context
+  )
+{
+  EFI_HANDLE                            Handle;
+  EFI_STATUS                            Status;
+  UINTN                                 BufferSize;
+  EFI_DEVICE_PATH_PROTOCOL             *DevPathNode;
+  ATAPI_DEVICE_PATH                    *Atapi;
+
+  //
+  // Examine all new handles
+  //
+  for (;;) {
+    //
+    // Get the next handle
+    //
+    BufferSize = sizeof (Handle);
+    Status = gBS->LocateHandle (
+              ByRegisterNotify,
+              NULL,
+              mEfiDevPathNotifyReg,
+              &BufferSize,
+              &Handle
+              );
+
+    //
+    // If not found, we're done
+    //
+    if (EFI_NOT_FOUND == Status) {
+      break;
+    }
+
+    if (EFI_ERROR (Status)) {
+      continue;
+    }
+
+    //
+    // Get the DevicePath protocol on that handle
+    //
+    Status = gBS->HandleProtocol (Handle, &gEfiDevicePathProtocolGuid,
+                    (VOID **)&DevPathNode);
+    ASSERT_EFI_ERROR (Status);
+
+    while (!IsDevicePathEnd (DevPathNode)) {
+      //
+      // Find the handler to dump this device path node
+      //
+      if (
+           (DevicePathType(DevPathNode) == MESSAGING_DEVICE_PATH) &&
+           (DevicePathSubType(DevPathNode) == MSG_ATAPI_DP)
+         ) {
+        Atapi = (ATAPI_DEVICE_PATH*) DevPathNode;
+        PciOr16 (
+          PCI_LIB_ADDRESS (
+            0,
+            1,
+            1,
+            (Atapi->PrimarySecondary == 1) ? 0x42: 0x40
+            ),
+          BIT15
+          );
+      }
+
+      //
+      // Next device path node
+      //
+      DevPathNode = NextDevicePathNode (DevPathNode);
+    }
+  }
+
+  return;
+}
+
+
+VOID
+InstallDevicePathCallback (
+  VOID
+  )
+{
+  DEBUG ((DEBUG_INFO, "Registered NotifyDevPath Event\n"));
+  mEfiDevPathEvent = EfiCreateProtocolNotifyEvent (
+                          &gEfiDevicePathProtocolGuid,
+                          TPL_CALLBACK,
+                          NotifyDevPath,
+                          NULL,
+                          &mEfiDevPathNotifyReg
+                          );
+}
+
+/**
+  This function is called each second during the boot manager waits the
+  timeout.
+
+  @param TimeoutRemain  The remaining timeout.
+**/
+VOID
+EFIAPI
+PlatformBootManagerWaitCallback (
+  UINT16          TimeoutRemain
+  )
+{
+  //
+  // Since the timeout should be forced to zero we should never
+  // Get here
+  //
+  ASSERT (FALSE);
+}
+
+/**
+  The function is called when no boot option could be launched,
+  including platform recovery options and options pointing to applications
+  built into firmware volumes.
+
+  If this function returns, BDS attempts to enter an infinite loop.
+**/
+VOID
+EFIAPI
+PlatformBootManagerUnableToBoot (
+  VOID
+  )
+{
+  //
+  // If we get here something failed about the grub boot but since
+  // We're privy to the secret we must panic and not retry or loop
+  //
+  CpuDeadLoop ();
+}
diff --git a/OvmfPkg/Library/PlatformBootManagerLibGrub/PlatformData.c b/OvmfPkg/Library/PlatformBootManagerLibGrub/PlatformData.c
new file mode 100644
index 000000000000..2858c3dfd5ca
--- /dev/null
+++ b/OvmfPkg/Library/PlatformBootManagerLibGrub/PlatformData.c
@@ -0,0 +1,213 @@
+/** @file
+  Defined the platform specific device path which will be used by
+  platform Bbd to perform the platform policy connect.
+
+  Copyright (c) 2004 - 2017, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include "BdsPlatform.h"
+#include <Guid/QemuRamfb.h>
+#include <Guid/SerialPortLibVendor.h>
+
+//
+// Vendor UART Device Path structure
+//
+#pragma pack (1)
+typedef struct {
+  VENDOR_DEVICE_PATH        VendorHardware;
+  UART_DEVICE_PATH          Uart;
+  VENDOR_DEVICE_PATH        TerminalType;
+  EFI_DEVICE_PATH_PROTOCOL  End;
+} VENDOR_UART_DEVICE_PATH;
+#pragma pack ()
+
+//
+// USB Keyboard Device Path structure
+//
+#pragma pack (1)
+typedef struct {
+  USB_CLASS_DEVICE_PATH    Keyboard;
+  EFI_DEVICE_PATH_PROTOCOL End;
+} USB_KEYBOARD_DEVICE_PATH;
+#pragma pack ()
+
+//
+// QemuRamfb Device Path structure
+//
+#pragma pack (1)
+typedef struct {
+  VENDOR_DEVICE_PATH        Vendor;
+  ACPI_ADR_DEVICE_PATH      AcpiAdr;
+  EFI_DEVICE_PATH_PROTOCOL  End;
+} VENDOR_RAMFB_DEVICE_PATH;
+#pragma pack ()
+
+ACPI_HID_DEVICE_PATH       gPnpPs2KeyboardDeviceNode  = gPnpPs2Keyboard;
+ACPI_HID_DEVICE_PATH       gPnp16550ComPortDeviceNode = gPnp16550ComPort;
+UART_DEVICE_PATH           gUartDeviceNode            = gUart;
+VENDOR_DEVICE_PATH         gTerminalTypeDeviceNode    = gPcAnsiTerminal;
+
+//
+// Platform specific keyboard device path
+//
+
+
+//
+// Debug Agent UART Device Path
+//
+VENDOR_UART_DEVICE_PATH gDebugAgentUartDevicePath = {
+  {
+    {
+      HARDWARE_DEVICE_PATH,
+      HW_VENDOR_DP,
+      {
+        (UINT8) (sizeof (VENDOR_DEVICE_PATH)),
+        (UINT8) ((sizeof (VENDOR_DEVICE_PATH)) >> 8)
+      }
+    },
+    EFI_DEBUG_AGENT_GUID,
+  },
+  {
+    {
+      MESSAGING_DEVICE_PATH,
+      MSG_UART_DP,
+      {
+        (UINT8) (sizeof (UART_DEVICE_PATH)),
+        (UINT8) ((sizeof (UART_DEVICE_PATH)) >> 8)
+      }
+    },
+    0,  // Reserved
+    0,  // BaudRate - Default
+    0,  // DataBits - Default
+    0,  // Parity   - Default
+    0,  // StopBits - Default
+  },
+  gPcAnsiTerminal,
+  gEndEntire
+};
+
+STATIC USB_KEYBOARD_DEVICE_PATH gUsbKeyboardDevicePath = {
+  {
+    {
+      MESSAGING_DEVICE_PATH,
+      MSG_USB_CLASS_DP,
+      {
+        (UINT8)sizeof (USB_CLASS_DEVICE_PATH),
+        (UINT8)(sizeof (USB_CLASS_DEVICE_PATH) >> 8)
+      }
+    },
+    0xFFFF, // VendorId: any
+    0xFFFF, // ProductId: any
+    3,      // DeviceClass: HID
+    1,      // DeviceSubClass: boot
+    1       // DeviceProtocol: keyboard
+  },
+  gEndEntire
+};
+
+STATIC VENDOR_RAMFB_DEVICE_PATH gQemuRamfbDevicePath = {
+  {
+    {
+      HARDWARE_DEVICE_PATH,
+      HW_VENDOR_DP,
+      {
+        (UINT8) (sizeof (VENDOR_DEVICE_PATH)),
+        (UINT8) ((sizeof (VENDOR_DEVICE_PATH)) >> 8)
+      }
+    },
+    QEMU_RAMFB_GUID,
+  },
+  {
+    {
+      ACPI_DEVICE_PATH,
+      ACPI_ADR_DP,
+      {
+        (UINT8) (sizeof (ACPI_ADR_DEVICE_PATH)),
+        (UINT8) ((sizeof (ACPI_ADR_DEVICE_PATH)) >> 8)
+      }
+    },
+    ACPI_DISPLAY_ADR (
+      1,                                       // DeviceIdScheme
+      0,                                       // HeadId
+      0,                                       // NonVgaOutput
+      1,                                       // BiosCanDetect
+      0,                                       // VendorInfo
+      ACPI_ADR_DISPLAY_TYPE_EXTERNAL_DIGITAL,  // Type
+      0,                                       // Port
+      0                                        // Index
+      ),
+  },
+  gEndEntire
+};
+
+STATIC VENDOR_UART_DEVICE_PATH gXenConsoleDevicePath = {
+  {
+    {
+      HARDWARE_DEVICE_PATH,
+      HW_VENDOR_DP,
+      {
+        (UINT8) (sizeof (VENDOR_DEVICE_PATH)),
+        (UINT8) ((sizeof (VENDOR_DEVICE_PATH)) >> 8)
+      }
+    },
+    EDKII_SERIAL_PORT_LIB_VENDOR_GUID
+  },
+  {
+    {
+      MESSAGING_DEVICE_PATH,
+      MSG_UART_DP,
+      {
+        (UINT8) (sizeof (UART_DEVICE_PATH)),
+        (UINT8) ((sizeof (UART_DEVICE_PATH)) >> 8)
+      }
+    },
+    0,
+    FixedPcdGet64 (PcdUartDefaultBaudRate),
+    FixedPcdGet8 (PcdUartDefaultDataBits),
+    FixedPcdGet8 (PcdUartDefaultParity),
+    FixedPcdGet8 (PcdUartDefaultStopBits),
+  },
+  gPcAnsiTerminal,
+  gEndEntire
+};
+
+//
+// Predefined platform default console device path
+//
+PLATFORM_CONSOLE_CONNECT_ENTRY   gPlatformConsole[] = {
+  {
+    (EFI_DEVICE_PATH_PROTOCOL *) &gDebugAgentUartDevicePath,
+    (CONSOLE_OUT | CONSOLE_IN | STD_ERROR)
+  },
+  {
+    (EFI_DEVICE_PATH_PROTOCOL *)&gUsbKeyboardDevicePath,
+    CONSOLE_IN
+  },
+  {
+    (EFI_DEVICE_PATH_PROTOCOL *)&gQemuRamfbDevicePath,
+    CONSOLE_OUT
+  },
+  {
+    NULL,
+    0
+  }
+};
+
+PLATFORM_CONSOLE_CONNECT_ENTRY   gXenPlatformConsole[] = {
+  {
+    (EFI_DEVICE_PATH_PROTOCOL *)&gXenConsoleDevicePath,
+    (CONSOLE_OUT | CONSOLE_IN | STD_ERROR)
+  },
+  {
+    NULL,
+    0
+  }
+};
+
+//
+// Predefined platform connect sequence
+//
+EFI_DEVICE_PATH_PROTOCOL    *gPlatformConnectSequence[] = { NULL };
+
diff --git a/OvmfPkg/AmdSev/Grub/.gitignore b/OvmfPkg/AmdSev/Grub/.gitignore
new file mode 100644
index 000000000000..7e3b30951f22
--- /dev/null
+++ b/OvmfPkg/AmdSev/Grub/.gitignore
@@ -0,0 +1 @@
+grub.efi
diff --git a/OvmfPkg/AmdSev/Grub/grub.cfg b/OvmfPkg/AmdSev/Grub/grub.cfg
new file mode 100644
index 000000000000..b2951bb13e41
--- /dev/null
+++ b/OvmfPkg/AmdSev/Grub/grub.cfg
@@ -0,0 +1,46 @@
+##  @file
+#  Execute a script to recover the SEV supplied secret and use it to
+#  decrypt a luks volume.  For security, the kernel must be on an encrypted
+#  volume so reboot if none are found.
+#
+#  Copyright (C) 2020 James Bottomley, IBM Corporation.
+#
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+echo "Entering grub config"
+sevsecret
+if [ $? -ne 0 ]; then
+    echo "Failed to locate anything in the SEV secret area, prompting for password"
+    cryptomount -a
+else
+    cryptomount -s
+    if [ $? -ne 0 ]; then
+        echo "Failed to mount root securely, retrying with password prompt"
+        cryptomount -a
+    fi
+fi
+set root=
+for f in (crypto*); do
+    if [ -e $f/boot/grub/grub.cfg ]; then
+        set root=$f
+	set prefix=($root)/boot/grub
+	break;
+    fi
+done
+if [ x$root = x ]; then
+    echo "Failed to find any grub configuration on the encrypted volume"
+    sleep 5
+    reboot
+fi
+# rest of modules to get boot to work
+set modules="
+    boot
+    loadenv
+    "
+for f in $modules; do
+    insmod $f
+done
+echo "Transferring to ${prefix}/grub.cfg"
+source $prefix/grub.cfg
diff --git a/OvmfPkg/AmdSev/Grub/grub.sh b/OvmfPkg/AmdSev/Grub/grub.sh
new file mode 100644
index 000000000000..fd28dc6ab274
--- /dev/null
+++ b/OvmfPkg/AmdSev/Grub/grub.sh
@@ -0,0 +1,92 @@
+##  @file
+#  Build a version of grub capable of decrypting a luks volume with a SEV
+#  Supplied secret
+#
+#  Copyright (C) 2020 James Bottomley, IBM Corporation.
+#
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+set -e
+remove_efi=1
+
+cleanup()  {
+    # remove the intermediates
+    for f in disk.fat grub-bootstrap.cfg; do
+	rm -f "${basedir}/$f"
+    done
+    if [ $remove_efi -eq 1 ]; then
+	rm -f "${basedir}/grub.efi"
+    fi
+}
+
+trap cleanup EXIT
+
+GRUB_MODULES="
+	    part_msdos
+	    part_gpt
+	    cryptodisk
+	    luks
+	    gcry_rijndael
+	    gcry_sha256
+	    ext2
+	    btrfs
+	    xfs
+	    fat
+	    configfile
+	    memdisk
+	    sleep
+	    normal
+	    echo
+	    test
+	    regexp
+	    linux
+	    linuxefi
+	    reboot
+	    sevsecret
+	    "
+basedir=$(dirname -- "$0")
+
+# don't run a build if grub.efi exists and is newer than the config files
+if [ -e "${basedir}/grub.efi" -a \
+     "${basedir}/grub.efi" -nt "${basedir}/grub.cfg" -a \
+     "${basedir}/grub.efi" -nt "${basedir}/grub.sh" ]; then
+    remove_efi=0
+    echo "preserving existing grub.efi"
+    exit 0
+fi
+
+##
+# different distributions have different names for grub-mkimage, so
+# search all the known ones
+##
+for b in grub2-mkimage grub-mkimage; do
+    if which "$b" > /dev/null 2>&1; then
+	mkimage="$b"
+	break;
+    fi
+done
+if [ -z "$mkimage" ]; then
+    echo "Can't find grub mkimage" >&2
+    exit 1
+fi
+
+# GRUB's rescue parser doesn't understand 'if'.
+echo 'normal (memdisk)/grub.cfg' > "${basedir}/grub-bootstrap.cfg"
+
+# Now build a memdisk with the correct grub.cfg
+rm -f -- "${basedir}/disk.fat"
+mkfs.msdos -C -- "${basedir}/disk.fat" 64
+mcopy -i "${basedir}/disk.fat" -- "${basedir}/grub.cfg" ::grub.cfg
+
+
+${mkimage} -O x86_64-efi \
+	   -p '(crypto0)' \
+	   -c "${basedir}/grub-bootstrap.cfg" \
+	   -m "${basedir}/disk.fat" \
+	   -o "${basedir}/grub.efi" \
+	   ${GRUB_MODULES}
+
+remove_efi=0
+echo "grub.efi generated in ${basedir}"
-- 
2.26.2


^ permalink raw reply related	[flat|nested] 37+ messages in thread

* [PATCH v2 3/6] OvmfPkg: convert ES Reset Block structure to be guided
  2020-11-20 18:45 [PATCH v2 0/6] SEV Encrypted Boot for Ovmf James Bottomley
  2020-11-20 18:45 ` [PATCH v2 1/6] OvmfPkg/Amdsev: Base commit to build encrypted boot specific OVMF James Bottomley
  2020-11-20 18:45 ` [PATCH v2 2/6] OvmfPkg/AmdSev: add Grub Firmware Volume Package James Bottomley
@ 2020-11-20 18:45 ` James Bottomley
  2020-11-23 22:16   ` Laszlo Ersek
  2020-11-20 18:45 ` [PATCH v2 4/6] OvmfPkg: create a SEV secret area in the AmdSev memfd James Bottomley
                   ` (2 subsequent siblings)
  5 siblings, 1 reply; 37+ messages in thread
From: James Bottomley @ 2020-11-20 18:45 UTC (permalink / raw)
  To: devel
  Cc: dovmurik, Dov.Murik1, ashish.kalra, brijesh.singh, tobin,
	david.kaplan, jon.grimm, thomas.lendacky, jejb, frankeh,
	Dr . David Alan Gilbert, Laszlo Ersek

Convert the current ES reset block structure to an extensible guid
based structure by appending a header and length, which allow for
multiple guid based data packets to be inserted.

Ref: https://bugzilla.tianocore.org/show_bug.cgi?id=3077
Signed-off-by: James Bottomley <jejb@linux.ibm.com>

---

v2: added
---
 OvmfPkg/ResetVector/Ia16/ResetVectorVtf0.asm | 49 +++++++++++++++-----
 1 file changed, 38 insertions(+), 11 deletions(-)

diff --git a/OvmfPkg/ResetVector/Ia16/ResetVectorVtf0.asm b/OvmfPkg/ResetVector/Ia16/ResetVectorVtf0.asm
index 980e0138e7fe..baf9d09f3625 100644
--- a/OvmfPkg/ResetVector/Ia16/ResetVectorVtf0.asm
+++ b/OvmfPkg/ResetVector/Ia16/ResetVectorVtf0.asm
@@ -25,21 +25,40 @@ ALIGN   16
     TIMES (0x1000 - ($ - EndOfPageTables) - 0x20) DB 0
 %endif
 
+;
+; Padding to ensure first guid starts at 0xffffffd0
+;
+TIMES (32 - ((guidedStructureEnd - guidedStructureStart) % 32)) DB 0
+
+; Guided structure.  To traverse this you should first verify the
+; presence of the table header guid
+; (96b582de-1fb2-45f7-baea-a366c55a082d) at 0xffffffd0.  If that
+; is found, the two bytes at 0xffffffce are the entire table length.
+;
+; The table is composed of structures with the form:
+;
+; Data (arbitrary bytes identified by guid)
+; length from start of guid to end of data (2 bytes)
+; guid (16 bytes)
+;
+; so work back from the header using the length to traverse until you
+; either find the guid you're looking for or run off the end of the
+; table.
+;
+guidedStructureStart:
+
 ;
 ; SEV-ES Processor Reset support
 ;
 ; sevEsResetBlock:
 ;   For the initial boot of an AP under SEV-ES, the "reset" RIP must be
-;   programmed to the RAM area defined by SEV_ES_AP_RESET_IP. A known offset
-;   and GUID will be used to locate this block in the firmware and extract
-;   the build time RIP value. The GUID must always be 48 bytes from the
-;   end of the firmware.
+;   programmed to the RAM area defined by SEV_ES_AP_RESET_IP. The data
+;   format is
 ;
-;   0xffffffca (-0x36) - IP value
-;   0xffffffcc (-0x34) - CS segment base [31:16]
-;   0xffffffce (-0x32) - Size of the SEV-ES reset block
-;   0xffffffd0 (-0x30) - SEV-ES reset block GUID
-;                        (00f771de-1a7e-4fcb-890e-68c77e2fb44e)
+;   IP value [0:15]
+;   CS segment base [31:16]
+;
+;   SEV-ES reset block GUID: 00f771de-1a7e-4fcb-890e-68c77e2fb44e
 ;
 ;   A hypervisor reads the CS segement base and IP value. The CS segment base
 ;   value represents the high order 16-bits of the CS segment base, so the
@@ -48,8 +67,6 @@ ALIGN   16
 ;   program the EIP register with the IP value as read.
 ;
 
-TIMES (32 - (sevEsResetBlockEnd - sevEsResetBlockStart)) DB 0
-
 sevEsResetBlockStart:
     DD      SEV_ES_AP_RESET_IP
     DW      sevEsResetBlockEnd - sevEsResetBlockStart
@@ -57,6 +74,16 @@ sevEsResetBlockStart:
     DB      0x89, 0x0E, 0x68, 0xC7, 0x7E, 0x2F, 0xB4, 0x4E
 sevEsResetBlockEnd:
 
+;
+; Table header: length of whole table followed by table header
+; guid: 96b582de-1fb2-45f7-baea-a366c55a082d
+;
+    DW      guidedStructureEnd - guidedStructureStart
+    DB      0xDE, 0x82, 0xB5, 0x96, 0xB2, 0x1F, 0xF7, 0x45
+    DB      0xBA, 0xEA, 0xA3, 0x66, 0xC5, 0x5A, 0x08, 0x2D
+
+guidedStructureEnd:
+
 ALIGN   16
 
 applicationProcessorEntryPoint:
-- 
2.26.2


^ permalink raw reply related	[flat|nested] 37+ messages in thread

* [PATCH v2 4/6] OvmfPkg: create a SEV secret area in the AmdSev memfd
  2020-11-20 18:45 [PATCH v2 0/6] SEV Encrypted Boot for Ovmf James Bottomley
                   ` (2 preceding siblings ...)
  2020-11-20 18:45 ` [PATCH v2 3/6] OvmfPkg: convert ES Reset Block structure to be guided James Bottomley
@ 2020-11-20 18:45 ` James Bottomley
  2020-11-23 22:28   ` Laszlo Ersek
  2020-11-20 18:45 ` [PATCH v2 5/6] OvmfPkg/AmdSev: assign and protect the Sev Secret area James Bottomley
  2020-11-20 18:45 ` [PATCH v2 6/6] OvmfPkg/AmdSev: Expose the Sev Secret area using a configuration table James Bottomley
  5 siblings, 1 reply; 37+ messages in thread
From: James Bottomley @ 2020-11-20 18:45 UTC (permalink / raw)
  To: devel
  Cc: dovmurik, Dov.Murik1, ashish.kalra, brijesh.singh, tobin,
	david.kaplan, jon.grimm, thomas.lendacky, jejb, frankeh,
	Dr . David Alan Gilbert, Laszlo Ersek

SEV needs an area to place an injected secret where OVMF can find it
and pass it up as a ConfigurationTable.  This patch implements the
area itself as an addition to the SEV enhanced reset vector table using
an additional guid (4c2eb361-7d9b-4cc3-8081-127c90d3d294).

Ref: https://bugzilla.tianocore.org/show_bug.cgi?id=3077
Signed-off-by: James Bottomley <jejb@linux.ibm.com>

---

v2: move guid to OVMF token space, separate patches
---
 OvmfPkg/OvmfPkg.dec                          |  6 ++++++
 OvmfPkg/ResetVector/ResetVector.inf          |  4 ++++
 OvmfPkg/ResetVector/Ia16/ResetVectorVtf0.asm | 14 ++++++++++++++
 OvmfPkg/ResetVector/ResetVector.nasmb        |  2 ++
 4 files changed, 26 insertions(+)

diff --git a/OvmfPkg/OvmfPkg.dec b/OvmfPkg/OvmfPkg.dec
index 3fbf7a0ee1a4..7d27f8e16040 100644
--- a/OvmfPkg/OvmfPkg.dec
+++ b/OvmfPkg/OvmfPkg.dec
@@ -304,6 +304,12 @@ [PcdsFixedAtBuild]
   gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecGhcbBase|0|UINT32|0x40
   gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecGhcbSize|0|UINT32|0x41
 
+  ## The base address and size of the SEV Launch Secret Area provisioned
+  #  after remote attestation.  If this is set in the .fdf, the platform
+  #  is responsible for protecting the area from DXE phase overwrites.
+  gUefiOvmfPkgTokenSpaceGuid.PcdSevLaunchSecretBase|0x0|UINT32|0x42
+  gUefiOvmfPkgTokenSpaceGuid.PcdSevLaunchSecretSize|0x0|UINT32|0x43
+
 [PcdsDynamic, PcdsDynamicEx]
   gUefiOvmfPkgTokenSpaceGuid.PcdEmuVariableEvent|0|UINT64|2
   gUefiOvmfPkgTokenSpaceGuid.PcdOvmfFlashVariablesEnable|FALSE|BOOLEAN|0x10
diff --git a/OvmfPkg/ResetVector/ResetVector.inf b/OvmfPkg/ResetVector/ResetVector.inf
index a53ae6c194ae..dc38f68919cd 100644
--- a/OvmfPkg/ResetVector/ResetVector.inf
+++ b/OvmfPkg/ResetVector/ResetVector.inf
@@ -43,3 +43,7 @@ [Pcd]
   gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecPageTablesSize
   gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecPeiTempRamBase
   gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecPeiTempRamSize
+
+[FixedPcd]
+  gUefiOvmfPkgTokenSpaceGuid.PcdSevLaunchSecretBase
+  gUefiOvmfPkgTokenSpaceGuid.PcdSevLaunchSecretSize
diff --git a/OvmfPkg/ResetVector/Ia16/ResetVectorVtf0.asm b/OvmfPkg/ResetVector/Ia16/ResetVectorVtf0.asm
index baf9d09f3625..8d6600f17310 100644
--- a/OvmfPkg/ResetVector/Ia16/ResetVectorVtf0.asm
+++ b/OvmfPkg/ResetVector/Ia16/ResetVectorVtf0.asm
@@ -47,6 +47,20 @@ TIMES (32 - ((guidedStructureEnd - guidedStructureStart) % 32)) DB 0
 ;
 guidedStructureStart:
 
+;
+; SEV Secret block Guid: 4c2eb361-7d9b-4cc3-8081-127c90d3d294
+;
+; This describes the guest ram area where the hypervisor may have
+; injected the secret
+;
+sevSecretBlockStart:
+    DD      SEV_LAUNCH_SECRET_BASE
+    DD      SEV_LAUNCH_SECRET_SIZE
+    DW      sevSecretBlockEnd - sevSecretBlockStart
+    DB      0x61, 0xB3, 0x2E, 0x4C, 0x9B, 0x7D, 0xC3, 0x4C
+    DB      0x80, 0x81, 0x12, 0x7C, 0x90, 0xD3, 0xD2, 0x94
+sevSecretBlockEnd:
+
 ;
 ; SEV-ES Processor Reset support
 ;
diff --git a/OvmfPkg/ResetVector/ResetVector.nasmb b/OvmfPkg/ResetVector/ResetVector.nasmb
index 4913b379a993..c5e0fe93abf4 100644
--- a/OvmfPkg/ResetVector/ResetVector.nasmb
+++ b/OvmfPkg/ResetVector/ResetVector.nasmb
@@ -83,5 +83,7 @@
 %include "Main.asm"
 
   %define SEV_ES_AP_RESET_IP  FixedPcdGet32 (PcdSevEsWorkAreaBase)
+  %define SEV_LAUNCH_SECRET_BASE  FixedPcdGet32 (PcdSevLaunchSecretBase)
+  %define SEV_LAUNCH_SECRET_SIZE  FixedPcdGet32 (PcdSevLaunchSecretSize)
 %include "Ia16/ResetVectorVtf0.asm"
 
-- 
2.26.2


^ permalink raw reply related	[flat|nested] 37+ messages in thread

* [PATCH v2 5/6] OvmfPkg/AmdSev: assign and protect the Sev Secret area
  2020-11-20 18:45 [PATCH v2 0/6] SEV Encrypted Boot for Ovmf James Bottomley
                   ` (3 preceding siblings ...)
  2020-11-20 18:45 ` [PATCH v2 4/6] OvmfPkg: create a SEV secret area in the AmdSev memfd James Bottomley
@ 2020-11-20 18:45 ` James Bottomley
  2020-11-23 22:38   ` Laszlo Ersek
  2020-11-20 18:45 ` [PATCH v2 6/6] OvmfPkg/AmdSev: Expose the Sev Secret area using a configuration table James Bottomley
  5 siblings, 1 reply; 37+ messages in thread
From: James Bottomley @ 2020-11-20 18:45 UTC (permalink / raw)
  To: devel
  Cc: dovmurik, Dov.Murik1, ashish.kalra, brijesh.singh, tobin,
	david.kaplan, jon.grimm, thomas.lendacky, jejb, frankeh,
	Dr . David Alan Gilbert, Laszlo Ersek

Create a one page secret area in the MEMFD and protect the area with a
boot time HOB.

Ref: https://bugzilla.tianocore.org/show_bug.cgi?id=3077
Signed-off-by: James Bottomley <jejb@linux.ibm.com>
---
 OvmfPkg/AmdSev/AmdSevX64.dsc           |  1 +
 OvmfPkg/AmdSev/AmdSevX64.fdf           |  4 +++
 OvmfPkg/AmdSev/SecretPei/SecretPei.inf | 39 ++++++++++++++++++++++++++
 OvmfPkg/AmdSev/SecretPei/SecretPei.c   | 25 +++++++++++++++++
 4 files changed, 69 insertions(+)
 create mode 100644 OvmfPkg/AmdSev/SecretPei/SecretPei.inf
 create mode 100644 OvmfPkg/AmdSev/SecretPei/SecretPei.c

diff --git a/OvmfPkg/AmdSev/AmdSevX64.dsc b/OvmfPkg/AmdSev/AmdSevX64.dsc
index c0b4e1b274fc..a3f75a626e5e 100644
--- a/OvmfPkg/AmdSev/AmdSevX64.dsc
+++ b/OvmfPkg/AmdSev/AmdSevX64.dsc
@@ -624,6 +624,7 @@ [Components]
     <LibraryClasses>
   }
   UefiCpuPkg/CpuMpPei/CpuMpPei.inf
+  OvmfPkg/AmdSev/SecretPei/SecretPei.inf
 
 !if $(TPM_ENABLE) == TRUE
   OvmfPkg/Tcg/Tcg2Config/Tcg2ConfigPei.inf
diff --git a/OvmfPkg/AmdSev/AmdSevX64.fdf b/OvmfPkg/AmdSev/AmdSevX64.fdf
index 97f031950abd..c628e6d8f6e7 100644
--- a/OvmfPkg/AmdSev/AmdSevX64.fdf
+++ b/OvmfPkg/AmdSev/AmdSevX64.fdf
@@ -59,6 +59,9 @@ [FD.MEMFD]
 0x00B000|0x001000
 gUefiCpuPkgTokenSpaceGuid.PcdSevEsWorkAreaBase|gUefiCpuPkgTokenSpaceGuid.PcdSevEsWorkAreaSize
 
+0x00C000|0x001000
+gUefiOvmfPkgTokenSpaceGuid.PcdSevLaunchSecretBase|gUefiOvmfPkgTokenSpaceGuid.PcdSevLaunchSecretSize
+
 0x010000|0x010000
 gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecPeiTempRamBase|gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecPeiTempRamSize
 
@@ -138,6 +141,7 @@ [FV.PEIFV]
 INF  MdeModulePkg/Core/DxeIplPeim/DxeIpl.inf
 INF  UefiCpuPkg/Universal/Acpi/S3Resume2Pei/S3Resume2Pei.inf
 INF  UefiCpuPkg/CpuMpPei/CpuMpPei.inf
+INF  OvmfPkg/AmdSev/SecretPei/SecretPei.inf
 
 !if $(TPM_ENABLE) == TRUE
 INF  OvmfPkg/Tcg/Tcg2Config/Tcg2ConfigPei.inf
diff --git a/OvmfPkg/AmdSev/SecretPei/SecretPei.inf b/OvmfPkg/AmdSev/SecretPei/SecretPei.inf
new file mode 100644
index 000000000000..1b40ac036aba
--- /dev/null
+++ b/OvmfPkg/AmdSev/SecretPei/SecretPei.inf
@@ -0,0 +1,39 @@
+## @file
+#  PEI support for SEV Secrets
+#
+#  Copyright (C) 2020 James Bottomley, IBM Corporation.
+#
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = SecretPei
+  FILE_GUID                      = 45260dde-0c3c-4b41-a226-ef3803fac7d4
+  MODULE_TYPE                    = PEIM
+  VERSION_STRING                 = 1.0
+  ENTRY_POINT                    = InitializeSecretPei
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+
+[Sources]
+  SecretPei.c
+
+[Packages]
+  OvmfPkg/OvmfPkg.dec
+  MdePkg/MdePkg.dec
+
+[LibraryClasses]
+  HobLib
+  PeimEntryPoint
+  PcdLib
+
+[FixedPcd]
+  gUefiOvmfPkgTokenSpaceGuid.PcdSevLaunchSecretBase
+  gUefiOvmfPkgTokenSpaceGuid.PcdSevLaunchSecretSize
+
+[Depex]
+  TRUE
diff --git a/OvmfPkg/AmdSev/SecretPei/SecretPei.c b/OvmfPkg/AmdSev/SecretPei/SecretPei.c
new file mode 100644
index 000000000000..ad491515dd5d
--- /dev/null
+++ b/OvmfPkg/AmdSev/SecretPei/SecretPei.c
@@ -0,0 +1,25 @@
+/** @file
+  SEV Secret boot time HOB placement
+
+  Copyright (C) 2020 James Bottomley, IBM Corporation.
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+#include <PiPei.h>
+#include <Library/HobLib.h>
+#include <Library/PcdLib.h>
+
+EFI_STATUS
+EFIAPI
+InitializeSecretPei (
+  IN       EFI_PEI_FILE_HANDLE  FileHandle,
+  IN CONST EFI_PEI_SERVICES     **PeiServices
+  )
+{
+  BuildMemoryAllocationHob (
+    PcdGet32 (PcdSevLaunchSecretBase),
+    PcdGet32 (PcdSevLaunchSecretSize),
+    EfiBootServicesData
+    );
+
+  return EFI_SUCCESS;
+}
-- 
2.26.2


^ permalink raw reply related	[flat|nested] 37+ messages in thread

* [PATCH v2 6/6] OvmfPkg/AmdSev: Expose the Sev Secret area using a configuration table
  2020-11-20 18:45 [PATCH v2 0/6] SEV Encrypted Boot for Ovmf James Bottomley
                   ` (4 preceding siblings ...)
  2020-11-20 18:45 ` [PATCH v2 5/6] OvmfPkg/AmdSev: assign and protect the Sev Secret area James Bottomley
@ 2020-11-20 18:45 ` James Bottomley
  2020-11-23 22:56   ` Laszlo Ersek
  5 siblings, 1 reply; 37+ messages in thread
From: James Bottomley @ 2020-11-20 18:45 UTC (permalink / raw)
  To: devel
  Cc: dovmurik, Dov.Murik1, ashish.kalra, brijesh.singh, tobin,
	david.kaplan, jon.grimm, thomas.lendacky, jejb, frankeh,
	Dr . David Alan Gilbert, Laszlo Ersek

Now that the secret area is protected by a boot time HOB, extract its
location details into a configuration table referenced by
gSevLaunchSecretGuid so the boot loader or OS can locate it before a
call to ExitBootServices().

Ref: https://bugzilla.tianocore.org/show_bug.cgi?id=3077
Signed-off-by: James Bottomley <jejb@linux.ibm.com>
---
 OvmfPkg/OvmfPkg.dec                    |  1 +
 OvmfPkg/AmdSev/AmdSevX64.dsc           |  1 +
 OvmfPkg/AmdSev/AmdSevX64.fdf           |  1 +
 OvmfPkg/AmdSev/SecretDxe/SecretDxe.inf | 37 ++++++++++++++++++++++++++
 OvmfPkg/Include/Guid/SevLaunchSecret.h | 28 +++++++++++++++++++
 OvmfPkg/AmdSev/SecretDxe/SecretDxe.c   | 25 +++++++++++++++++
 6 files changed, 93 insertions(+)
 create mode 100644 OvmfPkg/AmdSev/SecretDxe/SecretDxe.inf
 create mode 100644 OvmfPkg/Include/Guid/SevLaunchSecret.h
 create mode 100644 OvmfPkg/AmdSev/SecretDxe/SecretDxe.c

diff --git a/OvmfPkg/OvmfPkg.dec b/OvmfPkg/OvmfPkg.dec
index 7d27f8e16040..8a294116efaa 100644
--- a/OvmfPkg/OvmfPkg.dec
+++ b/OvmfPkg/OvmfPkg.dec
@@ -117,6 +117,7 @@ [Guids]
   gLinuxEfiInitrdMediaGuid              = {0x5568e427, 0x68fc, 0x4f3d, {0xac, 0x74, 0xca, 0x55, 0x52, 0x31, 0xcc, 0x68}}
   gQemuKernelLoaderFsMediaGuid          = {0x1428f772, 0xb64a, 0x441e, {0xb8, 0xc3, 0x9e, 0xbd, 0xd7, 0xf8, 0x93, 0xc7}}
   gGrubFileGuid                         = {0xb5ae312c, 0xbc8a, 0x43b1, {0x9c, 0x62, 0xeb, 0xb8, 0x26, 0xdd, 0x5d, 0x07}}
+  gSevLaunchSecretGuid                  = {0xadf956ad, 0xe98c, 0x484c, {0xae, 0x11, 0xb5, 0x1c, 0x7d, 0x33, 0x64, 0x47}}
 
 [Ppis]
   # PPI whose presence in the PPI database signals that the TPM base address
diff --git a/OvmfPkg/AmdSev/AmdSevX64.dsc b/OvmfPkg/AmdSev/AmdSevX64.dsc
index a3f75a626e5e..fa2d1d20d551 100644
--- a/OvmfPkg/AmdSev/AmdSevX64.dsc
+++ b/OvmfPkg/AmdSev/AmdSevX64.dsc
@@ -812,6 +812,7 @@ [Components]
       gEfiShellPkgTokenSpaceGuid.PcdShellLibAutoInitialize|FALSE
   }
 !endif
+  OvmfPkg/AmdSev/SecretDxe/SecretDxe.inf
   OvmfPkg/AmdSev/Grub/Grub.inf
 !if $(BUILD_SHELL) == TRUE
   ShellPkg/Application/Shell/Shell.inf {
diff --git a/OvmfPkg/AmdSev/AmdSevX64.fdf b/OvmfPkg/AmdSev/AmdSevX64.fdf
index c628e6d8f6e7..b60ff6227a4f 100644
--- a/OvmfPkg/AmdSev/AmdSevX64.fdf
+++ b/OvmfPkg/AmdSev/AmdSevX64.fdf
@@ -269,6 +269,7 @@ [FV.DXEFV]
 !if $(TOOL_CHAIN_TAG) != "XCODE5" && $(BUILD_SHELL) == TRUE
 INF  OvmfPkg/LinuxInitrdDynamicShellCommand/LinuxInitrdDynamicShellCommand.inf
 !endif
+INF OvmfPkg/AmdSev/SecretDxe/SecretDxe.inf
 INF  OvmfPkg/AmdSev/Grub/Grub.inf
 !if $(BUILD_SHELL) == TRUE
 INF  ShellPkg/Application/Shell/Shell.inf
diff --git a/OvmfPkg/AmdSev/SecretDxe/SecretDxe.inf b/OvmfPkg/AmdSev/SecretDxe/SecretDxe.inf
new file mode 100644
index 000000000000..62ab00a3d382
--- /dev/null
+++ b/OvmfPkg/AmdSev/SecretDxe/SecretDxe.inf
@@ -0,0 +1,37 @@
+## @file
+#  Sev Secret configuration Table installer
+#
+#  Copyright (C) 2020 James Bottomley, IBM Corporation.
+#
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = SecretDxe
+  FILE_GUID                      = 6e2b9619-8810-4e9d-a177-d432bb9abeda
+  MODULE_TYPE                    = DXE_DRIVER
+  VERSION_STRING                 = 1.0
+  ENTRY_POINT                    = InitializeSecretDxe
+
+[Sources]
+  SecretDxe.c
+
+[Packages]
+  OvmfPkg/OvmfPkg.dec
+  MdePkg/MdePkg.dec
+
+[LibraryClasses]
+  UefiBootServicesTableLib
+  UefiDriverEntryPoint
+
+[Guids]
+  gSevLaunchSecretGuid
+
+[FixedPcd]
+  gUefiOvmfPkgTokenSpaceGuid.PcdSevLaunchSecretBase
+  gUefiOvmfPkgTokenSpaceGuid.PcdSevLaunchSecretSize
+
+[Depex]
+  TRUE
diff --git a/OvmfPkg/Include/Guid/SevLaunchSecret.h b/OvmfPkg/Include/Guid/SevLaunchSecret.h
new file mode 100644
index 000000000000..fa5f3830bc2b
--- /dev/null
+++ b/OvmfPkg/Include/Guid/SevLaunchSecret.h
@@ -0,0 +1,28 @@
+ /** @file
+   UEFI Configuration Table for exposing the SEV Launch Secret location to UEFI
+   applications (boot loaders).
+
+   Copyright (C) 2020 James Bottomley, IBM Corporation.
+   SPDX-License-Identifier: BSD-2-Clause-Patent
+ **/
+
+#ifndef SEV_LAUNCH_SECRET_H_
+#define SEV_LAUNCH_SECRET_H_
+
+#include <Uefi/UefiBaseType.h>
+
+#define SEV_LAUNCH_SECRET_GUID                          \
+  { 0xadf956ad,                                         \
+    0xe98c,                                             \
+    0x484c,                                             \
+    { 0xae, 0x11, 0xb5, 0x1c, 0x7d, 0x33, 0x64, 0x47 }, \
+  }
+
+typedef struct {
+  UINT32 Base;
+  UINT32 Size;
+} SEV_LAUNCH_SECRET_LOCATION;
+
+extern EFI_GUID gSevLaunchSecretGuid;
+
+#endif // SEV_LAUNCH_SECRET_H_
diff --git a/OvmfPkg/AmdSev/SecretDxe/SecretDxe.c b/OvmfPkg/AmdSev/SecretDxe/SecretDxe.c
new file mode 100644
index 000000000000..e5a1624e3cd7
--- /dev/null
+++ b/OvmfPkg/AmdSev/SecretDxe/SecretDxe.c
@@ -0,0 +1,25 @@
+/** @file
+  SEV Secret configuration table constructor
+
+  Copyright (C) 2020 James Bottomley, IBM Corporation.
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+#include <PiDxe.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Guid/SevLaunchSecret.h>
+
+STATIC SEV_LAUNCH_SECRET_LOCATION mSecretDxeTable = {
+  FixedPcdGet32 (PcdSevLaunchSecretBase),
+  FixedPcdGet32 (PcdSevLaunchSecretSize),
+};
+
+EFI_STATUS
+EFIAPI
+InitializeSecretDxe(
+  IN EFI_HANDLE           ImageHandle,
+  IN EFI_SYSTEM_TABLE     *SystemTable
+  )
+{
+  return gBS->InstallConfigurationTable (&gSevLaunchSecretGuid,
+                                         &mSecretDxeTable);
+}
-- 
2.26.2


^ permalink raw reply related	[flat|nested] 37+ messages in thread

* Re: [PATCH v2 1/6] OvmfPkg/Amdsev: Base commit to build encrypted boot specific OVMF
  2020-11-20 18:45 ` [PATCH v2 1/6] OvmfPkg/Amdsev: Base commit to build encrypted boot specific OVMF James Bottomley
@ 2020-11-23 18:01   ` Laszlo Ersek
  2020-11-23 23:25     ` James Bottomley
  0 siblings, 1 reply; 37+ messages in thread
From: Laszlo Ersek @ 2020-11-23 18:01 UTC (permalink / raw)
  To: James Bottomley, devel
  Cc: dovmurik, Dov.Murik1, ashish.kalra, brijesh.singh, tobin,
	david.kaplan, jon.grimm, thomas.lendacky, frankeh,
	Dr . David Alan Gilbert

On 11/20/20 19:45, James Bottomley wrote:
> This commit represents the file copied from OvmfPkgX64 with minor
> changes to change the build name.
>
> This package will form the basis for adding Sev specific features.
> Since everything must go into a single rom file for attestation, the
> separated build of code and variables is eliminated.
>
> Ref: https://bugzilla.tianocore.org/show_bug.cgi?id=3077
> Signed-off-by: James Bottomley <jejb@linux.ibm.com>
>
> ---
>
> v2: remove secure boot, smm and networking
> ---
>  OvmfPkg/AmdSev/AmdSevX64.dsc | 867 +++++++++++++++++++++++++++++++++++
>  OvmfPkg/AmdSev/AmdSevX64.fdf | 461 +++++++++++++++++++
>  2 files changed, 1328 insertions(+)
>  create mode 100644 OvmfPkg/AmdSev/AmdSevX64.dsc
>  create mode 100644 OvmfPkg/AmdSev/AmdSevX64.fdf
>
> diff --git a/OvmfPkg/AmdSev/AmdSevX64.dsc b/OvmfPkg/AmdSev/AmdSevX64.dsc
> new file mode 100644
> index 000000000000..852be757bfbe
> --- /dev/null
> +++ b/OvmfPkg/AmdSev/AmdSevX64.dsc
> @@ -0,0 +1,867 @@

[...]

> +[LibraryClasses]

[...]

> +  VarCheckLib|MdeModulePkg/Library/VarCheckLib/VarCheckLib.inf

(1) The following two lib class resolutions are missing here:

  VariablePolicyLib|MdeModulePkg/Library/VariablePolicyLib/VariablePolicyLib.inf
  VariablePolicyHelperLib|MdeModulePkg/Library/VariablePolicyHelperLib/VariablePolicyHelperLib.inf

They were added to the other OVMF DSC files in commit 435a05aff54d
("OvmfPkg: Add VariablePolicy engine to OvmfPkg platform", 2020-11-17).
This dependency didn't exist at the time of your v1 posting (Nov 12th,
in my time zone).

But now the new platform doesn't seem to build without them:

> OvmfPkg/AmdSev/AmdSevX64.dsc(...): error 4000: Instance of library class [VariablePolicyLib] is not found
>         in [MdeModulePkg/Universal/Variable/RuntimeDxe/VariableRuntimeDxe.inf] [X64]
>         consumed by module [MdeModulePkg/Universal/Variable/RuntimeDxe/VariableRuntimeDxe.inf]

They are required by
"MdeModulePkg/Universal/Variable/RuntimeDxe/VariableRuntimeDxe.inf" too,
not just by "MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmm.inf"
(which is correctly removed by this patch).

... actually, for VariableRuntimeDxe:

On 11/20/20 19:45, James Bottomley wrote:

[...]

> +[LibraryClasses.common.DXE_RUNTIME_DRIVER]

[...]

> +  QemuFwCfgS3Lib|OvmfPkg/Library/QemuFwCfgS3Lib/DxeQemuFwCfgS3LibFwCfg.inf

(2) the following (DXE_RUNTIME_DRIVER-specific) lib class resolution is
missing here:

  VariablePolicyLib|MdeModulePkg/Library/VariablePolicyLib/VariablePolicyLibRuntimeDxe.inf


... So I think that, for (1)+(2) together, simply the "OvmfXen.dsc"
hunks from 435a05aff54d should be incorporated into this patch.

[...]

> +[PcdsFixedAtBuild]
> +  gEfiMdeModulePkgTokenSpaceGuid.PcdStatusCodeMemorySize|1
> +  gEfiMdeModulePkgTokenSpaceGuid.PcdResetOnMemoryTypeInformationChange|FALSE
> +  gEfiMdePkgTokenSpaceGuid.PcdMaximumGuidedExtractHandler|0x10
> +!if ($(FD_SIZE_IN_KB) == 1024) || ($(FD_SIZE_IN_KB) == 2048)
> +  gEfiMdeModulePkgTokenSpaceGuid.PcdMaxVariableSize|0x2000
> +  gEfiMdeModulePkgTokenSpaceGuid.PcdMaxAuthVariableSize|0x2800
> +  # match PcdFlashNvStorageVariableSize purely for convenience
> +  gEfiMdeModulePkgTokenSpaceGuid.PcdVariableStoreSize|0xe000
> +!endif
> +!if $(FD_SIZE_IN_KB) == 4096
> +  gEfiMdeModulePkgTokenSpaceGuid.PcdMaxVariableSize|0x8400
> +  gEfiMdeModulePkgTokenSpaceGuid.PcdMaxAuthVariableSize|0x8400
> +  # match PcdFlashNvStorageVariableSize purely for convenience
> +  gEfiMdeModulePkgTokenSpaceGuid.PcdVariableStoreSize|0x40000
> +!endif
> +  gEfiMdeModulePkgTokenSpaceGuid.PcdVariableStoreSize|0x80000
> +  gEfiMdeModulePkgTokenSpaceGuid.PcdMaxVolatileVariableSize|0x40000

(3) The above two PCD settings are conditional on NETWORK_TLS_ENABLE
being TRUE, so please remove them together with the condition.

Right now, they override the settings in the just preceding blocks
(which depend on FD_SIZE_IN_KB being 1M / 2M / 4M).

[...]

> +[PcdsDynamicDefault]
> +  # only set when
> +  #   ($(SMM_REQUIRE) == FALSE)

(4) please remove the comment (only the comment)

> +  gEfiMdeModulePkgTokenSpaceGuid.PcdEmuVariableNvStoreReserved|0

[...]

> +[Components]

[...]

> +  OvmfPkg/VirtioNetDxe/VirtioNet.inf

(5) Please remove this driver from the DSC file too (you correctly
removed it from the FDF file). Right now, the driver is built, just not
included. We shouldn't build it.

The rest looks good to me.

Thanks!
Laszlo


^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [PATCH v2 2/6] OvmfPkg/AmdSev: add Grub Firmware Volume Package
  2020-11-20 18:45 ` [PATCH v2 2/6] OvmfPkg/AmdSev: add Grub Firmware Volume Package James Bottomley
@ 2020-11-23 21:08   ` Laszlo Ersek
  2020-11-24  6:38     ` James Bottomley
  0 siblings, 1 reply; 37+ messages in thread
From: Laszlo Ersek @ 2020-11-23 21:08 UTC (permalink / raw)
  To: James Bottomley, devel
  Cc: dovmurik, Dov.Murik1, ashish.kalra, brijesh.singh, tobin,
	david.kaplan, jon.grimm, thomas.lendacky, frankeh,
	Dr . David Alan Gilbert

Hi James,

On 11/20/20 19:45, James Bottomley wrote:
> This is used to package up the grub bootloader into a firmware volume
> where it can be executed as a shell like the UEFI Shell.  Grub itself
> is built as a minimal entity into a Fv and then added as a boot
> option.  By default the UEFI shell isn't built but for debugging
> purposes it can be enabled and will then be presented as a boot option
> (This should never be allowed for secure boot in an external data
> centre but may be useful for local debugging).  Finally all other boot
> options except grub and possibly the shell are stripped and the boot
> timeout forced to 0 so the system will not enter a setup menu and will
> only boot to grub.  This is done by copying the
> Library/PlatformBootManagerLib into Library/PlatformBootManagerLibGrub
> and then customizing it.
>
> Boot failure is fatal to try to prevent secret theft.
>
> Ref: https://bugzilla.tianocore.org/show_bug.cgi?id=3077
> Signed-off-by: James Bottomley <jejb@linux.ibm.com>
>
> ---
>
> v2: strip out s3 and qemu boot contacts make grub script robust and
>     don't build grub.efi each time
> ---
>  OvmfPkg/OvmfPkg.dec                           |    1 +
>  OvmfPkg/AmdSev/AmdSevX64.dsc                  |   21 +-
>  OvmfPkg/AmdSev/AmdSevX64.fdf                  |    7 +-
>  OvmfPkg/AmdSev/Grub/Grub.inf                  |   37 +
>  .../PlatformBootManagerLibGrub.inf            |   79 +
>  .../PlatformBootManagerLibGrub/BdsPlatform.h  |  175 ++
>  .../PlatformBootManagerLibGrub/BdsPlatform.c  | 1483 +++++++++++++++++
>  .../PlatformBootManagerLibGrub/PlatformData.c |  213 +++
>  OvmfPkg/AmdSev/Grub/.gitignore                |    1 +
>  OvmfPkg/AmdSev/Grub/grub.cfg                  |   46 +
>  OvmfPkg/AmdSev/Grub/grub.sh                   |   92 +
>  11 files changed, 2146 insertions(+), 9 deletions(-)
>  create mode 100644 OvmfPkg/AmdSev/Grub/Grub.inf
>  create mode 100644 OvmfPkg/Library/PlatformBootManagerLibGrub/PlatformBootManagerLibGrub.inf
>  create mode 100644 OvmfPkg/Library/PlatformBootManagerLibGrub/BdsPlatform.h
>  create mode 100644 OvmfPkg/Library/PlatformBootManagerLibGrub/BdsPlatform.c
>  create mode 100644 OvmfPkg/Library/PlatformBootManagerLibGrub/PlatformData.c
>  create mode 100644 OvmfPkg/AmdSev/Grub/.gitignore
>  create mode 100644 OvmfPkg/AmdSev/Grub/grub.cfg
>  create mode 100644 OvmfPkg/AmdSev/Grub/grub.sh

In advance, a shortcut: my previous review was at [a].

[a] https://edk2.groups.io/g/devel/message/67618
    https://www.redhat.com/archives/edk2-devel-archive/2020-November/msg00778.html


> diff --git a/OvmfPkg/AmdSev/Grub/Grub.inf b/OvmfPkg/AmdSev/Grub/Grub.inf
> new file mode 100644
> index 000000000000..211e7b8b2be6
> --- /dev/null
> +++ b/OvmfPkg/AmdSev/Grub/Grub.inf
> @@ -0,0 +1,37 @@
> +##  @file
> +#  Create a Firmware Volume based Grub Bootloaded

(1) typo -- should be "Bootloader", I believe (apologies for missing it
in v1)


> +#
> +#  Copyright (C) 2020 James Bottomley, IBM Corporation.
> +#
> +#  SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +##
> +
> +[Defines]
> +  INF_VERSION                    = 0x00010006
> +  BASE_NAME                      = Grub
> +  # This is gGrubFileGuid
> +  FILE_GUID                      = b5ae312c-bc8a-43b1-9c62-ebb826dd5d07
> +  MODULE_TYPE                    = UEFI_APPLICATION
> +  VERSION_STRING                 = 1.0
> +  ENTRY_POINT                    = UefiMain
> +
> +[Packages]
> +  OvmfPkg/OvmfPkg.dec
> +
> +#
> +# The following information is for reference only and not required by
> +# the build tools.
> +#
> +#  VALID_ARCHITECTURES           = X64
> +#
> +
> +##
> +# Note: The version of grub.efi this picks up can be generated by
> +# grub.sh which must be specified as a PREBUILD in the .dsc file or
> +# you can simply move a precompiled grub into here and not do the
> +# PREBUILD)

(2) This part of the patch looks unchanged, and I asked for more
explanation in [a](3) -- "Can you elaborate how to skip PREBUILD"?

The comment in the patch remains the same, and (AFAICT) I have not
received a response within the v1 thread either. (Instead you stated "I
did everything except [...].)

So now I'm not sure... Did you miss [a](3), or did you decide it was not
important enough to discuss / address?


> +##
> +[Binaries]
> +   PE32|grub.efi|*
> +
> diff --git a/OvmfPkg/Library/PlatformBootManagerLibGrub/PlatformBootManagerLibGrub.inf b/OvmfPkg/Library/PlatformBootManagerLibGrub/PlatformBootManagerLibGrub.inf
> new file mode 100644
> index 000000000000..a997d7586e6a
> --- /dev/null
> +++ b/OvmfPkg/Library/PlatformBootManagerLibGrub/PlatformBootManagerLibGrub.inf
> @@ -0,0 +1,79 @@
> +## @file
> +#  Platform BDS customizations library.
> +#
> +#  Copyright (c) 2007 - 2019, Intel Corporation. All rights reserved.<BR>
> +#  SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +##

(3) In the v1 review thread, under patch #1, I requested: "In every new
file created in this series, please prepend an IBM Copyright Notice, to
the original (C) notices (if any)."

  https://edk2.groups.io/g/devel/message/67615
  https://www.redhat.com/archives/edk2-devel-archive/2020-November/msg00775.html

This is a new file, but it still has no IBM (C) notice.


> +
> +[Defines]
> +  INF_VERSION                    = 0x00010005
> +  BASE_NAME                      = PlatformBootManagerLibGrub
> +  FILE_GUID                      = 3a8f8431-f0c9-4c95-8a1d-04445c582d4e
> +  MODULE_TYPE                    = DXE_DRIVER
> +  VERSION_STRING                 = 1.0
> +  LIBRARY_CLASS                  = PlatformBootManagerLib|DXE_DRIVER
> +
> +#
> +# The following information is for reference only and not required by the build tools.
> +#
> +#  VALID_ARCHITECTURES           = X64
> +#
> +
> +[Sources]
> +  BdsPlatform.c
> +  PlatformData.c
> +  BdsPlatform.h
> +
> +[Packages]
> +  MdePkg/MdePkg.dec
> +  MdeModulePkg/MdeModulePkg.dec
> +  SourceLevelDebugPkg/SourceLevelDebugPkg.dec
> +  OvmfPkg/OvmfPkg.dec
> +  SecurityPkg/SecurityPkg.dec
> +  ShellPkg/ShellPkg.dec
> +
> +[LibraryClasses]
> +  BaseLib
> +  MemoryAllocationLib
> +  UefiBootServicesTableLib
> +  UefiRuntimeServicesTableLib
> +  BaseMemoryLib
> +  DebugLib
> +  PcdLib
> +  UefiBootManagerLib
> +  BootLogoLib
> +  DevicePathLib
> +  PciLib
> +  ReportStatusCodeLib
> +  UefiLib
> +  PlatformBmPrintScLib
> +  Tcg2PhysicalPresenceLib
> +  XenPlatformLib

(4) I suggested removing XenPlatformLib too, in [a](4).

Did you run into build problems with that?

Replacing the XenDetected() calls in "BdsPlatform.c" with constant
FALSE, and simplifying the resultant code, should suffice.


> +
> +[Pcd]
> +  gUefiOvmfPkgTokenSpaceGuid.PcdOvmfFlashVariablesEnable

(5) Thanks for removing PcdEmuVariableEvent.

But, PcdOvmfFlashVariablesEnable is just as superfluous; the INF file
now lists it without any references to the PCD in the code.


In [a](5) I requested the removal of everything in this INF file that
was not required for the desired semantics (i.e., for unconditionally
booting the builtin GRUB binary).

So again I'm unsure if you missed my feedback, or thought it was not
important. (I didn't get a request for clarification either.)

Keeping INF files minimal is relevant for future contributions. We
frequently need to determine the set of modules that depend on a
particular PCD. If some INF files list PCDs unjustifiedly, then the
affected module set may appear larger than it really is.

This applies to all sections of the INF file, not just [Pcd].


> +  gUefiOvmfPkgTokenSpaceGuid.PcdOvmfHostBridgePciDevId
> +  gEfiMdePkgTokenSpaceGuid.PcdPlatformBootTimeOut
> +  gEfiMdePkgTokenSpaceGuid.PcdUartDefaultBaudRate         ## CONSUMES
> +  gEfiMdePkgTokenSpaceGuid.PcdUartDefaultDataBits         ## CONSUMES
> +  gEfiMdePkgTokenSpaceGuid.PcdUartDefaultParity           ## CONSUMES
> +  gEfiMdePkgTokenSpaceGuid.PcdUartDefaultStopBits         ## CONSUMES
> +
> +[Pcd.IA32, Pcd.X64]
> +  gEfiMdePkgTokenSpaceGuid.PcdFSBClock
> +
> +[Protocols]
> +  gEfiDecompressProtocolGuid
> +  gEfiPciRootBridgeIoProtocolGuid
> +  gEfiS3SaveStateProtocolGuid                   # PROTOCOL SOMETIMES_CONSUMED
> +  gEfiDxeSmmReadyToLockProtocolGuid             # PROTOCOL SOMETIMES_PRODUCED
> +  gEfiLoadedImageProtocolGuid                   # PROTOCOL SOMETIMES_PRODUCED
> +  gEfiFirmwareVolume2ProtocolGuid               # PROTOCOL SOMETIMES_CONSUMED
> +
> +[Guids]
> +  gEfiEndOfDxeEventGroupGuid
> +  gEfiGlobalVariableGuid
> +  gRootBridgesConnectedEventGroupGuid
> +  gUefiShellFileGuid
> +  gGrubFileGuid
> diff --git a/OvmfPkg/Library/PlatformBootManagerLibGrub/BdsPlatform.h b/OvmfPkg/Library/PlatformBootManagerLibGrub/BdsPlatform.h
> new file mode 100644
> index 000000000000..a7fc4dbc3c1f
> --- /dev/null
> +++ b/OvmfPkg/Library/PlatformBootManagerLibGrub/BdsPlatform.h
> @@ -0,0 +1,175 @@
> +/** @file
> +  Platform BDS customizations include file.
> +
> +  Copyright (c) 2006 - 2017, Intel Corporation. All rights reserved.<BR>
> +  SPDX-License-Identifier: BSD-2-Clause-Patent

(6) Same as (3) -- missing IBM (C) on new file


> diff --git a/OvmfPkg/Library/PlatformBootManagerLibGrub/BdsPlatform.c b/OvmfPkg/Library/PlatformBootManagerLibGrub/BdsPlatform.c
> new file mode 100644
> index 000000000000..4fb2f904a10e
> --- /dev/null
> +++ b/OvmfPkg/Library/PlatformBootManagerLibGrub/BdsPlatform.c
> @@ -0,0 +1,1483 @@
> +/** @file
> +  Platform BDS customizations.
> +
> +  Copyright (c) 2004 - 2019, Intel Corporation. All rights reserved.<BR>
> +  SPDX-License-Identifier: BSD-2-Clause-Patent

(7) same as (3) -- missing IBM (C) on new file


> +/**
> +  The function is called when no boot option could be launched,
> +  including platform recovery options and options pointing to applications
> +  built into firmware volumes.
> +
> +  If this function returns, BDS attempts to enter an infinite loop.
> +**/
> +VOID
> +EFIAPI
> +PlatformBootManagerUnableToBoot (
> +  VOID
> +  )
> +{
> +  //
> +  // If we get here something failed about the grub boot but since
> +  // We're privy to the secret we must panic and not retry or loop
> +  //
> +  CpuDeadLoop ();
> +}

(8) In [a](7) I meant that both ASSERT() and CpuDeadLoop() should be
called. In DEBUG and NOOPT builds, the ASSERT() fires, produces a
somewhat helpful debug message, and the CpuDeadLoop() is not reached
(ASSERT() may call CpuDeadLoop() internally, or raise an exception). In
RELEASE builds, the message is not produced, but we still won't proceed
past the CpuDeadLoop().

Sorry about not being clear enough.


> diff --git a/OvmfPkg/Library/PlatformBootManagerLibGrub/PlatformData.c b/OvmfPkg/Library/PlatformBootManagerLibGrub/PlatformData.c
> new file mode 100644
> index 000000000000..2858c3dfd5ca
> --- /dev/null
> +++ b/OvmfPkg/Library/PlatformBootManagerLibGrub/PlatformData.c
> @@ -0,0 +1,213 @@
> +/** @file
> +  Defined the platform specific device path which will be used by
> +  platform Bbd to perform the platform policy connect.
> +
> +  Copyright (c) 2004 - 2017, Intel Corporation. All rights reserved.<BR>
> +  SPDX-License-Identifier: BSD-2-Clause-Patent

(9) same as (3) -- missing IBM (C) on new file


> diff --git a/OvmfPkg/AmdSev/Grub/grub.sh b/OvmfPkg/AmdSev/Grub/grub.sh
> new file mode 100644
> index 000000000000..fd28dc6ab274
> --- /dev/null
> +++ b/OvmfPkg/AmdSev/Grub/grub.sh
> @@ -0,0 +1,92 @@
> +##  @file
> +#  Build a version of grub capable of decrypting a luks volume with a SEV
> +#  Supplied secret
> +#
> +#  Copyright (C) 2020 James Bottomley, IBM Corporation.
> +#
> +#  SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +##
> +
> +set -e
> +remove_efi=1
> +
> +cleanup()  {
> +    # remove the intermediates
> +    for f in disk.fat grub-bootstrap.cfg; do
> +	rm -f "${basedir}/$f"
> +    done
> +    if [ $remove_efi -eq 1 ]; then
> +	rm -f "${basedir}/grub.efi"
> +    fi
> +}

(10) These two "rm -f" commands don't use the separator "--", unlike the
"rm -f" command below (which has been updated, thanks for that).


> +
> +trap cleanup EXIT
> +
> +GRUB_MODULES="
> +	    part_msdos
> +	    part_gpt
> +	    cryptodisk
> +	    luks
> +	    gcry_rijndael
> +	    gcry_sha256
> +	    ext2
> +	    btrfs
> +	    xfs
> +	    fat
> +	    configfile
> +	    memdisk
> +	    sleep
> +	    normal
> +	    echo
> +	    test
> +	    regexp
> +	    linux
> +	    linuxefi
> +	    reboot
> +	    sevsecret
> +	    "
> +basedir=$(dirname -- "$0")
> +
> +# don't run a build if grub.efi exists and is newer than the config files
> +if [ -e "${basedir}/grub.efi" -a \
> +     "${basedir}/grub.efi" -nt "${basedir}/grub.cfg" -a \
> +     "${basedir}/grub.efi" -nt "${basedir}/grub.sh" ]; then
> +    remove_efi=0
> +    echo "preserving existing grub.efi"

arguably this should go to stderr as well, but I don't insist

> +    exit 0
> +fi
>

Ah, OK. This sort of addresses my question (2). Not entirely -- the
comment at (2) implies the user is somehow responsible for skipping
PREBUILD. While in reality, PREBUILD will be launched, it will just exit
early.

(11) Independently, "-a" is considered obsolescent, per
<https://pubs.opengroup.org/onlinepubs/9699919799/utilities/test.html#tag_20_128_16>.

Anyway, feel free to ignore.


> +##
> +# different distributions have different names for grub-mkimage, so
> +# search all the known ones
> +##
> +for b in grub2-mkimage grub-mkimage; do
> +    if which "$b" > /dev/null 2>&1; then
> +	mkimage="$b"
> +	break;

(12) "muscle memory" semicolon after "break" :)


(13) the indentation seems strange (Linux kernel style?); please don't
use hardware tabs. (Hmmm, applies to other parts of this script too.)


> +    fi
> +done
> +if [ -z "$mkimage" ]; then
> +    echo "Can't find grub mkimage" >&2
> +    exit 1
> +fi

(14) The variable "mkimage" has not been emptied before the loop, like I
asked in [a](14).

The reason I had asked for emptying "mkimage" was two-fold: (i) I
considered that maybe you'd add "set -u" at the top of the script as
well, in which case the above "if" could fail ungracefully with "unbound
variable", (ii) "mkimage" is not a totally uncommon variable name, and
it could be inherited from the calling shell environment -- in case the
loop never matched.

Now, I may have been wrong in that reasoning. But please, if you think
I'm wrong, say so. I think it's quite possible to convince me. If you
simply ignore a request from me, that's not a good use of my time.

Whenever I review the next version of a series, I go over every single
request I made under the last one, and verify whether it has been
addressed, or explicitly refuted in the discussion. If neither happens,
then I just don't know what to do, as I obviously have to make the exact
same request in the next round of review. It's disappointing, and
discourages me from continuing the review.


> +
> +# GRUB's rescue parser doesn't understand 'if'.
> +echo 'normal (memdisk)/grub.cfg' > "${basedir}/grub-bootstrap.cfg"
> +
> +# Now build a memdisk with the correct grub.cfg
> +rm -f -- "${basedir}/disk.fat"
> +mkfs.msdos -C -- "${basedir}/disk.fat" 64
> +mcopy -i "${basedir}/disk.fat" -- "${basedir}/grub.cfg" ::grub.cfg
> +
> +
> +${mkimage} -O x86_64-efi \
> +	   -p '(crypto0)' \
> +	   -c "${basedir}/grub-bootstrap.cfg" \
> +	   -m "${basedir}/disk.fat" \
> +	   -o "${basedir}/grub.efi" \
> +	   ${GRUB_MODULES}
> +
> +remove_efi=0
> +echo "grub.efi generated in ${basedir}"
>

Thanks
Laszlo


^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [PATCH v2 3/6] OvmfPkg: convert ES Reset Block structure to be guided
  2020-11-20 18:45 ` [PATCH v2 3/6] OvmfPkg: convert ES Reset Block structure to be guided James Bottomley
@ 2020-11-23 22:16   ` Laszlo Ersek
  2020-11-24 14:57     ` Lendacky, Thomas
  2020-11-24 19:05     ` James Bottomley
  0 siblings, 2 replies; 37+ messages in thread
From: Laszlo Ersek @ 2020-11-23 22:16 UTC (permalink / raw)
  To: James Bottomley, devel
  Cc: dovmurik, Dov.Murik1, ashish.kalra, brijesh.singh, tobin,
	david.kaplan, jon.grimm, thomas.lendacky, frankeh,
	Dr . David Alan Gilbert

On 11/20/20 19:45, James Bottomley wrote:
> Convert the current ES reset block structure to an extensible guid
> based structure by appending a header and length, which allow for
> multiple guid based data packets to be inserted.
>
> Ref: https://bugzilla.tianocore.org/show_bug.cgi?id=3077
> Signed-off-by: James Bottomley <jejb@linux.ibm.com>
>
> ---
>
> v2: added
> ---
>  OvmfPkg/ResetVector/Ia16/ResetVectorVtf0.asm | 49 +++++++++++++++-----
>  1 file changed, 38 insertions(+), 11 deletions(-)

(1) Please update the subject line to:

OvmfPkg/ResetVector: convert SEV-ES Reset Block structure to be GUIDed

- edk2 prefers including module names too in the patch subjects
- "ES" is harder to understand than "SEV-ES"
- "GUIDed" is harder to misread as "guided"
- subject length is still OK (70 chars)


>
> diff --git a/OvmfPkg/ResetVector/Ia16/ResetVectorVtf0.asm b/OvmfPkg/ResetVector/Ia16/ResetVectorVtf0.asm
> index 980e0138e7fe..baf9d09f3625 100644
> --- a/OvmfPkg/ResetVector/Ia16/ResetVectorVtf0.asm
> +++ b/OvmfPkg/ResetVector/Ia16/ResetVectorVtf0.asm
> @@ -25,21 +25,40 @@ ALIGN   16
>      TIMES (0x1000 - ($ - EndOfPageTables) - 0x20) DB 0
>  %endif
>
> +;
> +; Padding to ensure first guid starts at 0xffffffd0
> +;
> +TIMES (32 - ((guidedStructureEnd - guidedStructureStart) % 32)) DB 0

(2) This will insert 32 zero bytes if the size is already aligned to 32
bytes (because 32-0 = 32). In other words, the above produces 1 to 32
zero bytes, dependent on table size.

The variant I proposed in point (5) at

  https://edk2.groups.io/g/devel/message/67621
  https://www.redhat.com/archives/edk2-devel-archive/2020-November/msg00781.html

takes this into account, and only prepends 0 to 31 bytes (inclusive):

  TIMES (31 - (guidedStructureEnd - guidedStructureStart + 31) % 32) DB 0

- This variant subtracts 1 inside the remainder operation (which is
  expressed as adding 31).

- For compensation, it adds 1 just outside of the remainder operation.
  This addition in effect increases the subtrahend for the leftmost 32.
  Therefore this (-1) addend is ultimately folded into the leftmost 32,
  yielding 31 on the leftmost side.

  TIMES (32 - ((guidedStructureEnd - guidedStructureStart - 1) % 32 + 1)) DB 0
                                                          ^^^       ^^^
                                                          |         |
                                                          |         compensate
                                                          |         in the
                                                          |         remainder
                                                          |
                                                          slide down residue
                                                          class modulo 32


 TIMES (32 - ((guidedStructureEnd - guidedStructureStart + 31) % 32) - 1) DB 0
                                                         ^^^^        ^^^
                                                         |           |
                                                         |           unnest
                                                         |           increment
                                                         |           from
                                                         |           subtrahend
                                                         |
                                                         express modular
                                                         subtraction as
                                                         addition, to avoid
                                                         using % on a negative
                                                         integer (in case size
                                                         were 0)

 TIMES (31 - ((guidedStructureEnd - guidedStructureStart + 31) % 32)) DB 0
        ^^
        |
        fold previous (-1) addend into leftmost constant

- This juggling of 1 results in no changes for residue classes 1 through
  31, but wraps the outermost result (the padding size) for residue
  class 0, from 32 to 0.


> +
> +; Guided structure.  To traverse this you should first verify the
> +; presence of the table header guid

(3) suggest "table footer GUID" (the GUID follows the data, in address
order)

> +; (96b582de-1fb2-45f7-baea-a366c55a082d) at 0xffffffd0.  If that
> +; is found, the two bytes at 0xffffffce are the entire table length.

(4) can we make the whole table size field 32-bit? I don't have a
particular use case in mind, it just looks more extensible than 16-bit.
We can still keep the individual structs we have in mind 16-bit sized.

> +;
> +; The table is composed of structures with the form:
> +;
> +; Data (arbitrary bytes identified by guid)
> +; length from start of guid to end of data (2 bytes)

(5) This is hard to interpret, as "data" precedes "guid" in address
space (guid is a footer, not a header).

I suggest "length from start of data to end of GUID"


> +; guid (16 bytes)
> +;
> +; so work back from the header using the length to traverse until you

(6) suggest "from the footer"


> +; either find the guid you're looking for or run off the end of the
> +; table.

(7) suggest "run off the beginning of the table"

... I realize "start" and "end" can be interpreted temporally and
spatially. In a forward traversal they are the same, but now they
aren't. I suggest we use the spatial (address space order)
interpretation.

> +;
> +guidedStructureStart:
> +
>  ;
>  ; SEV-ES Processor Reset support
>  ;
>  ; sevEsResetBlock:
>  ;   For the initial boot of an AP under SEV-ES, the "reset" RIP must be
> -;   programmed to the RAM area defined by SEV_ES_AP_RESET_IP. A known offset
> -;   and GUID will be used to locate this block in the firmware and extract
> -;   the build time RIP value. The GUID must always be 48 bytes from the
> -;   end of the firmware.
> +;   programmed to the RAM area defined by SEV_ES_AP_RESET_IP. The data
> +;   format is
>  ;
> -;   0xffffffca (-0x36) - IP value
> -;   0xffffffcc (-0x34) - CS segment base [31:16]
> -;   0xffffffce (-0x32) - Size of the SEV-ES reset block
> -;   0xffffffd0 (-0x30) - SEV-ES reset block GUID
> -;                        (00f771de-1a7e-4fcb-890e-68c77e2fb44e)
> +;   IP value [0:15]
> +;   CS segment base [31:16]
> +;
> +;   SEV-ES reset block GUID: 00f771de-1a7e-4fcb-890e-68c77e2fb44e

(8) Did I understand from the v1 discussion that the corresponding QEMU
parser is not upstream yet? (Or at least not released?)

(9) The 16-bit size field of the SEV-ES reset block structure is not
documented.


>  ;
>  ;   A hypervisor reads the CS segement base and IP value. The CS segment base
>  ;   value represents the high order 16-bits of the CS segment base, so the
> @@ -48,8 +67,6 @@ ALIGN   16
>  ;   program the EIP register with the IP value as read.
>  ;
>
> -TIMES (32 - (sevEsResetBlockEnd - sevEsResetBlockStart)) DB 0
> -
>  sevEsResetBlockStart:
>      DD      SEV_ES_AP_RESET_IP
>      DW      sevEsResetBlockEnd - sevEsResetBlockStart
> @@ -57,6 +74,16 @@ sevEsResetBlockStart:
>      DB      0x89, 0x0E, 0x68, 0xC7, 0x7E, 0x2F, 0xB4, 0x4E
>  sevEsResetBlockEnd:
>
> +;
> +; Table header: length of whole table followed by table header

(10) I suggest "table footer" (twice)


> +; guid: 96b582de-1fb2-45f7-baea-a366c55a082d
> +;
> +    DW      guidedStructureEnd - guidedStructureStart
> +    DB      0xDE, 0x82, 0xB5, 0x96, 0xB2, 0x1F, 0xF7, 0x45
> +    DB      0xBA, 0xEA, 0xA3, 0x66, 0xC5, 0x5A, 0x08, 0x2D
> +
> +guidedStructureEnd:
> +
>  ALIGN   16
>
>  applicationProcessorEntryPoint:
>

Thanks!
Laszlo


^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [PATCH v2 4/6] OvmfPkg: create a SEV secret area in the AmdSev memfd
  2020-11-20 18:45 ` [PATCH v2 4/6] OvmfPkg: create a SEV secret area in the AmdSev memfd James Bottomley
@ 2020-11-23 22:28   ` Laszlo Ersek
  0 siblings, 0 replies; 37+ messages in thread
From: Laszlo Ersek @ 2020-11-23 22:28 UTC (permalink / raw)
  To: James Bottomley, devel
  Cc: dovmurik, Dov.Murik1, ashish.kalra, brijesh.singh, tobin,
	david.kaplan, jon.grimm, thomas.lendacky, frankeh,
	Dr . David Alan Gilbert

On 11/20/20 19:45, James Bottomley wrote:
> SEV needs an area to place an injected secret where OVMF can find it
> and pass it up as a ConfigurationTable.  This patch implements the
> area itself as an addition to the SEV enhanced reset vector table using
> an additional guid (4c2eb361-7d9b-4cc3-8081-127c90d3d294).
> 
> Ref: https://bugzilla.tianocore.org/show_bug.cgi?id=3077
> Signed-off-by: James Bottomley <jejb@linux.ibm.com>
> 
> ---
> 
> v2: move guid to OVMF token space, separate patches
> ---
>  OvmfPkg/OvmfPkg.dec                          |  6 ++++++
>  OvmfPkg/ResetVector/ResetVector.inf          |  4 ++++
>  OvmfPkg/ResetVector/Ia16/ResetVectorVtf0.asm | 14 ++++++++++++++
>  OvmfPkg/ResetVector/ResetVector.nasmb        |  2 ++
>  4 files changed, 26 insertions(+)
> 
> diff --git a/OvmfPkg/OvmfPkg.dec b/OvmfPkg/OvmfPkg.dec
> index 3fbf7a0ee1a4..7d27f8e16040 100644
> --- a/OvmfPkg/OvmfPkg.dec
> +++ b/OvmfPkg/OvmfPkg.dec
> @@ -304,6 +304,12 @@ [PcdsFixedAtBuild]
>    gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecGhcbBase|0|UINT32|0x40
>    gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecGhcbSize|0|UINT32|0x41
>  
> +  ## The base address and size of the SEV Launch Secret Area provisioned
> +  #  after remote attestation.  If this is set in the .fdf, the platform
> +  #  is responsible for protecting the area from DXE phase overwrites.
> +  gUefiOvmfPkgTokenSpaceGuid.PcdSevLaunchSecretBase|0x0|UINT32|0x42
> +  gUefiOvmfPkgTokenSpaceGuid.PcdSevLaunchSecretSize|0x0|UINT32|0x43
> +
>  [PcdsDynamic, PcdsDynamicEx]
>    gUefiOvmfPkgTokenSpaceGuid.PcdEmuVariableEvent|0|UINT64|2
>    gUefiOvmfPkgTokenSpaceGuid.PcdOvmfFlashVariablesEnable|FALSE|BOOLEAN|0x10
> diff --git a/OvmfPkg/ResetVector/ResetVector.inf b/OvmfPkg/ResetVector/ResetVector.inf
> index a53ae6c194ae..dc38f68919cd 100644
> --- a/OvmfPkg/ResetVector/ResetVector.inf
> +++ b/OvmfPkg/ResetVector/ResetVector.inf
> @@ -43,3 +43,7 @@ [Pcd]
>    gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecPageTablesSize
>    gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecPeiTempRamBase
>    gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecPeiTempRamSize
> +
> +[FixedPcd]
> +  gUefiOvmfPkgTokenSpaceGuid.PcdSevLaunchSecretBase
> +  gUefiOvmfPkgTokenSpaceGuid.PcdSevLaunchSecretSize
> diff --git a/OvmfPkg/ResetVector/Ia16/ResetVectorVtf0.asm b/OvmfPkg/ResetVector/Ia16/ResetVectorVtf0.asm
> index baf9d09f3625..8d6600f17310 100644
> --- a/OvmfPkg/ResetVector/Ia16/ResetVectorVtf0.asm
> +++ b/OvmfPkg/ResetVector/Ia16/ResetVectorVtf0.asm
> @@ -47,6 +47,20 @@ TIMES (32 - ((guidedStructureEnd - guidedStructureStart) % 32)) DB 0
>  ;
>  guidedStructureStart:
>  
> +;
> +; SEV Secret block Guid: 4c2eb361-7d9b-4cc3-8081-127c90d3d294
> +;
> +; This describes the guest ram area where the hypervisor may have
> +; injected the secret

(1) I suggest s/may have injected/should inject/, as this structure gets
built into the uncompressed part of the pflash, and its intended
consumer is the hypervisor.

If you'd like to stick with the wording as posted, that's fine too, however.

Reviewed-by: Laszlo Ersek <lersek@redhat.com>

Thanks
Laszlo


> +;
> +sevSecretBlockStart:
> +    DD      SEV_LAUNCH_SECRET_BASE
> +    DD      SEV_LAUNCH_SECRET_SIZE
> +    DW      sevSecretBlockEnd - sevSecretBlockStart
> +    DB      0x61, 0xB3, 0x2E, 0x4C, 0x9B, 0x7D, 0xC3, 0x4C
> +    DB      0x80, 0x81, 0x12, 0x7C, 0x90, 0xD3, 0xD2, 0x94
> +sevSecretBlockEnd:
> +
>  ;
>  ; SEV-ES Processor Reset support
>  ;
> diff --git a/OvmfPkg/ResetVector/ResetVector.nasmb b/OvmfPkg/ResetVector/ResetVector.nasmb
> index 4913b379a993..c5e0fe93abf4 100644
> --- a/OvmfPkg/ResetVector/ResetVector.nasmb
> +++ b/OvmfPkg/ResetVector/ResetVector.nasmb
> @@ -83,5 +83,7 @@
>  %include "Main.asm"
>  
>    %define SEV_ES_AP_RESET_IP  FixedPcdGet32 (PcdSevEsWorkAreaBase)
> +  %define SEV_LAUNCH_SECRET_BASE  FixedPcdGet32 (PcdSevLaunchSecretBase)
> +  %define SEV_LAUNCH_SECRET_SIZE  FixedPcdGet32 (PcdSevLaunchSecretSize)
>  %include "Ia16/ResetVectorVtf0.asm"
>  
> 


^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [PATCH v2 5/6] OvmfPkg/AmdSev: assign and protect the Sev Secret area
  2020-11-20 18:45 ` [PATCH v2 5/6] OvmfPkg/AmdSev: assign and protect the Sev Secret area James Bottomley
@ 2020-11-23 22:38   ` Laszlo Ersek
  0 siblings, 0 replies; 37+ messages in thread
From: Laszlo Ersek @ 2020-11-23 22:38 UTC (permalink / raw)
  To: James Bottomley, devel
  Cc: dovmurik, Dov.Murik1, ashish.kalra, brijesh.singh, tobin,
	david.kaplan, jon.grimm, thomas.lendacky, frankeh,
	Dr . David Alan Gilbert

On 11/20/20 19:45, James Bottomley wrote:
> Create a one page secret area in the MEMFD and protect the area with a
> boot time HOB.
> 
> Ref: https://bugzilla.tianocore.org/show_bug.cgi?id=3077
> Signed-off-by: James Bottomley <jejb@linux.ibm.com>
> ---
>  OvmfPkg/AmdSev/AmdSevX64.dsc           |  1 +
>  OvmfPkg/AmdSev/AmdSevX64.fdf           |  4 +++
>  OvmfPkg/AmdSev/SecretPei/SecretPei.inf | 39 ++++++++++++++++++++++++++
>  OvmfPkg/AmdSev/SecretPei/SecretPei.c   | 25 +++++++++++++++++
>  4 files changed, 69 insertions(+)
>  create mode 100644 OvmfPkg/AmdSev/SecretPei/SecretPei.inf
>  create mode 100644 OvmfPkg/AmdSev/SecretPei/SecretPei.c
> 
> diff --git a/OvmfPkg/AmdSev/AmdSevX64.dsc b/OvmfPkg/AmdSev/AmdSevX64.dsc
> index c0b4e1b274fc..a3f75a626e5e 100644
> --- a/OvmfPkg/AmdSev/AmdSevX64.dsc
> +++ b/OvmfPkg/AmdSev/AmdSevX64.dsc
> @@ -624,6 +624,7 @@ [Components]
>      <LibraryClasses>
>    }
>    UefiCpuPkg/CpuMpPei/CpuMpPei.inf
> +  OvmfPkg/AmdSev/SecretPei/SecretPei.inf
>  
>  !if $(TPM_ENABLE) == TRUE
>    OvmfPkg/Tcg/Tcg2Config/Tcg2ConfigPei.inf
> diff --git a/OvmfPkg/AmdSev/AmdSevX64.fdf b/OvmfPkg/AmdSev/AmdSevX64.fdf
> index 97f031950abd..c628e6d8f6e7 100644
> --- a/OvmfPkg/AmdSev/AmdSevX64.fdf
> +++ b/OvmfPkg/AmdSev/AmdSevX64.fdf
> @@ -59,6 +59,9 @@ [FD.MEMFD]
>  0x00B000|0x001000
>  gUefiCpuPkgTokenSpaceGuid.PcdSevEsWorkAreaBase|gUefiCpuPkgTokenSpaceGuid.PcdSevEsWorkAreaSize
>  
> +0x00C000|0x001000
> +gUefiOvmfPkgTokenSpaceGuid.PcdSevLaunchSecretBase|gUefiOvmfPkgTokenSpaceGuid.PcdSevLaunchSecretSize
> +
>  0x010000|0x010000
>  gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecPeiTempRamBase|gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecPeiTempRamSize
>  
> @@ -138,6 +141,7 @@ [FV.PEIFV]
>  INF  MdeModulePkg/Core/DxeIplPeim/DxeIpl.inf
>  INF  UefiCpuPkg/Universal/Acpi/S3Resume2Pei/S3Resume2Pei.inf
>  INF  UefiCpuPkg/CpuMpPei/CpuMpPei.inf
> +INF  OvmfPkg/AmdSev/SecretPei/SecretPei.inf
>  
>  !if $(TPM_ENABLE) == TRUE
>  INF  OvmfPkg/Tcg/Tcg2Config/Tcg2ConfigPei.inf
> diff --git a/OvmfPkg/AmdSev/SecretPei/SecretPei.inf b/OvmfPkg/AmdSev/SecretPei/SecretPei.inf
> new file mode 100644
> index 000000000000..1b40ac036aba
> --- /dev/null
> +++ b/OvmfPkg/AmdSev/SecretPei/SecretPei.inf
> @@ -0,0 +1,39 @@
> +## @file
> +#  PEI support for SEV Secrets
> +#
> +#  Copyright (C) 2020 James Bottomley, IBM Corporation.
> +#
> +#  SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +##
> +
> +[Defines]
> +  INF_VERSION                    = 0x00010005
> +  BASE_NAME                      = SecretPei
> +  FILE_GUID                      = 45260dde-0c3c-4b41-a226-ef3803fac7d4
> +  MODULE_TYPE                    = PEIM
> +  VERSION_STRING                 = 1.0
> +  ENTRY_POINT                    = InitializeSecretPei
> +
> +#
> +# The following information is for reference only and not required by the build tools.
> +#

(1) I'm very sorry, my previous point on this was unclear.

The above comment refers to the VALID_ARCHITECTURES (non-)macro.
Therefore, if we keep VALID_ARCHITECTURES, then it should be restricted
to X64, and the comment should stay. If we remove VALID_ARCHITECTURES,
then the comment becomes dangling -- and it should disappear too.

With this updated:

Reviewed-by: Laszlo Ersek <lersek@redhat.com>

Thanks
Laszlo

> +
> +[Sources]
> +  SecretPei.c
> +
> +[Packages]
> +  OvmfPkg/OvmfPkg.dec
> +  MdePkg/MdePkg.dec
> +
> +[LibraryClasses]
> +  HobLib
> +  PeimEntryPoint
> +  PcdLib
> +
> +[FixedPcd]
> +  gUefiOvmfPkgTokenSpaceGuid.PcdSevLaunchSecretBase
> +  gUefiOvmfPkgTokenSpaceGuid.PcdSevLaunchSecretSize
> +
> +[Depex]
> +  TRUE
> diff --git a/OvmfPkg/AmdSev/SecretPei/SecretPei.c b/OvmfPkg/AmdSev/SecretPei/SecretPei.c
> new file mode 100644
> index 000000000000..ad491515dd5d
> --- /dev/null
> +++ b/OvmfPkg/AmdSev/SecretPei/SecretPei.c
> @@ -0,0 +1,25 @@
> +/** @file
> +  SEV Secret boot time HOB placement
> +
> +  Copyright (C) 2020 James Bottomley, IBM Corporation.
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +#include <PiPei.h>
> +#include <Library/HobLib.h>
> +#include <Library/PcdLib.h>
> +
> +EFI_STATUS
> +EFIAPI
> +InitializeSecretPei (
> +  IN       EFI_PEI_FILE_HANDLE  FileHandle,
> +  IN CONST EFI_PEI_SERVICES     **PeiServices
> +  )
> +{
> +  BuildMemoryAllocationHob (
> +    PcdGet32 (PcdSevLaunchSecretBase),
> +    PcdGet32 (PcdSevLaunchSecretSize),
> +    EfiBootServicesData
> +    );
> +
> +  return EFI_SUCCESS;
> +}
> 


^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [PATCH v2 6/6] OvmfPkg/AmdSev: Expose the Sev Secret area using a configuration table
  2020-11-20 18:45 ` [PATCH v2 6/6] OvmfPkg/AmdSev: Expose the Sev Secret area using a configuration table James Bottomley
@ 2020-11-23 22:56   ` Laszlo Ersek
  0 siblings, 0 replies; 37+ messages in thread
From: Laszlo Ersek @ 2020-11-23 22:56 UTC (permalink / raw)
  To: James Bottomley, devel
  Cc: dovmurik, Dov.Murik1, ashish.kalra, brijesh.singh, tobin,
	david.kaplan, jon.grimm, thomas.lendacky, frankeh,
	Dr . David Alan Gilbert

On 11/20/20 19:45, James Bottomley wrote:
> Now that the secret area is protected by a boot time HOB, extract its
> location details into a configuration table referenced by
> gSevLaunchSecretGuid so the boot loader or OS can locate it before a
> call to ExitBootServices().
>
> Ref: https://bugzilla.tianocore.org/show_bug.cgi?id=3077
> Signed-off-by: James Bottomley <jejb@linux.ibm.com>
> ---
>  OvmfPkg/OvmfPkg.dec                    |  1 +
>  OvmfPkg/AmdSev/AmdSevX64.dsc           |  1 +
>  OvmfPkg/AmdSev/AmdSevX64.fdf           |  1 +
>  OvmfPkg/AmdSev/SecretDxe/SecretDxe.inf | 37 ++++++++++++++++++++++++++
>  OvmfPkg/Include/Guid/SevLaunchSecret.h | 28 +++++++++++++++++++
>  OvmfPkg/AmdSev/SecretDxe/SecretDxe.c   | 25 +++++++++++++++++
>  6 files changed, 93 insertions(+)
>  create mode 100644 OvmfPkg/AmdSev/SecretDxe/SecretDxe.inf
>  create mode 100644 OvmfPkg/Include/Guid/SevLaunchSecret.h
>  create mode 100644 OvmfPkg/AmdSev/SecretDxe/SecretDxe.c
>
> diff --git a/OvmfPkg/OvmfPkg.dec b/OvmfPkg/OvmfPkg.dec
> index 7d27f8e16040..8a294116efaa 100644
> --- a/OvmfPkg/OvmfPkg.dec
> +++ b/OvmfPkg/OvmfPkg.dec
> @@ -117,6 +117,7 @@ [Guids]
>    gLinuxEfiInitrdMediaGuid              = {0x5568e427, 0x68fc, 0x4f3d, {0xac, 0x74, 0xca, 0x55, 0x52, 0x31, 0xcc, 0x68}}
>    gQemuKernelLoaderFsMediaGuid          = {0x1428f772, 0xb64a, 0x441e, {0xb8, 0xc3, 0x9e, 0xbd, 0xd7, 0xf8, 0x93, 0xc7}}
>    gGrubFileGuid                         = {0xb5ae312c, 0xbc8a, 0x43b1, {0x9c, 0x62, 0xeb, 0xb8, 0x26, 0xdd, 0x5d, 0x07}}
> +  gSevLaunchSecretGuid                  = {0xadf956ad, 0xe98c, 0x484c, {0xae, 0x11, 0xb5, 0x1c, 0x7d, 0x33, 0x64, 0x47}}
>
>  [Ppis]
>    # PPI whose presence in the PPI database signals that the TPM base address
> diff --git a/OvmfPkg/AmdSev/AmdSevX64.dsc b/OvmfPkg/AmdSev/AmdSevX64.dsc
> index a3f75a626e5e..fa2d1d20d551 100644
> --- a/OvmfPkg/AmdSev/AmdSevX64.dsc
> +++ b/OvmfPkg/AmdSev/AmdSevX64.dsc
> @@ -812,6 +812,7 @@ [Components]
>        gEfiShellPkgTokenSpaceGuid.PcdShellLibAutoInitialize|FALSE
>    }
>  !endif
> +  OvmfPkg/AmdSev/SecretDxe/SecretDxe.inf
>    OvmfPkg/AmdSev/Grub/Grub.inf
>  !if $(BUILD_SHELL) == TRUE
>    ShellPkg/Application/Shell/Shell.inf {
> diff --git a/OvmfPkg/AmdSev/AmdSevX64.fdf b/OvmfPkg/AmdSev/AmdSevX64.fdf
> index c628e6d8f6e7..b60ff6227a4f 100644
> --- a/OvmfPkg/AmdSev/AmdSevX64.fdf
> +++ b/OvmfPkg/AmdSev/AmdSevX64.fdf
> @@ -269,6 +269,7 @@ [FV.DXEFV]
>  !if $(TOOL_CHAIN_TAG) != "XCODE5" && $(BUILD_SHELL) == TRUE
>  INF  OvmfPkg/LinuxInitrdDynamicShellCommand/LinuxInitrdDynamicShellCommand.inf
>  !endif
> +INF OvmfPkg/AmdSev/SecretDxe/SecretDxe.inf
>  INF  OvmfPkg/AmdSev/Grub/Grub.inf
>  !if $(BUILD_SHELL) == TRUE
>  INF  ShellPkg/Application/Shell/Shell.inf
> diff --git a/OvmfPkg/AmdSev/SecretDxe/SecretDxe.inf b/OvmfPkg/AmdSev/SecretDxe/SecretDxe.inf
> new file mode 100644
> index 000000000000..62ab00a3d382
> --- /dev/null
> +++ b/OvmfPkg/AmdSev/SecretDxe/SecretDxe.inf
> @@ -0,0 +1,37 @@
> +## @file
> +#  Sev Secret configuration Table installer
> +#
> +#  Copyright (C) 2020 James Bottomley, IBM Corporation.
> +#
> +#  SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +##
> +
> +[Defines]
> +  INF_VERSION                    = 0x00010005
> +  BASE_NAME                      = SecretDxe
> +  FILE_GUID                      = 6e2b9619-8810-4e9d-a177-d432bb9abeda
> +  MODULE_TYPE                    = DXE_DRIVER
> +  VERSION_STRING                 = 1.0
> +  ENTRY_POINT                    = InitializeSecretDxe
> +
> +[Sources]
> +  SecretDxe.c
> +
> +[Packages]
> +  OvmfPkg/OvmfPkg.dec
> +  MdePkg/MdePkg.dec
> +
> +[LibraryClasses]
> +  UefiBootServicesTableLib
> +  UefiDriverEntryPoint
> +
> +[Guids]
> +  gSevLaunchSecretGuid
> +
> +[FixedPcd]
> +  gUefiOvmfPkgTokenSpaceGuid.PcdSevLaunchSecretBase
> +  gUefiOvmfPkgTokenSpaceGuid.PcdSevLaunchSecretSize
> +
> +[Depex]
> +  TRUE
> diff --git a/OvmfPkg/Include/Guid/SevLaunchSecret.h b/OvmfPkg/Include/Guid/SevLaunchSecret.h
> new file mode 100644
> index 000000000000..fa5f3830bc2b
> --- /dev/null
> +++ b/OvmfPkg/Include/Guid/SevLaunchSecret.h
> @@ -0,0 +1,28 @@
> + /** @file
> +   UEFI Configuration Table for exposing the SEV Launch Secret location to UEFI
> +   applications (boot loaders).
> +
> +   Copyright (C) 2020 James Bottomley, IBM Corporation.
> +   SPDX-License-Identifier: BSD-2-Clause-Patent
> + **/
> +
> +#ifndef SEV_LAUNCH_SECRET_H_
> +#define SEV_LAUNCH_SECRET_H_
> +
> +#include <Uefi/UefiBaseType.h>
> +
> +#define SEV_LAUNCH_SECRET_GUID                          \
> +  { 0xadf956ad,                                         \
> +    0xe98c,                                             \
> +    0x484c,                                             \
> +    { 0xae, 0x11, 0xb5, 0x1c, 0x7d, 0x33, 0x64, 0x47 }, \
> +  }
> +
> +typedef struct {
> +  UINT32 Base;
> +  UINT32 Size;
> +} SEV_LAUNCH_SECRET_LOCATION;
> +
> +extern EFI_GUID gSevLaunchSecretGuid;
> +
> +#endif // SEV_LAUNCH_SECRET_H_
> diff --git a/OvmfPkg/AmdSev/SecretDxe/SecretDxe.c b/OvmfPkg/AmdSev/SecretDxe/SecretDxe.c
> new file mode 100644
> index 000000000000..e5a1624e3cd7
> --- /dev/null
> +++ b/OvmfPkg/AmdSev/SecretDxe/SecretDxe.c
> @@ -0,0 +1,25 @@
> +/** @file
> +  SEV Secret configuration table constructor
> +
> +  Copyright (C) 2020 James Bottomley, IBM Corporation.
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +#include <PiDxe.h>
> +#include <Library/UefiBootServicesTableLib.h>
> +#include <Guid/SevLaunchSecret.h>
> +
> +STATIC SEV_LAUNCH_SECRET_LOCATION mSecretDxeTable = {
> +  FixedPcdGet32 (PcdSevLaunchSecretBase),
> +  FixedPcdGet32 (PcdSevLaunchSecretSize),
> +};
> +
> +EFI_STATUS
> +EFIAPI
> +InitializeSecretDxe(
> +  IN EFI_HANDLE           ImageHandle,
> +  IN EFI_SYSTEM_TABLE     *SystemTable
> +  )
> +{
> +  return gBS->InstallConfigurationTable (&gSevLaunchSecretGuid,
> +                                         &mSecretDxeTable);
> +}
>

(1) Point (13) from my previous review at

  https://edk2.groups.io/g/devel/message/67623
  https://www.redhat.com/archives/edk2-devel-archive/2020-November/msg00783.html

has not been addressed. To re-state it here, please use one of the
following indentations:

  return gBS->InstallConfigurationTable (
                &gSevLaunchSecretGuid,
                &mSecretDxeTable
                );

or

  return gBS->InstallConfigurationTable (&gSevLaunchSecretGuid,
                &mSecretDxeTable);

With the indentation fixed,

Reviewed-by: Laszlo Ersek <lersek@redhat.com>

Thanks,
Laszlo


^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [PATCH v2 1/6] OvmfPkg/Amdsev: Base commit to build encrypted boot specific OVMF
  2020-11-23 18:01   ` Laszlo Ersek
@ 2020-11-23 23:25     ` James Bottomley
  2020-11-23 23:43       ` Laszlo Ersek
  0 siblings, 1 reply; 37+ messages in thread
From: James Bottomley @ 2020-11-23 23:25 UTC (permalink / raw)
  To: Laszlo Ersek, devel
  Cc: dovmurik, Dov.Murik1, ashish.kalra, brijesh.singh, tobin,
	david.kaplan, jon.grimm, thomas.lendacky, frankeh,
	Dr . David Alan Gilbert

On Mon, 2020-11-23 at 19:01 +0100, Laszlo Ersek wrote:
> On 11/20/20 19:45, James Bottomley wrote:
> > This commit represents the file copied from OvmfPkgX64 with minor
> > changes to change the build name.
> > 
> > This package will form the basis for adding Sev specific features.
> > Since everything must go into a single rom file for attestation,
> > the separated build of code and variables is eliminated.
> > 
> > Ref: https://bugzilla.tianocore.org/show_bug.cgi?id=3077
> > Signed-off-by: James Bottomley <jejb@linux.ibm.com>
> > 
> > ---
> > 
> > v2: remove secure boot, smm and networking
> > ---
> >  OvmfPkg/AmdSev/AmdSevX64.dsc | 867
> > +++++++++++++++++++++++++++++++++++
> >  OvmfPkg/AmdSev/AmdSevX64.fdf | 461 +++++++++++++++++++
> >  2 files changed, 1328 insertions(+)
> >  create mode 100644 OvmfPkg/AmdSev/AmdSevX64.dsc
> >  create mode 100644 OvmfPkg/AmdSev/AmdSevX64.fdf
> > 
> > diff --git a/OvmfPkg/AmdSev/AmdSevX64.dsc
> > b/OvmfPkg/AmdSev/AmdSevX64.dsc
> > new file mode 100644
> > index 000000000000..852be757bfbe
> > --- /dev/null
> > +++ b/OvmfPkg/AmdSev/AmdSevX64.dsc
> > @@ -0,0 +1,867 @@
> 
> [...]
> 
> > +[LibraryClasses]
> 
> [...]
> 
> > +  VarCheckLib|MdeModulePkg/Library/VarCheckLib/VarCheckLib.inf
> 
> (1) The following two lib class resolutions are missing here:
> 
>  
> VariablePolicyLib|MdeModulePkg/Library/VariablePolicyLib/VariablePoli
> cyLib.inf
>  
> VariablePolicyHelperLib|MdeModulePkg/Library/VariablePolicyHelperLib/
> VariablePolicyHelperLib.inf
> 
> They were added to the other OVMF DSC files in commit 435a05aff54d
> ("OvmfPkg: Add VariablePolicy engine to OvmfPkg platform", 2020-11-
> 17). This dependency didn't exist at the time of your v1 posting (Nov
> 12th, in my time zone).
> 
> But now the new platform doesn't seem to build without them:
> 
> > OvmfPkg/AmdSev/AmdSevX64.dsc(...): error 4000: Instance of library
> > class [VariablePolicyLib] is not found
> >         in
> > [MdeModulePkg/Universal/Variable/RuntimeDxe/VariableRuntimeDxe.inf]
> > [X64]
> >         consumed by module
> > [MdeModulePkg/Universal/Variable/RuntimeDxe/VariableRuntimeDxe.inf]
> 
> They are required by
> "MdeModulePkg/Universal/Variable/RuntimeDxe/VariableRuntimeDxe.inf"
> too, not just by
> "MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmm.inf"
> (which is correctly removed by this patch).
> 
> ... actually, for VariableRuntimeDxe:

Yes, I've rebased and added the necessary new libraries to get it to
build.

> On 11/20/20 19:45, James Bottomley wrote:
> 
> [...]
> 
> > +[LibraryClasses.common.DXE_RUNTIME_DRIVER]
> 
> [...]
> 
> > +  QemuFwCfgS3Lib|OvmfPkg/Library/QemuFwCfgS3Lib/DxeQemuFwCfgS3LibF
> > wCfg.inf
> 
> (2) the following (DXE_RUNTIME_DRIVER-specific) lib class resolution
> is missing here:
> 
>  
> VariablePolicyLib|MdeModulePkg/Library/VariablePolicyLib/VariablePoli
> cyLibRuntimeDxe.inf
> 
> 
> ... So I think that, for (1)+(2) together, simply the "OvmfXen.dsc"
> hunks from 435a05aff54d should be incorporated into this patch.

Yes, I based the fix on that.

> [...]
> 
> > +[PcdsFixedAtBuild]
> > +  gEfiMdeModulePkgTokenSpaceGuid.PcdStatusCodeMemorySize|1
> > +  gEfiMdeModulePkgTokenSpaceGuid.PcdResetOnMemoryTypeInformationCh
> > ange|FALSE
> > +  gEfiMdePkgTokenSpaceGuid.PcdMaximumGuidedExtractHandler|0x10
> > +!if ($(FD_SIZE_IN_KB) == 1024) || ($(FD_SIZE_IN_KB) == 2048)
> > +  gEfiMdeModulePkgTokenSpaceGuid.PcdMaxVariableSize|0x2000
> > +  gEfiMdeModulePkgTokenSpaceGuid.PcdMaxAuthVariableSize|0x2800
> > +  # match PcdFlashNvStorageVariableSize purely for convenience
> > +  gEfiMdeModulePkgTokenSpaceGuid.PcdVariableStoreSize|0xe000
> > +!endif
> > +!if $(FD_SIZE_IN_KB) == 4096
> > +  gEfiMdeModulePkgTokenSpaceGuid.PcdMaxVariableSize|0x8400
> > +  gEfiMdeModulePkgTokenSpaceGuid.PcdMaxAuthVariableSize|0x8400
> > +  # match PcdFlashNvStorageVariableSize purely for convenience
> > +  gEfiMdeModulePkgTokenSpaceGuid.PcdVariableStoreSize|0x40000
> > +!endif
> > +  gEfiMdeModulePkgTokenSpaceGuid.PcdVariableStoreSize|0x80000
> > +  gEfiMdeModulePkgTokenSpaceGuid.PcdMaxVolatileVariableSize|0x4000
> > 0
> 
> (3) The above two PCD settings are conditional on NETWORK_TLS_ENABLE
> being TRUE, so please remove them together with the condition.

I removed them and assumed "with the condition" meant with the
condition you removed in the first iteration.

> Right now, they override the settings in the just preceding blocks
> (which depend on FD_SIZE_IN_KB being 1M / 2M / 4M).
> 
> [...]
> 
> > +[PcdsDynamicDefault]
> > +  # only set when
> > +  #   ($(SMM_REQUIRE) == FALSE)
> 
> (4) please remove the comment (only the comment)
> 
> > +  gEfiMdeModulePkgTokenSpaceGuid.PcdEmuVariableNvStoreReserved|0
> 
> [...]
> 
> > +[Components]
> 
> [...]
> 
> > +  OvmfPkg/VirtioNetDxe/VirtioNet.inf
> 
> (5) Please remove this driver from the DSC file too (you correctly
> removed it from the FDF file). Right now, the driver is built, just
> not included. We shouldn't build it.

Done.

Thanks!

James

> The rest looks good to me.
> 
> Thanks!
> Laszlo
> 



^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [PATCH v2 1/6] OvmfPkg/Amdsev: Base commit to build encrypted boot specific OVMF
  2020-11-23 23:25     ` James Bottomley
@ 2020-11-23 23:43       ` Laszlo Ersek
  0 siblings, 0 replies; 37+ messages in thread
From: Laszlo Ersek @ 2020-11-23 23:43 UTC (permalink / raw)
  To: jejb, devel
  Cc: dovmurik, Dov.Murik1, ashish.kalra, brijesh.singh, tobin,
	david.kaplan, jon.grimm, thomas.lendacky, frankeh,
	Dr . David Alan Gilbert

On 11/24/20 00:25, James Bottomley wrote:
> On Mon, 2020-11-23 at 19:01 +0100, Laszlo Ersek wrote:
>> On 11/20/20 19:45, James Bottomley wrote:

>>> +[PcdsFixedAtBuild]
>>> +  gEfiMdeModulePkgTokenSpaceGuid.PcdStatusCodeMemorySize|1
>>> +  gEfiMdeModulePkgTokenSpaceGuid.PcdResetOnMemoryTypeInformationCh
>>> ange|FALSE
>>> +  gEfiMdePkgTokenSpaceGuid.PcdMaximumGuidedExtractHandler|0x10
>>> +!if ($(FD_SIZE_IN_KB) == 1024) || ($(FD_SIZE_IN_KB) == 2048)
>>> +  gEfiMdeModulePkgTokenSpaceGuid.PcdMaxVariableSize|0x2000
>>> +  gEfiMdeModulePkgTokenSpaceGuid.PcdMaxAuthVariableSize|0x2800
>>> +  # match PcdFlashNvStorageVariableSize purely for convenience
>>> +  gEfiMdeModulePkgTokenSpaceGuid.PcdVariableStoreSize|0xe000
>>> +!endif
>>> +!if $(FD_SIZE_IN_KB) == 4096
>>> +  gEfiMdeModulePkgTokenSpaceGuid.PcdMaxVariableSize|0x8400
>>> +  gEfiMdeModulePkgTokenSpaceGuid.PcdMaxAuthVariableSize|0x8400
>>> +  # match PcdFlashNvStorageVariableSize purely for convenience
>>> +  gEfiMdeModulePkgTokenSpaceGuid.PcdVariableStoreSize|0x40000
>>> +!endif
>>> +  gEfiMdeModulePkgTokenSpaceGuid.PcdVariableStoreSize|0x80000
>>> +  gEfiMdeModulePkgTokenSpaceGuid.PcdMaxVolatileVariableSize|0x4000
>>> 0
>>
>> (3) The above two PCD settings are conditional on NETWORK_TLS_ENABLE
>> being TRUE, so please remove them together with the condition.
> 
> I removed them and assumed "with the condition" meant with the
> condition you removed in the first iteration.

Right, I meant that the entirety of:

!if $(NETWORK_TLS_ENABLE) == TRUE
  gEfiMdeModulePkgTokenSpaceGuid.PcdVariableStoreSize|0x80000
  gEfiMdeModulePkgTokenSpaceGuid.PcdMaxVolatileVariableSize|0x40000
!endif

should be removed.

Thanks!
Laszlo


^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [PATCH v2 2/6] OvmfPkg/AmdSev: add Grub Firmware Volume Package
  2020-11-23 21:08   ` Laszlo Ersek
@ 2020-11-24  6:38     ` James Bottomley
  2020-11-24  8:23       ` Laszlo Ersek
  0 siblings, 1 reply; 37+ messages in thread
From: James Bottomley @ 2020-11-24  6:38 UTC (permalink / raw)
  To: Laszlo Ersek, devel
  Cc: dovmurik, Dov.Murik1, ashish.kalra, brijesh.singh, tobin,
	david.kaplan, jon.grimm, thomas.lendacky, frankeh,
	Dr . David Alan Gilbert

On Mon, 2020-11-23 at 22:08 +0100, Laszlo Ersek wrote:
[...]
> (1) typo -- should be "Bootloader", I believe (apologies for missing
> it in v1)

fixed.


[...]
> > +##
> > +# Note: The version of grub.efi this picks up can be generated by
> > +# grub.sh which must be specified as a PREBUILD in the .dsc file
> > or
> > +# you can simply move a precompiled grub into here and not do the
> > +# PREBUILD)
> 
> (2) This part of the patch looks unchanged, and I asked for more
> explanation in [a](3) -- "Can you elaborate how to skip PREBUILD"?
> 
> The comment in the patch remains the same, and (AFAICT) I have not
> received a response within the v1 thread either. (Instead you stated
> "I did everything except [...].)
> 
> So now I'm not sure... Did you miss [a](3), or did you decide it was
> not important enough to discuss / address?

Actually, the change was to make it true.  In the previous patch
grub.efi was always rebuilt in spite of what the comment in Grub.inf
implied.  Now it's only rebuilt if grub.efi is non-existent or older
than either grub.sh or grub.cfg.  I've expanded the comment.  I see you
picked this up in 10 below.

> > +##
> > +[Binaries]
> > +   PE32|grub.efi|*
> > +
> > diff --git
> > a/OvmfPkg/Library/PlatformBootManagerLibGrub/PlatformBootManagerLib
> > Grub.inf
> > b/OvmfPkg/Library/PlatformBootManagerLibGrub/PlatformBootManagerLib
> > Grub.inf
> > new file mode 100644
> > index 000000000000..a997d7586e6a
> > --- /dev/null
> > +++
> > b/OvmfPkg/Library/PlatformBootManagerLibGrub/PlatformBootManagerLib
> > Grub.inf
> > @@ -0,0 +1,79 @@
> > +## @file
> > +#  Platform BDS customizations library.
> > +#
> > +#  Copyright (c) 2007 - 2019, Intel Corporation. All rights
> > reserved.<BR>
> > +#  SPDX-License-Identifier: BSD-2-Clause-Patent
> > +#
> > +##
> 
> (3) In the v1 review thread, under patch #1, I requested: "In every
> new file created in this series, please prepend an IBM Copyright
> Notice, to the original (C) notices (if any)."
> 
>   https://edk2.groups.io/g/devel/message/67615
>   
> https://www.redhat.com/archives/edk2-devel-archive/2020-November/msg00775.html
> 
> This is a new file, but it still has no IBM (C) notice.

Slipped through the cracks: I've added it.

> 
> > +
> > +[Defines]
> > +  INF_VERSION                    = 0x00010005
> > +  BASE_NAME                      = PlatformBootManagerLibGrub
> > +  FILE_GUID                      = 3a8f8431-f0c9-4c95-8a1d-
> > 04445c582d4e
> > +  MODULE_TYPE                    = DXE_DRIVER
> > +  VERSION_STRING                 = 1.0
> > +  LIBRARY_CLASS                  =
> > PlatformBootManagerLib|DXE_DRIVER
> > +
> > +#
> > +# The following information is for reference only and not required
> > by the build tools.
> > +#
> > +#  VALID_ARCHITECTURES           = X64
> > +#
> > +
> > +[Sources]
> > +  BdsPlatform.c
> > +  PlatformData.c
> > +  BdsPlatform.h
> > +
> > +[Packages]
> > +  MdePkg/MdePkg.dec
> > +  MdeModulePkg/MdeModulePkg.dec
> > +  SourceLevelDebugPkg/SourceLevelDebugPkg.dec
> > +  OvmfPkg/OvmfPkg.dec
> > +  SecurityPkg/SecurityPkg.dec
> > +  ShellPkg/ShellPkg.dec
> > +
> > +[LibraryClasses]
> > +  BaseLib
> > +  MemoryAllocationLib
> > +  UefiBootServicesTableLib
> > +  UefiRuntimeServicesTableLib
> > +  BaseMemoryLib
> > +  DebugLib
> > +  PcdLib
> > +  UefiBootManagerLib
> > +  BootLogoLib
> > +  DevicePathLib
> > +  PciLib
> > +  ReportStatusCodeLib
> > +  UefiLib
> > +  PlatformBmPrintScLib
> > +  Tcg2PhysicalPresenceLib
> > +  XenPlatformLib
> 
> (4) I suggested removing XenPlatformLib too, in [a](4).
> 
> Did you run into build problems with that?
> 
> Replacing the XenDetected() calls in "BdsPlatform.c" with constant
> FALSE, and simplifying the resultant code, should suffice.

No I just missed this part pursuing another set of stripping.

> > +
> > +[Pcd]
> > +  gUefiOvmfPkgTokenSpaceGuid.PcdOvmfFlashVariablesEnable
> 
> (5) Thanks for removing PcdEmuVariableEvent.
> 
> But, PcdOvmfFlashVariablesEnable is just as superfluous; the INF file
> now lists it without any references to the PCD in the code.

OK, removed.

> In [a](5) I requested the removal of everything in this INF file that
> was not required for the desired semantics (i.e., for unconditionally
> booting the builtin GRUB binary).
> 
> So again I'm unsure if you missed my feedback, or thought it was not
> important. (I didn't get a request for clarification either.)
>  
> Keeping INF files minimal is relevant for future contributions. We
> frequently need to determine the set of modules that depend on a
> particular PCD. If some INF files list PCDs unjustifiedly, then the
> affected module set may appear larger than it really is.
> 
> This applies to all sections of the INF file, not just [Pcd].

I did try stripping quite a lot, but then it wouldn't boot.  It seems
that the PCI devices are needed for grub to find the encrypted volume,
so I put most of it back again.  Is there some way of identifying
superfluous pieces so I can detect if I put too much back?

[...]
> > diff --git
> > a/OvmfPkg/Library/PlatformBootManagerLibGrub/BdsPlatform.h
> > b/OvmfPkg/Library/PlatformBootManagerLibGrub/BdsPlatform.h
> > new file mode 100644
> > index 000000000000..a7fc4dbc3c1f
> > --- /dev/null
> > +++ b/OvmfPkg/Library/PlatformBootManagerLibGrub/BdsPlatform.h
> > @@ -0,0 +1,175 @@
> > +/** @file
> > +  Platform BDS customizations include file.
> > +
> > +  Copyright (c) 2006 - 2017, Intel Corporation. All rights
> > reserved.<BR>
> > +  SPDX-License-Identifier: BSD-2-Clause-Patent
> 
> (6) Same as (3) -- missing IBM (C) on new file

Sorry, added.

> 
> > diff --git
> > a/OvmfPkg/Library/PlatformBootManagerLibGrub/BdsPlatform.c
> > b/OvmfPkg/Library/PlatformBootManagerLibGrub/BdsPlatform.c
> > new file mode 100644
> > index 000000000000..4fb2f904a10e
> > --- /dev/null
> > +++ b/OvmfPkg/Library/PlatformBootManagerLibGrub/BdsPlatform.c
> > @@ -0,0 +1,1483 @@
> > +/** @file
> > +  Platform BDS customizations.
> > +
> > +  Copyright (c) 2004 - 2019, Intel Corporation. All rights
> > reserved.<BR>
> > +  SPDX-License-Identifier: BSD-2-Clause-Patent
> 
> (7) same as (3) -- missing IBM (C) on new file

Sorry, added.

> > +/**
> > +  The function is called when no boot option could be launched,
> > +  including platform recovery options and options pointing to
> > applications
> > +  built into firmware volumes.
> > +
> > +  If this function returns, BDS attempts to enter an infinite
> > loop.
> > +**/
> > +VOID
> > +EFIAPI
> > +PlatformBootManagerUnableToBoot (
> > +  VOID
> > +  )
> > +{
> > +  //
> > +  // If we get here something failed about the grub boot but since
> > +  // We're privy to the secret we must panic and not retry or loop
> > +  //
> > +  CpuDeadLoop ();
> > +}
> 
> (8) In [a](7) I meant that both ASSERT() and CpuDeadLoop() should be
> called. In DEBUG and NOOPT builds, the ASSERT() fires, produces a
> somewhat helpful debug message, and the CpuDeadLoop() is not reached
> (ASSERT() may call CpuDeadLoop() internally, or raise an exception).
> In RELEASE builds, the message is not produced, but we still won't
> proceed past the CpuDeadLoop().
> 
> Sorry about not being clear enough.

OK, I put both in.

> > diff --git
> > a/OvmfPkg/Library/PlatformBootManagerLibGrub/PlatformData.c
> > b/OvmfPkg/Library/PlatformBootManagerLibGrub/PlatformData.c
> > new file mode 100644
> > index 000000000000..2858c3dfd5ca
> > --- /dev/null
> > +++ b/OvmfPkg/Library/PlatformBootManagerLibGrub/PlatformData.c
> > @@ -0,0 +1,213 @@
> > +/** @file
> > +  Defined the platform specific device path which will be used by
> > +  platform Bbd to perform the platform policy connect.
> > +
> > +  Copyright (c) 2004 - 2017, Intel Corporation. All rights
> > reserved.<BR>
> > +  SPDX-License-Identifier: BSD-2-Clause-Patent
> 
> (9) same as (3) -- missing IBM (C) on new file

Sorry, added.

> > diff --git a/OvmfPkg/AmdSev/Grub/grub.sh
> > b/OvmfPkg/AmdSev/Grub/grub.sh
> > new file mode 100644
> > index 000000000000..fd28dc6ab274
> > --- /dev/null
> > +++ b/OvmfPkg/AmdSev/Grub/grub.sh
> > @@ -0,0 +1,92 @@
> > +##  @file
> > +#  Build a version of grub capable of decrypting a luks volume
> > with a SEV
> > +#  Supplied secret
> > +#
> > +#  Copyright (C) 2020 James Bottomley, IBM Corporation.
> > +#
> > +#  SPDX-License-Identifier: BSD-2-Clause-Patent
> > +#
> > +##
> > +
> > +set -e
> > +remove_efi=1
> > +
> > +cleanup()  {
> > +    # remove the intermediates
> > +    for f in disk.fat grub-bootstrap.cfg; do
> > +	rm -f "${basedir}/$f"
> > +    done
> > +    if [ $remove_efi -eq 1 ]; then
> > +	rm -f "${basedir}/grub.efi"
> > +    fi
> > +}
> 
> (10) These two "rm -f" commands don't use the separator "--", unlike
> the "rm -f" command below (which has been updated, thanks for that).

Hm, yes, added.

> > +
> > +trap cleanup EXIT
> > +
> > +GRUB_MODULES="
> > +	    part_msdos
> > +	    part_gpt
> > +	    cryptodisk
> > +	    luks
> > +	    gcry_rijndael
> > +	    gcry_sha256
> > +	    ext2
> > +	    btrfs
> > +	    xfs
> > +	    fat
> > +	    configfile
> > +	    memdisk
> > +	    sleep
> > +	    normal
> > +	    echo
> > +	    test
> > +	    regexp
> > +	    linux
> > +	    linuxefi
> > +	    reboot
> > +	    sevsecret
> > +	    "
> > +basedir=$(dirname -- "$0")
> > +
> > +# don't run a build if grub.efi exists and is newer than the
> > config files
> > +if [ -e "${basedir}/grub.efi" -a \
> > +     "${basedir}/grub.efi" -nt "${basedir}/grub.cfg" -a \
> > +     "${basedir}/grub.efi" -nt "${basedir}/grub.sh" ]; then
> > +    remove_efi=0
> > +    echo "preserving existing grub.efi"
> 
> arguably this should go to stderr as well, but I don't insist

Sure, added.

> > +    exit 0
> > +fi
> > 
> 
> Ah, OK. This sort of addresses my question (2). Not entirely -- the
> comment at (2) implies the user is somehow responsible for skipping
> PREBUILD. While in reality, PREBUILD will be launched, it will just
> exit early.

Right, but I expanded the comment to describe the conditions.  The idea
is the distro could checkout edk2 then copy their own grub.efi in and
it will build.

> (11) Independently, "-a" is considered obsolescent, per
> <
> https://pubs.opengroup.org/onlinepubs/9699919799/utilities/test.html#tag_20_128_16>
> ;.
> 
> Anyway, feel free to ignore.

It's no trouble to use the && format.

> > +##
> > +# different distributions have different names for grub-mkimage,
> > so
> > +# search all the known ones
> > +##
> > +for b in grub2-mkimage grub-mkimage; do
> > +    if which "$b" > /dev/null 2>&1; then
> > +	mkimage="$b"
> > +	break;
> 
> (12) "muscle memory" semicolon after "break" :)

Um, yes ....

> (13) the indentation seems strange (Linux kernel style?); please
> don't use hardware tabs. (Hmmm, applies to other parts of this script
> too.)

OK, I got emacs to untabify it.  I did try converting it to DOS format
like the rest of edk2 but bash really doesn't like that:

/home/jejb/git/edk2/OvmfPkg/AmdSev/Grub/grub.sh: line 10: $'\r':
command not found

> > +    fi
> > +done
> > +if [ -z "$mkimage" ]; then
> > +    echo "Can't find grub mkimage" >&2
> > +    exit 1
> > +fi
> 
> (14) The variable "mkimage" has not been emptied before the loop,
> like I asked in [a](14).
> 
> The reason I had asked for emptying "mkimage" was two-fold: (i) I
> considered that maybe you'd add "set -u" at the top of the script as
> well, in which case the above "if" could fail ungracefully with
> "unbound variable", (ii) "mkimage" is not a totally uncommon variable
> name, and it could be inherited from the calling shell environment --
> in case the loop never matched.
> 
> Now, I may have been wrong in that reasoning. But please, if you
> think I'm wrong, say so. I think it's quite possible to convince me.
> If you simply ignore a request from me, that's not a good use of my
> time.

I actually just missed this, sorry.  I've updated the script.

> Whenever I review the next version of a series, I go over every
> single request I made under the last one, and verify whether it has
> been addressed, or explicitly refuted in the discussion. If neither
> happens, then I just don't know what to do, as I obviously have to
> make the exact same request in the next round of review. It's
> disappointing, and discourages me from continuing the review.

Yes, sorry, it's probably because I didn't go through it point by point
like I did this time.

James


> > +
> > +# GRUB's rescue parser doesn't understand 'if'.
> > +echo 'normal (memdisk)/grub.cfg' > "${basedir}/grub-bootstrap.cfg"
> > +
> > +# Now build a memdisk with the correct grub.cfg
> > +rm -f -- "${basedir}/disk.fat"
> > +mkfs.msdos -C -- "${basedir}/disk.fat" 64
> > +mcopy -i "${basedir}/disk.fat" -- "${basedir}/grub.cfg" ::grub.cfg
> > +
> > +
> > +${mkimage} -O x86_64-efi \
> > +	   -p '(crypto0)' \
> > +	   -c "${basedir}/grub-bootstrap.cfg" \
> > +	   -m "${basedir}/disk.fat" \
> > +	   -o "${basedir}/grub.efi" \
> > +	   ${GRUB_MODULES}
> > +
> > +remove_efi=0
> > +echo "grub.efi generated in ${basedir}"
> > 
> 
> Thanks
> Laszlo
> 



^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [PATCH v2 2/6] OvmfPkg/AmdSev: add Grub Firmware Volume Package
  2020-11-24  6:38     ` James Bottomley
@ 2020-11-24  8:23       ` Laszlo Ersek
  2020-11-24 14:54         ` Laszlo Ersek
  0 siblings, 1 reply; 37+ messages in thread
From: Laszlo Ersek @ 2020-11-24  8:23 UTC (permalink / raw)
  To: jejb, devel
  Cc: dovmurik, Dov.Murik1, ashish.kalra, brijesh.singh, tobin,
	david.kaplan, jon.grimm, thomas.lendacky, frankeh,
	Dr . David Alan Gilbert

On 11/24/20 07:38, James Bottomley wrote:
> On Mon, 2020-11-23 at 22:08 +0100, Laszlo Ersek wrote:

>> In [a](5) I requested the removal of everything in this INF file that
>> was not required for the desired semantics (i.e., for unconditionally
>> booting the builtin GRUB binary).
>>
>> So again I'm unsure if you missed my feedback, or thought it was not
>> important. (I didn't get a request for clarification either.)
>>  
>> Keeping INF files minimal is relevant for future contributions. We
>> frequently need to determine the set of modules that depend on a
>> particular PCD. If some INF files list PCDs unjustifiedly, then the
>> affected module set may appear larger than it really is.
>>
>> This applies to all sections of the INF file, not just [Pcd].
> 
> I did try stripping quite a lot, but then it wouldn't boot.  It seems
> that the PCI devices are needed for grub to find the encrypted volume,
> so I put most of it back again.  Is there some way of identifying
> superfluous pieces so I can detect if I put too much back?

I suggest proceeding element by element in the INF file (and matching
that, in the header / C files) -- remove one element per patch. Then you
can either build+test it as you go, or create a series of micro-patches
up-front, and if it doesn't boot, bisect it. Finally, squash the
removals that are justifiable into this patch (for posting), and drop
the rest.

It's unfortunately trial and error to some extent; however, given that
each step removes 1 element (PCD, Protocol, GUID, lib class, and finally
Package), and the number of elements summed over the INF file sections
is finite, this process is guaranteed to terminate.

Working in the other direction is much simpler, because the compiler
and/or the "build" tool will tell you if something is missing. Alas,
they don't tell us when something is listed superfluously. (The same
problem applies to #include directives in any C project -- I'm unaware
of any tool that flags a superfluous #include directive as such.)


>> (13) the indentation seems strange (Linux kernel style?); please
>> don't use hardware tabs. (Hmmm, applies to other parts of this script
>> too.)
> 
> OK, I got emacs to untabify it.  I did try converting it to DOS format
> like the rest of edk2 but bash really doesn't like that:
> 
> /home/jejb/git/edk2/OvmfPkg/AmdSev/Grub/grub.sh: line 10: $'\r':
> command not found

Yup, "grub.cfg" and "grub.sh" should use LF line terminators, not CRLF.

If you use 8bit or base64 Content-Transfer-Encoding with git-send-email,
it should be possible to send a patch that contains hunks with both LF
and CRLF line terminators.

This CRLF mess is a long-standing problem in edk2, and it has trained me
to look for files such as "grub.cfg" and "grub.sh" in patches. I tend to
verify them for LF manually, and if they appear to have CRLF after I
apply them locally -- which may or may not mean that they had CRLF on
the contributor's side too --, then I push them through dos2unix first
(rebasing the series).


... apologies that I sounded irritated earlier; it had been another
hectic day.

Thanks!
Laszlo


^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [PATCH v2 2/6] OvmfPkg/AmdSev: add Grub Firmware Volume Package
  2020-11-24  8:23       ` Laszlo Ersek
@ 2020-11-24 14:54         ` Laszlo Ersek
  2020-11-24 15:58           ` Laszlo Ersek
  0 siblings, 1 reply; 37+ messages in thread
From: Laszlo Ersek @ 2020-11-24 14:54 UTC (permalink / raw)
  To: jejb, devel
  Cc: dovmurik, Dov.Murik1, ashish.kalra, brijesh.singh, tobin,
	david.kaplan, jon.grimm, thomas.lendacky, frankeh,
	Dr . David Alan Gilbert

On 11/24/20 09:23, Laszlo Ersek wrote:
> On 11/24/20 07:38, James Bottomley wrote:
>> On Mon, 2020-11-23 at 22:08 +0100, Laszlo Ersek wrote:
> 
>>> In [a](5) I requested the removal of everything in this INF file that
>>> was not required for the desired semantics (i.e., for unconditionally
>>> booting the builtin GRUB binary).
>>>
>>> So again I'm unsure if you missed my feedback, or thought it was not
>>> important. (I didn't get a request for clarification either.)
>>>  
>>> Keeping INF files minimal is relevant for future contributions. We
>>> frequently need to determine the set of modules that depend on a
>>> particular PCD. If some INF files list PCDs unjustifiedly, then the
>>> affected module set may appear larger than it really is.
>>>
>>> This applies to all sections of the INF file, not just [Pcd].
>>
>> I did try stripping quite a lot, but then it wouldn't boot.  It seems
>> that the PCI devices are needed for grub to find the encrypted volume,
>> so I put most of it back again.  Is there some way of identifying
>> superfluous pieces so I can detect if I put too much back?
> 
> I suggest proceeding element by element in the INF file (and matching
> that, in the header / C files) -- remove one element per patch. Then you
> can either build+test it as you go, or create a series of micro-patches
> up-front, and if it doesn't boot, bisect it. Finally, squash the
> removals that are justifiable into this patch (for posting), and drop
> the rest.
> 
> It's unfortunately trial and error to some extent; however, given that
> each step removes 1 element (PCD, Protocol, GUID, lib class, and finally
> Package), and the number of elements summed over the INF file sections
> is finite, this process is guaranteed to terminate.

Looking briefly over the file "OvmfPkg/Library/PlatformBootManagerLibGrub/PlatformBootManagerLibGrub.inf", I suggest removing:

- [Packages]: whatever proves unnecessary in the end,

- [LibraryClasses]: ditto,

- [Pcd]: PcdOvmfFlashVariablesEnable, PcdPlatformBootTimeOut,

- [Pcd]: PcdUartDefaultBaudRate, PcdUartDefaultDataBits, PcdUartDefaultParity, PcdUartDefaultStopBits; together with "gXenConsoleDevicePath", "gXenPlatformConsole", XenDetected() / XenPlatformLib,

- [Pcd.IA32, Pcd.X64]: PcdFSBClock,

- [Protocols]: gEfiDecompressProtocolGuid, gEfiS3SaveStateProtocolGuid,

- [Guids]: gEfiGlobalVariableGuid,

Keep these:

- [Protocols]: gEfiPciRootBridgeIoProtocolGuid, gEfiDxeSmmReadyToLockProtocolGuid, gEfiLoadedImageProtocolGuid, gEfiFirmwareVolume2ProtocolGuid,

- [Guids]: gEfiEndOfDxeEventGroupGuid, gRootBridgesConnectedEventGroupGuid, gUefiShellFileGuid, gGrubFileGuid.

Thanks!
Laszlo


^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [PATCH v2 3/6] OvmfPkg: convert ES Reset Block structure to be guided
  2020-11-23 22:16   ` Laszlo Ersek
@ 2020-11-24 14:57     ` Lendacky, Thomas
  2020-11-24 19:07       ` James Bottomley
  2020-11-24 19:05     ` James Bottomley
  1 sibling, 1 reply; 37+ messages in thread
From: Lendacky, Thomas @ 2020-11-24 14:57 UTC (permalink / raw)
  To: Laszlo Ersek, James Bottomley, devel
  Cc: dovmurik, Dov.Murik1, ashish.kalra, brijesh.singh, tobin,
	david.kaplan, jon.grimm, frankeh, Dr . David Alan Gilbert

On 11/23/20 4:16 PM, Laszlo Ersek wrote:
> On 11/20/20 19:45, James Bottomley wrote:
>> Convert the current ES reset block structure to an extensible guid
>> based structure by appending a header and length, which allow for
>> multiple guid based data packets to be inserted.

I was wondering if this patch should be submitted outside of this series? 
I'm not sure it makes any difference, other than being able to be merged 
(possibly) quicker and independent of the series. Then this series simply 
takes advantage of it.

Thanks,
Tom

>>
>> Ref: https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Fbugzilla.tianocore.org%2Fshow_bug.cgi%3Fid%3D3077&amp;data=04%7C01%7Cthomas.lendacky%40amd.com%7Cd9de2a47d7d74b94e04208d88ffd6f03%7C3dd8961fe4884e608e11a82d994e183d%7C0%7C0%7C637417665948466692%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C1000&amp;sdata=x%2F%2Fbn5J9dNcXZqSs8Ui0GgABg6XDbmx%2BUh285EqwLcA%3D&amp;reserved=0
>> Signed-off-by: James Bottomley <jejb@linux.ibm.com>
>>
>> ---
>>
>> v2: added
>> ---
>>   OvmfPkg/ResetVector/Ia16/ResetVectorVtf0.asm | 49 +++++++++++++++-----
>>   1 file changed, 38 insertions(+), 11 deletions(-)
> 
> (1) Please update the subject line to:
> 
> OvmfPkg/ResetVector: convert SEV-ES Reset Block structure to be GUIDed
> 
> - edk2 prefers including module names too in the patch subjects
> - "ES" is harder to understand than "SEV-ES"
> - "GUIDed" is harder to misread as "guided"
> - subject length is still OK (70 chars)
> 
> 
>>
>> diff --git a/OvmfPkg/ResetVector/Ia16/ResetVectorVtf0.asm b/OvmfPkg/ResetVector/Ia16/ResetVectorVtf0.asm
>> index 980e0138e7fe..baf9d09f3625 100644
>> --- a/OvmfPkg/ResetVector/Ia16/ResetVectorVtf0.asm
>> +++ b/OvmfPkg/ResetVector/Ia16/ResetVectorVtf0.asm
>> @@ -25,21 +25,40 @@ ALIGN   16
>>       TIMES (0x1000 - ($ - EndOfPageTables) - 0x20) DB 0
>>   %endif
>>
>> +;
>> +; Padding to ensure first guid starts at 0xffffffd0
>> +;
>> +TIMES (32 - ((guidedStructureEnd - guidedStructureStart) % 32)) DB 0
> 
> (2) This will insert 32 zero bytes if the size is already aligned to 32
> bytes (because 32-0 = 32). In other words, the above produces 1 to 32
> zero bytes, dependent on table size.
> 
> The variant I proposed in point (5) at
> 
>    https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Fedk2.groups.io%2Fg%2Fdevel%2Fmessage%2F67621&amp;data=04%7C01%7Cthomas.lendacky%40amd.com%7Cd9de2a47d7d74b94e04208d88ffd6f03%7C3dd8961fe4884e608e11a82d994e183d%7C0%7C0%7C637417665948466692%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C1000&amp;sdata=nLOZvHpzFMRLV6uEeQvETY1SqI4AaSRc92WYbz8r9cA%3D&amp;reserved=0
>    https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Fwww.redhat.com%2Farchives%2Fedk2-devel-archive%2F2020-November%2Fmsg00781.html&amp;data=04%7C01%7Cthomas.lendacky%40amd.com%7Cd9de2a47d7d74b94e04208d88ffd6f03%7C3dd8961fe4884e608e11a82d994e183d%7C0%7C0%7C637417665948466692%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C1000&amp;sdata=yMYv%2BKKFtCs9G7qgdheAVmS2iLexxJWjbgSTTFcCetM%3D&amp;reserved=0
> 
> takes this into account, and only prepends 0 to 31 bytes (inclusive):
> 
>    TIMES (31 - (guidedStructureEnd - guidedStructureStart + 31) % 32) DB 0
> 
> - This variant subtracts 1 inside the remainder operation (which is
>    expressed as adding 31).
> 
> - For compensation, it adds 1 just outside of the remainder operation.
>    This addition in effect increases the subtrahend for the leftmost 32.
>    Therefore this (-1) addend is ultimately folded into the leftmost 32,
>    yielding 31 on the leftmost side.
> 
>    TIMES (32 - ((guidedStructureEnd - guidedStructureStart - 1) % 32 + 1)) DB 0
>                                                            ^^^       ^^^
>                                                            |         |
>                                                            |         compensate
>                                                            |         in the
>                                                            |         remainder
>                                                            |
>                                                            slide down residue
>                                                            class modulo 32
> 
> 
>   TIMES (32 - ((guidedStructureEnd - guidedStructureStart + 31) % 32) - 1) DB 0
>                                                           ^^^^        ^^^
>                                                           |           |
>                                                           |           unnest
>                                                           |           increment
>                                                           |           from
>                                                           |           subtrahend
>                                                           |
>                                                           express modular
>                                                           subtraction as
>                                                           addition, to avoid
>                                                           using % on a negative
>                                                           integer (in case size
>                                                           were 0)
> 
>   TIMES (31 - ((guidedStructureEnd - guidedStructureStart + 31) % 32)) DB 0
>          ^^
>          |
>          fold previous (-1) addend into leftmost constant
> 
> - This juggling of 1 results in no changes for residue classes 1 through
>    31, but wraps the outermost result (the padding size) for residue
>    class 0, from 32 to 0.
> 
> 
>> +
>> +; Guided structure.  To traverse this you should first verify the
>> +; presence of the table header guid
> 
> (3) suggest "table footer GUID" (the GUID follows the data, in address
> order)
> 
>> +; (96b582de-1fb2-45f7-baea-a366c55a082d) at 0xffffffd0.  If that
>> +; is found, the two bytes at 0xffffffce are the entire table length.
> 
> (4) can we make the whole table size field 32-bit? I don't have a
> particular use case in mind, it just looks more extensible than 16-bit.
> We can still keep the individual structs we have in mind 16-bit sized.
> 
>> +;
>> +; The table is composed of structures with the form:
>> +;
>> +; Data (arbitrary bytes identified by guid)
>> +; length from start of guid to end of data (2 bytes)
> 
> (5) This is hard to interpret, as "data" precedes "guid" in address
> space (guid is a footer, not a header).
> 
> I suggest "length from start of data to end of GUID"
> 
> 
>> +; guid (16 bytes)
>> +;
>> +; so work back from the header using the length to traverse until you
> 
> (6) suggest "from the footer"
> 
> 
>> +; either find the guid you're looking for or run off the end of the
>> +; table.
> 
> (7) suggest "run off the beginning of the table"
> 
> ... I realize "start" and "end" can be interpreted temporally and
> spatially. In a forward traversal they are the same, but now they
> aren't. I suggest we use the spatial (address space order)
> interpretation.
> 
>> +;
>> +guidedStructureStart:
>> +
>>   ;
>>   ; SEV-ES Processor Reset support
>>   ;
>>   ; sevEsResetBlock:
>>   ;   For the initial boot of an AP under SEV-ES, the "reset" RIP must be
>> -;   programmed to the RAM area defined by SEV_ES_AP_RESET_IP. A known offset
>> -;   and GUID will be used to locate this block in the firmware and extract
>> -;   the build time RIP value. The GUID must always be 48 bytes from the
>> -;   end of the firmware.
>> +;   programmed to the RAM area defined by SEV_ES_AP_RESET_IP. The data
>> +;   format is
>>   ;
>> -;   0xffffffca (-0x36) - IP value
>> -;   0xffffffcc (-0x34) - CS segment base [31:16]
>> -;   0xffffffce (-0x32) - Size of the SEV-ES reset block
>> -;   0xffffffd0 (-0x30) - SEV-ES reset block GUID
>> -;                        (00f771de-1a7e-4fcb-890e-68c77e2fb44e)
>> +;   IP value [0:15]
>> +;   CS segment base [31:16]
>> +;
>> +;   SEV-ES reset block GUID: 00f771de-1a7e-4fcb-890e-68c77e2fb44e
> 
> (8) Did I understand from the v1 discussion that the corresponding QEMU
> parser is not upstream yet? (Or at least not released?)
> 
> (9) The 16-bit size field of the SEV-ES reset block structure is not
> documented.
> 
> 
>>   ;
>>   ;   A hypervisor reads the CS segement base and IP value. The CS segment base
>>   ;   value represents the high order 16-bits of the CS segment base, so the
>> @@ -48,8 +67,6 @@ ALIGN   16
>>   ;   program the EIP register with the IP value as read.
>>   ;
>>
>> -TIMES (32 - (sevEsResetBlockEnd - sevEsResetBlockStart)) DB 0
>> -
>>   sevEsResetBlockStart:
>>       DD      SEV_ES_AP_RESET_IP
>>       DW      sevEsResetBlockEnd - sevEsResetBlockStart
>> @@ -57,6 +74,16 @@ sevEsResetBlockStart:
>>       DB      0x89, 0x0E, 0x68, 0xC7, 0x7E, 0x2F, 0xB4, 0x4E
>>   sevEsResetBlockEnd:
>>
>> +;
>> +; Table header: length of whole table followed by table header
> 
> (10) I suggest "table footer" (twice)
> 
> 
>> +; guid: 96b582de-1fb2-45f7-baea-a366c55a082d
>> +;
>> +    DW      guidedStructureEnd - guidedStructureStart
>> +    DB      0xDE, 0x82, 0xB5, 0x96, 0xB2, 0x1F, 0xF7, 0x45
>> +    DB      0xBA, 0xEA, 0xA3, 0x66, 0xC5, 0x5A, 0x08, 0x2D
>> +
>> +guidedStructureEnd:
>> +
>>   ALIGN   16
>>
>>   applicationProcessorEntryPoint:
>>
> 
> Thanks!
> Laszlo
> 

^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [PATCH v2 2/6] OvmfPkg/AmdSev: add Grub Firmware Volume Package
  2020-11-24 14:54         ` Laszlo Ersek
@ 2020-11-24 15:58           ` Laszlo Ersek
  2020-11-24 16:22             ` [edk2-devel] " James Bottomley
  0 siblings, 1 reply; 37+ messages in thread
From: Laszlo Ersek @ 2020-11-24 15:58 UTC (permalink / raw)
  To: jejb, devel
  Cc: dovmurik, Dov.Murik1, ashish.kalra, brijesh.singh, tobin,
	david.kaplan, jon.grimm, thomas.lendacky, frankeh,
	Dr . David Alan Gilbert

On 11/24/20 15:54, Laszlo Ersek wrote:
> On 11/24/20 09:23, Laszlo Ersek wrote:
>> On 11/24/20 07:38, James Bottomley wrote:
>>> On Mon, 2020-11-23 at 22:08 +0100, Laszlo Ersek wrote:
>>
>>>> In [a](5) I requested the removal of everything in this INF file that
>>>> was not required for the desired semantics (i.e., for unconditionally
>>>> booting the builtin GRUB binary).
>>>>
>>>> So again I'm unsure if you missed my feedback, or thought it was not
>>>> important. (I didn't get a request for clarification either.)
>>>>  
>>>> Keeping INF files minimal is relevant for future contributions. We
>>>> frequently need to determine the set of modules that depend on a
>>>> particular PCD. If some INF files list PCDs unjustifiedly, then the
>>>> affected module set may appear larger than it really is.
>>>>
>>>> This applies to all sections of the INF file, not just [Pcd].
>>>
>>> I did try stripping quite a lot, but then it wouldn't boot.  It seems
>>> that the PCI devices are needed for grub to find the encrypted volume,
>>> so I put most of it back again.  Is there some way of identifying
>>> superfluous pieces so I can detect if I put too much back?
>>
>> I suggest proceeding element by element in the INF file (and matching
>> that, in the header / C files) -- remove one element per patch. Then you
>> can either build+test it as you go, or create a series of micro-patches
>> up-front, and if it doesn't boot, bisect it. Finally, squash the
>> removals that are justifiable into this patch (for posting), and drop
>> the rest.
>>
>> It's unfortunately trial and error to some extent; however, given that
>> each step removes 1 element (PCD, Protocol, GUID, lib class, and finally
>> Package), and the number of elements summed over the INF file sections
>> is finite, this process is guaranteed to terminate.
> 
> Looking briefly over the file "OvmfPkg/Library/PlatformBootManagerLibGrub/PlatformBootManagerLibGrub.inf", I suggest removing:
> 
> - [Packages]: whatever proves unnecessary in the end,
> 
> - [LibraryClasses]: ditto,

Perhaps I can make that recommendation / request more detailed too:


* drop:

- UefiRuntimeServicesTableLib: no use of "gRT"

- ReportStatusCodeLib: commit 0a0566d5edad is not relevant, because we justifiedly removed TryRunningQemuKernel()

- XenPlatformLib: as discussed before; substitute FALSE for each XenDetected() call, and compress the resultant code


* keep:

- BaseLib: for CpuDeadLoop()

- MemoryAllocationLib: for FreePool()

- UefiBootServicesTableLib: for gBS->xxx()

- BaseMemoryLib: for CompareMem()

- DebugLib: for DEBUG() and ASSERT()

- PcdLib: for PcdGet16 (PcdOvmfHostBridgePciDevId)

- UefiBootManagerLib: for APIs central to the functionality of PlatformBootManagerLibGrub

- BootLogoLib: for BootLogoEnableLogo()

- DevicePathLib: for a bunch of device path manipulation

- PciLib: mainly for the functions called in PciAcpiInitialization()

- UefiLib: for EfiEventGroupSignal() etc

- PlatformBmPrintScLib: for PlatformBmPrintScRegisterHandler() -- this is responsible for printing the boot option processing steps to the UEFI console

- Tcg2PhysicalPresenceLib: for Tcg2PhysicalPresenceLibProcessRequest() -- we preserve TPM support


Then leaving the trimming of [Packages] to the end makes sense -- after trimming everything else, try to remove each package DEC in isolation, and see if the lib instance continues to build.

Thanks!
Laszlo



> 
> - [Pcd]: PcdOvmfFlashVariablesEnable, PcdPlatformBootTimeOut,
> 
> - [Pcd]: PcdUartDefaultBaudRate, PcdUartDefaultDataBits, PcdUartDefaultParity, PcdUartDefaultStopBits; together with "gXenConsoleDevicePath", "gXenPlatformConsole", XenDetected() / XenPlatformLib,
> 
> - [Pcd.IA32, Pcd.X64]: PcdFSBClock,
> 
> - [Protocols]: gEfiDecompressProtocolGuid, gEfiS3SaveStateProtocolGuid,
> 
> - [Guids]: gEfiGlobalVariableGuid,
> 
> Keep these:
> 
> - [Protocols]: gEfiPciRootBridgeIoProtocolGuid, gEfiDxeSmmReadyToLockProtocolGuid, gEfiLoadedImageProtocolGuid, gEfiFirmwareVolume2ProtocolGuid,
> 
> - [Guids]: gEfiEndOfDxeEventGroupGuid, gRootBridgesConnectedEventGroupGuid, gUefiShellFileGuid, gGrubFileGuid.
> 
> Thanks!
> Laszlo
> 


^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [edk2-devel] [PATCH v2 2/6] OvmfPkg/AmdSev: add Grub Firmware Volume Package
  2020-11-24 15:58           ` Laszlo Ersek
@ 2020-11-24 16:22             ` James Bottomley
  2020-11-24 23:22               ` Laszlo Ersek
  0 siblings, 1 reply; 37+ messages in thread
From: James Bottomley @ 2020-11-24 16:22 UTC (permalink / raw)
  To: devel, lersek
  Cc: dovmurik, Dov.Murik1, ashish.kalra, brijesh.singh, tobin,
	david.kaplan, jon.grimm, thomas.lendacky, frankeh,
	Dr . David Alan Gilbert

On Tue, 2020-11-24 at 16:58 +0100, Laszlo Ersek wrote:
> On 11/24/20 15:54, Laszlo Ersek wrote:
[...]
> Perhaps I can make that recommendation / request more detailed too:
> 
> 
> * drop:
> 
> - UefiRuntimeServicesTableLib: no use of "gRT"
> 
> - ReportStatusCodeLib: commit 0a0566d5edad is not relevant, because
> we justifiedly removed TryRunningQemuKernel()
> 
> - XenPlatformLib: as discussed before; substitute FALSE for each
> XenDetected() call, and compress the resultant code

All dropped.

> * keep:
> 
> - BaseLib: for CpuDeadLoop()
> 
> - MemoryAllocationLib: for FreePool()
> 
> - UefiBootServicesTableLib: for gBS->xxx()
> 
> - BaseMemoryLib: for CompareMem()
> 
> - DebugLib: for DEBUG() and ASSERT()
> 
> - PcdLib: for PcdGet16 (PcdOvmfHostBridgePciDevId)
> 
> - UefiBootManagerLib: for APIs central to the functionality of
> PlatformBootManagerLibGrub
> 
> - BootLogoLib: for BootLogoEnableLogo()
> 
> - DevicePathLib: for a bunch of device path manipulation
> 
> - PciLib: mainly for the functions called in PciAcpiInitialization()
> 
> - UefiLib: for EfiEventGroupSignal() etc
> 
> - PlatformBmPrintScLib: for PlatformBmPrintScRegisterHandler() --
> this is responsible for printing the boot option processing steps to
> the UEFI console
> 
> - Tcg2PhysicalPresenceLib: for
> Tcg2PhysicalItPresenceLibProcessRequest() -- we preserve TPM support
> 
> 
> Then leaving the trimming of [Packages] to the end makes sense --
> after trimming everything else, try to remove each package DEC in
> isolation, and see if the lib instance continues to build.

I can't seem to remove any packages.  Even the source debug agent one
is used by the uart devices.

It seems I can get rid of PcdFSBClock

and in the protocols section (with some header file removal)

gEfiDecompressProtocolGuid
gEfiS3SaveStateProtocolGuid

James



^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [PATCH v2 3/6] OvmfPkg: convert ES Reset Block structure to be guided
  2020-11-23 22:16   ` Laszlo Ersek
  2020-11-24 14:57     ` Lendacky, Thomas
@ 2020-11-24 19:05     ` James Bottomley
  2020-11-24 23:15       ` Laszlo Ersek
  1 sibling, 1 reply; 37+ messages in thread
From: James Bottomley @ 2020-11-24 19:05 UTC (permalink / raw)
  To: Laszlo Ersek, devel
  Cc: dovmurik, Dov.Murik1, ashish.kalra, brijesh.singh, tobin,
	david.kaplan, jon.grimm, thomas.lendacky, frankeh,
	Dr . David Alan Gilbert

On Mon, 2020-11-23 at 23:16 +0100, Laszlo Ersek wrote:
> On 11/20/20 19:45, James Bottomley wrote:
> > Convert the current ES reset block structure to an extensible guid
> > based structure by appending a header and length, which allow for
> > multiple guid based data packets to be inserted.
> > 
> > Ref: https://bugzilla.tianocore.org/show_bug.cgi?id=3077
> > Signed-off-by: James Bottomley <jejb@linux.ibm.com>
> > 
> > ---
> > 
> > v2: added
> > ---
> >  OvmfPkg/ResetVector/Ia16/ResetVectorVtf0.asm | 49 +++++++++++++++-
> > ----
> >  1 file changed, 38 insertions(+), 11 deletions(-)
> 
> (1) Please update the subject line to:
> 
> OvmfPkg/ResetVector: convert SEV-ES Reset Block structure to be
> GUIDed
> 
> - edk2 prefers including module names too in the patch subjects
> - "ES" is harder to understand than "SEV-ES"
> - "GUIDed" is harder to misread as "guided"
> - subject length is still OK (70 chars)

Done.

> > diff --git a/OvmfPkg/ResetVector/Ia16/ResetVectorVtf0.asm
> > b/OvmfPkg/ResetVector/Ia16/ResetVectorVtf0.asm
> > index 980e0138e7fe..baf9d09f3625 100644
> > --- a/OvmfPkg/ResetVector/Ia16/ResetVectorVtf0.asm
> > +++ b/OvmfPkg/ResetVector/Ia16/ResetVectorVtf0.asm
> > @@ -25,21 +25,40 @@ ALIGN   16
> >      TIMES (0x1000 - ($ - EndOfPageTables) - 0x20) DB 0
> >  %endif
> > 
> > +;
> > +; Padding to ensure first guid starts at 0xffffffd0
> > +;
> > +TIMES (32 - ((guidedStructureEnd - guidedStructureStart) % 32)) DB
> > 0
> 
> (2) This will insert 32 zero bytes if the size is already aligned to
> 32
> bytes (because 32-0 = 32). In other words, the above produces 1 to 32
> zero bytes, dependent on table size.
> 
> The variant I proposed in point (5) at
> 
>   https://edk2.groups.io/g/devel/message/67621
>   
> https://www.redhat.com/archives/edk2-devel-archive/2020-November/msg00781.html
> 
> takes this into account, and only prepends 0 to 31 bytes (inclusive):
> 
>   TIMES (31 - (guidedStructureEnd - guidedStructureStart + 31) % 32)
> DB 0
> 
> - This variant subtracts 1 inside the remainder operation (which is
>   expressed as adding 31).
> 
> - For compensation, it adds 1 just outside of the remainder
> operation.
>   This addition in effect increases the subtrahend for the leftmost
> 32.
>   Therefore this (-1) addend is ultimately folded into the leftmost
> 32,
>   yielding 31 on the leftmost side.
> 
>   TIMES (32 - ((guidedStructureEnd - guidedStructureStart - 1) % 32 +
> 1)) DB 0
>                                                           ^^^       ^
> ^^
>                                                           |         |
>                                                           |         c
> ompensate
>                                                           |         i
> n the
>                                                           |         r
> emainder
>                                                           |
>                                                           slide down
> residue
>                                                           class
> modulo 32
> 
> 
>  TIMES (32 - ((guidedStructureEnd - guidedStructureStart + 31) % 32)
> - 1) DB 0
>                                                          ^^^^        
> ^^^
>                                                          |           
> |
>                                                          |           
> unnest
>                                                          |           
> increment
>                                                          |           
> from
>                                                          |           
> subtrahend
>                                                          |
>                                                          express
> modular
>                                                          subtraction
> as
>                                                          addition, to
> avoid
>                                                          using % on a
> negative
>                                                          integer (in
> case size
>                                                          were 0)
> 
>  TIMES (31 - ((guidedStructureEnd - guidedStructureStart + 31) % 32))
> DB 0
>         ^^
>         |
>         fold previous (-1) addend into leftmost constant
> 
> - This juggling of 1 results in no changes for residue classes 1
> through
>   31, but wraps the outermost result (the padding size) for residue
>   class 0, from 32 to 0.

I get the mathematics, but I'm a bit hazy on the why.  I structured my
patch on the basis that some zero padding seems necessary (which does
mean you have to add extra zeros when the structure fits exactly into
32 bytes).  If we don't need any zero pad at all then I agree with what
you say above, we should use the shortest feasible pad.

My other question is why 32 above?  If the object is simply to push the
table guid to 0xffffffd0 in the OVMF.fd then 

TIMES (15 - ((guidedStructureEnd - guidedStructureStart + 15) % 16)) DB 0

or

TIMES 16 - ((guidedStructureEnd - guidedStructureStart) % 16)) DB 0

Depending on whether we need zeros or not, always works because the
code is align 16 not align 32.

> > +
> > +; Guided structure.  To traverse this you should first verify the
> > +; presence of the table header guid
> 
> (3) suggest "table footer GUID" (the GUID follows the data, in
> address order)

Yes, I think header because it's what I come to first traversing
backwards but perhaps footer is better because most people don't think
backwards.

> > +; (96b582de-1fb2-45f7-baea-a366c55a082d) at 0xffffffd0.  If that
> > +; is found, the two bytes at 0xffffffce are the entire table
> > length.
> 
> (4) can we make the whole table size field 32-bit? I don't have a
> particular use case in mind, it just looks more extensible than 16-
> bit. We can still keep the individual structs we have in mind 16-bit
> sized.

Actually, no ... or at least not unless we alter the reset vector.  The
problem is the reset vector is actually:

    nop
    nop
    jmp     EarlyBspInitReal16

But that jmp is 16-bit code, meaning the relative jump which goes over
the table is at most -32768, so the table can never be larger than
about 32k bytes.

That's not to say we can't have a larger table ... we definitely can,
but it can't be where it is now.  we'd have to do something different
like make the table guid describe where the actual table is located (as
a 32 bit offset and length) so as not to break up the 16 bit jump code.

> > +;
> > +; The table is composed of structures with the form:
> > +;
> > +; Data (arbitrary bytes identified by guid)
> > +; length from start of guid to end of data (2 bytes)
> 
> (5) This is hard to interpret, as "data" precedes "guid" in address
> space (guid is a footer, not a header).
> 
> I suggest "length from start of data to end of GUID"

done.

> > +; guid (16 bytes)
> > +;
> > +; so work back from the header using the length to traverse until
> > you
> 
> (6) suggest "from the footer"
> 
> 
> > +; either find the guid you're looking for or run off the end of
> > the
> > +; table.
> 
> (7) suggest "run off the beginning of the table"
> 
> ... I realize "start" and "end" can be interpreted temporally and
> spatially. In a forward traversal they are the same, but now they
> aren't. I suggest we use the spatial (address space order)
> interpretation.

Well we have to be consistent, so if you're thinking backwards it's
header and end, but the other way around it has to be footer and
beginning, so I updated it.

> > +;
> > +guidedStructureStart:
> > +
> >  ;
> >  ; SEV-ES Processor Reset support
> >  ;
> >  ; sevEsResetBlock:
> >  ;   For the initial boot of an AP under SEV-ES, the "reset" RIP
> > must be
> > -;   programmed to the RAM area defined by SEV_ES_AP_RESET_IP. A
> > known offset
> > -;   and GUID will be used to locate this block in the firmware and
> > extract
> > -;   the build time RIP value. The GUID must always be 48 bytes
> > from the
> > -;   end of the firmware.
> > +;   programmed to the RAM area defined by SEV_ES_AP_RESET_IP. The
> > data
> > +;   format is
> >  ;
> > -;   0xffffffca (-0x36) - IP value
> > -;   0xffffffcc (-0x34) - CS segment base [31:16]
> > -;   0xffffffce (-0x32) - Size of the SEV-ES reset block
> > -;   0xffffffd0 (-0x30) - SEV-ES reset block GUID
> > -;                        (00f771de-1a7e-4fcb-890e-68c77e2fb44e)
> > +;   IP value [0:15]
> > +;   CS segment base [31:16]
> > +;
> > +;   SEV-ES reset block GUID: 00f771de-1a7e-4fcb-890e-68c77e2fb44e
> 
> (8) Did I understand from the v1 discussion that the corresponding
> QEMU parser is not upstream yet? (Or at least not released?)

Yes, current QEMU upstream has no support yet for searching for this
table although I think patches have been sent.

> (9) The 16-bit size field of the SEV-ES reset block structure is not
> documented.

Well, it is ... it's become part of the table structure, so it's
documented at the top of the table as:

; The table is composed of structures with the form:
;
; Data (arbitrary bytes identified by guid)
; length from start of data to end of guid (2 bytes)
; guid (16 bytes)

All the comment is doing is describing the layout of the data.

I can add a length here if you like, but I'd probably better add one to
the secret table as well to be consistent.

> >  ;
> >  ;   A hypervisor reads the CS segement base and IP value. The CS
> > segment base
> >  ;   value represents the high order 16-bits of the CS segment
> > base, so the
> > @@ -48,8 +67,6 @@ ALIGN   16
> >  ;   program the EIP register with the IP value as read.
> >  ;
> > 
> > -TIMES (32 - (sevEsResetBlockEnd - sevEsResetBlockStart)) DB 0
> > -
> >  sevEsResetBlockStart:
> >      DD      SEV_ES_AP_RESET_IP
> >      DW      sevEsResetBlockEnd - sevEsResetBlockStart
> > @@ -57,6 +74,16 @@ sevEsResetBlockStart:
> >      DB      0x89, 0x0E, 0x68, 0xC7, 0x7E, 0x2F, 0xB4, 0x4E
> >  sevEsResetBlockEnd:
> > 
> > +;
> > +; Table header: length of whole table followed by table header
> 
> (10) I suggest "table footer" (twice)

done.

Regards,

James

> > +; guid: 96b582de-1fb2-45f7-baea-a366c55a082d
> > +;
> > +    DW      guidedStructureEnd - guidedStructureStart
> > +    DB      0xDE, 0x82, 0xB5, 0x96, 0xB2, 0x1F, 0xF7, 0x45
> > +    DB      0xBA, 0xEA, 0xA3, 0x66, 0xC5, 0x5A, 0x08, 0x2D
> > +
> > +guidedStructureEnd:
> > +
> >  ALIGN   16
> > 
> >  applicationProcessorEntryPoint:
> > 
> 
> Thanks!
> Laszlo
> 



^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [PATCH v2 3/6] OvmfPkg: convert ES Reset Block structure to be guided
  2020-11-24 14:57     ` Lendacky, Thomas
@ 2020-11-24 19:07       ` James Bottomley
  2020-11-24 23:19         ` Laszlo Ersek
  0 siblings, 1 reply; 37+ messages in thread
From: James Bottomley @ 2020-11-24 19:07 UTC (permalink / raw)
  To: Tom Lendacky, Laszlo Ersek, devel
  Cc: dovmurik, Dov.Murik1, ashish.kalra, brijesh.singh, tobin,
	david.kaplan, jon.grimm, frankeh, Dr . David Alan Gilbert

On Tue, 2020-11-24 at 08:57 -0600, Tom Lendacky wrote:
> On 11/23/20 4:16 PM, Laszlo Ersek wrote:
> > On 11/20/20 19:45, James Bottomley wrote:
> > > Convert the current ES reset block structure to an extensible
> > > guid based structure by appending a header and length, which
> > > allow for multiple guid based data packets to be inserted.
> 
> I was wondering if this patch should be submitted outside of this
> series? I'm not sure it makes any difference, other than being able
> to be merged (possibly) quicker and independent of the series. Then
> this series simply takes advantage of it.

How about if I shuffle it to the beginning of the series?  That way it
can be taken on its own or with the rest.

James



^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [PATCH v2 3/6] OvmfPkg: convert ES Reset Block structure to be guided
  2020-11-24 19:05     ` James Bottomley
@ 2020-11-24 23:15       ` Laszlo Ersek
  0 siblings, 0 replies; 37+ messages in thread
From: Laszlo Ersek @ 2020-11-24 23:15 UTC (permalink / raw)
  To: jejb, devel
  Cc: dovmurik, Dov.Murik1, ashish.kalra, brijesh.singh, tobin,
	david.kaplan, jon.grimm, thomas.lendacky, frankeh,
	Dr . David Alan Gilbert

On 11/24/20 20:05, James Bottomley wrote:
> On Mon, 2020-11-23 at 23:16 +0100, Laszlo Ersek wrote:
>> On 11/20/20 19:45, James Bottomley wrote:

>>> diff --git a/OvmfPkg/ResetVector/Ia16/ResetVectorVtf0.asm
>>> b/OvmfPkg/ResetVector/Ia16/ResetVectorVtf0.asm
>>> index 980e0138e7fe..baf9d09f3625 100644
>>> --- a/OvmfPkg/ResetVector/Ia16/ResetVectorVtf0.asm
>>> +++ b/OvmfPkg/ResetVector/Ia16/ResetVectorVtf0.asm
>>> @@ -25,21 +25,40 @@ ALIGN   16
>>>      TIMES (0x1000 - ($ - EndOfPageTables) - 0x20) DB 0
>>>  %endif
>>>
>>> +;
>>> +; Padding to ensure first guid starts at 0xffffffd0
>>> +;
>>> +TIMES (32 - ((guidedStructureEnd - guidedStructureStart) % 32)) DB
>>> 0
>>
>> (2) This will insert 32 zero bytes if the size is already aligned to
>> 32
>> bytes (because 32-0 = 32). In other words, the above produces 1 to 32
>> zero bytes, dependent on table size.
>>
>> The variant I proposed in point (5) at
>>
>>   https://edk2.groups.io/g/devel/message/67621
>>   
>> https://www.redhat.com/archives/edk2-devel-archive/2020-November/msg00781.html
>>
>> takes this into account, and only prepends 0 to 31 bytes (inclusive):
>>
>>   TIMES (31 - (guidedStructureEnd - guidedStructureStart + 31) % 32)
>> DB 0

[...]

> I get the mathematics, but I'm a bit hazy on the why.  I structured my
> patch on the basis that some zero padding seems necessary (which does
> mean you have to add extra zeros when the structure fits exactly into
> 32 bytes).  If we don't need any zero pad at all then I agree with what
> you say above, we should use the shortest feasible pad.

The outermost table footer reports the cumulative size, so a
zero-terminator at the front is not needed.


> My other question is why 32 above?  If the object is simply to push the
> table guid to 0xffffffd0 in the OVMF.fd then 
> 
> TIMES (15 - ((guidedStructureEnd - guidedStructureStart + 15) % 16)) DB 0
> 
> or
> 
> TIMES 16 - ((guidedStructureEnd - guidedStructureStart) % 16)) DB 0
> 
> Depending on whether we need zeros or not, always works because the
> code is align 16 not align 32.

Right, I think you are correct.


>> (4) can we make the whole table size field 32-bit? I don't have a
>> particular use case in mind, it just looks more extensible than 16-
>> bit. We can still keep the individual structs we have in mind 16-bit
>> sized.
> 
> Actually, no ... or at least not unless we alter the reset vector.  The
> problem is the reset vector is actually:
> 
>     nop
>     nop
>     jmp     EarlyBspInitReal16
> 
> But that jmp is 16-bit code, meaning the relative jump which goes over
> the table is at most -32768, so the table can never be larger than
> about 32k bytes.

Great catch! :)


>> (7) suggest "run off the beginning of the table"
>>
>> ... I realize "start" and "end" can be interpreted temporally and
>> spatially. In a forward traversal they are the same, but now they
>> aren't. I suggest we use the spatial (address space order)
>> interpretation.
> 
> Well we have to be consistent, so if you're thinking backwards it's
> header and end, but the other way around it has to be footer and
> beginning, so I updated it.

OK, thanks. I guess I should be OK with either interpretation, as long
as we'll have considered it from a consistency perspective.

>> (9) The 16-bit size field of the SEV-ES reset block structure is not
>> documented.
> 
> Well, it is ... it's become part of the table structure, so it's
> documented at the top of the table as:
> 
> ; The table is composed of structures with the form:
> ;
> ; Data (arbitrary bytes identified by guid)
> ; length from start of data to end of guid (2 bytes)
> ; guid (16 bytes)
> 
> All the comment is doing is describing the layout of the data.
> 
> I can add a length here if you like, but I'd probably better add one to
> the secret table as well to be consistent.

Ahh wait, no, now I understand it.

When I wrote my previous comment, I didn't understand why you listed all
of the fields explicitly, *except* the size. In particular, why you
listed the GUID (*unlike* the size), in spite of the GUID *too* being
pre-declared (*like* the size).

But now I understand -- you didn't re-declare the GUID *field* for this
particular GUIDed structure, you only provided the *value* of the GUID
field.

Perhaps juggling the words could improve understanding:

GUID ("SEV-ES reset block"): 00f771de-1a7e-4fcb-890e-68c77e2fb44e

But, it's up to you. I agree the listing is consistent the way you proposed.

Thanks!
Laszlo


^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [PATCH v2 3/6] OvmfPkg: convert ES Reset Block structure to be guided
  2020-11-24 19:07       ` James Bottomley
@ 2020-11-24 23:19         ` Laszlo Ersek
  0 siblings, 0 replies; 37+ messages in thread
From: Laszlo Ersek @ 2020-11-24 23:19 UTC (permalink / raw)
  To: jejb, Tom Lendacky, devel
  Cc: dovmurik, Dov.Murik1, ashish.kalra, brijesh.singh, tobin,
	david.kaplan, jon.grimm, frankeh, Dr . David Alan Gilbert

On 11/24/20 20:07, James Bottomley wrote:
> On Tue, 2020-11-24 at 08:57 -0600, Tom Lendacky wrote:
>> On 11/23/20 4:16 PM, Laszlo Ersek wrote:
>>> On 11/20/20 19:45, James Bottomley wrote:
>>>> Convert the current ES reset block structure to an extensible
>>>> guid based structure by appending a header and length, which
>>>> allow for multiple guid based data packets to be inserted.
>>
>> I was wondering if this patch should be submitted outside of this
>> series? I'm not sure it makes any difference, other than being able
>> to be merged (possibly) quicker and independent of the series. Then
>> this series simply takes advantage of it.
> 
> How about if I shuffle it to the beginning of the series?  That way it
> can be taken on its own or with the rest.

I wouldn't mind either approach in general; however, we're in hard
feature freeze now for edk2-stable202011 anyway, and I can't merge
anything resembling a new feature until after 2020-Nov-27.

https://github.com/tianocore/tianocore.github.io/wiki/EDK-II-Release-Planning

... Moving the patch to the front could still improve the structure /
build-up of the series, however. So yes, I guess please move it to the
front.

Cheers!
Laszlo


^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [edk2-devel] [PATCH v2 2/6] OvmfPkg/AmdSev: add Grub Firmware Volume Package
  2020-11-24 16:22             ` [edk2-devel] " James Bottomley
@ 2020-11-24 23:22               ` Laszlo Ersek
  2020-11-24 23:42                 ` James Bottomley
  0 siblings, 1 reply; 37+ messages in thread
From: Laszlo Ersek @ 2020-11-24 23:22 UTC (permalink / raw)
  To: jejb, devel
  Cc: dovmurik, Dov.Murik1, ashish.kalra, brijesh.singh, tobin,
	david.kaplan, jon.grimm, thomas.lendacky, frankeh,
	Dr . David Alan Gilbert

On 11/24/20 17:22, James Bottomley wrote:
> On Tue, 2020-11-24 at 16:58 +0100, Laszlo Ersek wrote:
>> On 11/24/20 15:54, Laszlo Ersek wrote:
> [...]
>> Perhaps I can make that recommendation / request more detailed too:
>>
>>
>> * drop:
>>
>> - UefiRuntimeServicesTableLib: no use of "gRT"
>>
>> - ReportStatusCodeLib: commit 0a0566d5edad is not relevant, because
>> we justifiedly removed TryRunningQemuKernel()
>>
>> - XenPlatformLib: as discussed before; substitute FALSE for each
>> XenDetected() call, and compress the resultant code
> 
> All dropped.
> 
>> * keep:
>>
>> - BaseLib: for CpuDeadLoop()
>>
>> - MemoryAllocationLib: for FreePool()
>>
>> - UefiBootServicesTableLib: for gBS->xxx()
>>
>> - BaseMemoryLib: for CompareMem()
>>
>> - DebugLib: for DEBUG() and ASSERT()
>>
>> - PcdLib: for PcdGet16 (PcdOvmfHostBridgePciDevId)
>>
>> - UefiBootManagerLib: for APIs central to the functionality of
>> PlatformBootManagerLibGrub
>>
>> - BootLogoLib: for BootLogoEnableLogo()
>>
>> - DevicePathLib: for a bunch of device path manipulation
>>
>> - PciLib: mainly for the functions called in PciAcpiInitialization()
>>
>> - UefiLib: for EfiEventGroupSignal() etc
>>
>> - PlatformBmPrintScLib: for PlatformBmPrintScRegisterHandler() --
>> this is responsible for printing the boot option processing steps to
>> the UEFI console
>>
>> - Tcg2PhysicalPresenceLib: for
>> Tcg2PhysicalItPresenceLibProcessRequest() -- we preserve TPM support
>>
>>
>> Then leaving the trimming of [Packages] to the end makes sense --
>> after trimming everything else, try to remove each package DEC in
>> isolation, and see if the lib instance continues to build.
> 
> I can't seem to remove any packages.  Even the source debug agent one
> is used by the uart devices.

OK! Thanks for checking.

> 
> It seems I can get rid of PcdFSBClock
> 
> and in the protocols section (with some header file removal)
> 
> gEfiDecompressProtocolGuid
> gEfiS3SaveStateProtocolGuid

Yes, I agree removing these is correct; they were also included in my
other email at <https://edk2.groups.io/g/devel/message/67892>.

There are some others that should be possible to remove (pls. refer to
the rest of that email).

Thanks!
Laszlo


^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [edk2-devel] [PATCH v2 2/6] OvmfPkg/AmdSev: add Grub Firmware Volume Package
  2020-11-24 23:22               ` Laszlo Ersek
@ 2020-11-24 23:42                 ` James Bottomley
  2020-11-25  1:27                   ` James Bottomley
  0 siblings, 1 reply; 37+ messages in thread
From: James Bottomley @ 2020-11-24 23:42 UTC (permalink / raw)
  To: Laszlo Ersek, devel
  Cc: dovmurik, Dov.Murik1, ashish.kalra, brijesh.singh, tobin,
	david.kaplan, jon.grimm, thomas.lendacky, frankeh,
	Dr . David Alan Gilbert

On Wed, 2020-11-25 at 00:22 +0100, Laszlo Ersek wrote:
> On 11/24/20 17:22, James Bottomley wrote:
> > On Tue, 2020-11-24 at 16:58 +0100, Laszlo Ersek wrote:
> > > On 11/24/20 15:54, Laszlo Ersek wrote:
> > [...]
> > > Perhaps I can make that recommendation / request more detailed
> > > too:
> > > 
> > > 
> > > * drop:
> > > 
> > > - UefiRuntimeServicesTableLib: no use of "gRT"
> > > 
> > > - ReportStatusCodeLib: commit 0a0566d5edad is not relevant,
> > > because
> > > we justifiedly removed TryRunningQemuKernel()
> > > 
> > > - XenPlatformLib: as discussed before; substitute FALSE for each
> > > XenDetected() call, and compress the resultant code
> > 
> > All dropped.
> > 
> > > * keep:
> > > 
> > > - BaseLib: for CpuDeadLoop()
> > > 
> > > - MemoryAllocationLib: for FreePool()
> > > 
> > > - UefiBootServicesTableLib: for gBS->xxx()
> > > 
> > > - BaseMemoryLib: for CompareMem()
> > > 
> > > - DebugLib: for DEBUG() and ASSERT()
> > > 
> > > - PcdLib: for PcdGet16 (PcdOvmfHostBridgePciDevId)
> > > 
> > > - UefiBootManagerLib: for APIs central to the functionality of
> > > PlatformBootManagerLibGrub
> > > 
> > > - BootLogoLib: for BootLogoEnableLogo()
> > > 
> > > - DevicePathLib: for a bunch of device path manipulation
> > > 
> > > - PciLib: mainly for the functions called in
> > > PciAcpiInitialization()
> > > 
> > > - UefiLib: for EfiEventGroupSignal() etc
> > > 
> > > - PlatformBmPrintScLib: for PlatformBmPrintScRegisterHandler() --
> > > this is responsible for printing the boot option processing steps
> > > to
> > > the UEFI console
> > > 
> > > - Tcg2PhysicalPresenceLib: for
> > > Tcg2PhysicalItPresenceLibProcessRequest() -- we preserve TPM
> > > support
> > > 
> > > 
> > > Then leaving the trimming of [Packages] to the end makes sense --
> > > after trimming everything else, try to remove each package DEC in
> > > isolation, and see if the lib instance continues to build.
> > 
> > I can't seem to remove any packages.  Even the source debug agent
> > one
> > is used by the uart devices.
> 
> OK! Thanks for checking.
> 
> > It seems I can get rid of PcdFSBClock
> > 
> > and in the protocols section (with some header file removal)
> > 
> > gEfiDecompressProtocolGuid
> > gEfiS3SaveStateProtocolGuid
> 
> Yes, I agree removing these is correct; they were also included in my
> other email at <https://edk2.groups.io/g/devel/message/67892>;.
> 
> There are some others that should be possible to remove (pls. refer
> to the rest of that email).

Heh, well, I spoke too soon.  Even though the OVMF this produces boots
to grub and decrypts an encrypted volume, the kernel boot panics
because of something missing in the runtime ... it looks like it's
tripping over gRT->SetVariable, so I'm going to have to start putting
some stuff back again ...

James



^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [edk2-devel] [PATCH v2 2/6] OvmfPkg/AmdSev: add Grub Firmware Volume Package
  2020-11-24 23:42                 ` James Bottomley
@ 2020-11-25  1:27                   ` James Bottomley
  2020-11-25 14:01                     ` Laszlo Ersek
  0 siblings, 1 reply; 37+ messages in thread
From: James Bottomley @ 2020-11-25  1:27 UTC (permalink / raw)
  To: devel, Laszlo Ersek, Bret Barkelew
  Cc: dovmurik, Dov.Murik1, ashish.kalra, brijesh.singh, tobin,
	david.kaplan, jon.grimm, thomas.lendacky, frankeh,
	Dr . David Alan Gilbert

On Tue, 2020-11-24 at 15:42 -0800, James Bottomley wrote:
> On Wed, 2020-11-25 at 00:22 +0100, Laszlo Ersek wrote:
[...]
> > There are some others that should be possible to remove (pls. refer
> > to the rest of that email).
> 
> Heh, well, I spoke too soon.  Even though the OVMF this produces
> boots to grub and decrypts an encrypted volume, the kernel boot
> panics because of something missing in the runtime ... it looks like
> it's tripping over gRT->SetVariable, so I'm going to have to start
> putting some stuff back again ...

Actually, this isn't me.  I can't get the vanilla OVMF package to boot
either.  It looks to be a problem with the variable policy stuff since
the last known good boot was before they were added.

I've attached the boot log with vanilla OVMF.  There's rather a lot of
policy commits to try reverting.  What's the best way to debug this?

James

---

Loading Linux 5.5.0-2-amd64 ...
Loading initial ramdisk ...
[    0.000000] Linux version 5.5.0-2-amd64 (debian-kernel@lists.debian.org) (gcc version 9.3.0 (Debian 9.3.0-10)) #1 SMP Debian 5.5.17-1 (2020-04-15)
[    0.000000] Command line: BOOT_IMAGE=/boot/vmlinuz-5.5.0-2-amd64 root=UUID=8ebba08b-ff72-4030-ba43-8ce252e2e5a4 ro console=ttyS0,115200n8
[    0.000000] x86/fpu: x87 FPU will use FXSAVE
[    0.000000] BIOS-provided physical RAM map:
[    0.000000] BIOS-e820: [mem 0x0000000000000000-0x000000000009ffff] usable
[    0.000000] BIOS-e820: [mem 0x0000000000100000-0x00000000007fffff] usable
[    0.000000] BIOS-e820: [mem 0x0000000000800000-0x0000000000807fff] ACPI NVS
[    0.000000] BIOS-e820: [mem 0x0000000000808000-0x000000000080ffff] usable
[    0.000000] BIOS-e820: [mem 0x0000000000810000-0x00000000008fffff] ACPI NVS
[    0.000000] BIOS-e820: [mem 0x0000000000900000-0x000000007f8eefff] usable
[    0.000000] BIOS-e820: [mem 0x000000007f8ef000-0x000000007f9eefff] reserved
[    0.000000] BIOS-e820: [mem 0x000000007f9ef000-0x000000007faeefff] type 20
[    0.000000] BIOS-e820: [mem 0x000000007faef000-0x000000007fb6efff] reserved
[    0.000000] BIOS-e820: [mem 0x000000007fb6f000-0x000000007fb7efff] ACPI data
[    0.000000] BIOS-e820: [mem 0x000000007fb7f000-0x000000007fbfefff] ACPI NVS
[    0.000000] BIOS-e820: [mem 0x000000007fbff000-0x000000007fef3fff] usable
[    0.000000] BIOS-e820: [mem 0x000000007fef4000-0x000000007ff77fff] reserved
[    0.000000] BIOS-e820: [mem 0x000000007ff78000-0x000000007fffffff] ACPI NVS
[    0.000000] BIOS-e820: [mem 0x00000000ffc00000-0x00000000ffffffff] reserved
[    0.000000] NX (Execute Disable) protection: active
[    0.000000] efi: EFI v2.70 by EDK II
[    0.000000] efi:  SMBIOS=0x7f942000  ACPI=0x7fb7e000  ACPI 2.0=0x7fb7e014  MEMATTR=0x7ebe9018 
[    0.000000] secureboot: Secure boot could not be determined (mode 0)
[    0.000000] SMBIOS 2.8 present.
[    0.000000] DMI: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 0.0.0 02/06/2015
[    0.000000] Hypervisor detected: KVM
[    0.000000] kvm-clock: Using msrs 4b564d01 and 4b564d00
[    0.000000] kvm-clock: cpu 0, msr 28031001, primary cpu clock
[    0.000000] kvm-clock: using sched offset of 16414477727 cycles
[    0.000006] clocksource: kvm-clock: mask: 0xffffffffffffffff max_cycles: 0x1cd42e4dffb, max_idle_ns: 881590591483 ns
[    0.000018] tsc: Detected 2400.000 MHz processor
[    0.000169] last_pfn = 0x7fef4 max_arch_pfn = 0x400000000
[    0.000220] x86/PAT: PAT not supported by CPU.
[    0.000227] x86/PAT: Configuration [0-7]: WB  WT  UC- UC  WB  WT  UC- UC  
[    0.015576] RAMDISK: [mem 0x34a09000-0x364fbfff]
[    0.015601] ACPI: Early table checksum verification disabled
[    0.015622] ACPI: RSDP 0x000000007FB7E014 000024 (v02 BOCHS )
[    0.015627] ACPI: XSDT 0x000000007FB7D0E8 000044 (v01 BOCHS  BXPCFACP 00000001      01000013)
[    0.015639] ACPI: FACP 0x000000007FB7A000 000074 (v01 BOCHS  BXPCFACP 00000001 BXPC 00000001)
[    0.015645] ACPI: DSDT 0x000000007FB7B000 00140B (v01 BOCHS  BXPCDSDT 00000001 BXPC 00000001)
[    0.015656] ACPI: FACS 0x000000007FBDD000 000040
[    0.015659] ACPI: APIC 0x000000007FB79000 000078 (v01 BOCHS  BXPCAPIC 00000001 BXPC 00000001)
[    0.015663] ACPI: HPET 0x000000007FB78000 000038 (v01 BOCHS  BXPCHPET 00000001 BXPC 00000001)
[    0.015669] ACPI: BGRT 0x000000007FB77000 000038 (v01 INTEL  EDK2     00000002      01000013)
[    0.016057] No NUMA configuration found
[    0.016058] Faking a node at [mem 0x0000000000000000-0x000000007fef3fff]
[    0.016066] NODE_DATA(0) allocated [mem 0x7fe7f000-0x7fe83fff]
[    0.016095] Zone ranges:
[    0.016100]   DMA      [mem 0x0000000000001000-0x0000000000ffffff]
[    0.016101]   DMA32    [mem 0x0000000001000000-0x000000007fef3fff]
[    0.016102]   Normal   empty
[    0.016103]   Device   empty
[    0.016104] Movable zone start for each node
[    0.016105] Early memory node ranges
[    0.016106]   node   0: [mem 0x0000000000001000-0x000000000009ffff]
[    0.016107]   node   0: [mem 0x0000000000100000-0x00000000007fffff]
[    0.016108]   node   0: [mem 0x0000000000808000-0x000000000080ffff]
[    0.016109]   node   0: [mem 0x0000000000900000-0x000000007f8eefff]
[    0.016110]   node   0: [mem 0x000000007fbff000-0x000000007fef3fff]
[    0.016459] Zeroed struct page in unavailable ranges: 1397 pages
[    0.016461] Initmem setup node 0 [mem 0x0000000000001000-0x000000007fef3fff]
[    0.019894] ACPI: PM-Timer IO Port: 0xb008
[    0.019926] ACPI: LAPIC_NMI (acpi_id[0xff] dfl dfl lint[0x1])
[    0.019972] IOAPIC[0]: apic_id 0, version 17, address 0xfec00000, GSI 0-23
[    0.019975] ACPI: INT_SRC_OVR (bus 0 bus_irq 0 global_irq 2 dfl dfl)
[    0.019981] ACPI: INT_SRC_OVR (bus 0 bus_irq 5 global_irq 5 high level)
[    0.019982] ACPI: INT_SRC_OVR (bus 0 bus_irq 9 global_irq 9 high level)
[    0.019987] ACPI: INT_SRC_OVR (bus 0 bus_irq 10 global_irq 10 high level)
[    0.019988] ACPI: INT_SRC_OVR (bus 0 bus_irq 11 global_irq 11 high level)
[    0.019993] Using ACPI (MADT) for SMP configuration information
[    0.019995] ACPI: HPET id: 0x8086a201 base: 0xfed00000
[    0.020024] smpboot: Allowing 1 CPUs, 0 hotplug CPUs
[    0.020051] PM: Registered nosave memory: [mem 0x00000000-0x00000fff]
[    0.020052] PM: Registered nosave memory: [mem 0x000a0000-0x000fffff]
[    0.020054] PM: Registered nosave memory: [mem 0x00800000-0x00807fff]
[    0.020055] PM: Registered nosave memory: [mem 0x00810000-0x008fffff]
[    0.020056] PM: Registered nosave memory: [mem 0x7e7e7000-0x7e7effff]
[    0.020057] PM: Registered nosave memory: [mem 0x7f8ef000-0x7f9eefff]
[    0.020058] PM: Registered nosave memory: [mem 0x7f9ef000-0x7faeefff]
[    0.020059] PM: Registered nosave memory: [mem 0x7faef000-0x7fb6efff]
[    0.020059] PM: Registered nosave memory: [mem 0x7fb6f000-0x7fb7efff]
[    0.020060] PM: Registered nosave memory: [mem 0x7fb7f000-0x7fbfefff]
[    0.020063] [mem 0x80000000-0xffbfffff] available for PCI devices
[    0.020064] Booting paravirtualized kernel on KVM
[    0.020069] clocksource: refined-jiffies: mask: 0xffffffff max_cycles: 0xffffffff, max_idle_ns: 7645519600211568 ns
[    0.108622] setup_percpu: NR_CPUS:512 nr_cpumask_bits:512 nr_cpu_ids:1 nr_node_ids:1
[    0.109877] percpu: Embedded 55 pages/cpu s187800 r8192 d29288 u2097152
[    0.109918] KVM setup async PF for cpu 0
[    0.109923] kvm-stealtime: cpu 0, msr 7c419500
[    0.109931] Built 1 zonelists, mobility grouping on.  Total pages: 512892
[    0.109932] Policy zone: DMA32
[    0.109934] Kernel command line: BOOT_IMAGE=/boot/vmlinuz-5.5.0-2-amd64 root=UUID=8ebba08b-ff72-4030-ba43-8ce252e2e5a4 ro console=ttyS0,115200n8
[    0.111356] Dentry cache hash table entries: 262144 (order: 9, 2097152 bytes, linear)
[    0.111796] Inode-cache hash table entries: 131072 (order: 8, 1048576 bytes, linear)
[    0.111837] mem auto-init: stack:off, heap alloc:off, heap free:off
[    0.114998] Memory: 248380K/2091564K available (10243K kernel code, 1221K rwdata, 3972K rodata, 1672K init, 1980K bss, 120832K reserved, 0K cma-reserved)
[    0.115028] random: get_random_u64 called from __kmem_cache_create+0x3e/0x530 with crng_init=0
[    0.115547] SLUB: HWalign=64, Order=0-3, MinObjects=0, CPUs=1, Nodes=1
[    0.115575] Kernel/User page tables isolation: enabled
[    0.115617] ftrace: allocating 34294 entries in 134 pages
[    0.130489] ftrace: allocated 134 pages with 3 groups
[    0.130821] rcu: Hierarchical RCU implementation.
[    0.130823] rcu: 	RCU restricting CPUs from NR_CPUS=512 to nr_cpu_ids=1.
[    0.130826] rcu: RCU calculated value of scheduler-enlistment delay is 25 jiffies.
[    0.130827] rcu: Adjusting geometry for rcu_fanout_leaf=16, nr_cpu_ids=1
[    0.133774] NR_IRQS: 33024, nr_irqs: 256, preallocated irqs: 16
[    0.134031] Console: colour dummy device 80x25
[    0.242024] printk: console [ttyS0] enabled
[    0.242695] ACPI: Core revision 20191018
[    0.243470] clocksource: hpet: mask: 0xffffffff max_cycles: 0xffffffff, max_idle_ns: 19112604467 ns
[    0.244954] APIC: Switch to symmetric I/O mode setup
[    0.246031] x2apic enabled
[    0.246800] Switched APIC routing to physical x2apic.
[    0.248946] ..TIMER: vector=0x30 apic1=0 pin1=2 apic2=-1 pin2=-1
[    0.249892] clocksource: tsc-early: mask: 0xffffffffffffffff max_cycles: 0x22983777dd9, max_idle_ns: 440795300422 ns
[    0.251455] Calibrating delay loop (skipped) preset value.. 4800.00 BogoMIPS (lpj=9600000)
[    0.252873] pid_max: default: 32768 minimum: 301
[    0.256847] BUG: unable to handle page fault for address: 000000007ed03020
[    0.258328] #PF: supervisor read access in kernel mode
[    0.259304] #PF: error_code(0x0000) - not-present page
[    0.259452] PGD fd2d063 P4D fd2d063 PUD fd30063 PMD fd3f063 PTE fffff812fc060
[    0.259452] Oops: 0000 [#1] SMP PTI
[    0.259452] CPU: 0 PID: 0 Comm: swapper/0 Not tainted 5.5.0-2-amd64 #1 Debian 5.5.17-1
[    0.259452] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 0.0.0 02/06/2015
[    0.259452] RIP: 0010:0xfffffffeff6c6648
[    0.259452] Code: 48 83 ec 20 e8 41 fd ff ff 48 85 c9 75 1c 84 c0 74 18 4c 8d 05 15 a1 00 00 48 8d 0d ec 93 00 00 ba ba 00 00 00 e8 c0 fe ff ff <48> 8b 03 48 83 c4 20 5b c3 55 57 56 53 48 89 d3 48 89 ce 48 83 ec
[    0.259452] RSP: 0000:ffffffffabc03b10 EFLAGS: 00010202
[    0.259452] RAX: 0000000000000001 RBX: 000000007ed03020 RCX: 000000007ed03020
[    0.259452] RDX: ffffffffabc03eb0 RSI: 000000007ed03020 RDI: ffffffffab809670
[    0.259452] RBP: 0000000000000000 R08: 0000000000000007 R09: 0000000000000000
[    0.259452] R10: 0000000000000000 R11: 800000007ff77063 R12: ffffffffabc03eb0
[    0.259452] R13: 0000000000000000 R14: 0000000000000000 R15: 0000000000000000
[    0.259452] FS:  0000000000000000(0000) GS:ffff9becbc400000(0000) knlGS:0000000000000000
[    0.259452] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[    0.259452] CR2: 000000007ed03020 CR3: 000000000fd38000 CR4: 00000000000006b0
[    0.259452] Call Trace:
[    0.259452]  ? __raw_callee_save___native_queued_spin_unlock+0x11/0x1e
[    0.259452]  ? prep_new_page+0x3e/0x150
[    0.259452]  ? get_page_from_freelist+0xfc1/0x1200
[    0.259452]  ? native_flush_tlb_global+0x97/0xa0
[    0.259452]  ? __flush_tlb_all+0x13/0x20
[    0.259452]  ? efi_call+0x58/0x90
[    0.259452]  ? virt_efi_set_variable_nonblocking+0xa0/0x120
[    0.259452]  ? efi_delete_dummy_variable+0x5e/0x80
[    0.259452]  ? efi_enter_virtual_mode+0x4f7/0x515
[    0.259452]  ? start_kernel+0x4cd/0x562
[    0.259452]  ? secondary_startup_64+0xa4/0xb0
[    0.259452] Modules linked in:
[    0.259452] CR2: 000000007ed03020
[    0.259452] ---[ end trace d144de23fcdf159d ]---
[    0.259452] RIP: 0010:0xfffffffeff6c6648
[    0.259452] Code: 48 83 ec 20 e8 41 fd ff ff 48 85 c9 75 1c 84 c0 74 18 4c 8d 05 15 a1 00 00 48 8d 0d ec 93 00 00 ba ba 00 00 00 e8 c0 fe ff ff <48> 8b 03 48 83 c4 20 5b c3 55 57 56 53 48 89 d3 48 89 ce 48 83 ec
[    0.259452] RSP: 0000:ffffffffabc03b10 EFLAGS: 00010202
[    0.259452] RAX: 0000000000000001 RBX: 000000007ed03020 RCX: 000000007ed03020
[    0.259452] RDX: ffffffffabc03eb0 RSI: 000000007ed03020 RDI: ffffffffab809670
[    0.259452] RBP: 0000000000000000 R08: 0000000000000007 R09: 0000000000000000
[    0.259452] R10: 0000000000000000 R11: 800000007ff77063 R12: ffffffffabc03eb0
[    0.259452] R13: 0000000000000000 R14: 0000000000000000 R15: 0000000000000000
[    0.259452] FS:  0000000000000000(0000) GS:ffff9becbc400000(0000) knlGS:0000000000000000
[    0.259452] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[    0.259452] CR2: 000000007ed03020 CR3: 000000000fd38000 CR4: 00000000000006b0
[    0.259452] Kernel panic - not syncing: Attempted to kill the idle task!
[    0.259452] ---[ end Kernel panic - not syncing: Attempted to kill the idle task! ]---






^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [edk2-devel] [PATCH v2 2/6] OvmfPkg/AmdSev: add Grub Firmware Volume Package
  2020-11-25  1:27                   ` James Bottomley
@ 2020-11-25 14:01                     ` Laszlo Ersek
  2020-11-25 16:02                       ` James Bottomley
  0 siblings, 1 reply; 37+ messages in thread
From: Laszlo Ersek @ 2020-11-25 14:01 UTC (permalink / raw)
  To: jejb, devel, Bret Barkelew, Liming Gao (Byosoft address)
  Cc: dovmurik, Dov.Murik1, ashish.kalra, brijesh.singh, tobin,
	david.kaplan, jon.grimm, thomas.lendacky, frankeh,
	Dr . David Alan Gilbert, Ard Biesheuvel (ARM address)

Adding Ard and Liming; and I see you added Bret already.

Comments below.

On 11/25/20 02:27, James Bottomley wrote:
> On Tue, 2020-11-24 at 15:42 -0800, James Bottomley wrote:
>> On Wed, 2020-11-25 at 00:22 +0100, Laszlo Ersek wrote:
> [...]
>>> There are some others that should be possible to remove (pls. refer
>>> to the rest of that email).
>>
>> Heh, well, I spoke too soon.  Even though the OVMF this produces
>> boots to grub and decrypts an encrypted volume, the kernel boot
>> panics because of something missing in the runtime ... it looks like
>> it's tripping over gRT->SetVariable, so I'm going to have to start
>> putting some stuff back again ...
>
> Actually, this isn't me.  I can't get the vanilla OVMF package to boot
> either.  It looks to be a problem with the variable policy stuff since
> the last known good boot was before they were added.
>
> I've attached the boot log with vanilla OVMF.  There's rather a lot of
> policy commits to try reverting.  What's the best way to debug this?

I encountered the exact same crash yesterday, with an old Fedora 30
virtual machine (running an 5.0.9-based Linux kernel).

I found the crash independently of SEV-ES -- I was simply performing
some regression tests due to the upcoming edk2-stable202011 tag. We're
approaching the release, and I thought this would be about the latest
that I could report issues with the release, or even send patches if
necessary.

So, indeed, because the backtrace below includes
"efi_enter_virtual_mode" and "virt_efi_set_variable_nonblocking", I
immediately thought of the VariablePolicy series. Notably, there is no
crash with the SMM build of OVMF, so I looked at the file

MdeModulePkg/Library/VariablePolicyLib/VariablePolicyExtraInitRuntimeDxe.c

I couldn't see anything wrong with it however (beyond the questionable C
language practice of reinterpreting a pointer-to-function as a
pointer-to-void, but I digress).

Furthermore, ArmVirtQemu also does *not* suffer from the crash, and
ArmVirtQemu uses the same non-SMM variable driver stack as the SMM-less
build of OVMF (modulo the lowest level driver, namely the flash driver).
This was another argument against suspecting the VariablePolicy series.

So my suspicion shifted from the firmware to the guest kernel. I booted
the guest with "efi=noruntime", and then upgraded it to the latest
Fedora 30 packages (dnf upgrade --refresh).

That brought me "kernel-5.6.13-100.fc30" -- which would *still* crash,
when I removed "efi=noruntime". So, as next step, I kept
"efi=noruntime", and upgraded the guest to Fedora 31
<https://docs.fedoraproject.org/en-US/quick-docs/dnf-system-upgrade/>.
Coincidentally, Fedora 31 is now the oldest Fedora release that's still
supported.

This upgrade gave me kernel 5.8.18-100.fc31.x86_64 in the guest -- and
this one does *not* crash. From your boot log below, I see your guest
kernel is 5.5.0; I suggest upgrading it.

So in the end I didn't report the crash on edk2-devel, I decided it was
a Linux kernel bug that got only tickled (unmasked), but not *caused*,
by the VariablePolicy work. I guess the kernel fix in question could be
determined with a reverse bisection, but I don't have time for that now.

For a semi-random git-log command,

$ git log --reverse --oneline v5.6.13..v5.8.18 -- \
    arch/x86/platform/efi/efi.c

14b60cc8e0ea efi/x86: Reindent struct initializer for legibility
a570b0624b3f efi/x86: Replace #ifdefs with IS_ENABLED() checks
50d53c58dd77 efi: Drop handling of 'boot_info' configuration table
120540f230d5 efi/ia64: Move HCDP and MPS table handling into IA64 arch code
fd506e0cf9fd efi: Move UGA and PROP table handling to x86 code
a17e809ea573 efi: Move mem_attr_table out of struct efi
14fb42090943 efi: Merge EFI system table revision and vendor checks
3a0701dc7ff8 efi: Make efi_config_init() x86 only
06c0bd93434c efi: Clean up config_parse_tables()
0a67361dcdaa efi/x86: Remove runtime table address from kexec EFI setup data
9cd437ac0ef4 efi/x86: Make fw_vendor, config_table and runtime sysfs nodes x86 specific
09308012d854 efi/x86: Merge assignments of efi.runtime_version
59f2a619a2db efi: Add 'runtime' pointer to struct efi
fd26830423e5 efi/x86: Drop 'systab' member from struct efi
f10e80a19b07 efi/x86: Add TPM related EFI tables to unencrypted mapping checks
badc61982adb efi/x86: Add RNG seed EFI table to unencrypted mapping check
0e72a6a3cfc3 efi: Export boot-services code and data as debugfs-blobs
f0df68d5bae8 efi: Add embedded peripheral firmware support
3be5f0d286dc Merge tag 'efi-next' of git://git.kernel.org/pub/scm/linux/kernel/git/efi/efi into efi/core
4e9a0f73f030 efi: Clean up config table description arrays

Nothing strikes me (from the subjects) as immediately relevant, but it's
totally possible that the log is too narrow
("arch/x86/platform/efi/efi.c" only).

Ard, do you have an idea which commit in recent Linux history could be
the fix?

(BTW: the ArmVirtQemu guest that I used for testing (successfully!) runs
Fedora 33, meaning its kernel is even more recent:
5.9.9-200.fc33.aarch64.)

I'll make one other comment below:


> Loading Linux 5.5.0-2-amd64 ...
> Loading initial ramdisk ...
> [    0.000000] Linux version 5.5.0-2-amd64 (debian-kernel@lists.debian.org) (gcc version 9.3.0 (Debian 9.3.0-10)) #1 SMP Debian 5.5.17-1 (2020-04-15)
> [    0.000000] Command line: BOOT_IMAGE=/boot/vmlinuz-5.5.0-2-amd64 root=UUID=8ebba08b-ff72-4030-ba43-8ce252e2e5a4 ro console=ttyS0,115200n8
> [    0.000000] x86/fpu: x87 FPU will use FXSAVE
> [    0.000000] BIOS-provided physical RAM map:
> [    0.000000] BIOS-e820: [mem 0x0000000000000000-0x000000000009ffff] usable
> [    0.000000] BIOS-e820: [mem 0x0000000000100000-0x00000000007fffff] usable
> [    0.000000] BIOS-e820: [mem 0x0000000000800000-0x0000000000807fff] ACPI NVS
> [    0.000000] BIOS-e820: [mem 0x0000000000808000-0x000000000080ffff] usable
> [    0.000000] BIOS-e820: [mem 0x0000000000810000-0x00000000008fffff] ACPI NVS
> [    0.000000] BIOS-e820: [mem 0x0000000000900000-0x000000007f8eefff] usable
> [    0.000000] BIOS-e820: [mem 0x000000007f8ef000-0x000000007f9eefff] reserved
> [    0.000000] BIOS-e820: [mem 0x000000007f9ef000-0x000000007faeefff] type 20
> [    0.000000] BIOS-e820: [mem 0x000000007faef000-0x000000007fb6efff] reserved
> [    0.000000] BIOS-e820: [mem 0x000000007fb6f000-0x000000007fb7efff] ACPI data
> [    0.000000] BIOS-e820: [mem 0x000000007fb7f000-0x000000007fbfefff] ACPI NVS
> [    0.000000] BIOS-e820: [mem 0x000000007fbff000-0x000000007fef3fff] usable
> [    0.000000] BIOS-e820: [mem 0x000000007fef4000-0x000000007ff77fff] reserved
> [    0.000000] BIOS-e820: [mem 0x000000007ff78000-0x000000007fffffff] ACPI NVS
> [    0.000000] BIOS-e820: [mem 0x00000000ffc00000-0x00000000ffffffff] reserved
> [    0.000000] NX (Execute Disable) protection: active
> [    0.000000] efi: EFI v2.70 by EDK II
> [    0.000000] efi:  SMBIOS=0x7f942000  ACPI=0x7fb7e000  ACPI 2.0=0x7fb7e014  MEMATTR=0x7ebe9018
> [    0.000000] secureboot: Secure boot could not be determined (mode 0)
> [    0.000000] SMBIOS 2.8 present.
> [    0.000000] DMI: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 0.0.0 02/06/2015
> [    0.000000] Hypervisor detected: KVM
> [    0.000000] kvm-clock: Using msrs 4b564d01 and 4b564d00
> [    0.000000] kvm-clock: cpu 0, msr 28031001, primary cpu clock
> [    0.000000] kvm-clock: using sched offset of 16414477727 cycles
> [    0.000006] clocksource: kvm-clock: mask: 0xffffffffffffffff max_cycles: 0x1cd42e4dffb, max_idle_ns: 881590591483 ns
> [    0.000018] tsc: Detected 2400.000 MHz processor
> [    0.000169] last_pfn = 0x7fef4 max_arch_pfn = 0x400000000
> [    0.000220] x86/PAT: PAT not supported by CPU.
> [    0.000227] x86/PAT: Configuration [0-7]: WB  WT  UC- UC  WB  WT  UC- UC
> [    0.015576] RAMDISK: [mem 0x34a09000-0x364fbfff]
> [    0.015601] ACPI: Early table checksum verification disabled
> [    0.015622] ACPI: RSDP 0x000000007FB7E014 000024 (v02 BOCHS )
> [    0.015627] ACPI: XSDT 0x000000007FB7D0E8 000044 (v01 BOCHS  BXPCFACP 00000001      01000013)
> [    0.015639] ACPI: FACP 0x000000007FB7A000 000074 (v01 BOCHS  BXPCFACP 00000001 BXPC 00000001)
> [    0.015645] ACPI: DSDT 0x000000007FB7B000 00140B (v01 BOCHS  BXPCDSDT 00000001 BXPC 00000001)
> [    0.015656] ACPI: FACS 0x000000007FBDD000 000040
> [    0.015659] ACPI: APIC 0x000000007FB79000 000078 (v01 BOCHS  BXPCAPIC 00000001 BXPC 00000001)
> [    0.015663] ACPI: HPET 0x000000007FB78000 000038 (v01 BOCHS  BXPCHPET 00000001 BXPC 00000001)
> [    0.015669] ACPI: BGRT 0x000000007FB77000 000038 (v01 INTEL  EDK2     00000002      01000013)
> [    0.016057] No NUMA configuration found
> [    0.016058] Faking a node at [mem 0x0000000000000000-0x000000007fef3fff]
> [    0.016066] NODE_DATA(0) allocated [mem 0x7fe7f000-0x7fe83fff]
> [    0.016095] Zone ranges:
> [    0.016100]   DMA      [mem 0x0000000000001000-0x0000000000ffffff]
> [    0.016101]   DMA32    [mem 0x0000000001000000-0x000000007fef3fff]
> [    0.016102]   Normal   empty
> [    0.016103]   Device   empty
> [    0.016104] Movable zone start for each node
> [    0.016105] Early memory node ranges
> [    0.016106]   node   0: [mem 0x0000000000001000-0x000000000009ffff]
> [    0.016107]   node   0: [mem 0x0000000000100000-0x00000000007fffff]
> [    0.016108]   node   0: [mem 0x0000000000808000-0x000000000080ffff]
> [    0.016109]   node   0: [mem 0x0000000000900000-0x000000007f8eefff]
> [    0.016110]   node   0: [mem 0x000000007fbff000-0x000000007fef3fff]
> [    0.016459] Zeroed struct page in unavailable ranges: 1397 pages
> [    0.016461] Initmem setup node 0 [mem 0x0000000000001000-0x000000007fef3fff]
> [    0.019894] ACPI: PM-Timer IO Port: 0xb008
> [    0.019926] ACPI: LAPIC_NMI (acpi_id[0xff] dfl dfl lint[0x1])
> [    0.019972] IOAPIC[0]: apic_id 0, version 17, address 0xfec00000, GSI 0-23
> [    0.019975] ACPI: INT_SRC_OVR (bus 0 bus_irq 0 global_irq 2 dfl dfl)
> [    0.019981] ACPI: INT_SRC_OVR (bus 0 bus_irq 5 global_irq 5 high level)
> [    0.019982] ACPI: INT_SRC_OVR (bus 0 bus_irq 9 global_irq 9 high level)
> [    0.019987] ACPI: INT_SRC_OVR (bus 0 bus_irq 10 global_irq 10 high level)
> [    0.019988] ACPI: INT_SRC_OVR (bus 0 bus_irq 11 global_irq 11 high level)
> [    0.019993] Using ACPI (MADT) for SMP configuration information
> [    0.019995] ACPI: HPET id: 0x8086a201 base: 0xfed00000
> [    0.020024] smpboot: Allowing 1 CPUs, 0 hotplug CPUs
> [    0.020051] PM: Registered nosave memory: [mem 0x00000000-0x00000fff]
> [    0.020052] PM: Registered nosave memory: [mem 0x000a0000-0x000fffff]
> [    0.020054] PM: Registered nosave memory: [mem 0x00800000-0x00807fff]
> [    0.020055] PM: Registered nosave memory: [mem 0x00810000-0x008fffff]
> [    0.020056] PM: Registered nosave memory: [mem 0x7e7e7000-0x7e7effff]
> [    0.020057] PM: Registered nosave memory: [mem 0x7f8ef000-0x7f9eefff]
> [    0.020058] PM: Registered nosave memory: [mem 0x7f9ef000-0x7faeefff]
> [    0.020059] PM: Registered nosave memory: [mem 0x7faef000-0x7fb6efff]
> [    0.020059] PM: Registered nosave memory: [mem 0x7fb6f000-0x7fb7efff]
> [    0.020060] PM: Registered nosave memory: [mem 0x7fb7f000-0x7fbfefff]
> [    0.020063] [mem 0x80000000-0xffbfffff] available for PCI devices
> [    0.020064] Booting paravirtualized kernel on KVM
> [    0.020069] clocksource: refined-jiffies: mask: 0xffffffff max_cycles: 0xffffffff, max_idle_ns: 7645519600211568 ns
> [    0.108622] setup_percpu: NR_CPUS:512 nr_cpumask_bits:512 nr_cpu_ids:1 nr_node_ids:1
> [    0.109877] percpu: Embedded 55 pages/cpu s187800 r8192 d29288 u2097152
> [    0.109918] KVM setup async PF for cpu 0
> [    0.109923] kvm-stealtime: cpu 0, msr 7c419500
> [    0.109931] Built 1 zonelists, mobility grouping on.  Total pages: 512892
> [    0.109932] Policy zone: DMA32
> [    0.109934] Kernel command line: BOOT_IMAGE=/boot/vmlinuz-5.5.0-2-amd64 root=UUID=8ebba08b-ff72-4030-ba43-8ce252e2e5a4 ro console=ttyS0,115200n8
> [    0.111356] Dentry cache hash table entries: 262144 (order: 9, 2097152 bytes, linear)
> [    0.111796] Inode-cache hash table entries: 131072 (order: 8, 1048576 bytes, linear)
> [    0.111837] mem auto-init: stack:off, heap alloc:off, heap free:off
> [    0.114998] Memory: 248380K/2091564K available (10243K kernel code, 1221K rwdata, 3972K rodata, 1672K init, 1980K bss, 120832K reserved, 0K cma-reserved)
> [    0.115028] random: get_random_u64 called from __kmem_cache_create+0x3e/0x530 with crng_init=0
> [    0.115547] SLUB: HWalign=64, Order=0-3, MinObjects=0, CPUs=1, Nodes=1
> [    0.115575] Kernel/User page tables isolation: enabled
> [    0.115617] ftrace: allocating 34294 entries in 134 pages
> [    0.130489] ftrace: allocated 134 pages with 3 groups
> [    0.130821] rcu: Hierarchical RCU implementation.
> [    0.130823] rcu: 	RCU restricting CPUs from NR_CPUS=512 to nr_cpu_ids=1.
> [    0.130826] rcu: RCU calculated value of scheduler-enlistment delay is 25 jiffies.
> [    0.130827] rcu: Adjusting geometry for rcu_fanout_leaf=16, nr_cpu_ids=1
> [    0.133774] NR_IRQS: 33024, nr_irqs: 256, preallocated irqs: 16
> [    0.134031] Console: colour dummy device 80x25
> [    0.242024] printk: console [ttyS0] enabled
> [    0.242695] ACPI: Core revision 20191018
> [    0.243470] clocksource: hpet: mask: 0xffffffff max_cycles: 0xffffffff, max_idle_ns: 19112604467 ns
> [    0.244954] APIC: Switch to symmetric I/O mode setup
> [    0.246031] x2apic enabled
> [    0.246800] Switched APIC routing to physical x2apic.
> [    0.248946] ..TIMER: vector=0x30 apic1=0 pin1=2 apic2=-1 pin2=-1
> [    0.249892] clocksource: tsc-early: mask: 0xffffffffffffffff max_cycles: 0x22983777dd9, max_idle_ns: 440795300422 ns
> [    0.251455] Calibrating delay loop (skipped) preset value.. 4800.00 BogoMIPS (lpj=9600000)
> [    0.252873] pid_max: default: 32768 minimum: 301
> [    0.256847] BUG: unable to handle page fault for address: 000000007ed03020
> [    0.258328] #PF: supervisor read access in kernel mode
> [    0.259304] #PF: error_code(0x0000) - not-present page
> [    0.259452] PGD fd2d063 P4D fd2d063 PUD fd30063 PMD fd3f063 PTE fffff812fc060
> [    0.259452] Oops: 0000 [#1] SMP PTI
> [    0.259452] CPU: 0 PID: 0 Comm: swapper/0 Not tainted 5.5.0-2-amd64 #1 Debian 5.5.17-1
> [    0.259452] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 0.0.0 02/06/2015
> [    0.259452] RIP: 0010:0xfffffffeff6c6648
> [    0.259452] Code: 48 83 ec 20 e8 41 fd ff ff 48 85 c9 75 1c 84 c0 74 18 4c 8d 05 15 a1 00 00 48 8d 0d ec 93 00 00 ba ba 00 00 00 e8 c0 fe ff ff <48> 8b 03 48 83 c4 20 5b c3 55 57 56 53 48 89 d3 48 89 ce 48 83 ec
> [    0.259452] RSP: 0000:ffffffffabc03b10 EFLAGS: 00010202
> [    0.259452] RAX: 0000000000000001 RBX: 000000007ed03020 RCX: 000000007ed03020
> [    0.259452] RDX: ffffffffabc03eb0 RSI: 000000007ed03020 RDI: ffffffffab809670
> [    0.259452] RBP: 0000000000000000 R08: 0000000000000007 R09: 0000000000000000
> [    0.259452] R10: 0000000000000000 R11: 800000007ff77063 R12: ffffffffabc03eb0
> [    0.259452] R13: 0000000000000000 R14: 0000000000000000 R15: 0000000000000000
> [    0.259452] FS:  0000000000000000(0000) GS:ffff9becbc400000(0000) knlGS:0000000000000000
> [    0.259452] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
> [    0.259452] CR2: 000000007ed03020 CR3: 000000000fd38000 CR4: 00000000000006b0
> [    0.259452] Call Trace:
> [    0.259452]  ? __raw_callee_save___native_queued_spin_unlock+0x11/0x1e
> [    0.259452]  ? prep_new_page+0x3e/0x150
> [    0.259452]  ? get_page_from_freelist+0xfc1/0x1200
> [    0.259452]  ? native_flush_tlb_global+0x97/0xa0
> [    0.259452]  ? __flush_tlb_all+0x13/0x20
> [    0.259452]  ? efi_call+0x58/0x90
> [    0.259452]  ? virt_efi_set_variable_nonblocking+0xa0/0x120
> [    0.259452]  ? efi_delete_dummy_variable+0x5e/0x80
> [    0.259452]  ? efi_enter_virtual_mode+0x4f7/0x515
> [    0.259452]  ? start_kernel+0x4cd/0x562
> [    0.259452]  ? secondary_startup_64+0xa4/0xb0
> [    0.259452] Modules linked in:
> [    0.259452] CR2: 000000007ed03020
> [    0.259452] ---[ end trace d144de23fcdf159d ]---
> [    0.259452] RIP: 0010:0xfffffffeff6c6648
> [    0.259452] Code: 48 83 ec 20 e8 41 fd ff ff 48 85 c9 75 1c 84 c0 74 18 4c 8d 05 15 a1 00 00 48 8d 0d ec 93 00 00 ba ba 00 00 00 e8 c0 fe ff ff <48> 8b 03 48 83 c4 20 5b c3 55 57 56 53 48 89 d3 48 89 ce 48 83 ec
> [    0.259452] RSP: 0000:ffffffffabc03b10 EFLAGS: 00010202
> [    0.259452] RAX: 0000000000000001 RBX: 000000007ed03020 RCX: 000000007ed03020
> [    0.259452] RDX: ffffffffabc03eb0 RSI: 000000007ed03020 RDI: ffffffffab809670
> [    0.259452] RBP: 0000000000000000 R08: 0000000000000007 R09: 0000000000000000
> [    0.259452] R10: 0000000000000000 R11: 800000007ff77063 R12: ffffffffabc03eb0
> [    0.259452] R13: 0000000000000000 R14: 0000000000000000 R15: 0000000000000000
> [    0.259452] FS:  0000000000000000(0000) GS:ffff9becbc400000(0000) knlGS:0000000000000000
> [    0.259452] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
> [    0.259452] CR2: 000000007ed03020 CR3: 000000000fd38000 CR4: 00000000000006b0
> [    0.259452] Kernel panic - not syncing: Attempted to kill the idle task!
> [    0.259452] ---[ end Kernel panic - not syncing: Attempted to kill the idle task! ]---

In my case, the final frame in the stack dump was
get_page_from_freelist() (the above backtrace contains two more frames).

I booted the crashing guest with "efi=debug", and compared the crashing
address (CR2) with the UEFI memmap. In my case, the CR2 address pointed
into a "Boot Data" area.

Now, while crashing with a CR2 that points into a "Boot Data" area
*seems* consistent with a broken UEFI runtime DXE driver (either holding
a reference to non-runtime memory, or having failed to convert a pointer
during SetVirtualAddressMap()), I abandoned this idea because (1) I
couldn't determine anything bad or missing -- from code inspection -- in
"MdeModulePkg/Library/VariablePolicyLib/VariablePolicyExtraInitRuntimeDxe.c",
and (2) the backtrace contains get_page_from_freelist(), which I
*believe* indicates it's not EFI runtime code proper that crashes, but
something in the guest kernel memory management.

I also assume Bret had successfully tested the SMM-less build of the
VariablePolicy feature against a number of Windows guests.

If we can locate the kernel fix (with reverse bisection or otherwise),
then I guess it will have to be backported to a bunch of kernels.

... Anyway, just to be safe -- do we want to extend the Hard Feature
Freeze until we track this down with 100% certainty? The release is
currently planned for Nov  27th.

Thanks
Laszlo


^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [edk2-devel] [PATCH v2 2/6] OvmfPkg/AmdSev: add Grub Firmware Volume Package
  2020-11-25 14:01                     ` Laszlo Ersek
@ 2020-11-25 16:02                       ` James Bottomley
  2020-11-25 17:09                         ` James Bottomley
  0 siblings, 1 reply; 37+ messages in thread
From: James Bottomley @ 2020-11-25 16:02 UTC (permalink / raw)
  To: Laszlo Ersek, devel, Bret Barkelew, Liming Gao (Byosoft address)
  Cc: dovmurik, Dov.Murik1, ashish.kalra, brijesh.singh, tobin,
	david.kaplan, jon.grimm, thomas.lendacky, frankeh,
	Dr . David Alan Gilbert, Ard Biesheuvel (ARM address)

On Wed, 2020-11-25 at 15:01 +0100, Laszlo Ersek wrote:
> This upgrade gave me kernel 5.8.18-100.fc31.x86_64 in the guest --
> and this one does *not* crash. From your boot log below, I see your
> guest kernel is 5.5.0; I suggest upgrading it.

Heh, that's easier said than done ... I always make my encrypted images
too small to upgrade a kernel easily.  Anyway, after doing the remove
and add stuff dance, I finally got it upgraded to the latest debian
testing linux-image-5.8.0-3 it's still crashing although with a
slightly different traceback.  It looks like there might be something
additional in the fedora 5.8 kernel that fixes this.  I'm going to try
out upstream kernels next.

James

---

Loading Linux 5.9.0-3-amd64 ...
Loading initial ramdisk ...
[    0.000000] Linux version 5.9.0-3-amd64 (debian-kernel@lists.debian.org) (gcc-10 (Debian 10.2.0-17) 10.2.0, GNU ld (GNU Binutils for Debian) 2.35.1) #1 SMP Debian 5.9.9-1 (2020-11-19)
[    0.000000] Command line: BOOT_IMAGE=/boot/vmlinuz-5.9.0-3-amd64 root=UUID=8ebba08b-ff72-4030-ba43-8ce252e2e5a4 ro console=ttyS0,115200n8
[    0.000000] x86/fpu: x87 FPU will use FXSAVE
[    0.000000] BIOS-provided physical RAM map:
[    0.000000] BIOS-e820: [mem 0x0000000000000000-0x000000000009ffff] usable
[    0.000000] BIOS-e820: [mem 0x0000000000100000-0x00000000007fffff] usable
[    0.000000] BIOS-e820: [mem 0x0000000000800000-0x0000000000807fff] ACPI NVS
[    0.000000] BIOS-e820: [mem 0x0000000000808000-0x000000000080ffff] usable
[    0.000000] BIOS-e820: [mem 0x0000000000810000-0x00000000008fffff] ACPI NVS
[    0.000000] BIOS-e820: [mem 0x0000000000900000-0x000000007f8eefff] usable
[    0.000000] BIOS-e820: [mem 0x000000007f8ef000-0x000000007f9eefff] reserved
[    0.000000] BIOS-e820: [mem 0x000000007f9ef000-0x000000007faeefff] type 20
[    0.000000] BIOS-e820: [mem 0x000000007faef000-0x000000007fb6efff] reserved
[    0.000000] BIOS-e820: [mem 0x000000007fb6f000-0x000000007fb7efff] ACPI data
[    0.000000] BIOS-e820: [mem 0x000000007fb7f000-0x000000007fbfefff] ACPI NVS
[    0.000000] BIOS-e820: [mem 0x000000007fbff000-0x000000007fef3fff] usable
[    0.000000] BIOS-e820: [mem 0x000000007fef4000-0x000000007ff77fff] reserved
[    0.000000] BIOS-e820: [mem 0x000000007ff78000-0x000000007fffffff] ACPI NVS
[    0.000000] BIOS-e820: [mem 0x00000000ffc00000-0x00000000ffffffff] reserved
[    0.000000] NX (Execute Disable) protection: active
[    0.000000] efi: EFI v2.70 by EDK II
[    0.000000] efi: SMBIOS=0x7f942000 ACPI=0x7fb7e000 ACPI 2.0=0x7fb7e014 MEMATTR=0x7ebe9018 
[    0.000000] secureboot: Secure boot could not be determined (mode 0)
[    0.000000] SMBIOS 2.8 present.
[    0.000000] DMI: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 0.0.0 02/06/2015
[    0.000000] Hypervisor detected: KVM
[    0.000000] kvm-clock: Using msrs 4b564d01 and 4b564d00
[    0.000000] kvm-clock: cpu 0, msr 57267001, primary cpu clock
[    0.000000] kvm-clock: using sched offset of 16019535822 cycles
[    0.000006] clocksource: kvm-clock: mask: 0xffffffffffffffff max_cycles: 0x1cd42e4dffb, max_idle_ns: 881590591483 ns
[    0.000013] tsc: Detected 2400.000 MHz processor
[    0.000110] last_pfn = 0x7fef4 max_arch_pfn = 0x400000000
[    0.000153] x86/PAT: PAT not supported by the CPU.
[    0.000161] x86/PAT: Configuration [0-7]: WB  WT  UC- UC  WB  WT  UC- UC  
[    0.016709] RAMDISK: [mem 0x34945000-0x36499fff]
[    0.016727] ACPI: Early table checksum verification disabled
[    0.016740] ACPI: RSDP 0x000000007FB7E014 000024 (v02 BOCHS )
[    0.016744] ACPI: XSDT 0x000000007FB7D0E8 000044 (v01 BOCHS  BXPCFACP 00000001      01000013)
[    0.016753] ACPI: FACP 0x000000007FB7A000 000074 (v01 BOCHS  BXPCFACP 00000001 BXPC 00000001)
[    0.016758] ACPI: DSDT 0x000000007FB7B000 00140B (v01 BOCHS  BXPCDSDT 00000001 BXPC 00000001)
[    0.016765] ACPI: FACS 0x000000007FBDD000 000040
[    0.016768] ACPI: APIC 0x000000007FB79000 000078 (v01 BOCHS  BXPCAPIC 00000001 BXPC 00000001)
[    0.016771] ACPI: HPET 0x000000007FB78000 000038 (v01 BOCHS  BXPCHPET 00000001 BXPC 00000001)
[    0.016777] ACPI: BGRT 0x000000007FB77000 000038 (v01 INTEL  EDK2     00000002      01000013)
[    0.017076] No NUMA configuration found
[    0.017077] Faking a node at [mem 0x0000000000000000-0x000000007fef3fff]
[    0.017084] NODE_DATA(0) allocated [mem 0x7fe7f000-0x7fe83fff]
[    0.017118] Zone ranges:
[    0.017119]   DMA      [mem 0x0000000000001000-0x0000000000ffffff]
[    0.017120]   DMA32    [mem 0x0000000001000000-0x000000007fef3fff]
[    0.017122]   Normal   empty
[    0.017122]   Device   empty
[    0.017123] Movable zone start for each node
[    0.017124] Early memory node ranges
[    0.017125]   node   0: [mem 0x0000000000001000-0x000000000009ffff]
[    0.017126]   node   0: [mem 0x0000000000100000-0x00000000007fffff]
[    0.017127]   node   0: [mem 0x0000000000808000-0x000000000080ffff]
[    0.017127]   node   0: [mem 0x0000000000900000-0x000000007f8eefff]
[    0.017128]   node   0: [mem 0x000000007fbff000-0x000000007fef3fff]
[    0.017395] Zeroed struct page in unavailable ranges: 1397 pages
[    0.017396] Initmem setup node 0 [mem 0x0000000000001000-0x000000007fef3fff]
[    0.023450] ACPI: PM-Timer IO Port: 0xb008
[    0.023466] ACPI: LAPIC_NMI (acpi_id[0xff] dfl dfl lint[0x1])
[    0.023510] IOAPIC[0]: apic_id 0, version 17, address 0xfec00000, GSI 0-23
[    0.023513] ACPI: INT_SRC_OVR (bus 0 bus_irq 0 global_irq 2 dfl dfl)
[    0.023515] ACPI: INT_SRC_OVR (bus 0 bus_irq 5 global_irq 5 high level)
[    0.023515] ACPI: INT_SRC_OVR (bus 0 bus_irq 9 global_irq 9 high level)
[    0.023521] ACPI: INT_SRC_OVR (bus 0 bus_irq 10 global_irq 10 high level)
[    0.023522] ACPI: INT_SRC_OVR (bus 0 bus_irq 11 global_irq 11 high level)
[    0.023527] Using ACPI (MADT) for SMP configuration information
[    0.023529] ACPI: HPET id: 0x8086a201 base: 0xfed00000
[    0.023559] smpboot: Allowing 1 CPUs, 0 hotplug CPUs
[    0.023586] PM: hibernation: Registered nosave memory: [mem 0x00000000-0x00000fff]
[    0.023588] PM: hibernation: Registered nosave memory: [mem 0x000a0000-0x000fffff]
[    0.023589] PM: hibernation: Registered nosave memory: [mem 0x00800000-0x00807fff]
[    0.023590] PM: hibernation: Registered nosave memory: [mem 0x00810000-0x008fffff]
[    0.023592] PM: hibernation: Registered nosave memory: [mem 0x7e7e7000-0x7e7effff]
[    0.023593] PM: hibernation: Registered nosave memory: [mem 0x7f8ef000-0x7f9eefff]
[    0.023594] PM: hibernation: Registered nosave memory: [mem 0x7f9ef000-0x7faeefff]
[    0.023594] PM: hibernation: Registered nosave memory: [mem 0x7faef000-0x7fb6efff]
[    0.023595] PM: hibernation: Registered nosave memory: [mem 0x7fb6f000-0x7fb7efff]
[    0.023596] PM: hibernation: Registered nosave memory: [mem 0x7fb7f000-0x7fbfefff]
[    0.023597] [mem 0x80000000-0xffbfffff] available for PCI devices
[    0.023598] Booting paravirtualized kernel on KVM
[    0.023602] clocksource: refined-jiffies: mask: 0xffffffff max_cycles: 0xffffffff, max_idle_ns: 7645519600211568 ns
[    0.027609] setup_percpu: NR_CPUS:512 nr_cpumask_bits:512 nr_cpu_ids:1 nr_node_ids:1
[    0.027833] percpu: Embedded 55 pages/cpu s185048 r8192 d32040 u2097152
[    0.027868] kvm-guest: stealtime: cpu 0, msr 7c418580
[    0.027872] kvm-guest: PV spinlocks disabled, no host support
[    0.027877] Built 1 zonelists, mobility grouping on.  Total pages: 512892
[    0.027878] Policy zone: DMA32
[    0.027880] Kernel command line: BOOT_IMAGE=/boot/vmlinuz-5.9.0-3-amd64 root=UUID=8ebba08b-ff72-4030-ba43-8ce252e2e5a4 ro console=ttyS0,115200n8
[    0.028094] Dentry cache hash table entries: 262144 (order: 9, 2097152 bytes, linear)
[    0.028524] Inode-cache hash table entries: 131072 (order: 8, 1048576 bytes, linear)
[    0.028570] mem auto-init: stack:off, heap alloc:on, heap free:off
[    0.033164] Memory: 1968032K/2091564K available (12291K kernel code, 1298K rwdata, 3804K rodata, 1640K init, 1768K bss, 123272K reserved, 0K cma-reserved)
[    0.033179] random: get_random_u64 called from __kmem_cache_create+0x2e/0x540 with crng_init=0
[    0.033271] SLUB: HWalign=64, Order=0-3, MinObjects=0, CPUs=1, Nodes=1
[    0.033281] Kernel/User page tables isolation: enabled
[    0.033297] ftrace: allocating 34815 entries in 136 pages
[    0.046678] ftrace: allocated 136 pages with 2 groups
[    0.046769] rcu: Hierarchical RCU implementation.
[    0.046770] rcu: 	RCU restricting CPUs from NR_CPUS=512 to nr_cpu_ids=1.
[    0.046771] 	Rude variant of Tasks RCU enabled.
[    0.046772] rcu: RCU calculated value of scheduler-enlistment delay is 25 jiffies.
[    0.046773] rcu: Adjusting geometry for rcu_fanout_leaf=16, nr_cpu_ids=1
[    0.049462] NR_IRQS: 33024, nr_irqs: 256, preallocated irqs: 16
[    0.049696] Console: colour dummy device 80x25
[    0.161997] printk: console [ttyS0] enabled
[    0.162674] ACPI: Core revision 20200717
[    0.163453] clocksource: hpet: mask: 0xffffffff max_cycles: 0xffffffff, max_idle_ns: 19112604467 ns
[    0.164992] APIC: Switch to symmetric I/O mode setup
[    0.166044] x2apic enabled
[    0.166784] Switched APIC routing to physical x2apic.
[    0.169130] ..TIMER: vector=0x30 apic1=0 pin1=2 apic2=-1 pin2=-1
[    0.170151] clocksource: tsc-early: mask: 0xffffffffffffffff max_cycles: 0x22983777dd9, max_idle_ns: 440795300422 ns
[    0.172152] Calibrating delay loop (skipped) preset value.. 4800.00 BogoMIPS (lpj=9600000)
[    0.176152] pid_max: default: 32768 minimum: 301
[    0.178520] BUG: unable to handle page fault for address: 000000007ed03020
[    0.179561] #PF: supervisor read access in kernel mode
[    0.180146] #PF: error_code(0x0000) - not-present page
[    0.180146] PGD 7b971063 P4D 7b971063 PUD 7b974063 PMD 7b97f063 PTE 800fffff812fc060
[    0.180146] Oops: 0000 [#1] SMP PTI
[    0.180146] CPU: 0 PID: 0 Comm: swapper/0 Not tainted 5.9.0-3-amd64 #1 Debian 5.9.9-1
[    0.180146] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 0.0.0 02/06/2015
[    0.180146] RIP: 0010:0xfffffffeff6c6648
[    0.180146] Code: 48 83 ec 20 e8 41 fd ff ff 48 85 c9 75 1c 84 c0 74 18 4c 8d 05 15 a1 00 00 48 8d 0d ec 93 00 00 ba ba 00 00 00 e8 c0 fe ff ff <48> 8b 03 48 83 c4 20 5b c3 55 57 56 53 48 89 d3 48 89 ce 48 83 ec
[    0.180146] RSP: 0000:ffffffff8ca03b80 EFLAGS: 00010202
[    0.180146] RAX: 0000000000000001 RBX: 000000007ed03020 RCX: 000000007ed03020
[    0.180146] RDX: ffffffff8ca03eb0 RSI: 000000007ed03020 RDI: ffffffff8c60a378
[    0.180146] RBP: 0000000000000000 R08: 0000000000000007 R09: 0000000000000000
[    0.180146] R10: 0000000000000048 R11: 0000000000001000 R12: ffffffff8ca03eb0
[    0.180146] R13: 0000000000000000 R14: 0000000000000000 R15: 0000000000000000
[    0.180146] FS:  0000000000000000(0000) GS:ffff9d1e7c400000(0000) knlGS:0000000000000000
[    0.180146] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[    0.180146] CR2: 000000007ed03020 CR3: 000000007b9ac000 CR4: 00000000000006b0
[    0.180146] Call Trace:
[    0.180146]  ? __alloc_pages_nodemask+0x15e/0x310
[    0.180146]  ? __change_page_attr_set_clr+0x652/0xcf0
[    0.180146]  ? native_flush_tlb_global+0x8a/0xa0
[    0.180146]  ? __flush_tlb_all+0x18/0x30
[    0.180146]  ? kernel_map_pages_in_pgd+0xba/0xda
[    0.180146]  ? efi_update_mappings+0x66/0x91
[    0.180146]  ? __efi_call+0x25/0x30
[    0.180146]  ? switch_mm_irqs_off+0x195/0x3c0
[    0.180146]  ? virt_efi_set_variable_nonblocking+0x9d/0x100
[    0.180146]  ? efi_delete_dummy_variable+0x54/0x70
[    0.180146]  ? efi_enter_virtual_mode+0x3df/0x3fa
[    0.180146]  ? start_kernel+0x50f/0x5a8
[    0.180146]  ? secondary_startup_64+0xa4/0xb0
[    0.180146] Modules linked in:
[    0.180146] CR2: 000000007ed03020
[    0.180146] ---[ end trace 842329954bcb47b2 ]---
[    0.180146] RIP: 0010:0xfffffffeff6c6648
[    0.180146] Code: 48 83 ec 20 e8 41 fd ff ff 48 85 c9 75 1c 84 c0 74 18 4c 8d 05 15 a1 00 00 48 8d 0d ec 93 00 00 ba ba 00 00 00 e8 c0 fe ff ff <48> 8b 03 48 83 c4 20 5b c3 55 57 56 53 48 89 d3 48 89 ce 48 83 ec
[    0.180146] RSP: 0000:ffffffff8ca03b80 EFLAGS: 00010202
[    0.180146] RAX: 0000000000000001 RBX: 000000007ed03020 RCX: 000000007ed03020
[    0.180146] RDX: ffffffff8ca03eb0 RSI: 000000007ed03020 RDI: ffffffff8c60a378
[    0.180146] RBP: 0000000000000000 R08: 0000000000000007 R09: 0000000000000000
[    0.180146] R10: 0000000000000048 R11: 0000000000001000 R12: ffffffff8ca03eb0
[    0.180146] R13: 0000000000000000 R14: 0000000000000000 R15: 0000000000000000
[    0.180146] FS:  0000000000000000(0000) GS:ffff9d1e7c400000(0000) knlGS:0000000000000000
[    0.180146] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[    0.180146] CR2: 000000007ed03020 CR3: 000000007b9ac000 CR4: 00000000000006b0
[    0.180146] Kernel panic - not syncing: Attempted to kill the idle task!
[    0.180146] ---[ end Kernel panic - not syncing: Attempted to kill the idle task! ]---



^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [edk2-devel] [PATCH v2 2/6] OvmfPkg/AmdSev: add Grub Firmware Volume Package
  2020-11-25 16:02                       ` James Bottomley
@ 2020-11-25 17:09                         ` James Bottomley
  2020-11-25 18:17                           ` James Bottomley
  2020-11-25 18:35                           ` Laszlo Ersek
  0 siblings, 2 replies; 37+ messages in thread
From: James Bottomley @ 2020-11-25 17:09 UTC (permalink / raw)
  To: Laszlo Ersek, devel, Bret Barkelew, Liming Gao (Byosoft address)
  Cc: dovmurik, Dov.Murik1, ashish.kalra, brijesh.singh, tobin,
	david.kaplan, jon.grimm, thomas.lendacky, frankeh,
	Dr . David Alan Gilbert, Ard Biesheuvel (ARM address)

On Wed, 2020-11-25 at 08:02 -0800, James Bottomley wrote:
> On Wed, 2020-11-25 at 15:01 +0100, Laszlo Ersek wrote:
> > This upgrade gave me kernel 5.8.18-100.fc31.x86_64 in the guest --
> > and this one does *not* crash. From your boot log below, I see your
> > guest kernel is 5.5.0; I suggest upgrading it.
> 
> Heh, that's easier said than done ... I always make my encrypted
> images too small to upgrade a kernel easily.  Anyway, after doing the
> remove and add stuff dance, I finally got it upgraded to the latest
> debian testing linux-image-5.8.0-3 it's still crashing although with
> a slightly different traceback.  It looks like there might be
> something additional in the fedora 5.8 kernel that fixes this.  I'm
> going to try out upstream kernels next.

I've got the upstream kernel booting through OVMF with a qemu -kernel
command line.  I also have a fix: it's not to delete the dummy variable
which was part of the ancient x86 anti bricking code (which is also why
arm64 doesn't have the problem).

If you remove the set variable in arch/x86/platform/efi/quirks.c:

/*
 * Deleting the dummy variable which kicks off garbage collection
*/
void efi_delete_dummy_variable(void)
{
	efi.set_variable_nonblocking((efi_char16_t *)efi_dummy_name,
				     &EFI_DUMMY_GUID,
				     EFI_VARIABLE_NON_VOLATILE |
				     EFI_VARIABLE_BOOTSERVICE_ACCESS |
				     EFI_VARIABLE_RUNTIME_ACCESS, 0, NULL);
}

The kernel will boot.  I'm not sure why we have this deletion
unconditionally in efi_enter_virtual_mode, but removing the call with
the patch below allows the kernel to boot.

However, once the kernel has booted, any attempt to write to an EFI
variable results in this:

[  975.440240] [Firmware Bug]: Page fault caused by firmware at PA: 0x7e450020

And then the efi runtime gets disabled.

James

---

diff --git a/arch/x86/platform/efi/efi.c b/arch/x86/platform/efi/efi.c
index 8a26e705cb06..dfae61f07196 100644
--- a/arch/x86/platform/efi/efi.c
+++ b/arch/x86/platform/efi/efi.c
@@ -844,7 +844,7 @@ static void __init __efi_enter_virtual_mode(void)
 	efi_runtime_update_mappings();
 
 	/* clean DUMMY object */
-	efi_delete_dummy_variable();
+	//efi_delete_dummy_variable();
 	return;
 
 err:


^ permalink raw reply related	[flat|nested] 37+ messages in thread

* Re: [edk2-devel] [PATCH v2 2/6] OvmfPkg/AmdSev: add Grub Firmware Volume Package
  2020-11-25 17:09                         ` James Bottomley
@ 2020-11-25 18:17                           ` James Bottomley
  2020-11-25 19:20                             ` Laszlo Ersek
  2020-11-25 18:35                           ` Laszlo Ersek
  1 sibling, 1 reply; 37+ messages in thread
From: James Bottomley @ 2020-11-25 18:17 UTC (permalink / raw)
  To: Laszlo Ersek, devel, Bret Barkelew, Liming Gao (Byosoft address)
  Cc: dovmurik, Dov.Murik1, ashish.kalra, brijesh.singh, tobin,
	david.kaplan, jon.grimm, thomas.lendacky, frankeh,
	Dr . David Alan Gilbert, Ard Biesheuvel (ARM address)

On Wed, 2020-11-25 at 09:09 -0800, James Bottomley wrote:
> On Wed, 2020-11-25 at 08:02 -0800, James Bottomley wrote:
> > On Wed, 2020-11-25 at 15:01 +0100, Laszlo Ersek wrote:
> > > This upgrade gave me kernel 5.8.18-100.fc31.x86_64 in the guest
> > > --
> > > and this one does *not* crash. From your boot log below, I see
> > > your guest kernel is 5.5.0; I suggest upgrading it.
> > 
> > Heh, that's easier said than done ... I always make my encrypted
> > images too small to upgrade a kernel easily.  Anyway, after doing
> > the remove and add stuff dance, I finally got it upgraded to the
> > latest debian testing linux-image-5.8.0-3 it's still crashing
> > although with a slightly different traceback.  It looks like there
> > might be something additional in the fedora 5.8 kernel that fixes
> > this.  I'm going to try out upstream kernels next.
> 
> I've got the upstream kernel booting through OVMF with a qemu -kernel
> command line.  I also have a fix: it's not to delete the dummy
> variable which was part of the ancient x86 anti bricking code (which
> is also why arm64 doesn't have the problem).

OK, found the problem: the memory the variable policy itself is stored
in doesn't survive into the linux runtime.  It looks to be pretty
generic except you need a way of detecting the boot time memory is
free.  Because Linux does a remapping, we see this.  I'm not sure how
you'd construct a regression test for something like this, though.

I propose this as the fix ... at least it gets my SEV kernels booting
again.

James

---8>8>8><8<8<8----

>From b33aa8bd8ded4c7cfec67c2d5aa5e23271c75f51 Mon Sep 17 00:00:00 2001
From: James Bottomley <James.Bottomley@HansenPartnership.com>
Date: Wed, 25 Nov 2020 10:10:30 -0800
Subject: [PATCH 1/1] VariablePolicyLib: Fix Runtime panic in
 ValidateSetVariable

The current variable policy is allocated by AllocatePool, which is
boot time only.  This means that if you do any variable setting in the
runtime, the policy has been freed.  Ordinarily this isn't detected
because freed memory is still there, but when you boot the Linux
kernel, it's been remapped so the actual memory no longer exists in
the memory map causing a page fault.

Fix this by making it AllocateRuntimePool.

Signed-off-by: James Bottomley <jejb@linux.ibm.com>
---
 MdeModulePkg/Library/VariablePolicyLib/VariablePolicyLib.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/MdeModulePkg/Library/VariablePolicyLib/VariablePolicyLib.c b/MdeModulePkg/Library/VariablePolicyLib/VariablePolicyLib.c
index 5029ddb96adb..12944ac7ea81 100644
--- a/MdeModulePkg/Library/VariablePolicyLib/VariablePolicyLib.c
+++ b/MdeModulePkg/Library/VariablePolicyLib/VariablePolicyLib.c
@@ -411,7 +411,7 @@ RegisterVariablePolicy (
     }
 
     // Reallocate and copy the table.
-    NewTable = AllocatePool( NewSize );
+    NewTable = AllocateRuntimePool( NewSize );
     if (NewTable == NULL) {
       return EFI_OUT_OF_RESOURCES;
     }
-- 
2.26.2



^ permalink raw reply related	[flat|nested] 37+ messages in thread

* Re: [edk2-devel] [PATCH v2 2/6] OvmfPkg/AmdSev: add Grub Firmware Volume Package
  2020-11-25 17:09                         ` James Bottomley
  2020-11-25 18:17                           ` James Bottomley
@ 2020-11-25 18:35                           ` Laszlo Ersek
  2020-11-25 19:08                             ` Laszlo Ersek
  1 sibling, 1 reply; 37+ messages in thread
From: Laszlo Ersek @ 2020-11-25 18:35 UTC (permalink / raw)
  To: jejb, devel, Bret Barkelew, Liming Gao (Byosoft address)
  Cc: dovmurik, Dov.Murik1, ashish.kalra, brijesh.singh, tobin,
	david.kaplan, jon.grimm, thomas.lendacky, frankeh,
	Dr . David Alan Gilbert, Ard Biesheuvel (ARM address)

On 11/25/20 18:09, James Bottomley wrote:
> On Wed, 2020-11-25 at 08:02 -0800, James Bottomley wrote:
>> On Wed, 2020-11-25 at 15:01 +0100, Laszlo Ersek wrote:
>>> This upgrade gave me kernel 5.8.18-100.fc31.x86_64 in the guest --
>>> and this one does *not* crash. From your boot log below, I see your
>>> guest kernel is 5.5.0; I suggest upgrading it.
>>
>> Heh, that's easier said than done ... I always make my encrypted
>> images too small to upgrade a kernel easily.  Anyway, after doing the
>> remove and add stuff dance, I finally got it upgraded to the latest
>> debian testing linux-image-5.8.0-3 it's still crashing although with
>> a slightly different traceback.  It looks like there might be
>> something additional in the fedora 5.8 kernel that fixes this.  I'm
>> going to try out upstream kernels next.
> 
> I've got the upstream kernel booting through OVMF with a qemu -kernel
> command line.  I also have a fix: it's not to delete the dummy variable
> which was part of the ancient x86 anti bricking code (which is also why
> arm64 doesn't have the problem).
> 
> If you remove the set variable in arch/x86/platform/efi/quirks.c:
> 
> /*
>  * Deleting the dummy variable which kicks off garbage collection
> */
> void efi_delete_dummy_variable(void)
> {
> 	efi.set_variable_nonblocking((efi_char16_t *)efi_dummy_name,
> 				     &EFI_DUMMY_GUID,
> 				     EFI_VARIABLE_NON_VOLATILE |
> 				     EFI_VARIABLE_BOOTSERVICE_ACCESS |
> 				     EFI_VARIABLE_RUNTIME_ACCESS, 0, NULL);
> }
> 
> The kernel will boot.  I'm not sure why we have this deletion
> unconditionally in efi_enter_virtual_mode, but removing the call with
> the patch below allows the kernel to boot.

I think commit 2ecb7402cfc7 ("efi/x86: Do not clean dummy variable in
kexec path", 2019-10-07) is related (part of v5.4), but it's not
sufficient to prevent the boot crash. (That removal only covered the
kexec path, and not the normal boot path.)

> 
> However, once the kernel has booted, any attempt to write to an EFI
> variable results in this:
> 
> [  975.440240] [Firmware Bug]: Page fault caused by firmware at PA: 0x7e450020
> 
> And then the efi runtime gets disabled.

Blech, that doesn't look good. We still get a page fault somewhere in
the firmware, it just doesn't kill the kernel outright. That kind of
suggests the crash on the boot path *is* firmware-originated, it's just
that the kernel is unable to mask the problem that early.

OK, I'll try to look into this more closely... In such cases, I
generally reproduce the guest kernel crash, and while the guest is in
that crashed state, I use

$ virsh dump ovmf.fedora vmcore --memory-only --format kdump-lzo

Then, I force off the VM.

Next, install the "kernel-debuginfo" and "kernel-debuginfo-common"
packages matching the crashed guest kernel.

Finally, run the "crash" utility on the vmcore, to poke around in the
vmcore. "crash" is very powerful, I hope it turns up something...


BTW, the Fedora 5.8.18-100.fc31 kernel does carry like 71 broken-out
extra patches in the SRPM, as far as I can tell...

Thanks
Laszlo


> 
> James
> 
> ---
> 
> diff --git a/arch/x86/platform/efi/efi.c b/arch/x86/platform/efi/efi.c
> index 8a26e705cb06..dfae61f07196 100644
> --- a/arch/x86/platform/efi/efi.c
> +++ b/arch/x86/platform/efi/efi.c
> @@ -844,7 +844,7 @@ static void __init __efi_enter_virtual_mode(void)
>  	efi_runtime_update_mappings();
>  
>  	/* clean DUMMY object */
> -	efi_delete_dummy_variable();
> +	//efi_delete_dummy_variable();
>  	return;
>  
>  err:
> 


^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [edk2-devel] [PATCH v2 2/6] OvmfPkg/AmdSev: add Grub Firmware Volume Package
  2020-11-25 18:35                           ` Laszlo Ersek
@ 2020-11-25 19:08                             ` Laszlo Ersek
  2020-11-25 19:14                               ` Laszlo Ersek
  0 siblings, 1 reply; 37+ messages in thread
From: Laszlo Ersek @ 2020-11-25 19:08 UTC (permalink / raw)
  To: jejb, devel, Bret Barkelew, Liming Gao (Byosoft address)
  Cc: dovmurik, Dov.Murik1, ashish.kalra, brijesh.singh, tobin,
	david.kaplan, jon.grimm, thomas.lendacky, frankeh,
	Dr . David Alan Gilbert, Ard Biesheuvel (ARM address)

On 11/25/20 19:35, Laszlo Ersek wrote:
> On 11/25/20 18:09, James Bottomley wrote:
>> On Wed, 2020-11-25 at 08:02 -0800, James Bottomley wrote:
>>> On Wed, 2020-11-25 at 15:01 +0100, Laszlo Ersek wrote:
>>>> This upgrade gave me kernel 5.8.18-100.fc31.x86_64 in the guest --
>>>> and this one does *not* crash. From your boot log below, I see your
>>>> guest kernel is 5.5.0; I suggest upgrading it.
>>>
>>> Heh, that's easier said than done ... I always make my encrypted
>>> images too small to upgrade a kernel easily.  Anyway, after doing the
>>> remove and add stuff dance, I finally got it upgraded to the latest
>>> debian testing linux-image-5.8.0-3 it's still crashing although with
>>> a slightly different traceback.  It looks like there might be
>>> something additional in the fedora 5.8 kernel that fixes this.  I'm
>>> going to try out upstream kernels next.
>>
>> I've got the upstream kernel booting through OVMF with a qemu -kernel
>> command line.  I also have a fix: it's not to delete the dummy variable
>> which was part of the ancient x86 anti bricking code (which is also why
>> arm64 doesn't have the problem).
>>
>> If you remove the set variable in arch/x86/platform/efi/quirks.c:
>>
>> /*
>>  * Deleting the dummy variable which kicks off garbage collection
>> */
>> void efi_delete_dummy_variable(void)
>> {
>> 	efi.set_variable_nonblocking((efi_char16_t *)efi_dummy_name,
>> 				     &EFI_DUMMY_GUID,
>> 				     EFI_VARIABLE_NON_VOLATILE |
>> 				     EFI_VARIABLE_BOOTSERVICE_ACCESS |
>> 				     EFI_VARIABLE_RUNTIME_ACCESS, 0, NULL);
>> }
>>
>> The kernel will boot.  I'm not sure why we have this deletion
>> unconditionally in efi_enter_virtual_mode, but removing the call with
>> the patch below allows the kernel to boot.
> 
> I think commit 2ecb7402cfc7 ("efi/x86: Do not clean dummy variable in
> kexec path", 2019-10-07) is related (part of v5.4), but it's not
> sufficient to prevent the boot crash. (That removal only covered the
> kexec path, and not the normal boot path.)
> 
>>
>> However, once the kernel has booted, any attempt to write to an EFI
>> variable results in this:
>>
>> [  975.440240] [Firmware Bug]: Page fault caused by firmware at PA: 0x7e450020
>>
>> And then the efi runtime gets disabled.
> 
> Blech, that doesn't look good. We still get a page fault somewhere in
> the firmware, it just doesn't kill the kernel outright. That kind of
> suggests the crash on the boot path *is* firmware-originated, it's just
> that the kernel is unable to mask the problem that early.

Actually, I do think we have a bug in the firmware. I need to verify it
(and if verification confirms it, to send a patch for it). Consider the
following snippet in file
"MdeModulePkg/Library/VariablePolicyLib/VariablePolicyLib.c", function
RegisterVariablePolicy():

    // Reallocate and copy the table.
    NewTable = AllocatePool( NewSize );
    if (NewTable == NULL) {
      return EFI_OUT_OF_RESOURCES;
    }
    CopyMem( NewTable, mPolicyTable, mCurrentTableUsage );
    mCurrentTableSize = NewSize;
    if (mPolicyTable != NULL) {
      FreePool( mPolicyTable );
    }
    mPolicyTable = NewTable;


* In the SMM build of OVMF, this code is linked (via
"MdeModulePkg/Library/VariablePolicyLib/VariablePolicyLib.inf") into the
following SMM driver:

  MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmm.inf

For that module (well, for SMM drivers in general), the AllocatePool()
function comes from the following MemoryAllocationLib instance:

  MdePkg/Library/SmmMemoryAllocationLib/SmmMemoryAllocationLib.inf

and so the AllocatePool() call ultimately boils down to allocating *SMRAM*:

  gSmst->SmmAllocatePool()

Which is fine.


* However, in the non-SMM build, the same code snippet is linked (via
"MdeModulePkg/Library/VariablePolicyLib/VariablePolicyLibRuntimeDxe.inf")
into the following driver:

  MdeModulePkg/Universal/Variable/RuntimeDxe/VariableRuntimeDxe.inf

In this module (well, in runtime DXE drivers in general), the
AllocatePool() call function comes from the following
MemoryAllocationLib instance:

  MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAllocationLib.inf

And that is *wrong*. Because there, AllocatePool() allocates Boot
Services Data type memory, via

  gBS->AllocatePool() *plus* "EfiBootServicesData"

Therefore, even though VariablePolicyLibVirtualAddressCallback() in file
"MdeModulePkg/Library/VariablePolicyLib/VariablePolicyExtraInitRuntimeDxe.c"
attempts to convert "mPolicyTable" to a runtime virtual address, in the
SMM-less build, that conversion fails -- the original memory that the
pointer points at, pre-conversion, is not runtime, but boot time memory.


The fix *should be* to call AllocateRuntimePool() from the
MemoryAllocationLib class. In the SMM instance, that will make no
difference; compare, in
"MdePkg/Library/SmmMemoryAllocationLib/MemoryAllocationLib.c":

VOID *
EFIAPI
AllocatePool (
  IN UINTN  AllocationSize
  )
{
  return InternalAllocatePool (EfiRuntimeServicesData, AllocationSize);
}

VOID *
EFIAPI
AllocateRuntimePool (
  IN UINTN  AllocationSize
  )
{
  return InternalAllocatePool (EfiRuntimeServicesData, AllocationSize);
}

The InternalAllocatePool() calls are identical, in the SMM instance.


Whereas in the UEFI instance, in
"MdePkg/Library/UefiMemoryAllocationLib/MemoryAllocationLib.c", it does
make a difference; compare:

VOID *
EFIAPI
AllocatePool (
  IN UINTN  AllocationSize
  )
{
  return InternalAllocatePool (EfiBootServicesData, AllocationSize);
}

VOID *
EFIAPI
AllocateRuntimePool (
  IN UINTN  AllocationSize
  )
{
  return InternalAllocatePool (EfiRuntimeServicesData, AllocationSize);
}

The "MemoryType" parameter of InternalAllocatePool(), which gets
forwarded to gBS->AllocatePool(), changes from "EfiBootServicesData" to
"EfiRuntimeServicesData".

Let me test this.

(BTW I see some more pool allocations in
"MdeModulePkg/Library/VariablePolicyHelperLib" to... I guess I'll have
to check those as well.)

Thanks
Laszlo


^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [edk2-devel] [PATCH v2 2/6] OvmfPkg/AmdSev: add Grub Firmware Volume Package
  2020-11-25 19:08                             ` Laszlo Ersek
@ 2020-11-25 19:14                               ` Laszlo Ersek
  0 siblings, 0 replies; 37+ messages in thread
From: Laszlo Ersek @ 2020-11-25 19:14 UTC (permalink / raw)
  To: jejb, devel, Bret Barkelew, Liming Gao (Byosoft address)
  Cc: dovmurik, Dov.Murik1, ashish.kalra, brijesh.singh, tobin,
	david.kaplan, jon.grimm, thomas.lendacky, frankeh,
	Dr . David Alan Gilbert, Ard Biesheuvel (ARM address)

On 11/25/20 20:08, Laszlo Ersek wrote:

> (BTW I see some more pool allocations in
> "MdeModulePkg/Library/VariablePolicyHelperLib" to... I guess I'll have
> to check those as well.)

The VariablePolicyHelperLib functions should be OK -- they create
VariablePolicy objects on the heap only temporarily, so they can be
copied into "mPolicyTable". Right after these one-off objects get released.

Thanks
Laszlo


^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [edk2-devel] [PATCH v2 2/6] OvmfPkg/AmdSev: add Grub Firmware Volume Package
  2020-11-25 18:17                           ` James Bottomley
@ 2020-11-25 19:20                             ` Laszlo Ersek
  2020-11-25 20:11                               ` James Bottomley
  0 siblings, 1 reply; 37+ messages in thread
From: Laszlo Ersek @ 2020-11-25 19:20 UTC (permalink / raw)
  To: jejb, devel, Bret Barkelew, Liming Gao (Byosoft address)
  Cc: dovmurik, Dov.Murik1, ashish.kalra, brijesh.singh, tobin,
	david.kaplan, jon.grimm, thomas.lendacky, frankeh,
	Dr . David Alan Gilbert, Ard Biesheuvel (ARM address)

On 11/25/20 19:17, James Bottomley wrote:
> On Wed, 2020-11-25 at 09:09 -0800, James Bottomley wrote:
>> On Wed, 2020-11-25 at 08:02 -0800, James Bottomley wrote:
>>> On Wed, 2020-11-25 at 15:01 +0100, Laszlo Ersek wrote:
>>>> This upgrade gave me kernel 5.8.18-100.fc31.x86_64 in the guest
>>>> --
>>>> and this one does *not* crash. From your boot log below, I see
>>>> your guest kernel is 5.5.0; I suggest upgrading it.
>>>
>>> Heh, that's easier said than done ... I always make my encrypted
>>> images too small to upgrade a kernel easily.  Anyway, after doing
>>> the remove and add stuff dance, I finally got it upgraded to the
>>> latest debian testing linux-image-5.8.0-3 it's still crashing
>>> although with a slightly different traceback.  It looks like there
>>> might be something additional in the fedora 5.8 kernel that fixes
>>> this.  I'm going to try out upstream kernels next.
>>
>> I've got the upstream kernel booting through OVMF with a qemu -kernel
>> command line.  I also have a fix: it's not to delete the dummy
>> variable which was part of the ancient x86 anti bricking code (which
>> is also why arm64 doesn't have the problem).
> 
> OK, found the problem: the memory the variable policy itself is stored
> in doesn't survive into the linux runtime.  It looks to be pretty
> generic except you need a way of detecting the boot time memory is
> free.  Because Linux does a remapping, we see this.  I'm not sure how
> you'd construct a regression test for something like this, though.
> 
> I propose this as the fix ... at least it gets my SEV kernels booting
> again.
> 
> James
> 
> ---8>8>8><8<8<8----
> 
> From b33aa8bd8ded4c7cfec67c2d5aa5e23271c75f51 Mon Sep 17 00:00:00 2001
> From: James Bottomley <James.Bottomley@HansenPartnership.com>
> Date: Wed, 25 Nov 2020 10:10:30 -0800
> Subject: [PATCH 1/1] VariablePolicyLib: Fix Runtime panic in
>  ValidateSetVariable
> 
> The current variable policy is allocated by AllocatePool, which is
> boot time only.  This means that if you do any variable setting in the
> runtime, the policy has been freed.  Ordinarily this isn't detected
> because freed memory is still there, but when you boot the Linux
> kernel, it's been remapped so the actual memory no longer exists in
> the memory map causing a page fault.
> 
> Fix this by making it AllocateRuntimePool.
> 
> Signed-off-by: James Bottomley <jejb@linux.ibm.com>
> ---
>  MdeModulePkg/Library/VariablePolicyLib/VariablePolicyLib.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/MdeModulePkg/Library/VariablePolicyLib/VariablePolicyLib.c b/MdeModulePkg/Library/VariablePolicyLib/VariablePolicyLib.c
> index 5029ddb96adb..12944ac7ea81 100644
> --- a/MdeModulePkg/Library/VariablePolicyLib/VariablePolicyLib.c
> +++ b/MdeModulePkg/Library/VariablePolicyLib/VariablePolicyLib.c
> @@ -411,7 +411,7 @@ RegisterVariablePolicy (
>      }
>  
>      // Reallocate and copy the table.
> -    NewTable = AllocatePool( NewSize );
> +    NewTable = AllocateRuntimePool( NewSize );
>      if (NewTable == NULL) {
>        return EFI_OUT_OF_RESOURCES;
>      }
> 

... yes. :)

Since you got to writing this up and testing it first, can you please
file a new TianoCore BZ about the issue (kernel crash log welcome), and
post this patch to edk2-devel stand-alone?

One request for the commit message: right after "Fix this by making it
AllocateRuntimePool", please add:

"For SMM drivers, the platform DSC is responsible for resolving the
MemoryAllocationLib class to the SmmMemoryAllocationLib instance. In the
SmmMemoryAllocationLib instance, AllocatePool() and
AllocateRuntimePool() are implemented identically. Therefore this change
is a no-op when the RegisterVariablePolicy() function is built into an
SMM driver. The fix affects runtime DXE drivers only."

Thanks!
Laszlo


^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [edk2-devel] [PATCH v2 2/6] OvmfPkg/AmdSev: add Grub Firmware Volume Package
  2020-11-25 19:20                             ` Laszlo Ersek
@ 2020-11-25 20:11                               ` James Bottomley
  0 siblings, 0 replies; 37+ messages in thread
From: James Bottomley @ 2020-11-25 20:11 UTC (permalink / raw)
  To: Laszlo Ersek, devel, Bret Barkelew, Liming Gao (Byosoft address)
  Cc: dovmurik, Dov.Murik1, ashish.kalra, brijesh.singh, tobin,
	david.kaplan, jon.grimm, thomas.lendacky, frankeh,
	Dr . David Alan Gilbert, Ard Biesheuvel (ARM address)

On Wed, 2020-11-25 at 20:20 +0100, Laszlo Ersek wrote:
> On 11/25/20 19:17, James Bottomley wrote:
[...]
> > diff --git
> > a/MdeModulePkg/Library/VariablePolicyLib/VariablePolicyLib.c
> > b/MdeModulePkg/Library/VariablePolicyLib/VariablePolicyLib.c
> > index 5029ddb96adb..12944ac7ea81 100644
> > --- a/MdeModulePkg/Library/VariablePolicyLib/VariablePolicyLib.c
> > +++ b/MdeModulePkg/Library/VariablePolicyLib/VariablePolicyLib.c
> > @@ -411,7 +411,7 @@ RegisterVariablePolicy (
> >      }
> >  
> >      // Reallocate and copy the table.
> > -    NewTable = AllocatePool( NewSize );
> > +    NewTable = AllocateRuntimePool( NewSize );
> >      if (NewTable == NULL) {
> >        return EFI_OUT_OF_RESOURCES;
> >      }
> > 
> 
> ... yes. :)
> 
> Since you got to writing this up and testing it first, can you please
> file a new TianoCore BZ about the issue (kernel crash log welcome),
> and post this patch to edk2-devel stand-alone?

OK, done:

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

And about to press send.

> One request for the commit message: right after "Fix this by making
> it AllocateRuntimePool", please add:
> 
> "For SMM drivers, the platform DSC is responsible for resolving the
> MemoryAllocationLib class to the SmmMemoryAllocationLib instance. In
> the SmmMemoryAllocationLib instance, AllocatePool() and
> AllocateRuntimePool() are implemented identically. Therefore this
> change is a no-op when the RegisterVariablePolicy() function is built
> into an SMM driver. The fix affects runtime DXE drivers only."

Added.

James



^ permalink raw reply	[flat|nested] 37+ messages in thread

end of thread, other threads:[~2020-11-25 20:11 UTC | newest]

Thread overview: 37+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2020-11-20 18:45 [PATCH v2 0/6] SEV Encrypted Boot for Ovmf James Bottomley
2020-11-20 18:45 ` [PATCH v2 1/6] OvmfPkg/Amdsev: Base commit to build encrypted boot specific OVMF James Bottomley
2020-11-23 18:01   ` Laszlo Ersek
2020-11-23 23:25     ` James Bottomley
2020-11-23 23:43       ` Laszlo Ersek
2020-11-20 18:45 ` [PATCH v2 2/6] OvmfPkg/AmdSev: add Grub Firmware Volume Package James Bottomley
2020-11-23 21:08   ` Laszlo Ersek
2020-11-24  6:38     ` James Bottomley
2020-11-24  8:23       ` Laszlo Ersek
2020-11-24 14:54         ` Laszlo Ersek
2020-11-24 15:58           ` Laszlo Ersek
2020-11-24 16:22             ` [edk2-devel] " James Bottomley
2020-11-24 23:22               ` Laszlo Ersek
2020-11-24 23:42                 ` James Bottomley
2020-11-25  1:27                   ` James Bottomley
2020-11-25 14:01                     ` Laszlo Ersek
2020-11-25 16:02                       ` James Bottomley
2020-11-25 17:09                         ` James Bottomley
2020-11-25 18:17                           ` James Bottomley
2020-11-25 19:20                             ` Laszlo Ersek
2020-11-25 20:11                               ` James Bottomley
2020-11-25 18:35                           ` Laszlo Ersek
2020-11-25 19:08                             ` Laszlo Ersek
2020-11-25 19:14                               ` Laszlo Ersek
2020-11-20 18:45 ` [PATCH v2 3/6] OvmfPkg: convert ES Reset Block structure to be guided James Bottomley
2020-11-23 22:16   ` Laszlo Ersek
2020-11-24 14:57     ` Lendacky, Thomas
2020-11-24 19:07       ` James Bottomley
2020-11-24 23:19         ` Laszlo Ersek
2020-11-24 19:05     ` James Bottomley
2020-11-24 23:15       ` Laszlo Ersek
2020-11-20 18:45 ` [PATCH v2 4/6] OvmfPkg: create a SEV secret area in the AmdSev memfd James Bottomley
2020-11-23 22:28   ` Laszlo Ersek
2020-11-20 18:45 ` [PATCH v2 5/6] OvmfPkg/AmdSev: assign and protect the Sev Secret area James Bottomley
2020-11-23 22:38   ` Laszlo Ersek
2020-11-20 18:45 ` [PATCH v2 6/6] OvmfPkg/AmdSev: Expose the Sev Secret area using a configuration table James Bottomley
2020-11-23 22:56   ` Laszlo Ersek

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox