Date   

[PATCH edk2-platforms v3 1/4] SbsaQemu: Build infrastructure for StandaloneMm image

Masahisa Kojima
 

Add the build infrastructure for compilation of StandaloneMm image.
SbsaQemu.fdf is modified to extend the FLASH0 region enough big to
contain StandaloneMM image(BL32).

Signed-off-by: Masahisa Kojima <masahisa.kojima@...>
---
Platform/Qemu/SbsaQemu/SbsaQemuStandaloneMm.dsc | 132 ++++++++++++++++++++
Platform/Qemu/SbsaQemu/SbsaQemu.fdf | 6 +-
Platform/Qemu/SbsaQemu/SbsaQemuStandaloneMm.fdf | 93 ++++++++++++++
3 files changed, 228 insertions(+), 3 deletions(-)

diff --git a/Platform/Qemu/SbsaQemu/SbsaQemuStandaloneMm.dsc b/Platform/Qemu/SbsaQemu/SbsaQemuStandaloneMm.dsc
new file mode 100644
index 000000000000..87f5ee351eaa
--- /dev/null
+++ b/Platform/Qemu/SbsaQemu/SbsaQemuStandaloneMm.dsc
@@ -0,0 +1,132 @@
+#
+# Copyright (c) 2020, Linaro Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+
+################################################################################
+#
+# Defines Section - statements that will be processed to create a Makefile.
+#
+################################################################################
+[Defines]
+ PLATFORM_NAME = SbsaQemuStandaloneMm
+ PLATFORM_GUID = A64CC0F5-7ACD-4975-BBE7-7EF6739C8668
+ PLATFORM_VERSION = 1.0
+ DSC_SPECIFICATION = 0x00010011
+ OUTPUT_DIRECTORY = Build/$(PLATFORM_NAME)
+ SUPPORTED_ARCHITECTURES = AARCH64
+ BUILD_TARGETS = DEBUG|RELEASE|NOOPT
+ SKUID_IDENTIFIER = DEFAULT
+ FLASH_DEFINITION = Platform/Qemu/SbsaQemu/SbsaQemuStandaloneMm.fdf
+ DEFINE DEBUG_MESSAGE = TRUE
+
+ # LzmaF86
+ DEFINE COMPRESSION_TOOL_GUID = D42AE6BD-1352-4bfb-909A-CA72A6EAE889
+
+################################################################################
+#
+# Library Class section - list of all Library Classes needed by this Platform.
+#
+################################################################################
+[LibraryClasses]
+ #
+ # Basic
+ #
+ BaseLib|MdePkg/Library/BaseLib/BaseLib.inf
+ BaseMemoryLib|MdePkg/Library/BaseMemoryLib/BaseMemoryLib.inf
+ DebugLib|MdePkg/Library/BaseDebugLibSerialPort/BaseDebugLibSerialPort.inf
+ DebugPrintErrorLevelLib|MdePkg/Library/BaseDebugPrintErrorLevelLib/BaseDebugPrintErrorLevelLib.inf
+ ExtractGuidedSectionLib|EmbeddedPkg/Library/PrePiExtractGuidedSectionLib/PrePiExtractGuidedSectionLib.inf
+ FvLib|StandaloneMmPkg/Library/FvLib/FvLib.inf
+ HobLib|StandaloneMmPkg/Library/StandaloneMmCoreHobLib/StandaloneMmCoreHobLib.inf
+ IoLib|MdePkg/Library/BaseIoLibIntrinsic/BaseIoLibIntrinsic.inf
+ MemLib|StandaloneMmPkg/Library/StandaloneMmMemLib/StandaloneMmMemLib.inf
+ MemoryAllocationLib|StandaloneMmPkg/Library/StandaloneMmCoreMemoryAllocationLib/StandaloneMmCoreMemoryAllocationLib.inf
+ PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf
+ PeCoffLib|MdePkg/Library/BasePeCoffLib/BasePeCoffLib.inf
+ PrintLib|MdePkg/Library/BasePrintLib/BasePrintLib.inf
+ ReportStatusCodeLib|MdePkg/Library/BaseReportStatusCodeLibNull/BaseReportStatusCodeLibNull.inf
+
+ #
+ # Entry point
+ #
+ StandaloneMmDriverEntryPoint|MdePkg/Library/StandaloneMmDriverEntryPoint/StandaloneMmDriverEntryPoint.inf
+
+ ArmLib|ArmPkg/Library/ArmLib/ArmBaseLib.inf
+ StandaloneMmMmuLib|ArmPkg/Library/StandaloneMmMmuLib/ArmMmuStandaloneMmLib.inf
+ ArmSvcLib|ArmPkg/Library/ArmSvcLib/ArmSvcLib.inf
+ CacheMaintenanceLib|ArmPkg/Library/ArmCacheMaintenanceLib/ArmCacheMaintenanceLib.inf
+ PeCoffExtraActionLib|StandaloneMmPkg/Library/StandaloneMmPeCoffExtraActionLib/StandaloneMmPeCoffExtraActionLib.inf
+
+ # ARM PL011 UART Driver
+ PL011UartClockLib|ArmPlatformPkg/Library/PL011UartClockLib/PL011UartClockLib.inf
+ PL011UartLib|ArmPlatformPkg/Library/PL011UartLib/PL011UartLib.inf
+ SerialPortLib|ArmPlatformPkg/Library/PL011SerialPortLib/PL011SerialPortLib.inf
+
+ StandaloneMmCoreEntryPoint|StandaloneMmPkg/Library/StandaloneMmCoreEntryPoint/StandaloneMmCoreEntryPoint.inf
+
+ #
+ # It is not possible to prevent the ARM compiler for generic intrinsic functions.
+ # This library provides the instrinsic functions generate by a given compiler.
+ # And NULL mean link this library into all ARM images.
+ #
+ NULL|ArmPkg/Library/CompilerIntrinsicsLib/CompilerIntrinsicsLib.inf
+
+[LibraryClasses.common.MM_STANDALONE]
+ HobLib|StandaloneMmPkg/Library/StandaloneMmHobLib/StandaloneMmHobLib.inf
+ MmServicesTableLib|MdePkg/Library/StandaloneMmServicesTableLib/StandaloneMmServicesTableLib.inf
+ MemoryAllocationLib|StandaloneMmPkg/Library/StandaloneMmMemoryAllocationLib/StandaloneMmMemoryAllocationLib.inf
+
+################################################################################
+#
+# Pcd Section - list of all EDK II PCD Entries defined by this Platform
+#
+################################################################################
+[PcdsFixedAtBuild]
+ gEfiMdePkgTokenSpaceGuid.PcdDebugPrintErrorLevel|0x800000CF
+ gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask|0xff
+ gEfiMdePkgTokenSpaceGuid.PcdReportStatusCodePropertyMask|0x0f
+
+ ## PL011 - Serial Terminal
+ gEfiMdeModulePkgTokenSpaceGuid.PcdSerialRegisterBase|0x60040000
+ gEfiMdePkgTokenSpaceGuid.PcdUartDefaultBaudRate|115200
+
+ gEfiMdePkgTokenSpaceGuid.PcdMaximumGuidedExtractHandler|0x2
+
+###################################################################################################
+#
+# Components Section - list of the modules and components that will be processed by compilation
+# tools and the EDK II tools to generate PE32/PE32+/Coff image files.
+#
+# Note: The EDK II DSC file is not used to specify how compiled binary images get placed
+# into firmware volume images. This section is just a list of modules to compile from
+# source into UEFI-compliant binaries.
+# It is the FDF file that contains information on combining binary files into firmware
+# volume images, whose concept is beyond UEFI and is described in PI specification.
+# Binary modules do not need to be listed in this section, as they should be
+# specified in the FDF file. For example: Shell binary (Shell_Full.efi), FAT binary (Fat.efi),
+# Logo (Logo.bmp), and etc.
+# There may also be modules listed in this section that are not required in the FDF file,
+# When a module listed here is excluded from FDF file, then UEFI-compliant binary will be
+# generated for it, but the binary will not be put into any firmware volume.
+#
+###################################################################################################
+[Components.common]
+ #
+ # MM Core
+ #
+ StandaloneMmPkg/Core/StandaloneMmCore.inf
+ StandaloneMmPkg/Drivers/StandaloneMmCpu/AArch64/StandaloneMmCpu.inf
+
+###################################################################################################
+#
+# BuildOptions Section - Define the module specific tool chain flags that should be used as
+# the default flags for a module. These flags are appended to any
+# standard flags that are defined by the build process. They can be
+# applied for any modules or only those modules with the specific
+# module style (EDK or EDKII) specified in [Components] section.
+#
+###################################################################################################
+[BuildOptions.AARCH64]
+ GCC:*_*_*_DLINK_FLAGS = -z common-page-size=0x1000 -march=armv8-a+nofp
diff --git a/Platform/Qemu/SbsaQemu/SbsaQemu.fdf b/Platform/Qemu/SbsaQemu/SbsaQemu.fdf
index c35e3ed44054..b61ae1891233 100644
--- a/Platform/Qemu/SbsaQemu/SbsaQemu.fdf
+++ b/Platform/Qemu/SbsaQemu/SbsaQemu.fdf
@@ -21,10 +21,10 @@

[FD.SBSA_FLASH0]
BaseAddress = 0x00000000
-Size = 0x00200000
+Size = 0x00400000
ErasePolarity = 1
BlockSize = 0x00001000
-NumBlocks = 0x200
+NumBlocks = 0x400

################################################################################
#
@@ -47,7 +47,7 @@ [FD.SBSA_FLASH0]
FILE = Platform/Qemu/Sbsa/bl1.bin

# and FIP (BL2 + BL31)
-0x00008000|0x00020000
+0x00008000|0x00300000
FILE = Platform/Qemu/Sbsa/fip.bin

################################################################################
diff --git a/Platform/Qemu/SbsaQemu/SbsaQemuStandaloneMm.fdf b/Platform/Qemu/SbsaQemu/SbsaQemuStandaloneMm.fdf
new file mode 100644
index 000000000000..a1acefcfb0a7
--- /dev/null
+++ b/Platform/Qemu/SbsaQemu/SbsaQemuStandaloneMm.fdf
@@ -0,0 +1,93 @@
+#
+# Copyright (c) 2020, Linaro Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+
+################################################################################
+#
+# FD Section
+# The [FD] Section is made up of the definition statements and a
+# description of what goes into the Flash Device Image. Each FD section
+# defines one flash "device" image. A flash device image may be one of
+# the following: Removable media bootable image (like a boot floppy
+# image,) an Option ROM image (that would be "flashed" into an add-in
+# card,) a System "Flash" image (that would be burned into a system's
+# flash) or an Update ("Capsule") image that will be used to update and
+# existing system flash.
+#
+################################################################################
+
+[FD.STANDALONE_MM]
+BaseAddress = 0x20001000|gArmTokenSpaceGuid.PcdFdBaseAddress
+Size = 0x00e00000|gArmTokenSpaceGuid.PcdFdSize # The size in bytes of the device (14MiB).
+ErasePolarity = 1
+
+BlockSize = 0x00001000
+NumBlocks = 0x0e00
+
+0x00000000|0x00280000
+gArmTokenSpaceGuid.PcdFvBaseAddress|gArmTokenSpaceGuid.PcdFvSize
+FV = FVMAIN_COMPACT
+
+[FV.FVMAIN_COMPACT]
+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
+
+ INF StandaloneMmPkg/Core/StandaloneMmCore.inf
+ INF StandaloneMmPkg/Drivers/StandaloneMmCpu/AArch64/StandaloneMmCpu.inf
+
+################################################################################
+#
+# Rules are use with the [FV] section's module INF type to define
+# how an FFS file is created for a given INF file. The following Rule are the default
+# rules for the different module type. User can add the customized rules to define the
+# content of the FFS file.
+#
+################################################################################
+
+
+############################################################################
+# Example of a DXE_DRIVER FFS file with a Checksum encapsulation section #
+############################################################################
+#
+#[Rule.Common.DXE_DRIVER]
+# FILE DRIVER = $(NAMED_GUID) {
+# DXE_DEPEX DXE_DEPEX Optional $(INF_OUTPUT)/$(MODULE_NAME).depex
+# COMPRESS PI_STD {
+# GUIDED {
+# PE32 PE32 $(INF_OUTPUT)/$(MODULE_NAME).efi
+# UI STRING="$(MODULE_NAME)" Optional
+# VERSION STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER)
+# }
+# }
+# }
+#
+############################################################################
+
+[Rule.Common.MM_CORE_STANDALONE]
+ FILE SEC = $(NAMED_GUID) RELOCS_STRIPPED FIXED {
+ PE32 PE32 Align = Auto $(INF_OUTPUT)/$(MODULE_NAME).efi
+ }
+
+[Rule.Common.MM_STANDALONE]
+ FILE MM_STANDALONE = $(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.17.1


[PATCH edk2-platforms v3 0/4] add MM based UEFI secure boot on SbsaQemu

Masahisa Kojima
 

This patch series implment the UEFI secure boot on SbsaQemu.

Cc: Ard Biesheuvel <ardb+tianocore@...>
Cc: Leif Lindholm <leif@...>
Cc: Graeme Gregory <graeme@...>
Cc: Radoslaw Biernacki <rad@...>
Cc: Shashi Mallela <shashi.mallela@...>

v3:
- create device-tree parsing helper functions
- update the .dsc file layout to minimize the modification
- remove unnesessary blank line updates

v2:
- get aligned to the tf-a update, it supports 512 cores
and memory map is updated.

Masahisa Kojima (4):
SbsaQemu: Build infrastructure for StandaloneMm image
SbsaQemu: add MM based UEFI secure boot support
SbsaQemu: add standalone MM build instruction
SbsaQemu: fix typo

Platform/Qemu/SbsaQemu/SbsaQemu.dsc | 25 ++-
.../Qemu/SbsaQemu/SbsaQemuStandaloneMm.dsc | 171 ++++++++++++++++++
Platform/Qemu/SbsaQemu/SbsaQemu.fdf | 83 ++++++++-
.../Qemu/SbsaQemu/SbsaQemuStandaloneMm.fdf | 96 ++++++++++
.../Library/SbsaQemuLib/SbsaQemuLib.inf | 3 +
.../SbsaQemu/Include/Library/FdtHelperLib.h | 27 +++
.../Library/FdtHelperLib/FdtHelperLib.c | 111 ++++++++++++
.../Library/SbsaQemuLib/SbsaQemuMem.c | 55 ++----
Platform/Qemu/SbsaQemu/Readme.md | 37 +++-
9 files changed, 554 insertions(+), 54 deletions(-)
create mode 100644 Platform/Qemu/SbsaQemu/SbsaQemuStandaloneMm.dsc
create mode 100644 Platform/Qemu/SbsaQemu/SbsaQemuStandaloneMm.fdf

--
2.17.1


Re: [PATCH edk2-platforms v2 2/4] SbsaQemu: add MM based UEFI secure boot support

Masahisa Kojima
 

On Tue, 2 Mar 2021 at 02:22, Leif Lindholm <leif@...> wrote:

On Mon, Mar 01, 2021 at 14:19:50 +0900, Masahisa Kojima wrote:
This implements support for UEFI secure boot on SbsaQemu using
the standalone MM framework. This moves all of the software handling
of the UEFI authenticated variable store into the standalone MM
context residing in a secure partition.

Secure variable storage is located at 0x01000000 in secure NOR Flash.

Non-secure shared memory between UEFI and standalone MM
is allocated at the top of DRAM.
DRAM size of SbsaQemu varies depends on the QEMU parameter,
the non-secure shared memory base address is passed from
trusted-firmware through the device tree "/reserved-memory" node.

Signed-off-by: Masahisa Kojima <masahisa.kojima@...>
---
Platform/Qemu/SbsaQemu/SbsaQemu.dsc | 43 +++++++---
.../Qemu/SbsaQemu/SbsaQemuStandaloneMm.dsc | 39 +++++++++
Platform/Qemu/SbsaQemu/SbsaQemu.fdf | 82 +++++++++++++++++--
.../Qemu/SbsaQemu/SbsaQemuStandaloneMm.fdf | 7 +-
.../Library/SbsaQemuLib/SbsaQemuLib.inf | 2 +
.../Library/SbsaQemuLib/SbsaQemuMem.c | 37 ++++++++-
6 files changed, 190 insertions(+), 20 deletions(-)

diff --git a/Platform/Qemu/SbsaQemu/SbsaQemu.dsc b/Platform/Qemu/SbsaQemu/SbsaQemu.dsc
index c1f8a4696560..a75116ee70fc 100644
--- a/Platform/Qemu/SbsaQemu/SbsaQemu.dsc
+++ b/Platform/Qemu/SbsaQemu/SbsaQemu.dsc
@@ -28,6 +28,8 @@ [Defines]

DEFINE DEBUG_PRINT_ERROR_LEVEL = 0x8000004F

+ DEFINE SECURE_BOOT_ENABLE = FALSE
+
#
# Network definition
#
@@ -152,12 +154,10 @@ [LibraryClasses.common]
# Secure Boot dependencies
#
TpmMeasurementLib|SecurityPkg/Library/DxeTpmMeasurementLib/DxeTpmMeasurementLib.inf
- AuthVariableLib|SecurityPkg/Library/AuthVariableLib/AuthVariableLib.inf

# re-use the UserPhysicalPresent() dummy implementation from the ovmf tree
PlatformSecureLib|OvmfPkg/Library/PlatformSecureLib/PlatformSecureLib.inf

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

@@ -171,6 +171,7 @@ [LibraryClasses.common]
ArmPlatformLib|ArmPlatformPkg/Library/ArmPlatformLibNull/ArmPlatformLibNull.inf

TimerLib|ArmPkg/Library/ArmArchTimerLib/ArmArchTimerLib.inf
+
This blank line is added for no apparent reason.

NorFlashPlatformLib|Silicon/Qemu/SbsaQemu/Library/SbsaQemuNorFlashLib/SbsaQemuNorFlashLib.inf

CapsuleLib|MdeModulePkg/Library/DxeCapsuleLibNull/DxeCapsuleLibNull.inf
@@ -300,6 +301,8 @@ [PcdsFeatureFlag.common]
gEfiMdeModulePkgTokenSpaceGuid.PcdConOutGopSupport|TRUE
gEfiMdeModulePkgTokenSpaceGuid.PcdConOutUgaSupport|FALSE

+ gEfiMdeModulePkgTokenSpaceGuid.PcdEnableVariableRuntimeCache|FALSE
+
[PcdsFixedAtBuild.common]
gEfiMdePkgTokenSpaceGuid.PcdMaximumUnicodeStringLength|1000000
gEfiMdePkgTokenSpaceGuid.PcdMaximumAsciiStringLength|1000000
@@ -551,6 +554,9 @@ [PcdsDynamicDefault.common]
gArmVirtSbsaQemuPlatformTokenSpaceGuid.PcdChassisAssetTag|L"AT0000"
gArmVirtSbsaQemuPlatformTokenSpaceGuid.PcdChassisSKU|L"SK0000"

+ gArmTokenSpaceGuid.PcdMmBufferBase|0x10000000000
+ gArmTokenSpaceGuid.PcdMmBufferSize|0x00200000
+
################################################################################
#
# Components Section - list of all EDK II Modules needed by this Platform
@@ -604,7 +610,6 @@ [Components.common]
ArmPlatformPkg/MemoryInitPei/MemoryInitPeim.inf
ArmPkg/Drivers/CpuPei/CpuPei.inf

-
MdeModulePkg/Core/DxeIplPeim/DxeIpl.inf {
<LibraryClasses>
NULL|MdeModulePkg/Library/LzmaCustomDecompressLib/LzmaCustomDecompressLib.inf
@@ -628,24 +633,40 @@ [Components.common]
#
ArmPkg/Drivers/CpuDxe/CpuDxe.inf
MdeModulePkg/Core/RuntimeDxe/RuntimeDxe.inf
- MdeModulePkg/Universal/Variable/RuntimeDxe/VariableRuntimeDxe.inf {
- <LibraryClasses>
- NULL|MdeModulePkg/Library/VarCheckUefiLib/VarCheckUefiLib.inf
- # don't use unaligned CopyMem () on the UEFI varstore NOR flash region
- BaseMemoryLib|MdePkg/Library/BaseMemoryLib/BaseMemoryLib.inf
- }
MdeModulePkg/Universal/SecurityStubDxe/SecurityStubDxe.inf {
<LibraryClasses>
+!if $(SECURE_BOOT_ENABLE) == TRUE
NULL|SecurityPkg/Library/DxeImageVerificationLib/DxeImageVerificationLib.inf
+!endif
}
- SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigDxe.inf
MdeModulePkg/Universal/CapsuleRuntimeDxe/CapsuleRuntimeDxe.inf
- MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteDxe.inf
MdeModulePkg/Universal/MonotonicCounterRuntimeDxe/MonotonicCounterRuntimeDxe.inf
MdeModulePkg/Universal/ResetSystemRuntimeDxe/ResetSystemRuntimeDxe.inf
EmbeddedPkg/RealTimeClockRuntimeDxe/RealTimeClockRuntimeDxe.inf
EmbeddedPkg/MetronomeDxe/MetronomeDxe.inf

+ #
+ # Variable services
+ #
+!if $(SECURE_BOOT_ENABLE) == FALSE
+ MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteDxe.inf
+ MdeModulePkg/Universal/Variable/RuntimeDxe/VariableRuntimeDxe.inf {
+ <LibraryClasses>
+ NULL|MdeModulePkg/Library/VarCheckUefiLib/VarCheckUefiLib.inf
+ AuthVariableLib|MdeModulePkg/Library/AuthVariableLibNull/AuthVariableLibNull.inf
+ VarCheckLib|MdeModulePkg/Library/VarCheckLib/VarCheckLib.inf
+ # don't use unaligned CopyMem () on the UEFI varstore NOR flash region
+ BaseMemoryLib|MdePkg/Library/BaseMemoryLib/BaseMemoryLib.inf
Would this diff be neater if this if statement moved up to the
original location of the
MdeModulePkg/Universal/Variable/RuntimeDxe/VariableRuntimeDxe.inf {
stanza?

+ }
+!else
+ ArmPkg/Drivers/MmCommunicationDxe/MmCommunication.inf {
+ <LibraryClasses>
+ NULL|StandaloneMmPkg/Library/VariableMmDependency/VariableMmDependency.inf
+ }
+ MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmmRuntimeDxe.inf
+ SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigDxe.inf
+!endif
+
MdeModulePkg/Universal/Console/ConPlatformDxe/ConPlatformDxe.inf
MdeModulePkg/Universal/Console/ConSplitterDxe/ConSplitterDxe.inf
MdeModulePkg/Universal/Console/GraphicsConsoleDxe/GraphicsConsoleDxe.inf
diff --git a/Platform/Qemu/SbsaQemu/SbsaQemuStandaloneMm.dsc b/Platform/Qemu/SbsaQemu/SbsaQemuStandaloneMm.dsc
index 87f5ee351eaa..b80379acd1ad 100644
--- a/Platform/Qemu/SbsaQemu/SbsaQemuStandaloneMm.dsc
+++ b/Platform/Qemu/SbsaQemu/SbsaQemuStandaloneMm.dsc
@@ -77,6 +77,18 @@ [LibraryClasses.common.MM_STANDALONE]
HobLib|StandaloneMmPkg/Library/StandaloneMmHobLib/StandaloneMmHobLib.inf
MmServicesTableLib|MdePkg/Library/StandaloneMmServicesTableLib/StandaloneMmServicesTableLib.inf
MemoryAllocationLib|StandaloneMmPkg/Library/StandaloneMmMemoryAllocationLib/StandaloneMmMemoryAllocationLib.inf
+ AuthVariableLib|SecurityPkg/Library/AuthVariableLib/AuthVariableLib.inf
+ BaseCryptLib|CryptoPkg/Library/BaseCryptLib/SmmCryptLib.inf
+ IntrinsicLib|CryptoPkg/Library/IntrinsicLib/IntrinsicLib.inf
+ NorFlashPlatformLib|Silicon/Qemu/SbsaQemu/Library/SbsaQemuNorFlashLib/SbsaQemuNorFlashLib.inf
+ OpensslLib|CryptoPkg/Library/OpensslLib/OpensslLib.inf
+ RngLib|MdePkg/Library/BaseRngLibTimerLib/BaseRngLibTimerLib.inf
+ PlatformSecureLib|SecurityPkg/Library/PlatformSecureLibNull/PlatformSecureLibNull.inf
+ SynchronizationLib|MdePkg/Library/BaseSynchronizationLib/BaseSynchronizationLib.inf
+ TimerLib|ArmPkg/Library/ArmArchTimerLib/ArmArchTimerLib.inf
+ VarCheckLib|MdeModulePkg/Library/VarCheckLib/VarCheckLib.inf
+ SafeIntLib|MdePkg/Library/BaseSafeIntLib/BaseSafeIntLib.inf
+ ArmGenericTimerCounterLib|ArmPkg/Library/ArmGenericTimerPhyCounterLib/ArmGenericTimerPhyCounterLib.inf

################################################################################
#
@@ -94,6 +106,20 @@ [PcdsFixedAtBuild]

gEfiMdePkgTokenSpaceGuid.PcdMaximumGuidedExtractHandler|0x2

+ gArmTokenSpaceGuid.PcdFdBaseAddress|0x01000000
+ gArmTokenSpaceGuid.PcdFdSize|0x000C0000
+
+ gEfiMdeModulePkgTokenSpaceGuid.PcdMaxVariableSize|0x2000
+ gEfiSecurityPkgTokenSpaceGuid.PcdUserPhysicalPresence|TRUE
+ gEfiMdeModulePkgTokenSpaceGuid.PcdMaxAuthVariableSize|0x2800
+
+ gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableBase|0x01000000
+ gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableSize|0x00040000
+ gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingBase|0x01040000
+ gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingSize|0x00040000
+ gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareBase|0x01080000
+ gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareSize|0x00040000
+
###################################################################################################
#
# Components Section - list of the modules and components that will be processed by compilation
@@ -118,6 +144,19 @@ [Components.common]
#
StandaloneMmPkg/Core/StandaloneMmCore.inf
StandaloneMmPkg/Drivers/StandaloneMmCpu/AArch64/StandaloneMmCpu.inf
+ ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashStandaloneMm.inf
+ MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteStandaloneMm.inf
+
+ MdeModulePkg/Universal/Variable/RuntimeDxe/VariableStandaloneMm.inf {
+ <LibraryClasses>
+ DevicePathLib|MdePkg/Library/UefiDevicePathLib/UefiDevicePathLib.inf
+ NULL|MdeModulePkg/Library/VarCheckUefiLib/VarCheckUefiLib.inf
+ NULL|MdeModulePkg/Library/VarCheckPolicyLib/VarCheckPolicyLibStandaloneMm.inf
+ # don't use unaligned CopyMem () on the UEFI varstore NOR flash region
+ BaseMemoryLib|MdePkg/Library/BaseMemoryLib/BaseMemoryLib.inf
+ VariablePolicyLib|MdeModulePkg/Library/VariablePolicyLib/VariablePolicyLib.inf
+ VariablePolicyHelperLib|MdeModulePkg/Library/VariablePolicyHelperLib/VariablePolicyHelperLib.inf
+ }

###################################################################################################
#
diff --git a/Platform/Qemu/SbsaQemu/SbsaQemu.fdf b/Platform/Qemu/SbsaQemu/SbsaQemu.fdf
index b61ae1891233..a46a47063ccc 100644
--- a/Platform/Qemu/SbsaQemu/SbsaQemu.fdf
+++ b/Platform/Qemu/SbsaQemu/SbsaQemu.fdf
@@ -21,10 +21,10 @@

[FD.SBSA_FLASH0]
BaseAddress = 0x00000000
-Size = 0x00400000
+Size = 0x01100000
ErasePolarity = 1
BlockSize = 0x00001000
-NumBlocks = 0x400
+NumBlocks = 0x1100

################################################################################
#
@@ -50,6 +50,66 @@ [FD.SBSA_FLASH0]
0x00008000|0x00300000
FILE = Platform/Qemu/Sbsa/fip.bin

+!if $(SECURE_BOOT_ENABLE)
+## Place for Secure Variables.
+# Must be aligned to Flash Block size 0x40000
+0x01000000|0x00040000
+gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableBase|gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableSize
+#NV_VARIABLE_STORE
+DATA = {
+ ## This is the EFI_FIRMWARE_VOLUME_HEADER
+ # ZeroVector []
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ # FileSystemGuid: gEfiSystemNvDataFvGuid =
+ # { 0xFFF12B8D, 0x7696, 0x4C8B,
+ # { 0xA9, 0x85, 0x27, 0x47, 0x07, 0x5B, 0x4F, 0x50 }}
+ 0x8D, 0x2B, 0xF1, 0xFF, 0x96, 0x76, 0x8B, 0x4C,
+ 0xA9, 0x85, 0x27, 0x47, 0x07, 0x5B, 0x4F, 0x50,
+ # FvLength: 0xC0000
+ 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00,
+ # Signature "_FVH" # Attributes
+ 0x5f, 0x46, 0x56, 0x48, 0xff, 0xfe, 0x04, 0x00,
+ # HeaderLength # CheckSum # ExtHeaderOffset #Reserved #Revision
+ 0x48, 0x00, 0x28, 0x09, 0x00, 0x00, 0x00, 0x02,
+ # Blockmap[0]: 0x3 Blocks * 0x40000 Bytes / Block
+ 0x3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00,
+ # Blockmap[1]: End
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ ## This is the VARIABLE_STORE_HEADER
+ # It is compatible with SECURE_BOOT_ENABLE == FALSE as well.
+ # Signature: gEfiAuthenticatedVariableGuid =
+ # { 0xaaf32c78, 0x947b, 0x439a,
+ # { 0xa1, 0x80, 0x2e, 0x14, 0x4e, 0xc3, 0x77, 0x92 }}
+ 0x78, 0x2c, 0xf3, 0xaa, 0x7b, 0x94, 0x9a, 0x43,
+ 0xa1, 0x80, 0x2e, 0x14, 0x4e, 0xc3, 0x77, 0x92,
+ # Size: 0x40000 (gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableSize) -
+ # 0x48 (size of EFI_FIRMWARE_VOLUME_HEADER) = 0x3ffb8
+ # This can speed up the Variable Dispatch a bit.
+ 0xB8, 0xFF, 0x03, 0x00,
+ # FORMATTED: 0x5A #HEALTHY: 0xFE #Reserved: UINT16 #Reserved1: UINT32
+ 0x5A, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+}
+
+0x01040000|0x00040000
+gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingBase|gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingSize
+#NV_FTW_WORKING
+DATA = {
+ # EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER->Signature = gEdkiiWorkingBlockSignatureGuid =
+ # { 0x9e58292b, 0x7c68, 0x497d, { 0xa0, 0xce, 0x65, 0x0, 0xfd, 0x9f, 0x1b, 0x95 }}
+ 0x2b, 0x29, 0x58, 0x9e, 0x68, 0x7c, 0x7d, 0x49,
+ 0xa0, 0xce, 0x65, 0x0, 0xfd, 0x9f, 0x1b, 0x95,
+ # Crc:UINT32 #WorkingBlockValid:1, WorkingBlockInvalid:1, Reserved
+ 0x5b, 0xe7, 0xc6, 0x86, 0xFE, 0xFF, 0xFF, 0xFF,
+ # WriteQueueSize: UINT64
+ 0xE0, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00
+}
+
+0x01080000|0x00040000
+gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareBase|gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareSize
+#NV_FTW_SPARE
+!endif
+
################################################################################
#
# FD Section for FLASH1
@@ -169,15 +229,25 @@ [FV.FvMain]
INF MdeModulePkg/Core/RuntimeDxe/RuntimeDxe.inf
INF MdeModulePkg/Universal/SecurityStubDxe/SecurityStubDxe.inf
INF MdeModulePkg/Universal/CapsuleRuntimeDxe/CapsuleRuntimeDxe.inf
- INF MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteDxe.inf
- INF MdeModulePkg/Universal/Variable/RuntimeDxe/VariableRuntimeDxe.inf
- INF SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigDxe.inf
INF MdeModulePkg/Universal/MonotonicCounterRuntimeDxe/MonotonicCounterRuntimeDxe.inf
INF MdeModulePkg/Universal/ResetSystemRuntimeDxe/ResetSystemRuntimeDxe.inf
INF EmbeddedPkg/RealTimeClockRuntimeDxe/RealTimeClockRuntimeDxe.inf
INF EmbeddedPkg/MetronomeDxe/MetronomeDxe.inf
INF MdeModulePkg/Universal/HiiDatabaseDxe/HiiDatabaseDxe.inf

+ #
+ # Variable services
+ #
+!if $(SECURE_BOOT_ENABLE) == FALSE
+ INF ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashDxe.inf
+ INF MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteDxe.inf
+ INF MdeModulePkg/Universal/Variable/RuntimeDxe/VariableRuntimeDxe.inf
+!else
+ INF ArmPkg/Drivers/MmCommunicationDxe/MmCommunication.inf
+ INF MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmmRuntimeDxe.inf
+ INF SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigDxe.inf
+!endif
+
#
# Multiple Console IO support
#
@@ -189,7 +259,6 @@ [FV.FvMain]

INF ArmPkg/Drivers/ArmGic/ArmGicDxe.inf
INF ArmPkg/Drivers/TimerDxe/TimerDxe.inf
- INF ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashDxe.inf
INF MdeModulePkg/Universal/WatchdogTimerDxe/WatchdogTimer.inf

#
@@ -294,6 +363,7 @@ [FV.FVMAIN_COMPACT]
INF ArmPlatformPkg/MemoryInitPei/MemoryInitPeim.inf
INF ArmPkg/Drivers/CpuPei/CpuPei.inf
INF MdeModulePkg/Universal/PCD/Pei/Pcd.inf
+
Another spuriously added blank line.

INF MdeModulePkg/Core/DxeIplPeim/DxeIpl.inf

# IDE/AHCI Support
diff --git a/Platform/Qemu/SbsaQemu/SbsaQemuStandaloneMm.fdf b/Platform/Qemu/SbsaQemu/SbsaQemuStandaloneMm.fdf
index a1acefcfb0a7..dbe1555c68f2 100644
--- a/Platform/Qemu/SbsaQemu/SbsaQemuStandaloneMm.fdf
+++ b/Platform/Qemu/SbsaQemu/SbsaQemuStandaloneMm.fdf
@@ -19,8 +19,8 @@
################################################################################

[FD.STANDALONE_MM]
-BaseAddress = 0x20001000|gArmTokenSpaceGuid.PcdFdBaseAddress
-Size = 0x00e00000|gArmTokenSpaceGuid.PcdFdSize # The size in bytes of the device (14MiB).
+BaseAddress = 0x20002000
+Size = 0x00e00000
ErasePolarity = 1

BlockSize = 0x00001000
@@ -49,6 +49,9 @@ [FV.FVMAIN_COMPACT]
READ_LOCK_STATUS = TRUE

INF StandaloneMmPkg/Core/StandaloneMmCore.inf
+ INF ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashStandaloneMm.inf
+ INF MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteStandaloneMm.inf
+ INF MdeModulePkg/Universal/Variable/RuntimeDxe/VariableStandaloneMm.inf
INF StandaloneMmPkg/Drivers/StandaloneMmCpu/AArch64/StandaloneMmCpu.inf

################################################################################
diff --git a/Silicon/Qemu/SbsaQemu/Library/SbsaQemuLib/SbsaQemuLib.inf b/Silicon/Qemu/SbsaQemu/Library/SbsaQemuLib/SbsaQemuLib.inf
index c067a80cc715..1d7f12202ecc 100644
--- a/Silicon/Qemu/SbsaQemu/Library/SbsaQemuLib/SbsaQemuLib.inf
+++ b/Silicon/Qemu/SbsaQemu/Library/SbsaQemuLib/SbsaQemuLib.inf
@@ -40,6 +40,8 @@ [Pcd]
gArmTokenSpaceGuid.PcdSystemMemoryBase
gArmTokenSpaceGuid.PcdSystemMemorySize
gArmVirtSbsaQemuPlatformTokenSpaceGuid.PcdDeviceTreeBaseAddress
+ gArmTokenSpaceGuid.PcdMmBufferBase
+ gArmTokenSpaceGuid.PcdMmBufferSize

[FixedPcd]
gArmTokenSpaceGuid.PcdFdBaseAddress
diff --git a/Silicon/Qemu/SbsaQemu/Library/SbsaQemuLib/SbsaQemuMem.c b/Silicon/Qemu/SbsaQemu/Library/SbsaQemuLib/SbsaQemuMem.c
index 8c2eb0b6a028..fa164ff455f5 100644
--- a/Silicon/Qemu/SbsaQemu/Library/SbsaQemuLib/SbsaQemuMem.c
+++ b/Silicon/Qemu/SbsaQemu/Library/SbsaQemuLib/SbsaQemuMem.c
@@ -25,15 +25,20 @@ SbsaQemuLibConstructor (
{
VOID *DeviceTreeBase;
INT32 Node, Prev;
- UINT64 NewBase, CurBase;
+ UINT64 NewBase, CurBase, NsBufBase;
UINT64 NewSize, CurSize;
+ UINT32 NsBufSize;
CONST CHAR8 *Type;
INT32 Len;
CONST UINT64 *RegProp;
RETURN_STATUS PcdStatus;
+ INT32 ParentOffset;
+ INT32 Offset;

NewBase = 0;
NewSize = 0;
+ NsBufBase = 0;
+ NsBufSize = 0;

DeviceTreeBase = (VOID *)(UINTN)PcdGet64 (PcdDeviceTreeBaseAddress);
ASSERT (DeviceTreeBase != NULL);
@@ -73,9 +78,39 @@ SbsaQemuLibConstructor (
}
}

+ // StandaloneMM non-secure shared buffer is allocated at the top of
+ // the system memory by trusted-firmware using "/reserved-memory" node.
+ ParentOffset = fdt_path_offset(DeviceTreeBase, "/reserved-memory");
+ if (ParentOffset < 0) {
+ DEBUG ((DEBUG_ERROR, "%a: reserved-memory node not found\n",
+ __FUNCTION__));
+ }
+ Offset = fdt_subnode_offset(DeviceTreeBase, ParentOffset, "ns-buf-spm-mm");
+ if (Offset < 0) {
+ DEBUG ((DEBUG_ERROR, "%a: ns-buf-spm-mm node not found\n",
+ __FUNCTION__));
+ }
+ // Get the 'reg' property of this node. 8 byte quantities for base address
+ // and 4 byte quantities for size.
+ RegProp = fdt_getprop (DeviceTreeBase, Offset, "reg", &Len);
+ if (RegProp != 0 && Len == (sizeof (UINT64) + sizeof(UINT32))) {
+ NsBufBase = fdt64_to_cpu (ReadUnaligned64 (RegProp));
+ NsBufSize = fdt32_to_cpu (ReadUnaligned32 ((UINT32 *)(RegProp + 1)));
+
+ DEBUG ((DEBUG_INFO, "%a: ns buf @ 0x%lx - 0x%lx\n",
+ __FUNCTION__, NsBufBase, NsBufBase + NsBufSize - 1));
+ } else {
+ DEBUG ((DEBUG_ERROR, "%a: Failed to parse FDT reserved-memory node Len %d\n",
+ __FUNCTION__, Len));
+ }
Could the above device-tree parsing be moved to a helper function in
Silicon/Qemu/SbsaQemu/Library/FdtHelperLib/ ?

(Yes, I should also move the memory node parsing there, but it wasn't
quite worth creating the library just for that before.)
I created both "memory" and "/reserved-memory" parsing helper function.
Could you check the next version of patch?

Thanks,
Masahisa


Best Regards,

Leif

+
+ NewSize -= NsBufSize;
+
// Make sure the start of DRAM matches our expectation
ASSERT (FixedPcdGet64 (PcdSystemMemoryBase) == NewBase);
PcdStatus = PcdSet64S (PcdSystemMemorySize, NewSize);
+ PcdStatus = PcdSet64S (PcdMmBufferBase, NsBufBase);
+ PcdStatus = PcdSet64S (PcdMmBufferSize, (UINT64)NsBufSize);
ASSERT_RETURN_ERROR (PcdStatus);

return RETURN_SUCCESS;
--
2.17.1


Re: [PATCH v3] ShellPkg: add more items for smbiosview -t 3 .

Gao, Zhichao
 

Hi Mars,

 

I still cannot extract your patch thru this email. But I got it from the BZ link. There still some problems I missed last time.

You should add a length check before showing the contained elements.

 

Thanks,

Zhichao

 

From: Mars CC Lin <mars_cc_lin@...>
Sent: Tuesday, March 2, 2021 11:14 AM
To: devel@edk2.groups.io
Cc: mars_cc_lin@...; Gao, Zhichao <zhichao.gao@...>; Philippe Mathieu-Daude <philmd@...>; Liming Gao <gaoliming@...>
Subject: [PATCH v3] ShellPkg: add more items for smbiosview -t 3 .

 

https://bugzilla.tianocore.org/show_bug.cgi?id=3177
Add ContainedElementCount, ContainedElementRecordLength and
ContainedElements for smbiosview type 3.

Signed-off-by: Mars CC Lin <mars_cc_lin@...>
Cc: Zhichao Gao <zhichao.gao@...>
Cc: Philippe Mathieu-Daude <philmd@...>
Cc: Liming Gao <gaoliming@...>
---
.../SmbiosView/PrintInfo.c | 14 ++++++++++++++
.../SmbiosView/SmbiosViewStrings.uni | 1 +
2 files changed, 15 insertions(+)

diff --git a/ShellPkg/Library/UefiShellDebug1CommandsLib/SmbiosView/PrintInfo.c b/ShellPkg/Library/UefiShellDebug1CommandsLib/SmbiosView/PrintInfo.c
index a3dc7b68c4..4be6cf2df4 100644
--- a/ShellPkg/Library/UefiShellDebug1CommandsLib/SmbiosView/PrintInfo.c
+++ b/ShellPkg/Library/UefiShellDebug1CommandsLib/SmbiosView/PrintInfo.c
@@ -280,6 +280,7 @@ SmbiosPrintStructure (
)
{
UINT8 Index;
+ UINT8 Index2 = 0;
UINT8 *Buffer;

if (Struct == NULL) {
@@ -404,6 +405,19 @@ SmbiosPrintStructure (
if (Struct->Hdr->Length > 0x12) {
PRINT_STRUCT_VALUE (Struct, Type3, NumberofPowerCords);
}
+ if (Struct->Hdr->Length > 0x13) {
+ PRINT_STRUCT_VALUE (Struct, Type3, ContainedElementCount);
+ }
+ if (Struct->Hdr->Length > 0x14) {
+ PRINT_STRUCT_VALUE (Struct, Type3, ContainedElementRecordLength);
+ }
+ for (Index = 0; Index < Struct->Type3->ContainedElementCount; Index++) {
+ ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_CONTAINED_ELEMENT), gShellDebug1HiiHandle, Index+1);
+ for (Index2 = 0; Index2< Struct->Type3->ContainedElementRecordLength; Index2++) {
+ Print (L"%02X ", Buffer[0x15 + (Index * Struct->Type3->ContainedElementRecordLength) + Index2]);
+ }
+ Print (L"\n");
+ }
}
if (AE_SMBIOS_VERSION (0x2, 0x7) && (Struct->Hdr->Length > 0x13)) {
if (Struct->Hdr->Length > (0x15 + (Struct->Type3->ContainedElementCount * Struct->Type3->ContainedElementRecordLength))) {
diff --git a/ShellPkg/Library/UefiShellDebug1CommandsLib/SmbiosView/SmbiosViewStrings.uni b/ShellPkg/Library/UefiShellDebug1CommandsLib/SmbiosView/SmbiosViewStrings.uni
index 8bcba7ccf7..9433e8a25f 100644
--- a/ShellPkg/Library/UefiShellDebug1CommandsLib/SmbiosView/SmbiosViewStrings.uni
+++ b/ShellPkg/Library/UefiShellDebug1CommandsLib/SmbiosView/SmbiosViewStrings.uni
@@ -93,6 +93,7 @@
#string STR_SMBIOSVIEW_PRINTINFO_POWER_SUPPLY_STATE #language en-US "Power Supply State "
#string STR_SMBIOSVIEW_PRINTINFO_THERMAL_STATE #language en-US "Thermal state "
#string STR_SMBIOSVIEW_PRINTINFO_SECURITY_STATUS #language en-US "Security Status "
+#string STR_SMBIOSVIEW_PRINTINFO_CONTAINED_ELEMENT #language en-US "Contained Element %d: "
#string STR_SMBIOSVIEW_PRINTINFO_SUPOPRT #language en-US "Support "
#string STR_SMBIOSVIEW_PRINTINFO_CURRENT #language en-US "Current "
#string STR_SMBIOSVIEW_PRINTINFO_INSTALLED #language en-US "Installed "
--
2.29.1.windows.1


[PATCH 1/1] BaseTools: Modify struct parser for StructPcd

Yuwei Chen
 

Currently the struct parser for StructPcd Generation does not
fliter the types such as UINT8 which should be ignored successfully.
This patch modifies this issue.

Cc: Bob Feng <bob.c.feng@...>
Cc: Liming Gao <gaoliming@...>
Signed-off-by: Yuwei Chen <yuwei.chen@...>
---
BaseTools/Scripts/ConvertFceToStructurePcd.py | 2 ++
1 file changed, 2 insertions(+)

diff --git a/BaseTools/Scripts/ConvertFceToStructurePcd.py b/BaseTools/Scripts/ConvertFceToStructurePcd.py
index 867660fba9cf..d72a20d62a5d 100644
--- a/BaseTools/Scripts/ConvertFceToStructurePcd.py
+++ b/BaseTools/Scripts/ConvertFceToStructurePcd.py
@@ -197,6 +197,8 @@ class parser_lst(object):
efitxt = efivarstore_format.findall(self.text)
for i in efitxt:
struct = struct_re.findall(i.replace(' ',''))
+ if struct[0] in self._ignore:
+ continue
name = name_re.findall(i.replace(' ',''))
if struct and name:
efivarstore_dict[name[0]]=struct[0]
--
2.27.0.windows.1


Re: [PATCH v4 6/7] SecurityPkg: Tcg2Smm: Added support for Standalone Mm

Yao, Jiewen
 

Reviewed-by: Jiewen Yao <Jiewen.yao@...>

-----Original Message-----
From: Kun Qin <kun.q@...>
Sent: Wednesday, March 3, 2021 4:05 AM
To: devel@edk2.groups.io
Cc: Yao, Jiewen <jiewen.yao@...>; Wang, Jian J <jian.j.wang@...>;
Zhang, Qi1 <qi1.zhang@...>; Kumar, Rahul1 <rahul1.kumar@...>
Subject: [PATCH v4 6/7] SecurityPkg: Tcg2Smm: Added support for Standalone
Mm

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

This change added Standalone MM instance of Tcg2. The notify function for
Standalone MM instance is left empty.

A dependency DXE driver with a Depex of gEfiMmCommunication2ProtocolGuid
was created to indicate the readiness of Standalone MM Tcg2 driver.

Lastly, the support of CI build for Tcg2 Standalone MM module is added.

Cc: Jiewen Yao <jiewen.yao@...>
Cc: Jian J Wang <jian.j.wang@...>
Cc: Qi Zhang <qi1.zhang@...>
Cc: Rahul Kumar <rahul1.kumar@...>

Signed-off-by: Kun Qin <kun.q@...>
---

Notes:
v4:
- Changed dependency module from anonymous lib to Dxe driver. [Jiewen]

v3:
- No change.

v2:
- Newly added.

SecurityPkg/Tcg/Tcg2Smm/Tcg2MmDependencyDxe.c | 48 ++++++++++++
SecurityPkg/Tcg/Tcg2Smm/Tcg2StandaloneMm.c | 71 ++++++++++++++++++
SecurityPkg/SecurityPkg.ci.yaml | 1 +
SecurityPkg/SecurityPkg.dec | 1 +
SecurityPkg/SecurityPkg.dsc | 10 +++
SecurityPkg/Tcg/Tcg2Smm/Tcg2MmDependencyDxe.inf | 43 +++++++++++
SecurityPkg/Tcg/Tcg2Smm/Tcg2StandaloneMm.inf | 77
++++++++++++++++++++
7 files changed, 251 insertions(+)

diff --git a/SecurityPkg/Tcg/Tcg2Smm/Tcg2MmDependencyDxe.c
b/SecurityPkg/Tcg/Tcg2Smm/Tcg2MmDependencyDxe.c
new file mode 100644
index 000000000000..4f2d7c58ed86
--- /dev/null
+++ b/SecurityPkg/Tcg/Tcg2Smm/Tcg2MmDependencyDxe.c
@@ -0,0 +1,48 @@
+/** @file
+ Runtime DXE part corresponding to StandaloneMM Tcg2 module.
+
+This module installs gTcg2MmSwSmiRegisteredGuid to notify readiness of
+StandaloneMM Tcg2 module.
+
+Copyright (c) 2019 - 2021, Arm Ltd. All rights reserved.
+Copyright (c) Microsoft Corporation.
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <PiDxe.h>
+
+#include <Library/DebugLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+
+/**
+ The constructor function installs gTcg2MmSwSmiRegisteredGuid to notify
+ readiness of StandaloneMM Tcg2 module.
+
+ @param ImageHandle The firmware allocated handle for the EFI image.
+ @param SystemTable A pointer to the Management mode System Table.
+
+ @retval EFI_SUCCESS The constructor always returns EFI_SUCCESS.
+
+**/
+EFI_STATUS
+EFIAPI
+Tcg2MmDependencyDxeEntryPoint (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ EFI_STATUS Status;
+ EFI_HANDLE Handle;
+
+ Handle = NULL;
+ Status = gBS->InstallProtocolInterface (
+ &Handle,
+ &gTcg2MmSwSmiRegisteredGuid,
+ EFI_NATIVE_INTERFACE,
+ NULL
+ );
+ ASSERT_EFI_ERROR (Status);
+ return EFI_SUCCESS;
+}
diff --git a/SecurityPkg/Tcg/Tcg2Smm/Tcg2StandaloneMm.c
b/SecurityPkg/Tcg/Tcg2Smm/Tcg2StandaloneMm.c
new file mode 100644
index 000000000000..9e0095efbc5e
--- /dev/null
+++ b/SecurityPkg/Tcg/Tcg2Smm/Tcg2StandaloneMm.c
@@ -0,0 +1,71 @@
+/** @file
+ TCG2 Standalone MM driver that updates TPM2 items in ACPI table and
registers
+ SMI2 callback functions for Tcg2 physical presence, ClearMemory, and
+ sample for dTPM StartMethod.
+
+ Caution: This module requires additional review when modified.
+ This driver will have external input - variable and ACPINvs data in SMM mode.
+ This external input must be validated carefully to avoid security issue.
+
+ PhysicalPresenceCallback() and MemoryClearCallback() will receive untrusted
input and do some check.
+
+Copyright (c) 2015 - 2018, Intel Corporation. All rights reserved.<BR>
+Copyright (c) Microsoft Corporation.
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include "Tcg2Smm.h"
+#include <Library/StandaloneMmMemLib.h>
+
+/**
+ Notify the system that the SMM variable driver is ready.
+**/
+VOID
+Tcg2NotifyMmReady (
+ VOID
+ )
+{
+ // Do nothing
+}
+
+/**
+ This function is an abstraction layer for implementation specific Mm buffer
validation routine.
+
+ @param Buffer The buffer start address to be checked.
+ @param Length The buffer length to be checked.
+
+ @retval TRUE This buffer is valid per processor architecture and not overlap
with SMRAM.
+ @retval FALSE This buffer is not valid per processor architecture or overlap
with SMRAM.
+**/
+BOOLEAN
+IsBufferOutsideMmValid (
+ IN EFI_PHYSICAL_ADDRESS Buffer,
+ IN UINT64 Length
+ )
+{
+ return MmIsBufferOutsideMmValid (Buffer, Length);
+}
+
+/**
+ The driver's entry point.
+
+ It install callbacks for TPM physical presence and MemoryClear, and locate
+ SMM variable to be used in the callback function.
+
+ @param[in] ImageHandle The firmware allocated handle for the EFI image.
+ @param[in] SystemTable A pointer to the EFI System Table.
+
+ @retval EFI_SUCCESS The entry point is executed successfully.
+ @retval Others Some error occurs when executing this entry point.
+
+**/
+EFI_STATUS
+EFIAPI
+InitializeTcgStandaloneMm (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_MM_SYSTEM_TABLE *SystemTable
+ )
+{
+ return InitializeTcgCommon ();
+}
diff --git a/SecurityPkg/SecurityPkg.ci.yaml b/SecurityPkg/SecurityPkg.ci.yaml
index 03be2e94ca97..d7b9e1f4e239 100644
--- a/SecurityPkg/SecurityPkg.ci.yaml
+++ b/SecurityPkg/SecurityPkg.ci.yaml
@@ -31,6 +31,7 @@
"MdePkg/MdePkg.dec",
"MdeModulePkg/MdeModulePkg.dec",
"SecurityPkg/SecurityPkg.dec",
+ "StandaloneMmPkg/StandaloneMmPkg.dec",
"CryptoPkg/CryptoPkg.dec"
],
# For host based unit tests
diff --git a/SecurityPkg/SecurityPkg.dec b/SecurityPkg/SecurityPkg.dec
index 0970cae5c75e..dfbbb0365a2b 100644
--- a/SecurityPkg/SecurityPkg.dec
+++ b/SecurityPkg/SecurityPkg.dec
@@ -383,6 +383,7 @@ [PcdsFixedAtBuild, PcdsPatchableInModule,
PcdsDynamic, PcdsDynamicEx]
gEfiSecurityPkgTokenSpaceGuid.PcdTpmScrtmPolicy|1|UINT8|0x0001000E

## Guid name to identify TPM instance.<BR><BR>
+ # NOTE: This Pcd must be FixedAtBuild if Standalone MM is used
# TPM_DEVICE_INTERFACE_NONE means disable.<BR>
# TPM_DEVICE_INTERFACE_TPM12 means TPM 1.2 DTPM.<BR>
# TPM_DEVICE_INTERFACE_DTPM2 means TPM 2.0 DTPM.<BR>
diff --git a/SecurityPkg/SecurityPkg.dsc b/SecurityPkg/SecurityPkg.dsc
index 928bff72baa3..74ec42966273 100644
--- a/SecurityPkg/SecurityPkg.dsc
+++ b/SecurityPkg/SecurityPkg.dsc
@@ -166,6 +166,14 @@ [LibraryClasses.common.DXE_SMM_DRIVER]

Tcg2PhysicalPresenceLib|SecurityPkg/Library/SmmTcg2PhysicalPresenceLib/Sm
mTcg2PhysicalPresenceLib.inf
SmmIoLib|MdePkg/Library/SmmIoLib/SmmIoLib.inf

+[LibraryClasses.common.MM_STANDALONE]
+
StandaloneMmDriverEntryPoint|MdePkg/Library/StandaloneMmDriverEntryPoin
t/StandaloneMmDriverEntryPoint.inf
+
MmServicesTableLib|MdePkg/Library/StandaloneMmServicesTableLib/Standalo
neMmServicesTableLib.inf
+
Tcg2PhysicalPresenceLib|SecurityPkg/Library/SmmTcg2PhysicalPresenceLib/Sta
ndaloneMmTcg2PhysicalPresenceLib.inf
+
MemLib|StandaloneMmPkg/Library/StandaloneMmMemLib/StandaloneMmMe
mLib.inf
+
HobLib|StandaloneMmPkg/Library/StandaloneMmHobLib/StandaloneMmHobLi
b.inf
+
MemoryAllocationLib|StandaloneMmPkg/Library/StandaloneMmMemoryAlloca
tionLib/StandaloneMmMemoryAllocationLib.inf
+
[PcdsDynamicDefault.common.DEFAULT]
gEfiSecurityPkgTokenSpaceGuid.PcdTpmInstanceGuid|{0xb6, 0xe5, 0x01, 0x8b,
0x19, 0x4f, 0xe8, 0x46, 0xab, 0x93, 0x1c, 0x53, 0x67, 0x1b, 0x90, 0xcc}
gEfiSecurityPkgTokenSpaceGuid.PcdTpm2InitializationPolicy|1
@@ -317,6 +325,8 @@ [Components.IA32, Components.X64]
SecurityPkg/Tcg/MemoryOverwriteRequestControlLock/TcgMorLockSmm.inf
SecurityPkg/Tcg/TcgSmm/TcgSmm.inf
SecurityPkg/Tcg/Tcg2Smm/Tcg2Smm.inf
+ SecurityPkg/Tcg/Tcg2Smm/Tcg2StandaloneMm.inf
+ SecurityPkg/Tcg/Tcg2Smm/Tcg2MmDependencyDxe.inf
SecurityPkg/Tcg/Tcg2Acpi/Tcg2Acpi.inf

SecurityPkg/Library/SmmTcg2PhysicalPresenceLib/SmmTcg2PhysicalPresenceLib
.inf

SecurityPkg/Library/SmmTcg2PhysicalPresenceLib/StandaloneMmTcg2PhysicalP
resenceLib.inf
diff --git a/SecurityPkg/Tcg/Tcg2Smm/Tcg2MmDependencyDxe.inf
b/SecurityPkg/Tcg/Tcg2Smm/Tcg2MmDependencyDxe.inf
new file mode 100644
index 000000000000..44c64ccb832c
--- /dev/null
+++ b/SecurityPkg/Tcg/Tcg2Smm/Tcg2MmDependencyDxe.inf
@@ -0,0 +1,43 @@
+## @file
+# Runtime DXE part corresponding to StandaloneMM Tcg2 module.
+#
+# This module installs gTcg2MmSwSmiRegisteredGuid to notify readiness of
+# StandaloneMM Tcg2 module.
+#
+# Copyright (c) Microsoft Corporation.
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+ INF_VERSION = 0x0001001A
+ BASE_NAME = Tcg2MmDependencyDxe
+ FILE_GUID = 94C210EA-3113-4563-ADEB-76FE759C2F46
+ MODULE_TYPE = DXE_DRIVER
+ ENTRY_POINT = Tcg2MmDependencyDxeEntryPoint
+
+#
+# The following information is for reference only and not required by the build
tools.
+#
+# VALID_ARCHITECTURES = IA32 X64
+#
+#
+
+[Sources]
+ Tcg2MmDependencyDxe.c
+
+[Packages]
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+ SecurityPkg/SecurityPkg.dec
+
+[LibraryClasses]
+ DebugLib
+ UefiBootServicesTableLib
+ UefiDriverEntryPoint
+
+[Guids]
+ gTcg2MmSwSmiRegisteredGuid ## PRODUCES ## GUID # Install
protocol
+
+[Depex]
+ gEfiMmCommunication2ProtocolGuid
diff --git a/SecurityPkg/Tcg/Tcg2Smm/Tcg2StandaloneMm.inf
b/SecurityPkg/Tcg/Tcg2Smm/Tcg2StandaloneMm.inf
new file mode 100644
index 000000000000..746eda3e9fed
--- /dev/null
+++ b/SecurityPkg/Tcg/Tcg2Smm/Tcg2StandaloneMm.inf
@@ -0,0 +1,77 @@
+## @file
+# Provides ACPI methods for TPM 2.0 support
+#
+# Spec Compliance Info:
+# "TCG ACPI Specification Version 1.2 Revision 8"
+# "Physical Presence Interface Specification Version 1.30 Revision 00.52"
+# along with
+# "Errata Version 0.4 for TCG PC Client Platform Physical Presence Interface
Specification"
+# "Platform Reset Attack Mitigation Specification Version 1.00"
+# TPM2.0 ACPI device object
+# "TCG PC Client Platform Firmware Profile Specification for TPM Family 2.0
Level 00 Revision 1.03 v51"
+# along with
+# "Errata for PC Client Specific Platform Firmware Profile Specification
Version 1.0 Revision 1.03"
+#
+# This driver implements TPM 2.0 definition block in ACPI table and
+# registers SMI callback functions for Tcg2 physical presence and
+# MemoryClear to handle the requests from ACPI method.
+#
+# Caution: This module requires additional review when modified.
+# This driver will have external input - variable and ACPINvs data in SMM mode.
+# This external input must be validated carefully to avoid security issue.
+#
+# Copyright (c) 2015 - 2019, Intel Corporation. All rights reserved.<BR>
+# Copyright (c) Microsoft Corporation.<BR>
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = Tcg2StandaloneMm
+ FILE_GUID = D40F321F-5349-4724-B667-131670587861
+ MODULE_TYPE = MM_STANDALONE
+ PI_SPECIFICATION_VERSION = 0x00010032
+ VERSION_STRING = 1.0
+ ENTRY_POINT = InitializeTcgStandaloneMm
+
+[Sources]
+ Tcg2Smm.h
+ Tcg2Smm.c
+ Tcg2StandaloneMm.c
+
+[Packages]
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+ SecurityPkg/SecurityPkg.dec
+ StandaloneMmPkg/StandaloneMmPkg.dec
+
+[LibraryClasses]
+ BaseLib
+ BaseMemoryLib
+ StandaloneMmDriverEntryPoint
+ MmServicesTableLib
+ DebugLib
+ Tcg2PhysicalPresenceLib
+ PcdLib
+ MemLib
+
+[Guids]
+ ## SOMETIMES_PRODUCES ## Variable:L"MemoryOverwriteRequestControl"
+ ## SOMETIMES_CONSUMES ## Variable:L"MemoryOverwriteRequestControl"
+ gEfiMemoryOverwriteControlDataGuid
+
+ gEfiTpmDeviceInstanceTpm20DtpmGuid ## PRODUCES ##
GUID # TPM device identifier
+ gTpmNvsMmGuid ## CONSUMES
+
+[Protocols]
+ gEfiSmmSwDispatch2ProtocolGuid ## CONSUMES
+ gEfiSmmVariableProtocolGuid ## CONSUMES
+ gEfiMmReadyToLockProtocolGuid ## CONSUMES
+
+[Pcd]
+ gEfiSecurityPkgTokenSpaceGuid.PcdTpmInstanceGuid ## CONSUMES
+
+[Depex]
+ gEfiSmmSwDispatch2ProtocolGuid AND
+ gEfiSmmVariableProtocolGuid
--
2.30.0.windows.1


Re: [PATCH edk2-platforms v2 1/4] SbsaQemu: Build infrastructure for StandaloneMm image

Masahisa Kojima
 

On Tue, 2 Mar 2021 at 23:13, Leif Lindholm <leif@...> wrote:

On Tue, Mar 02, 2021 at 21:45:26 +0900, Masahisa Kojima wrote:
Hi Leif,

Thank you for you comments.

On Tue, 2 Mar 2021 at 02:05, Leif Lindholm <leif@...> wrote:

On Mon, Mar 01, 2021 at 14:19:49 +0900, Masahisa Kojima wrote:
Add the build infrastructure for compilation of StandaloneMm image.

Signed-off-by: Masahisa Kojima <masahisa.kojima@...>
---
.../Qemu/SbsaQemu/SbsaQemuStandaloneMm.dsc | 132 ++++++++++++++++++
Please use --stat=1000 --stat-graph-width=20 when generating patches.
Sorry I forgot to add these options, will be included in the next version.


Platform/Qemu/SbsaQemu/SbsaQemu.fdf | 6 +-
It is not immediately obvious to me why the pre-existing
SbsaQemuStandaloneMm.dsc needs to change. Is this something that can
be clarified in commit message?
I probably does not understand your comment correctly, but
SbsaQemuStandaloneMm.dsc
is newly created file with this commit.
Sorry, that's just my brain failure: I meant to say SbsaQemu.fdf.
SbsaQemu.fdf is modified to extend the FLASH0 region enough big to
contain StandaloneMM image(BL32).
I will note in the commit message in the next version.

Thanks,
Masahisa



Regards,

Leif

Thanks,
Masahisa


Best Regards,

Leif

.../Qemu/SbsaQemu/SbsaQemuStandaloneMm.fdf | 93 ++++++++++++
3 files changed, 228 insertions(+), 3 deletions(-)
create mode 100644 Platform/Qemu/SbsaQemu/SbsaQemuStandaloneMm.dsc
create mode 100644 Platform/Qemu/SbsaQemu/SbsaQemuStandaloneMm.fdf

diff --git a/Platform/Qemu/SbsaQemu/SbsaQemuStandaloneMm.dsc b/Platform/Qemu/SbsaQemu/SbsaQemuStandaloneMm.dsc
new file mode 100644
index 000000000000..87f5ee351eaa
--- /dev/null
+++ b/Platform/Qemu/SbsaQemu/SbsaQemuStandaloneMm.dsc
@@ -0,0 +1,132 @@
+#
+# Copyright (c) 2020, Linaro Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+
+################################################################################
+#
+# Defines Section - statements that will be processed to create a Makefile.
+#
+################################################################################
+[Defines]
+ PLATFORM_NAME = SbsaQemuStandaloneMm
+ PLATFORM_GUID = A64CC0F5-7ACD-4975-BBE7-7EF6739C8668
+ PLATFORM_VERSION = 1.0
+ DSC_SPECIFICATION = 0x00010011
+ OUTPUT_DIRECTORY = Build/$(PLATFORM_NAME)
+ SUPPORTED_ARCHITECTURES = AARCH64
+ BUILD_TARGETS = DEBUG|RELEASE|NOOPT
+ SKUID_IDENTIFIER = DEFAULT
+ FLASH_DEFINITION = Platform/Qemu/SbsaQemu/SbsaQemuStandaloneMm.fdf
+ DEFINE DEBUG_MESSAGE = TRUE
+
+ # LzmaF86
+ DEFINE COMPRESSION_TOOL_GUID = D42AE6BD-1352-4bfb-909A-CA72A6EAE889
+
+################################################################################
+#
+# Library Class section - list of all Library Classes needed by this Platform.
+#
+################################################################################
+[LibraryClasses]
+ #
+ # Basic
+ #
+ BaseLib|MdePkg/Library/BaseLib/BaseLib.inf
+ BaseMemoryLib|MdePkg/Library/BaseMemoryLib/BaseMemoryLib.inf
+ DebugLib|MdePkg/Library/BaseDebugLibSerialPort/BaseDebugLibSerialPort.inf
+ DebugPrintErrorLevelLib|MdePkg/Library/BaseDebugPrintErrorLevelLib/BaseDebugPrintErrorLevelLib.inf
+ ExtractGuidedSectionLib|EmbeddedPkg/Library/PrePiExtractGuidedSectionLib/PrePiExtractGuidedSectionLib.inf
+ FvLib|StandaloneMmPkg/Library/FvLib/FvLib.inf
+ HobLib|StandaloneMmPkg/Library/StandaloneMmCoreHobLib/StandaloneMmCoreHobLib.inf
+ IoLib|MdePkg/Library/BaseIoLibIntrinsic/BaseIoLibIntrinsic.inf
+ MemLib|StandaloneMmPkg/Library/StandaloneMmMemLib/StandaloneMmMemLib.inf
+ MemoryAllocationLib|StandaloneMmPkg/Library/StandaloneMmCoreMemoryAllocationLib/StandaloneMmCoreMemoryAllocationLib.inf
+ PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf
+ PeCoffLib|MdePkg/Library/BasePeCoffLib/BasePeCoffLib.inf
+ PrintLib|MdePkg/Library/BasePrintLib/BasePrintLib.inf
+ ReportStatusCodeLib|MdePkg/Library/BaseReportStatusCodeLibNull/BaseReportStatusCodeLibNull.inf
+
+ #
+ # Entry point
+ #
+ StandaloneMmDriverEntryPoint|MdePkg/Library/StandaloneMmDriverEntryPoint/StandaloneMmDriverEntryPoint.inf
+
+ ArmLib|ArmPkg/Library/ArmLib/ArmBaseLib.inf
+ StandaloneMmMmuLib|ArmPkg/Library/StandaloneMmMmuLib/ArmMmuStandaloneMmLib.inf
+ ArmSvcLib|ArmPkg/Library/ArmSvcLib/ArmSvcLib.inf
+ CacheMaintenanceLib|ArmPkg/Library/ArmCacheMaintenanceLib/ArmCacheMaintenanceLib.inf
+ PeCoffExtraActionLib|StandaloneMmPkg/Library/StandaloneMmPeCoffExtraActionLib/StandaloneMmPeCoffExtraActionLib.inf
+
+ # ARM PL011 UART Driver
+ PL011UartClockLib|ArmPlatformPkg/Library/PL011UartClockLib/PL011UartClockLib.inf
+ PL011UartLib|ArmPlatformPkg/Library/PL011UartLib/PL011UartLib.inf
+ SerialPortLib|ArmPlatformPkg/Library/PL011SerialPortLib/PL011SerialPortLib.inf
+
+ StandaloneMmCoreEntryPoint|StandaloneMmPkg/Library/StandaloneMmCoreEntryPoint/StandaloneMmCoreEntryPoint.inf
+
+ #
+ # It is not possible to prevent the ARM compiler for generic intrinsic functions.
+ # This library provides the instrinsic functions generate by a given compiler.
+ # And NULL mean link this library into all ARM images.
+ #
+ NULL|ArmPkg/Library/CompilerIntrinsicsLib/CompilerIntrinsicsLib.inf
+
+[LibraryClasses.common.MM_STANDALONE]
+ HobLib|StandaloneMmPkg/Library/StandaloneMmHobLib/StandaloneMmHobLib.inf
+ MmServicesTableLib|MdePkg/Library/StandaloneMmServicesTableLib/StandaloneMmServicesTableLib.inf
+ MemoryAllocationLib|StandaloneMmPkg/Library/StandaloneMmMemoryAllocationLib/StandaloneMmMemoryAllocationLib.inf
+
+################################################################################
+#
+# Pcd Section - list of all EDK II PCD Entries defined by this Platform
+#
+################################################################################
+[PcdsFixedAtBuild]
+ gEfiMdePkgTokenSpaceGuid.PcdDebugPrintErrorLevel|0x800000CF
+ gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask|0xff
+ gEfiMdePkgTokenSpaceGuid.PcdReportStatusCodePropertyMask|0x0f
+
+ ## PL011 - Serial Terminal
+ gEfiMdeModulePkgTokenSpaceGuid.PcdSerialRegisterBase|0x60040000
+ gEfiMdePkgTokenSpaceGuid.PcdUartDefaultBaudRate|115200
+
+ gEfiMdePkgTokenSpaceGuid.PcdMaximumGuidedExtractHandler|0x2
+
+###################################################################################################
+#
+# Components Section - list of the modules and components that will be processed by compilation
+# tools and the EDK II tools to generate PE32/PE32+/Coff image files.
+#
+# Note: The EDK II DSC file is not used to specify how compiled binary images get placed
+# into firmware volume images. This section is just a list of modules to compile from
+# source into UEFI-compliant binaries.
+# It is the FDF file that contains information on combining binary files into firmware
+# volume images, whose concept is beyond UEFI and is described in PI specification.
+# Binary modules do not need to be listed in this section, as they should be
+# specified in the FDF file. For example: Shell binary (Shell_Full.efi), FAT binary (Fat.efi),
+# Logo (Logo.bmp), and etc.
+# There may also be modules listed in this section that are not required in the FDF file,
+# When a module listed here is excluded from FDF file, then UEFI-compliant binary will be
+# generated for it, but the binary will not be put into any firmware volume.
+#
+###################################################################################################
+[Components.common]
+ #
+ # MM Core
+ #
+ StandaloneMmPkg/Core/StandaloneMmCore.inf
+ StandaloneMmPkg/Drivers/StandaloneMmCpu/AArch64/StandaloneMmCpu.inf
+
+###################################################################################################
+#
+# BuildOptions Section - Define the module specific tool chain flags that should be used as
+# the default flags for a module. These flags are appended to any
+# standard flags that are defined by the build process. They can be
+# applied for any modules or only those modules with the specific
+# module style (EDK or EDKII) specified in [Components] section.
+#
+###################################################################################################
+[BuildOptions.AARCH64]
+ GCC:*_*_*_DLINK_FLAGS = -z common-page-size=0x1000 -march=armv8-a+nofp
diff --git a/Platform/Qemu/SbsaQemu/SbsaQemu.fdf b/Platform/Qemu/SbsaQemu/SbsaQemu.fdf
index c35e3ed44054..b61ae1891233 100644
--- a/Platform/Qemu/SbsaQemu/SbsaQemu.fdf
+++ b/Platform/Qemu/SbsaQemu/SbsaQemu.fdf
@@ -21,10 +21,10 @@

[FD.SBSA_FLASH0]
BaseAddress = 0x00000000
-Size = 0x00200000
+Size = 0x00400000
ErasePolarity = 1
BlockSize = 0x00001000
-NumBlocks = 0x200
+NumBlocks = 0x400

################################################################################
#
@@ -47,7 +47,7 @@ [FD.SBSA_FLASH0]
FILE = Platform/Qemu/Sbsa/bl1.bin

# and FIP (BL2 + BL31)
-0x00008000|0x00020000
+0x00008000|0x00300000
FILE = Platform/Qemu/Sbsa/fip.bin

################################################################################
diff --git a/Platform/Qemu/SbsaQemu/SbsaQemuStandaloneMm.fdf b/Platform/Qemu/SbsaQemu/SbsaQemuStandaloneMm.fdf
new file mode 100644
index 000000000000..a1acefcfb0a7
--- /dev/null
+++ b/Platform/Qemu/SbsaQemu/SbsaQemuStandaloneMm.fdf
@@ -0,0 +1,93 @@
+#
+# Copyright (c) 2020, Linaro Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+
+################################################################################
+#
+# FD Section
+# The [FD] Section is made up of the definition statements and a
+# description of what goes into the Flash Device Image. Each FD section
+# defines one flash "device" image. A flash device image may be one of
+# the following: Removable media bootable image (like a boot floppy
+# image,) an Option ROM image (that would be "flashed" into an add-in
+# card,) a System "Flash" image (that would be burned into a system's
+# flash) or an Update ("Capsule") image that will be used to update and
+# existing system flash.
+#
+################################################################################
+
+[FD.STANDALONE_MM]
+BaseAddress = 0x20001000|gArmTokenSpaceGuid.PcdFdBaseAddress
+Size = 0x00e00000|gArmTokenSpaceGuid.PcdFdSize # The size in bytes of the device (14MiB).
+ErasePolarity = 1
+
+BlockSize = 0x00001000
+NumBlocks = 0x0e00
+
+0x00000000|0x00280000
+gArmTokenSpaceGuid.PcdFvBaseAddress|gArmTokenSpaceGuid.PcdFvSize
+FV = FVMAIN_COMPACT
+
+[FV.FVMAIN_COMPACT]
+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
+
+ INF StandaloneMmPkg/Core/StandaloneMmCore.inf
+ INF StandaloneMmPkg/Drivers/StandaloneMmCpu/AArch64/StandaloneMmCpu.inf
+
+################################################################################
+#
+# Rules are use with the [FV] section's module INF type to define
+# how an FFS file is created for a given INF file. The following Rule are the default
+# rules for the different module type. User can add the customized rules to define the
+# content of the FFS file.
+#
+################################################################################
+
+
+############################################################################
+# Example of a DXE_DRIVER FFS file with a Checksum encapsulation section #
+############################################################################
+#
+#[Rule.Common.DXE_DRIVER]
+# FILE DRIVER = $(NAMED_GUID) {
+# DXE_DEPEX DXE_DEPEX Optional $(INF_OUTPUT)/$(MODULE_NAME).depex
+# COMPRESS PI_STD {
+# GUIDED {
+# PE32 PE32 $(INF_OUTPUT)/$(MODULE_NAME).efi
+# UI STRING="$(MODULE_NAME)" Optional
+# VERSION STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER)
+# }
+# }
+# }
+#
+############################################################################
+
+[Rule.Common.MM_CORE_STANDALONE]
+ FILE SEC = $(NAMED_GUID) RELOCS_STRIPPED FIXED {
+ PE32 PE32 Align = Auto $(INF_OUTPUT)/$(MODULE_NAME).efi
+ }
+
+[Rule.Common.MM_STANDALONE]
+ FILE MM_STANDALONE = $(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.17.1


Re: [RFC PATCH 02/14] OvmfPkg/PlatformPei: Mark SEC GHCB page in the page encrpytion bitmap.

Ashish Kalra
 

Hello Tobin,

Just a high level question, why is this patch included in this
patch series, i don't think you are supporting SEV-ES platform
migration in this patch-set ?

Thanks,
Ashish

On Tue, Mar 02, 2021 at 03:48:27PM -0500, Tobin Feldman-Fitzthum wrote:
From: Ashish Kalra <ashish.kalra@...>

Mark the SEC GHCB page that is mapped as unencrypted in
ResetVector code in the hypervisor page encryption bitmap.

Cc: Jordan Justen <jordan.l.justen@...>
Cc: Laszlo Ersek <lersek@...>
Cc: Ard Biesheuvel <ard.biesheuvel@...>

Signed-off-by: Ashish Kalra <ashish.kalra@...>
---
OvmfPkg/PlatformPei/AmdSev.c | 10 ++++++++++
1 file changed, 10 insertions(+)

diff --git a/OvmfPkg/PlatformPei/AmdSev.c b/OvmfPkg/PlatformPei/AmdSev.c
index dddffdebda..c72eeb37c5 100644
--- a/OvmfPkg/PlatformPei/AmdSev.c
+++ b/OvmfPkg/PlatformPei/AmdSev.c
@@ -15,6 +15,7 @@
#include <Library/HobLib.h>
#include <Library/MemEncryptSevLib.h>
#include <Library/MemoryAllocationLib.h>
+#include <Library/MemEncryptHypercallLib.h>
#include <Library/PcdLib.h>
#include <PiPei.h>
#include <Register/Amd/Msr.h>
@@ -52,6 +53,15 @@ AmdSevEsInitialize (
PcdStatus = PcdSetBoolS (PcdSevEsIsEnabled, TRUE);
ASSERT_RETURN_ERROR (PcdStatus);

+ //
+ // GHCB_BASE setup during reset-vector needs to be marked as
+ // decrypted in the hypervisor page encryption bitmap.
+ //
+ SetMemoryEncDecHypercall3 (FixedPcdGet32 (PcdOvmfSecGhcbBase),
+ EFI_SIZE_TO_PAGES(FixedPcdGet32 (PcdOvmfSecGhcbSize)),
+ FALSE
+ );
+
//
// Allocate GHCB and per-CPU variable pages.
// Since the pages must survive across the UEFI to OS transition
--
2.20.1


[RFC PATCH 07/14] OvmfPkg/AmdSev: MH support for mailbox protocol

Tobin Feldman-Fitzthum <tobin@...>
 

The migration handler communicates with the hypervisor
via a shared mailbox page. The MH can perform four functions
at the behest of the HV: init, save page, restore page, and
reset.

Signed-off-by: Tobin Feldman-Fitzthum <tobin@...>
---
.../ConfidentialMigrationDxe.inf | 1 +
.../ConfidentialMigrationDxe.c | 78 +++++++++++++++++++
2 files changed, 79 insertions(+)

diff --git a/OvmfPkg/AmdSev/ConfidentialMigration/ConfidentialMigrationDxe.inf b/OvmfPkg/AmdSev/ConfidentialMigration/ConfidentialMigrationDxe.inf
index a4906a2451..49457d5d17 100644
--- a/OvmfPkg/AmdSev/ConfidentialMigration/ConfidentialMigrationDxe.inf
+++ b/OvmfPkg/AmdSev/ConfidentialMigration/ConfidentialMigrationDxe.inf
@@ -34,6 +34,7 @@
[Pcd]
gUefiOvmfPkgTokenSpaceGuid.PcdIsConfidentialMigrationTarget
gUefiOvmfPkgTokenSpaceGuid.PcdStartConfidentialMigrationHandler
+ gUefiOvmfPkgTokenSpaceGuid.PcdConfidentialMigrationMailboxBase

[Depex]
gEfiMpServiceProtocolGuid
diff --git a/OvmfPkg/AmdSev/ConfidentialMigration/ConfidentialMigrationDxe.c b/OvmfPkg/AmdSev/ConfidentialMigration/ConfidentialMigrationDxe.c
index 6d9fe7043b..8402fcc4fa 100644
--- a/OvmfPkg/AmdSev/ConfidentialMigration/ConfidentialMigrationDxe.c
+++ b/OvmfPkg/AmdSev/ConfidentialMigration/ConfidentialMigrationDxe.c
@@ -9,16 +9,94 @@
#include <Library/UefiRuntimeServicesTableLib.h>
#include <Library/DebugLib.h>
#include <Protocol/MpService.h>
+#include <Library/BaseMemoryLib.h>

+//
+// Functions implemented by the migration handler
+//
+#define MH_FUNC_INIT 0
+#define MH_FUNC_SAVE_PAGE 1
+#define MH_FUNC_RESTORE_PAGE 2
+#define MH_FUNC_RESET 3
+
+//
+// Return codes for MH functions
+//
+#define MH_SUCCESS 0
+#define MH_INVALID_FUNC (-1)
+#define MH_AUTH_ERR (-2)
+
+//
+// Index of CPU that MH runs on.
+//
UINTN MigrationHandlerCpuIndex;

+//
+// Mailbox for communication with hypervisor
+//
+typedef volatile struct {
+ UINT64 nr;
+ UINT64 gpa;
+ UINT32 do_prefetch;
+ UINT32 ret;
+ UINT32 go;
+ UINT32 done;
+} MH_COMMAND_PARAMETERS;
+
+
VOID
EFIAPI
MigrationHandlerMain (
IN OUT VOID *Buffer
)
{
+ UINT64 params_base;
+ MH_COMMAND_PARAMETERS *params;
+ VOID *page_va;
+
DebugPrint (DEBUG_INFO,"MIGRATION Handler Started\n");
+
+ params_base = PcdGet32 (PcdConfidentialMigrationMailboxBase);
+ params = (VOID *)params_base;
+ page_va = (VOID *)params_base + 0x1000;
+
+ DisableInterrupts();
+ params->go = 0;
+
+ while (1) {
+ while (!params->go) {
+ CpuPause();
+ }
+ params->done = 0;
+
+ switch (params->nr) {
+ case MH_FUNC_INIT:
+ params->ret = MH_SUCCESS;
+ break;
+
+ case MH_FUNC_SAVE_PAGE:
+ CopyMem(page_va, (VOID *)params->gpa, 4096);
+ params->ret = MH_SUCCESS;
+ break;
+
+ case MH_FUNC_RESTORE_PAGE:
+ CopyMem((VOID *)params->gpa, page_va, 4096);
+ params->ret = MH_SUCCESS;
+ break;
+
+ case MH_FUNC_RESET:
+ params->ret = MH_SUCCESS;
+ break;
+
+ default:
+ params->ret = MH_INVALID_FUNC;
+ break;
+ }
+
+ params->go = 0;
+ params->done = 1;
+
+ }
}

EFI_STATUS
--
2.20.1


[RFC PATCH 11/14] OvmfPkg/AmdSev: Build page table for migration handler

Tobin Feldman-Fitzthum <tobin@...>
 

From: Dov Murik <dovmurik@...>

The migration handler builds its own page tables and switches
to them. The MH pagetables are reserved as runtime memory.

When the hypervisor asks the MH to import/export a page, the HV
writes the guest physical address of the page in question to the
mailbox. The MH uses an identity mapping so that it can read/write
whatever GPA is requested by the HV. The hypervisor only asks the
MH to import/export encrypted pages. Thus, the C-Bit can be set
for every page in the identity map.

The MH also needs to read shared pages, such as the mailbox.
These are mapped at an offset. The offset must be added to
the physical address before it can be resolved.

Signed-off-by: Tobin Feldman-Fitzthum <tobin@...>
Signed-off-by: Dov Murik <dovmurik@...>
---
.../ConfidentialMigrationDxe.inf | 1 +
.../ConfidentialMigration/VirtualMemory.h | 177 ++++++++++++++++++
.../ConfidentialMigrationDxe.c | 88 ++++++++-
3 files changed, 265 insertions(+), 1 deletion(-)
create mode 100644 OvmfPkg/AmdSev/ConfidentialMigration/VirtualMemory.h

diff --git a/OvmfPkg/AmdSev/ConfidentialMigration/ConfidentialMigrationDxe.inf b/OvmfPkg/AmdSev/ConfidentialMigration/ConfidentialMigrationDxe.inf
index 49457d5d17..8dadfd1d13 100644
--- a/OvmfPkg/AmdSev/ConfidentialMigration/ConfidentialMigrationDxe.inf
+++ b/OvmfPkg/AmdSev/ConfidentialMigration/ConfidentialMigrationDxe.inf
@@ -15,6 +15,7 @@

[Sources]
ConfidentialMigrationDxe.c
+ VirtualMemory.h

[Packages]
MdePkg/MdePkg.dec
diff --git a/OvmfPkg/AmdSev/ConfidentialMigration/VirtualMemory.h b/OvmfPkg/AmdSev/ConfidentialMigration/VirtualMemory.h
new file mode 100644
index 0000000000..c50cb64c63
--- /dev/null
+++ b/OvmfPkg/AmdSev/ConfidentialMigration/VirtualMemory.h
@@ -0,0 +1,177 @@
+/** @file
+ Virtual Memory Management Services to set or clear the memory encryption bit
+ Copyright (c) 2006 - 2016, Intel Corporation. All rights reserved.<BR>
+ Copyright (c) 2017, AMD Incorporated. All rights reserved.<BR>
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+ Code is derived from OvmfPkg/Library/BaseMemEncryptSevLib/X64/VirtualMemory.h
+
+**/
+
+#ifndef __VIRTUAL_MEMORY__
+#define __VIRTUAL_MEMORY__
+
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/CacheMaintenanceLib.h>
+#include <Library/DebugLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Uefi.h>
+
+#define SYS_CODE64_SEL 0x38
+
+#pragma pack(1)
+
+//
+// Page-Map Level-4 Offset (PML4) and
+// Page-Directory-Pointer Offset (PDPE) entries 4K & 2MB
+//
+
+typedef union {
+ struct {
+ UINT64 Present:1; // 0 = Not present in memory,
+ // 1 = Present in memory
+ UINT64 ReadWrite:1; // 0 = Read-Only, 1= Read/Write
+ UINT64 UserSupervisor:1; // 0 = Supervisor, 1=User
+ UINT64 WriteThrough:1; // 0 = Write-Back caching,
+ // 1 = Write-Through caching
+ UINT64 CacheDisabled:1; // 0 = Cached, 1=Non-Cached
+ UINT64 Accessed:1; // 0 = Not accessed,
+ // 1 = Accessed (set by CPU)
+ UINT64 Reserved:1; // Reserved
+ UINT64 MustBeZero:2; // Must Be Zero
+ UINT64 Available:3; // Available for use by system software
+ UINT64 PageTableBaseAddress:40; // Page Table Base Address
+ UINT64 AvabilableHigh:11; // Available for use by system software
+ UINT64 Nx:1; // No Execute bit
+ } Bits;
+ UINT64 Uint64;
+} PAGE_MAP_AND_DIRECTORY_POINTER;
+
+//
+// Page Table Entry 4KB
+//
+typedef union {
+ struct {
+ UINT64 Present:1; // 0 = Not present in memory,
+ // 1 = Present in memory
+ UINT64 ReadWrite:1; // 0 = Read-Only, 1= Read/Write
+ UINT64 UserSupervisor:1; // 0 = Supervisor, 1=User
+ UINT64 WriteThrough:1; // 0 = Write-Back caching,
+ // 1 = Write-Through caching
+ UINT64 CacheDisabled:1; // 0 = Cached, 1=Non-Cached
+ UINT64 Accessed:1; // 0 = Not accessed,
+ // 1 = Accessed (set by CPU)
+ UINT64 Dirty:1; // 0 = Not Dirty, 1 = written by
+ // processor on access to page
+ UINT64 PAT:1; //
+ UINT64 Global:1; // 0 = Not global page, 1 = global page
+ // TLB not cleared on CR3 write
+ UINT64 Available:3; // Available for use by system software
+ UINT64 PageTableBaseAddress:40; // Page Table Base Address
+ UINT64 AvabilableHigh:11; // Available for use by system software
+ UINT64 Nx:1; // 0 = Execute Code,
+ // 1 = No Code Execution
+ } Bits;
+ UINT64 Uint64;
+} PAGE_TABLE_4K_ENTRY;
+
+//
+// Page Table Entry 2MB
+//
+typedef union {
+ struct {
+ UINT64 Present:1; // 0 = Not present in memory,
+ // 1 = Present in memory
+ UINT64 ReadWrite:1; // 0 = Read-Only, 1= Read/Write
+ UINT64 UserSupervisor:1; // 0 = Supervisor, 1=User
+ UINT64 WriteThrough:1; // 0 = Write-Back caching,
+ // 1=Write-Through caching
+ UINT64 CacheDisabled:1; // 0 = Cached, 1=Non-Cached
+ UINT64 Accessed:1; // 0 = Not accessed,
+ // 1 = Accessed (set by CPU)
+ UINT64 Dirty:1; // 0 = Not Dirty, 1 = written by
+ // processor on access to page
+ UINT64 MustBe1:1; // Must be 1
+ UINT64 Global:1; // 0 = Not global page, 1 = global page
+ // TLB not cleared on CR3 write
+ UINT64 Available:3; // Available for use by system software
+ UINT64 PAT:1; //
+ UINT64 MustBeZero:8; // Must be zero;
+ UINT64 PageTableBaseAddress:31; // Page Table Base Address
+ UINT64 AvabilableHigh:11; // Available for use by system software
+ UINT64 Nx:1; // 0 = Execute Code,
+ // 1 = No Code Execution
+ } Bits;
+ UINT64 Uint64;
+} PAGE_TABLE_ENTRY;
+
+//
+// Page Table Entry 1GB
+//
+typedef union {
+ struct {
+ UINT64 Present:1; // 0 = Not present in memory,
+ // 1 = Present in memory
+ UINT64 ReadWrite:1; // 0 = Read-Only, 1= Read/Write
+ UINT64 UserSupervisor:1; // 0 = Supervisor, 1=User
+ UINT64 WriteThrough:1; // 0 = Write-Back caching,
+ // 1 = Write-Through caching
+ UINT64 CacheDisabled:1; // 0 = Cached, 1=Non-Cached
+ UINT64 Accessed:1; // 0 = Not accessed,
+ // 1 = Accessed (set by CPU)
+ UINT64 Dirty:1; // 0 = Not Dirty, 1 = written by
+ // processor on access to page
+ UINT64 MustBe1:1; // Must be 1
+ UINT64 Global:1; // 0 = Not global page, 1 = global page
+ // TLB not cleared on CR3 write
+ UINT64 Available:3; // Available for use by system software
+ UINT64 PAT:1; //
+ UINT64 MustBeZero:17; // Must be zero;
+ UINT64 PageTableBaseAddress:22; // Page Table Base Address
+ UINT64 AvabilableHigh:11; // Available for use by system software
+ UINT64 Nx:1; // 0 = Execute Code,
+ // 1 = No Code Execution
+ } Bits;
+ UINT64 Uint64;
+} PAGE_TABLE_1G_ENTRY;
+
+#pragma pack()
+
+#define IA32_PG_P BIT0
+#define IA32_PG_RW BIT1
+#define IA32_PG_PS BIT7
+
+#define PAGING_PAE_INDEX_MASK 0x1FF
+
+#define PAGING_4K_ADDRESS_MASK_64 0x000FFFFFFFFFF000ull
+#define PAGING_2M_ADDRESS_MASK_64 0x000FFFFFFFE00000ull
+#define PAGING_1G_ADDRESS_MASK_64 0x000FFFFFC0000000ull
+
+#define PAGING_L1_ADDRESS_SHIFT 12
+#define PAGING_L2_ADDRESS_SHIFT 21
+#define PAGING_L3_ADDRESS_SHIFT 30
+#define PAGING_L4_ADDRESS_SHIFT 39
+
+#define PAGING_PML4E_NUMBER 4
+
+#define PAGETABLE_ENTRY_MASK ((1UL << 9) - 1)
+#define PML4_OFFSET(x) ( (x >> 39) & PAGETABLE_ENTRY_MASK)
+#define PDP_OFFSET(x) ( (x >> 30) & PAGETABLE_ENTRY_MASK)
+#define PDE_OFFSET(x) ( (x >> 21) & PAGETABLE_ENTRY_MASK)
+#define PTE_OFFSET(x) ( (x >> 12) & PAGETABLE_ENTRY_MASK)
+#define PAGING_1G_ADDRESS_MASK_64 0x000FFFFFC0000000ull
+
+#define PAGE_TABLE_POOL_ALIGNMENT BASE_2MB
+#define PAGE_TABLE_POOL_UNIT_SIZE SIZE_2MB
+#define PAGE_TABLE_POOL_UNIT_PAGES \
+ EFI_SIZE_TO_PAGES (PAGE_TABLE_POOL_UNIT_SIZE)
+#define PAGE_TABLE_POOL_ALIGN_MASK \
+ (~(EFI_PHYSICAL_ADDRESS)(PAGE_TABLE_POOL_ALIGNMENT - 1))
+
+typedef struct {
+ VOID *NextPool;
+ UINTN Offset;
+ UINTN FreePages;
+} PAGE_TABLE_POOL;
+
+#endif
diff --git a/OvmfPkg/AmdSev/ConfidentialMigration/ConfidentialMigrationDxe.c b/OvmfPkg/AmdSev/ConfidentialMigration/ConfidentialMigrationDxe.c
index 8402fcc4fa..3df3b09732 100644
--- a/OvmfPkg/AmdSev/ConfidentialMigration/ConfidentialMigrationDxe.c
+++ b/OvmfPkg/AmdSev/ConfidentialMigration/ConfidentialMigrationDxe.c
@@ -11,6 +11,7 @@
#include <Protocol/MpService.h>
#include <Library/BaseMemoryLib.h>

+#include "VirtualMemory.h"
//
// Functions implemented by the migration handler
//
@@ -43,6 +44,83 @@ typedef volatile struct {
UINT32 done;
} MH_COMMAND_PARAMETERS;

+//
+// Addresses for MH page table.
+//
+STATIC PAGE_TABLE_POOL *mPageTablePool = NULL;
+STATIC PHYSICAL_ADDRESS mMigrationHelperPageTables = 0;
+
+//
+// Offset for non-cbit mapping.
+//
+#define UNENC_VIRT_ADDR_BASE 0xffffff8000000000ULL
+
+
+/**
+ Allocates and fills in custom page tables for Migration Handler.
+ The MH must be able to write to any encrypted page. Thus, it
+ uses an identity map where the C-bit is set for every page. The
+ HV should never ask the MH to import/export a shared page. The
+ MH must also be able to read some shared pages. The first 1GB
+ of memory is mapped at offset UNENC_VIRT_ADDR_BASE.
+
+**/
+VOID
+PrepareMigrationHandlerPageTables (
+ VOID
+ )
+{
+ UINTN PoolPages;
+ VOID *Buffer;
+ VOID *Start;
+ PAGE_MAP_AND_DIRECTORY_POINTER *PageMapLevel4Entry;
+ PAGE_TABLE_1G_ENTRY *PageDirectory1GEntry;
+ PAGE_TABLE_1G_ENTRY *Unenc1GEntry;
+ UINT64 AddressEncMask;
+
+ PoolPages = 1 + 10;
+ Buffer = AllocateAlignedRuntimePages (PoolPages, PAGE_TABLE_POOL_ALIGNMENT);
+ mPageTablePool = Buffer;
+ mPageTablePool->NextPool = mPageTablePool;
+ mPageTablePool->FreePages = PoolPages - 1;
+ mPageTablePool->Offset = EFI_PAGES_TO_SIZE (1);
+
+ Start = (UINT8 *)mPageTablePool + mPageTablePool->Offset;
+ ZeroMem(Start, mPageTablePool->FreePages * EFI_PAGE_SIZE);
+
+ AddressEncMask = 1ULL << 47;
+
+ PageMapLevel4Entry = Start;
+ PageDirectory1GEntry = (PAGE_TABLE_1G_ENTRY*)((UINT8*)Start + EFI_PAGE_SIZE);
+ Unenc1GEntry = (PAGE_TABLE_1G_ENTRY*)((UINT8*)Start + 2 * EFI_PAGE_SIZE);
+
+ PageMapLevel4Entry = Start;
+ PageMapLevel4Entry += PML4_OFFSET(0x0ULL);
+ PageMapLevel4Entry->Uint64 = (UINT64)PageDirectory1GEntry | AddressEncMask | 0x23;
+
+ PageMapLevel4Entry = Start;
+ PageMapLevel4Entry += PML4_OFFSET(UNENC_VIRT_ADDR_BASE); // should be 511
+ PageMapLevel4Entry->Uint64 = (UINT64)Unenc1GEntry | AddressEncMask | 0x23;
+
+ UINT64 PageAddr = 0;
+ for (int i = 0; i < 512; i++, PageAddr += SIZE_1GB) {
+ PAGE_TABLE_1G_ENTRY *e = PageDirectory1GEntry + i;
+ e->Uint64 = PageAddr | AddressEncMask | 0xe3; // 1GB page
+ }
+
+ UINT64 UnencPageAddr = 0;
+ Unenc1GEntry->Uint64 = UnencPageAddr | 0xe3; // 1GB page unencrypted
+
+ mMigrationHelperPageTables = (UINT64)Start | AddressEncMask;
+}
+
+VOID
+SwitchToMigrationHelperPageTables(VOID)
+{
+ AsmWriteCr3(mMigrationHelperPageTables);
+}
+
+

VOID
EFIAPI
@@ -56,7 +134,12 @@ MigrationHandlerMain (

DebugPrint (DEBUG_INFO,"MIGRATION Handler Started\n");

- params_base = PcdGet32 (PcdConfidentialMigrationMailboxBase);
+ SwitchToMigrationHelperPageTables();
+
+ //
+ // Shared pages must be offset by UNENC_VIRT_ADDR_BASE.
+ //
+ params_base = PcdGet32 (PcdConfidentialMigrationMailboxBase) + UNENC_VIRT_ADDR_BASE;
params = (VOID *)params_base;
page_va = (VOID *)params_base + 0x1000;

@@ -134,6 +217,8 @@ LaunchMigrationHandler (

MigrationHandlerCpuIndex = NumProc - 1;

+ PrepareMigrationHandlerPageTables();
+
EFI_EVENT Event;
MpProto->GetProcessorInfo (MpProto, MigrationHandlerCpuIndex, &Tcb);
if (Tcb.StatusFlag != 7) {
@@ -154,6 +239,7 @@ LaunchMigrationHandler (
if (PcdGetBool(PcdIsConfidentialMigrationTarget)) {
DebugPrint (DEBUG_INFO,"Waiting for incoming confidential migration.\n");
DisableInterrupts ();
+ SwitchToMigrationHelperPageTables();
CpuDeadLoop ();
}

--
2.20.1


[RFC PATCH 13/14] OvmfPkg/AmdSev: Don't overwrite MH stack

Tobin Feldman-Fitzthum <tobin@...>
 

When restoring pages, the Migration Handler shoudl avoid overwriting
its own stack.

Signed-off-by: Tobin Feldman-Fitzthum <tobin@...>
---
.../ConfidentialMigrationDxe.inf | 2 +
OvmfPkg/AmdSev/ConfidentialMigration/MpLib.h | 235 ++++++++++++++++++
.../ConfidentialMigrationDxe.c | 30 ++-
3 files changed, 266 insertions(+), 1 deletion(-)
create mode 100644 OvmfPkg/AmdSev/ConfidentialMigration/MpLib.h

diff --git a/OvmfPkg/AmdSev/ConfidentialMigration/ConfidentialMigrationDxe.inf b/OvmfPkg/AmdSev/ConfidentialMigration/ConfidentialMigrationDxe.inf
index 8dadfd1d13..2816952863 100644
--- a/OvmfPkg/AmdSev/ConfidentialMigration/ConfidentialMigrationDxe.inf
+++ b/OvmfPkg/AmdSev/ConfidentialMigration/ConfidentialMigrationDxe.inf
@@ -16,6 +16,7 @@
[Sources]
ConfidentialMigrationDxe.c
VirtualMemory.h
+ MpLib.h

[Packages]
MdePkg/MdePkg.dec
@@ -36,6 +37,7 @@
gUefiOvmfPkgTokenSpaceGuid.PcdIsConfidentialMigrationTarget
gUefiOvmfPkgTokenSpaceGuid.PcdStartConfidentialMigrationHandler
gUefiOvmfPkgTokenSpaceGuid.PcdConfidentialMigrationMailboxBase
+ gUefiCpuPkgTokenSpaceGuid.PcdCpuApStackSize

[Depex]
gEfiMpServiceProtocolGuid
diff --git a/OvmfPkg/AmdSev/ConfidentialMigration/MpLib.h b/OvmfPkg/AmdSev/ConfidentialMigration/MpLib.h
new file mode 100644
index 0000000000..5007e25243
--- /dev/null
+++ b/OvmfPkg/AmdSev/ConfidentialMigration/MpLib.h
@@ -0,0 +1,235 @@
+/** @file
+ Common header file for MP Initialize Library.
+ -- adapted from UefiCpuPkg/Library/MpInitLib/MpLib.h
+ Copyright (c) 2016 - 2020, Intel Corporation. All rights reserved.<BR>
+ Copyright (c) 2020, AMD Inc. All rights reserved.<BR>
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _MP_LIB_H_
+#define _MP_LIB_H_
+
+#include <PiPei.h>
+
+#include <Library/MpInitLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/CpuLib.h>
+#include <Library/HobLib.h>
+#include <Library/SynchronizationLib.h>
+#include <Library/MtrrLib.h>
+
+#define CPU_INIT_MP_LIB_HOB_GUID \
+ { \
+ 0x58eb6a19, 0x3699, 0x4c68, { 0xa8, 0x36, 0xda, 0xcd, 0x8e, 0xdc, 0xad, 0x4a } \
+ }
+
+
+//
+// CPU exchange information for switch BSP
+//
+typedef struct {
+ UINT8 State; // offset 0
+ UINTN StackPointer; // offset 4 / 8
+ IA32_DESCRIPTOR Gdtr; // offset 8 / 16
+ IA32_DESCRIPTOR Idtr; // offset 14 / 26
+} CPU_EXCHANGE_ROLE_INFO;
+
+//
+// AP initialization state during APs wakeup
+//
+typedef enum {
+ ApInitConfig = 1,
+ ApInitReconfig = 2,
+ ApInitDone = 3
+} AP_INIT_STATE;
+
+//
+// AP state
+//
+// The state transitions for an AP when it process a procedure are:
+// Idle ----> Ready ----> Busy ----> Idle
+// [BSP] [AP] [AP]
+//
+typedef enum {
+ CpuStateIdle,
+ CpuStateReady,
+ CpuStateBusy,
+ CpuStateFinished,
+ CpuStateDisabled
+} CPU_STATE;
+
+//
+// CPU volatile registers around INIT-SIPI-SIPI
+//
+typedef struct {
+ UINTN Cr0;
+ UINTN Cr3;
+ UINTN Cr4;
+ UINTN Dr0;
+ UINTN Dr1;
+ UINTN Dr2;
+ UINTN Dr3;
+ UINTN Dr6;
+ UINTN Dr7;
+ IA32_DESCRIPTOR Gdtr;
+ IA32_DESCRIPTOR Idtr;
+ UINT16 Tr;
+} CPU_VOLATILE_REGISTERS;
+
+//
+// AP related data
+//
+typedef struct {
+ SPIN_LOCK ApLock;
+ volatile UINT32 *StartupApSignal;
+ volatile UINTN ApFunction;
+ volatile UINTN ApFunctionArgument;
+ BOOLEAN CpuHealthy;
+ volatile CPU_STATE State;
+ CPU_VOLATILE_REGISTERS VolatileRegisters;
+ BOOLEAN Waiting;
+ BOOLEAN *Finished;
+ UINT64 ExpectedTime;
+ UINT64 CurrentTime;
+ UINT64 TotalTime;
+ EFI_EVENT WaitEvent;
+ UINT32 ProcessorSignature;
+ UINT8 PlatformId;
+ UINT64 MicrocodeEntryAddr;
+} CPU_AP_DATA;
+
+//
+// Basic CPU information saved in Guided HOB.
+// Because the contents will be shard between PEI and DXE,
+// we need to make sure the each fields offset same in different
+// architecture.
+//
+#pragma pack (1)
+typedef struct {
+ UINT32 InitialApicId;
+ UINT32 ApicId;
+ UINT32 Health;
+ UINT64 ApTopOfStack;
+} CPU_INFO_IN_HOB;
+#pragma pack ()
+
+//
+// AP reset code information including code address and size,
+// this structure will be shared be C code and assembly code.
+// It is natural aligned by design.
+//
+typedef struct {
+ UINT8 *RendezvousFunnelAddress;
+ UINTN ModeEntryOffset;
+ UINTN RendezvousFunnelSize;
+ UINT8 *RelocateApLoopFuncAddress;
+ UINTN RelocateApLoopFuncSize;
+ UINTN ModeTransitionOffset;
+} MP_ASSEMBLY_ADDRESS_MAP;
+
+typedef struct _CPU_MP_DATA CPU_MP_DATA;
+
+#pragma pack(1)
+
+//
+// MP CPU exchange information for AP reset code
+// This structure is required to be packed because fixed field offsets
+// into this structure are used in assembly code in this module
+//
+typedef struct {
+ UINTN Lock;
+ UINTN StackStart;
+ UINTN StackSize;
+ UINTN CFunction;
+ IA32_DESCRIPTOR GdtrProfile;
+ IA32_DESCRIPTOR IdtrProfile;
+ UINTN BufferStart;
+ UINTN ModeOffset;
+ UINTN ApIndex;
+ UINTN CodeSegment;
+ UINTN DataSegment;
+ UINTN EnableExecuteDisable;
+ UINTN Cr3;
+ UINTN InitFlag;
+ CPU_INFO_IN_HOB *CpuInfo;
+ UINTN NumApsExecuting;
+ CPU_MP_DATA *CpuMpData;
+ UINTN InitializeFloatingPointUnitsAddress;
+ UINT32 ModeTransitionMemory;
+ UINT16 ModeTransitionSegment;
+ UINT32 ModeHighMemory;
+ UINT16 ModeHighSegment;
+ //
+ // Enable5LevelPaging indicates whether 5-level paging is enabled in long mode.
+ //
+ BOOLEAN Enable5LevelPaging;
+} MP_CPU_EXCHANGE_INFO;
+
+#pragma pack()
+
+//
+// CPU MP Data save in memory
+//
+struct _CPU_MP_DATA {
+ UINT64 CpuInfoInHob;
+ UINT32 CpuCount;
+ UINT32 BspNumber;
+ //
+ // The above fields data will be passed from PEI to DXE
+ // Please make sure the fields offset same in the different
+ // architecture.
+ //
+ SPIN_LOCK MpLock;
+ UINTN Buffer;
+ UINTN CpuApStackSize;
+ MP_ASSEMBLY_ADDRESS_MAP AddressMap;
+ UINTN WakeupBuffer;
+ UINTN WakeupBufferHigh;
+ UINTN BackupBuffer;
+ UINTN BackupBufferSize;
+
+ volatile UINT32 FinishedCount;
+ UINT32 RunningCount;
+ BOOLEAN SingleThread;
+ EFI_AP_PROCEDURE Procedure;
+ VOID *ProcArguments;
+ BOOLEAN *Finished;
+ UINT64 ExpectedTime;
+ UINT64 CurrentTime;
+ UINT64 TotalTime;
+ EFI_EVENT WaitEvent;
+ UINTN **FailedCpuList;
+
+ AP_INIT_STATE InitFlag;
+ BOOLEAN SwitchBspFlag;
+ UINTN NewBspNumber;
+ CPU_EXCHANGE_ROLE_INFO BSPInfo;
+ CPU_EXCHANGE_ROLE_INFO APInfo;
+ MTRR_SETTINGS MtrrTable;
+ UINT8 ApLoopMode;
+ UINT8 ApTargetCState;
+ UINT16 PmCodeSegment;
+ CPU_AP_DATA *CpuData;
+ volatile MP_CPU_EXCHANGE_INFO *MpCpuExchangeInfo;
+
+ UINT32 CurrentTimerCount;
+ UINTN DivideValue;
+ UINT8 Vector;
+ BOOLEAN PeriodicMode;
+ BOOLEAN TimerInterruptState;
+ UINT64 MicrocodePatchAddress;
+ UINT64 MicrocodePatchRegionSize;
+
+ //
+ // Whether need to use Init-Sipi-Sipi to wake up the APs.
+ // Two cases need to set this value to TRUE. One is in HLT
+ // loop mode, the other is resume from S3 which loop mode
+ // will be hardcode change to HLT mode by PiSmmCpuDxeSmm
+ // driver.
+ //
+ BOOLEAN WakeUpByInitSipiSipi;
+};
+
+extern EFI_GUID mCpuInitMpLibHobGuid;
+
+#endif
diff --git a/OvmfPkg/AmdSev/ConfidentialMigration/ConfidentialMigrationDxe.c b/OvmfPkg/AmdSev/ConfidentialMigration/ConfidentialMigrationDxe.c
index f609e16f8d..42b99be552 100644
--- a/OvmfPkg/AmdSev/ConfidentialMigration/ConfidentialMigrationDxe.c
+++ b/OvmfPkg/AmdSev/ConfidentialMigration/ConfidentialMigrationDxe.c
@@ -12,6 +12,8 @@
#include <Library/BaseMemoryLib.h>

#include "VirtualMemory.h"
+#include "MpLib.h"
+
//
// Functions implemented by the migration handler
//
@@ -114,6 +116,7 @@ PrepareMigrationHandlerPageTables (
mMigrationHelperPageTables = (UINT64)Start | AddressEncMask;
}

+
VOID
SwitchToMigrationHelperPageTables(VOID)
{
@@ -121,6 +124,25 @@ SwitchToMigrationHelperPageTables(VOID)
}


+UINT64
+GetMHTopOfStack()
+{
+ EFI_HOB_GUID_TYPE *GuidHob;
+ VOID *DataInHob;
+ CPU_MP_DATA *CpuMpData;
+ CPU_INFO_IN_HOB *CpuInfoInHob;
+
+ GuidHob = GetFirstGuidHob (&mCpuInitMpLibHobGuid);
+ ASSERT(GuidHob != NULL);
+
+ DataInHob = GET_GUID_HOB_DATA (GuidHob);
+ CpuMpData = (CPU_MP_DATA *) (*(UINTN *) DataInHob);
+ CpuInfoInHob = (CPU_INFO_IN_HOB *) (UINTN) CpuMpData->CpuInfoInHob;
+
+ return CpuInfoInHob[MigrationHandlerCpuIndex].ApTopOfStack;
+
+}
+

VOID
EFIAPI
@@ -132,6 +154,8 @@ MigrationHandlerMain (
UINT64 mailbox_end;
UINT64 pagetable_start;
UINT64 pagetable_end;
+ UINT64 stack_start;
+ UINT64 stack_end;
UINT64 params_base;
MH_COMMAND_PARAMETERS *params;
VOID *page_va;
@@ -153,6 +177,9 @@ MigrationHandlerMain (
pagetable_start = mMigrationHelperPageTables;
pagetable_end = pagetable_start + 11 * EFI_PAGE_SIZE;

+ stack_end = GetMHTopOfStack();
+ stack_start = stack_end - PcdGet32(PcdCpuApStackSize);
+
DisableInterrupts();
params->go = 0;

@@ -177,7 +204,8 @@ MigrationHandlerMain (
// Don't import a page that covers the mailbox or pagetables.
//
if ((params->gpa >= mailbox_start && params->gpa < mailbox_end) ||
- (params->gpa >= pagetable_start && params->gpa < pagetable_end)) {
+ (params->gpa >= pagetable_start && params->gpa < pagetable_end) ||
+ (params->gpa >= stack_start && params->gpa < stack_end)) {
}
else {
CopyMem((VOID *)params->gpa, page_va, 4096);
--
2.20.1


[RFC PATCH 14/14] OvmfPkg/AmdSev: MH page encryption POC

Tobin Feldman-Fitzthum <tobin@...>
 

This code is for demonstration purposes only. It is not secure or
robust. The purpose is to show where encryption will be incorporated
and to get a sense of the performance impact of adding encryption.

We plan to use AES-GCM to encrypt the pages as a stream. This will
also allow us to verify the GPA as part of the AAD, ensuring that
a malicious hypervisor hasn't exchanged pages in-flight.

Currently the CryptoPkg and the BaseCryptLib do not expose AES-GCM,
despite it being included in OpensslLib. Thus, we use CBC here.

Key sharing is out of scope for this part of the RFC. We assume that
the source and destination MH share a key. This will probably be
implemented via inject-launch-secret in the future. For now, we
hardcode a key, but this is strictly temporary.

We have had trouble using RandomBytes() in the MH when SEV is
enabled. Thus the IV is hardcoded. Again, this is temporary.

The HV and the MH will exchange information pertaining to encryption,
like the IV, via an additional header on the shared mailbox page.

This patch does not do any safety checks or handle encrypt/decrypt
failures. Again, this is only here to show where encryption will
go and generally how the MH on the source and target can share
pages without exposing guest memory to the HV.

Signed-off-by: Tobin Feldman-Fitzthum <tobin@...>
---
.../ConfidentialMigrationDxe.inf | 2 ++
.../ConfidentialMigrationDxe.c | 36 +++++++++++++++++--
2 files changed, 36 insertions(+), 2 deletions(-)

diff --git a/OvmfPkg/AmdSev/ConfidentialMigration/ConfidentialMigrationDxe.inf b/OvmfPkg/AmdSev/ConfidentialMigration/ConfidentialMigrationDxe.inf
index 2816952863..ae074a8b07 100644
--- a/OvmfPkg/AmdSev/ConfidentialMigration/ConfidentialMigrationDxe.inf
+++ b/OvmfPkg/AmdSev/ConfidentialMigration/ConfidentialMigrationDxe.inf
@@ -22,6 +22,7 @@
MdePkg/MdePkg.dec
OvmfPkg/OvmfPkg.dec
UefiCpuPkg/UefiCpuPkg.dec
+ CryptoPkg/CryptoPkg.dec

[LibraryClasses]
MemoryAllocationLib
@@ -29,6 +30,7 @@
UefiBootServicesTableLib
MpInitLib
UefiDriverEntryPoint
+ BaseCryptLib

[Protocols]
gEfiMpServiceProtocolGuid
diff --git a/OvmfPkg/AmdSev/ConfidentialMigration/ConfidentialMigrationDxe.c b/OvmfPkg/AmdSev/ConfidentialMigration/ConfidentialMigrationDxe.c
index 42b99be552..a9cb490561 100644
--- a/OvmfPkg/AmdSev/ConfidentialMigration/ConfidentialMigrationDxe.c
+++ b/OvmfPkg/AmdSev/ConfidentialMigration/ConfidentialMigrationDxe.c
@@ -10,6 +10,7 @@
#include <Library/DebugLib.h>
#include <Protocol/MpService.h>
#include <Library/BaseMemoryLib.h>
+#include <Library/BaseCryptLib.h>

#include "VirtualMemory.h"
#include "MpLib.h"
@@ -46,6 +47,14 @@ typedef volatile struct {
UINT32 done;
} MH_COMMAND_PARAMETERS;

+//
+// Additional header for encryption support.
+//
+struct page_hdr {
+ UINT8 IV[16];
+ UINT8 tag[16];
+};
+
//
// Addresses for MH page table.
//
@@ -57,6 +66,20 @@ STATIC PHYSICAL_ADDRESS mMigrationHelperPageTables = 0;
//
#define UNENC_VIRT_ADDR_BASE 0xffffff8000000000ULL

+//
+// Key shared between source and target MH (temporary)
+//
+GLOBAL_REMOVE_IF_UNREFERENCED CONST UINT8 cipher_key[] = {
+ 0xc2, 0x86, 0x69, 0x6d, 0x88, 0x7c, 0x9a, 0xa0, 0x61, 0x1b, 0xbb, 0x3e, 0x20, 0x25, 0xa4, 0x5a
+ };
+
+//
+// IV for CBC cipher (temporary). We are having trouble with
+// calling RandomBytes from inside the Migration Handler
+//
+GLOBAL_REMOVE_IF_UNREFERENCED UINT8 Ivec[] = {
+ 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10
+};

/**
Allocates and fills in custom page tables for Migration Handler.
@@ -159,6 +182,8 @@ MigrationHandlerMain (
UINT64 params_base;
MH_COMMAND_PARAMETERS *params;
VOID *page_va;
+ VOID *cipher_ctx;
+ INTN ctx_size;

DebugPrint (DEBUG_INFO,"MIGRATION Handler Started\n");

@@ -171,6 +196,7 @@ MigrationHandlerMain (
params_base = mailbox_start + UNENC_VIRT_ADDR_BASE;
params = (VOID *)params_base;
page_va = (VOID *)params_base + 0x1000;
+ //struct page_hdr *hdr_va = (void *) params_base + 0x800;

mailbox_end = mailbox_start + 2 * EFI_PAGE_SIZE;

@@ -180,6 +206,9 @@ MigrationHandlerMain (
stack_end = GetMHTopOfStack();
stack_start = stack_end - PcdGet32(PcdCpuApStackSize);

+ ctx_size = AesGetContextSize ();
+ cipher_ctx = AllocateRuntimePool (ctx_size);
+
DisableInterrupts();
params->go = 0;

@@ -195,7 +224,9 @@ MigrationHandlerMain (
break;

case MH_FUNC_SAVE_PAGE:
- CopyMem(page_va, (VOID *)params->gpa, 4096);
+ AesInit (cipher_ctx, cipher_key, 128);
+ AesCbcEncrypt(cipher_ctx, (VOID *)params->gpa, 4096, Ivec, page_va);
+
params->ret = MH_SUCCESS;
break;

@@ -208,7 +239,8 @@ MigrationHandlerMain (
(params->gpa >= stack_start && params->gpa < stack_end)) {
}
else {
- CopyMem((VOID *)params->gpa, page_va, 4096);
+ AesInit (cipher_ctx, cipher_key, 128);
+ AesCbcDecrypt (cipher_ctx, page_va, 4096, Ivec, (VOID *)params->gpa);
}
params->ret = MH_SUCCESS;
break;
--
2.20.1


[RFC PATCH 12/14] OvmfPkg/AmdSev: Don't overwrite mailbox or pagetables

Tobin Feldman-Fitzthum <tobin@...>
 

While restoring pages, the MH should avoid overwriting its
pagetables or the mailbox it uses to communicate with the HV.

Signed-off-by: Tobin Feldman-Fitzthum <tobin@...>
---
.../ConfidentialMigrationDxe.c | 22 +++++++++++++++++--
1 file changed, 20 insertions(+), 2 deletions(-)

diff --git a/OvmfPkg/AmdSev/ConfidentialMigration/ConfidentialMigrationDxe.c b/OvmfPkg/AmdSev/ConfidentialMigration/ConfidentialMigrationDxe.c
index 3df3b09732..f609e16f8d 100644
--- a/OvmfPkg/AmdSev/ConfidentialMigration/ConfidentialMigrationDxe.c
+++ b/OvmfPkg/AmdSev/ConfidentialMigration/ConfidentialMigrationDxe.c
@@ -128,6 +128,10 @@ MigrationHandlerMain (
IN OUT VOID *Buffer
)
{
+ UINT64 mailbox_start;
+ UINT64 mailbox_end;
+ UINT64 pagetable_start;
+ UINT64 pagetable_end;
UINT64 params_base;
MH_COMMAND_PARAMETERS *params;
VOID *page_va;
@@ -139,10 +143,16 @@ MigrationHandlerMain (
//
// Shared pages must be offset by UNENC_VIRT_ADDR_BASE.
//
- params_base = PcdGet32 (PcdConfidentialMigrationMailboxBase) + UNENC_VIRT_ADDR_BASE;
+ mailbox_start = PcdGet32 (PcdConfidentialMigrationMailboxBase);
+ params_base = mailbox_start + UNENC_VIRT_ADDR_BASE;
params = (VOID *)params_base;
page_va = (VOID *)params_base + 0x1000;

+ mailbox_end = mailbox_start + 2 * EFI_PAGE_SIZE;
+
+ pagetable_start = mMigrationHelperPageTables;
+ pagetable_end = pagetable_start + 11 * EFI_PAGE_SIZE;
+
DisableInterrupts();
params->go = 0;

@@ -163,7 +173,15 @@ MigrationHandlerMain (
break;

case MH_FUNC_RESTORE_PAGE:
- CopyMem((VOID *)params->gpa, page_va, 4096);
+ //
+ // Don't import a page that covers the mailbox or pagetables.
+ //
+ if ((params->gpa >= mailbox_start && params->gpa < mailbox_end) ||
+ (params->gpa >= pagetable_start && params->gpa < pagetable_end)) {
+ }
+ else {
+ CopyMem((VOID *)params->gpa, page_va, 4096);
+ }
params->ret = MH_SUCCESS;
break;

--
2.20.1


[RFC PATCH 10/14] UefiCpuPkg/CpuExceptionHandlerLib: Exception handling as runtime memory

Tobin Feldman-Fitzthum <tobin@...>
 

Reserve IDT and other exception-related memory as runtime so
it won't be overwritten by the OS while the MH is running.

Signed-off-by: Tobin Feldman-Fitzthum <tobin@...>
---
UefiCpuPkg/Library/CpuExceptionHandlerLib/DxeException.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/UefiCpuPkg/Library/CpuExceptionHandlerLib/DxeException.c b/UefiCpuPkg/Library/CpuExceptionHandlerLib/DxeException.c
index fd59f09ecd..35610f8cf5 100644
--- a/UefiCpuPkg/Library/CpuExceptionHandlerLib/DxeException.c
+++ b/UefiCpuPkg/Library/CpuExceptionHandlerLib/DxeException.c
@@ -102,7 +102,7 @@ InitializeCpuInterruptHandlers (
EFI_CPU_INTERRUPT_HANDLER *ExternalInterruptHandler;

Status = gBS->AllocatePool (
- EfiBootServicesCode,
+ EfiRuntimeServicesCode,
sizeof (RESERVED_VECTORS_DATA) * CPU_INTERRUPT_NUM,
(VOID **)&ReservedVectors
);
@@ -116,7 +116,7 @@ InitializeCpuInterruptHandlers (
}
}

- ExternalInterruptHandler = AllocateZeroPool (sizeof (EFI_CPU_INTERRUPT_HANDLER) * CPU_INTERRUPT_NUM);
+ ExternalInterruptHandler = AllocateRuntimeZeroPool (sizeof (EFI_CPU_INTERRUPT_HANDLER) * CPU_INTERRUPT_NUM);
ASSERT (ExternalInterruptHandler != NULL);

//
@@ -130,7 +130,7 @@ InitializeCpuInterruptHandlers (
//
// Create Interrupt Descriptor Table and Copy the old IDT table in
//
- IdtTable = AllocateZeroPool (sizeof (IA32_IDT_GATE_DESCRIPTOR) * CPU_INTERRUPT_NUM);
+ IdtTable = AllocateRuntimeZeroPool (sizeof (IA32_IDT_GATE_DESCRIPTOR) * CPU_INTERRUPT_NUM);
ASSERT (IdtTable != NULL);
CopyMem (IdtTable, (VOID *)IdtDescriptor.Base, sizeof (IA32_IDT_GATE_DESCRIPTOR) * IdtEntryCount);

@@ -138,7 +138,7 @@ InitializeCpuInterruptHandlers (
ASSERT (TemplateMap.ExceptionStubHeaderSize <= HOOKAFTER_STUB_SIZE);

Status = gBS->AllocatePool (
- EfiBootServicesCode,
+ EfiRuntimeServicesCode,
TemplateMap.ExceptionStubHeaderSize * CPU_INTERRUPT_NUM,
(VOID **)&InterruptEntryCode
);
--
2.20.1


[RFC PATCH 09/14] UefiCpuPkg/MpInitLib: Allocate MP buffer as runtime memory

Tobin Feldman-Fitzthum <tobin@...>
 

Another temporary change to support the persistence of the MH.
The Mp buffer needs to be allocated as runtime memory or it
may be overwritten by the OS.

Signed-off-by: Tobin Feldman-Fitzthum <tobin@...>
---
UefiCpuPkg/Library/MpInitLib/PeiMpInitLib.inf | 2 ++
UefiCpuPkg/Library/MpInitLib/MpLib.c | 7 ++++++-
2 files changed, 8 insertions(+), 1 deletion(-)

diff --git a/UefiCpuPkg/Library/MpInitLib/PeiMpInitLib.inf b/UefiCpuPkg/Library/MpInitLib/PeiMpInitLib.inf
index 34abf25d43..0b26cf6aaf 100644
--- a/UefiCpuPkg/Library/MpInitLib/PeiMpInitLib.inf
+++ b/UefiCpuPkg/Library/MpInitLib/PeiMpInitLib.inf
@@ -39,6 +39,7 @@
MdePkg/MdePkg.dec
UefiCpuPkg/UefiCpuPkg.dec
MdeModulePkg/MdeModulePkg.dec
+ OvmfPkg/OvmfPkg.dec

[LibraryClasses]
BaseLib
@@ -65,6 +66,7 @@
gUefiCpuPkgTokenSpaceGuid.PcdSevEsIsEnabled ## CONSUMES
gUefiCpuPkgTokenSpaceGuid.PcdSevEsWorkAreaBase ## SOMETIMES_CONSUMES
gEfiMdeModulePkgTokenSpaceGuid.PcdGhcbBase ## CONSUMES
+ gUefiOvmfPkgTokenSpaceGuid.PcdStartConfidentialMigrationHandler

[Ppis]
gEdkiiPeiShadowMicrocodePpiGuid ## SOMETIMES_CONSUMES
diff --git a/UefiCpuPkg/Library/MpInitLib/MpLib.c b/UefiCpuPkg/Library/MpInitLib/MpLib.c
index 2568986d8c..0ca2858ca3 100644
--- a/UefiCpuPkg/Library/MpInitLib/MpLib.c
+++ b/UefiCpuPkg/Library/MpInitLib/MpLib.c
@@ -1974,7 +1974,12 @@ MpInitLibInitialize (
BufferSize += VolatileRegisters.Idtr.Limit + 1;
BufferSize += sizeof (CPU_MP_DATA);
BufferSize += (sizeof (CPU_AP_DATA) + sizeof (CPU_INFO_IN_HOB))* MaxLogicalProcessorNumber;
- MpBuffer = AllocatePages (EFI_SIZE_TO_PAGES (BufferSize));
+ if (PcdGetBool (PcdStartConfidentialMigrationHandler)) {
+ MpBuffer = AllocateRuntimePages (EFI_SIZE_TO_PAGES (BufferSize));
+ }
+ else {
+ MpBuffer = AllocatePages (EFI_SIZE_TO_PAGES (BufferSize));
+ }
ASSERT (MpBuffer != NULL);
ZeroMem (MpBuffer, BufferSize);
Buffer = (UINTN) MpBuffer;
--
2.20.1


[RFC PATCH 08/14] UefiCpuPkg/MpInitLib: temp removal of MpLib cleanup

Tobin Feldman-Fitzthum <tobin@...>
 

The Migration Handdler is started using the Mp Service, which
is only designed to function during boot time. The MH needs
to run continuously. In the abscence of a generalized persitent
Mp Service, temporary alterations were made to keep the MH running.

Here, we skip registering the ExitBootServices callback that
would normally clean up the APs. Obviously this is not suitable
for production, as it does not generalize for multiple APs
(it leaves all APs untouched rather than just the MH) and it
introduces a weird dependency where the MpLib needs an
OVMF PCD.

Signed-off-by: Tobin Feldman-Fitzthum <tobin@...>
---
UefiCpuPkg/Library/MpInitLib/DxeMpInitLib.inf | 2 ++
UefiCpuPkg/Library/MpInitLib/DxeMpLib.c | 21 ++++++++++++-------
2 files changed, 15 insertions(+), 8 deletions(-)

diff --git a/UefiCpuPkg/Library/MpInitLib/DxeMpInitLib.inf b/UefiCpuPkg/Library/MpInitLib/DxeMpInitLib.inf
index 1771575c69..71cc968de8 100644
--- a/UefiCpuPkg/Library/MpInitLib/DxeMpInitLib.inf
+++ b/UefiCpuPkg/Library/MpInitLib/DxeMpInitLib.inf
@@ -39,6 +39,7 @@
MdePkg/MdePkg.dec
MdeModulePkg/MdeModulePkg.dec
UefiCpuPkg/UefiCpuPkg.dec
+ OvmfPkg/OvmfPkg.dec

[LibraryClasses]
BaseLib
@@ -76,3 +77,4 @@
gUefiCpuPkgTokenSpaceGuid.PcdSevEsWorkAreaBase ## SOMETIMES_CONSUMES
gEfiMdeModulePkgTokenSpaceGuid.PcdCpuStackGuard ## CONSUMES
gEfiMdeModulePkgTokenSpaceGuid.PcdGhcbBase ## CONSUMES
+ gUefiOvmfPkgTokenSpaceGuid.PcdStartConfidentialMigrationHandler
diff --git a/UefiCpuPkg/Library/MpInitLib/DxeMpLib.c b/UefiCpuPkg/Library/MpInitLib/DxeMpLib.c
index 7839c24976..7d59ec4a92 100644
--- a/UefiCpuPkg/Library/MpInitLib/DxeMpLib.c
+++ b/UefiCpuPkg/Library/MpInitLib/DxeMpLib.c
@@ -569,14 +569,19 @@ InitMpGlobalData (
);
ASSERT_EFI_ERROR (Status);

- Status = gBS->CreateEvent (
- EVT_SIGNAL_EXIT_BOOT_SERVICES,
- TPL_CALLBACK,
- MpInitChangeApLoopCallback,
- NULL,
- &mMpInitExitBootServicesEvent
- );
- ASSERT_EFI_ERROR (Status);
+ //
+ // Workaround for persistent processes .
+ //
+ if (!PcdGetBool (PcdStartConfidentialMigrationHandler)) {
+ Status = gBS->CreateEvent (
+ EVT_SIGNAL_EXIT_BOOT_SERVICES,
+ TPL_CALLBACK,
+ MpInitChangeApLoopCallback,
+ NULL,
+ &mMpInitExitBootServicesEvent
+ );
+ ASSERT_EFI_ERROR (Status);
+ }

Status = gBS->CreateEventEx (
EVT_NOTIFY_SIGNAL,
--
2.20.1


[RFC PATCH 05/14] OvmfPkg/PlatfomPei: Set Confidential Migration PCD

Tobin Feldman-Fitzthum <tobin@...>
 

Confidential Migration relies on two boolean PCDs set from FW_CFG

Signed-off-by: Tobin Feldman-Fitzthum <tobin@...>
---
OvmfPkg/PlatformPei/PlatformPei.inf | 2 ++
OvmfPkg/PlatformPei/Platform.c | 10 ++++++++++
2 files changed, 12 insertions(+)

diff --git a/OvmfPkg/PlatformPei/PlatformPei.inf b/OvmfPkg/PlatformPei/PlatformPei.inf
index 6ef77ba7bb..66e6fcfa4f 100644
--- a/OvmfPkg/PlatformPei/PlatformPei.inf
+++ b/OvmfPkg/PlatformPei/PlatformPei.inf
@@ -92,6 +92,8 @@
gUefiOvmfPkgTokenSpaceGuid.PcdOvmfDecompressionScratchEnd
gUefiOvmfPkgTokenSpaceGuid.PcdQ35TsegMbytes
gUefiOvmfPkgTokenSpaceGuid.PcdQ35SmramAtDefaultSmbase
+ gUefiOvmfPkgTokenSpaceGuid.PcdStartConfidentialMigrationHandler
+ gUefiOvmfPkgTokenSpaceGuid.PcdIsConfidentialMigrationTarget
gEfiMdePkgTokenSpaceGuid.PcdGuidedExtractHandlerTableAddress
gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareSize
gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableSize
diff --git a/OvmfPkg/PlatformPei/Platform.c b/OvmfPkg/PlatformPei/Platform.c
index 96468701e3..5926c8d414 100644
--- a/OvmfPkg/PlatformPei/Platform.c
+++ b/OvmfPkg/PlatformPei/Platform.c
@@ -275,6 +275,15 @@ NoexecDxeInitialization (
UPDATE_BOOLEAN_PCD_FROM_FW_CFG (PcdSetNxForStack);
}

+VOID
+ConfidentialMigrationInitialization (
+ VOID
+ )
+{
+ UPDATE_BOOLEAN_PCD_FROM_FW_CFG (PcdStartConfidentialMigrationHandler);
+ UPDATE_BOOLEAN_PCD_FROM_FW_CFG (PcdIsConfidentialMigrationTarget);
+}
+
VOID
PciExBarInitialization (
VOID
@@ -752,6 +761,7 @@ InitializePlatform (

InstallClearCacheCallback ();
AmdSevInitialize ();
+ ConfidentialMigrationInitialization ();
MiscInitialization ();
InstallFeatureControlCallback ();

--
2.20.1


[RFC PATCH 06/14] OvmfPkg/AmdSev: Setup Migration Handler Mailbox

Tobin Feldman-Fitzthum <tobin@...>
 

The migration handler communicates with the hypervisor using a
special mailbox, a page of shared memory where pending commands
can be written. Another shared page is used to pass the incoming
or outgoing guest memory pages. These pages are set aside in MEMFD,
which this patch expands, and reserved as runtime memory in
ConfidentialMigrationPei, which this patch introduces.

Signed-off-by: Tobin Feldman-Fitzthum <tobin@...>
---
OvmfPkg/OvmfPkg.dec | 5 +++
OvmfPkg/AmdSev/AmdSevX64.dsc | 1 +
OvmfPkg/AmdSev/AmdSevX64.fdf | 12 ++++---
.../ConfidentialMigrationPei.inf | 35 +++++++++++++++++++
.../ConfidentialMigrationPei.c | 25 +++++++++++++
5 files changed, 74 insertions(+), 4 deletions(-)
create mode 100644 OvmfPkg/AmdSev/ConfidentialMigration/ConfidentialMigrationPei.inf
create mode 100644 OvmfPkg/AmdSev/ConfidentialMigration/ConfidentialMigrationPei.c

diff --git a/OvmfPkg/OvmfPkg.dec b/OvmfPkg/OvmfPkg.dec
index 402c3b61fa..5c55e3c7c9 100644
--- a/OvmfPkg/OvmfPkg.dec
+++ b/OvmfPkg/OvmfPkg.dec
@@ -318,6 +318,11 @@
gUefiOvmfPkgTokenSpaceGuid.PcdSevLaunchSecretBase|0x0|UINT32|0x42
gUefiOvmfPkgTokenSpaceGuid.PcdSevLaunchSecretSize|0x0|UINT32|0x43

+ ## Area used by the confidential migration handler to communicate with
+ # the hypervisor.
+ gUefiOvmfPkgTokenSpaceGuid.PcdConfidentialMigrationMailboxBase|0x0|UINT32|0x48
+ gUefiOvmfPkgTokenSpaceGuid.PcdConfidentialMigrationMailboxSize|0x0|UINT32|0x49
+
[PcdsDynamic, PcdsDynamicEx]
gUefiOvmfPkgTokenSpaceGuid.PcdEmuVariableEvent|0|UINT64|2
gUefiOvmfPkgTokenSpaceGuid.PcdOvmfFlashVariablesEnable|FALSE|BOOLEAN|0x10
diff --git a/OvmfPkg/AmdSev/AmdSevX64.dsc b/OvmfPkg/AmdSev/AmdSevX64.dsc
index fa68143663..4f748a0015 100644
--- a/OvmfPkg/AmdSev/AmdSevX64.dsc
+++ b/OvmfPkg/AmdSev/AmdSevX64.dsc
@@ -620,6 +620,7 @@
UefiCpuPkg/Universal/Acpi/S3Resume2Pei/S3Resume2Pei.inf
UefiCpuPkg/CpuMpPei/CpuMpPei.inf
OvmfPkg/AmdSev/SecretPei/SecretPei.inf
+ OvmfPkg/AmdSev/ConfidentialMigration/ConfidentialMigrationPei.inf

!if $(TPM_ENABLE) == TRUE
OvmfPkg/Tcg/Tcg2Config/Tcg2ConfigPei.inf
diff --git a/OvmfPkg/AmdSev/AmdSevX64.fdf b/OvmfPkg/AmdSev/AmdSevX64.fdf
index 6ef6dc89f2..94468f2ca0 100644
--- a/OvmfPkg/AmdSev/AmdSevX64.fdf
+++ b/OvmfPkg/AmdSev/AmdSevX64.fdf
@@ -36,10 +36,10 @@ FV = SECFV

[FD.MEMFD]
BaseAddress = $(MEMFD_BASE_ADDRESS)
-Size = 0xD00000
+Size = 0xE00000
ErasePolarity = 1
BlockSize = 0x10000
-NumBlocks = 0xD0
+NumBlocks = 0xE0

0x000000|0x006000
gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecPageTablesBase|gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecPageTablesSize
@@ -68,11 +68,14 @@ gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecGhcbBackupBase|gUefiOvmfPkgTokenSpaceGuid.P
0x010000|0x010000
gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecPeiTempRamBase|gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecPeiTempRamSize

-0x020000|0x0E0000
+0x020000|0x003000
+gUefiOvmfPkgTokenSpaceGuid.PcdConfidentialMigrationMailboxBase|gUefiOvmfPkgTokenSpaceGuid.PcdConfidentialMigrationMailboxSize
+
+0x120000|0x0E0000
gUefiOvmfPkgTokenSpaceGuid.PcdOvmfPeiMemFvBase|gUefiOvmfPkgTokenSpaceGuid.PcdOvmfPeiMemFvSize
FV = PEIFV

-0x100000|0xC00000
+0x200000|0xC00000
gUefiOvmfPkgTokenSpaceGuid.PcdOvmfDxeMemFvBase|gUefiOvmfPkgTokenSpaceGuid.PcdOvmfDxeMemFvSize
FV = DXEFV

@@ -145,6 +148,7 @@ INF MdeModulePkg/Core/DxeIplPeim/DxeIpl.inf
INF UefiCpuPkg/Universal/Acpi/S3Resume2Pei/S3Resume2Pei.inf
INF UefiCpuPkg/CpuMpPei/CpuMpPei.inf
INF OvmfPkg/AmdSev/SecretPei/SecretPei.inf
+INF OvmfPkg/AmdSev/ConfidentialMigration/ConfidentialMigrationPei.inf

!if $(TPM_ENABLE) == TRUE
INF OvmfPkg/Tcg/Tcg2Config/Tcg2ConfigPei.inf
diff --git a/OvmfPkg/AmdSev/ConfidentialMigration/ConfidentialMigrationPei.inf b/OvmfPkg/AmdSev/ConfidentialMigration/ConfidentialMigrationPei.inf
new file mode 100644
index 0000000000..918cf22abd
--- /dev/null
+++ b/OvmfPkg/AmdSev/ConfidentialMigration/ConfidentialMigrationPei.inf
@@ -0,0 +1,35 @@
+## @file
+# PEI support for confidential migration.
+#
+# Copyright (C) 2021 IBM Corporation.
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = ConfidentialMigration
+ FILE_GUID = a747792e-71a1-4c24-84a9-a76a0a279878
+ MODULE_TYPE = PEIM
+ VERSION_STRING = 1.0
+ ENTRY_POINT = InitializeConfidentialMigrationPei
+
+[Sources]
+ ConfidentialMigrationPei.c
+
+[Packages]
+ OvmfPkg/OvmfPkg.dec
+ MdePkg/MdePkg.dec
+
+[LibraryClasses]
+ HobLib
+ PeimEntryPoint
+ PcdLib
+
+[FixedPcd]
+ gUefiOvmfPkgTokenSpaceGuid.PcdConfidentialMigrationMailboxBase
+ gUefiOvmfPkgTokenSpaceGuid.PcdConfidentialMigrationMailboxSize
+
+[Depex]
+ TRUE
diff --git a/OvmfPkg/AmdSev/ConfidentialMigration/ConfidentialMigrationPei.c b/OvmfPkg/AmdSev/ConfidentialMigration/ConfidentialMigrationPei.c
new file mode 100644
index 0000000000..ce304bc07b
--- /dev/null
+++ b/OvmfPkg/AmdSev/ConfidentialMigration/ConfidentialMigrationPei.c
@@ -0,0 +1,25 @@
+/** @file
+ Reserve memory for confidential migration handler.
+
+ Copyright (C) 2020 IBM Corporation.
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+#include <PiPei.h>
+#include <Library/HobLib.h>
+#include <Library/PcdLib.h>
+
+EFI_STATUS
+EFIAPI
+InitializeConfidentialMigrationPei (
+ IN EFI_PEI_FILE_HANDLE FileHandle,
+ IN CONST EFI_PEI_SERVICES **PeiServices
+ )
+{
+ BuildMemoryAllocationHob (
+ PcdGet32 (PcdConfidentialMigrationMailboxBase),
+ PcdGet32 (PcdConfidentialMigrationMailboxSize),
+ EfiRuntimeServicesData
+ );
+
+ return EFI_SUCCESS;
+}
--
2.20.1


[RFC PATCH 04/14] OvmfPkg/AmdSev: Base for Confidential Migration Handler

Tobin Feldman-Fitzthum <tobin@...>
 

Base enablement of DXE driver that supports confidential migration.

Signed-off-by: Tobin Feldman-Fitzthum <tobin@...>
---
OvmfPkg/OvmfPkg.dec | 5 ++
OvmfPkg/AmdSev/AmdSevX64.dsc | 1 +
OvmfPkg/AmdSev/AmdSevX64.fdf | 1 +
.../ConfidentialMigrationDxe.inf | 39 +++++++++
.../ConfidentialMigrationDxe.c | 83 +++++++++++++++++++
5 files changed, 129 insertions(+)
create mode 100644 OvmfPkg/AmdSev/ConfidentialMigration/ConfidentialMigrationDxe.inf
create mode 100644 OvmfPkg/AmdSev/ConfidentialMigration/ConfidentialMigrationDxe.c

diff --git a/OvmfPkg/OvmfPkg.dec b/OvmfPkg/OvmfPkg.dec
index 4450d78b91..402c3b61fa 100644
--- a/OvmfPkg/OvmfPkg.dec
+++ b/OvmfPkg/OvmfPkg.dec
@@ -324,6 +324,11 @@
gUefiOvmfPkgTokenSpaceGuid.PcdOvmfHostBridgePciDevId|0|UINT16|0x1b
gUefiOvmfPkgTokenSpaceGuid.PcdQemuSmbiosValidated|FALSE|BOOLEAN|0x21

+ ## Set via FW_CFG to enable confidentialmigration as source or target.
+ #
+ gUefiOvmfPkgTokenSpaceGuid.PcdIsConfidentialMigrationTarget|FALSE|BOOLEAN|0x46
+ gUefiOvmfPkgTokenSpaceGuid.PcdStartConfidentialMigrationHandler|FALSE|BOOLEAN|0x47
+
## The IO port aperture shared by all PCI root bridges.
#
gUefiOvmfPkgTokenSpaceGuid.PcdPciIoBase|0x0|UINT64|0x22
diff --git a/OvmfPkg/AmdSev/AmdSevX64.dsc b/OvmfPkg/AmdSev/AmdSevX64.dsc
index ca21fd6e5f..fa68143663 100644
--- a/OvmfPkg/AmdSev/AmdSevX64.dsc
+++ b/OvmfPkg/AmdSev/AmdSevX64.dsc
@@ -787,6 +787,7 @@
!endif
OvmfPkg/AmdSev/SecretDxe/SecretDxe.inf
OvmfPkg/AmdSev/Grub/Grub.inf
+ OvmfPkg/AmdSev/ConfidentialMigration/ConfidentialMigrationDxe.inf
!if $(BUILD_SHELL) == TRUE
ShellPkg/Application/Shell/Shell.inf {
<LibraryClasses>
diff --git a/OvmfPkg/AmdSev/AmdSevX64.fdf b/OvmfPkg/AmdSev/AmdSevX64.fdf
index c0098502aa..6ef6dc89f2 100644
--- a/OvmfPkg/AmdSev/AmdSevX64.fdf
+++ b/OvmfPkg/AmdSev/AmdSevX64.fdf
@@ -273,6 +273,7 @@ INF MdeModulePkg/Universal/Disk/UdfDxe/UdfDxe.inf
INF OvmfPkg/LinuxInitrdDynamicShellCommand/LinuxInitrdDynamicShellCommand.inf
!endif
INF OvmfPkg/AmdSev/SecretDxe/SecretDxe.inf
+INF OvmfPkg/AmdSev/ConfidentialMigration/ConfidentialMigrationDxe.inf
INF OvmfPkg/AmdSev/Grub/Grub.inf
!if $(BUILD_SHELL) == TRUE
INF ShellPkg/Application/Shell/Shell.inf
diff --git a/OvmfPkg/AmdSev/ConfidentialMigration/ConfidentialMigrationDxe.inf b/OvmfPkg/AmdSev/ConfidentialMigration/ConfidentialMigrationDxe.inf
new file mode 100644
index 0000000000..a4906a2451
--- /dev/null
+++ b/OvmfPkg/AmdSev/ConfidentialMigration/ConfidentialMigrationDxe.inf
@@ -0,0 +1,39 @@
+## @file
+#
+# Copyright (C) 2021 IBM Corporation.
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = ConfidentialMigration
+ FILE_GUID = 5c2978f4-f175-434b-9e6c-9b03bd7e346f
+ MODULE_TYPE = DXE_DRIVER
+ VERSION_STRING = 1.0
+ ENTRY_POINT = LaunchMigrationHandler
+
+[Sources]
+ ConfidentialMigrationDxe.c
+
+[Packages]
+ MdePkg/MdePkg.dec
+ OvmfPkg/OvmfPkg.dec
+ UefiCpuPkg/UefiCpuPkg.dec
+
+[LibraryClasses]
+ MemoryAllocationLib
+ DebugLib
+ UefiBootServicesTableLib
+ MpInitLib
+ UefiDriverEntryPoint
+
+[Protocols]
+ gEfiMpServiceProtocolGuid
+
+[Pcd]
+ gUefiOvmfPkgTokenSpaceGuid.PcdIsConfidentialMigrationTarget
+ gUefiOvmfPkgTokenSpaceGuid.PcdStartConfidentialMigrationHandler
+
+[Depex]
+ gEfiMpServiceProtocolGuid
diff --git a/OvmfPkg/AmdSev/ConfidentialMigration/ConfidentialMigrationDxe.c b/OvmfPkg/AmdSev/ConfidentialMigration/ConfidentialMigrationDxe.c
new file mode 100644
index 0000000000..6d9fe7043b
--- /dev/null
+++ b/OvmfPkg/AmdSev/ConfidentialMigration/ConfidentialMigrationDxe.c
@@ -0,0 +1,83 @@
+/** @file
+ In-guest support for confidential migration
+
+ Copyright (C) 2021 IBM Coporation.
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+#include <Library/UefiLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UefiRuntimeServicesTableLib.h>
+#include <Library/DebugLib.h>
+#include <Protocol/MpService.h>
+
+UINTN MigrationHandlerCpuIndex;
+
+VOID
+EFIAPI
+MigrationHandlerMain (
+ IN OUT VOID *Buffer
+ )
+{
+ DebugPrint (DEBUG_INFO,"MIGRATION Handler Started\n");
+}
+
+EFI_STATUS
+EFIAPI
+LaunchMigrationHandler (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ EFI_MP_SERVICES_PROTOCOL *MpProto;
+ EFI_PROCESSOR_INFORMATION Tcb;
+ EFI_STATUS Status;
+ UINTN NumProc;
+ UINTN NumEnabled;
+
+ gST = SystemTable;
+ gBS = gST->BootServices;
+ gRT = gST->RuntimeServices;
+
+ Status = EFI_NOT_STARTED;
+
+ if (!PcdGetBool(PcdStartConfidentialMigrationHandler)) {
+ return 0;
+ }
+
+ //
+ // Use the MP Service protocol to start Migration Handler on AP
+ //
+ gBS->LocateProtocol (&gEfiMpServiceProtocolGuid, NULL, (void**)&MpProto);
+ MpProto->GetNumberOfProcessors (MpProto, &NumProc, &NumEnabled);
+ if (NumProc < 2) {
+ DebugPrint (DEBUG_ERROR,"Only one vCPU enabled. Please start an extra for the MH.\n");
+ return 0;
+ }
+
+ MigrationHandlerCpuIndex = NumProc - 1;
+
+ EFI_EVENT Event;
+ MpProto->GetProcessorInfo (MpProto, MigrationHandlerCpuIndex, &Tcb);
+ if (Tcb.StatusFlag != 7) {
+ gBS->CreateEvent (EVT_TIMER, TPL_NOTIFY, NULL, NULL, &Event);
+
+ Status = MpProto->StartupThisAP(MpProto, MigrationHandlerMain, 1, Event,
+ 0, MpProto, NULL);
+ }
+ if (Status != EFI_SUCCESS) {
+ DebugPrint (DEBUG_ERROR,"Failed to start Migration Handler\n");
+ return 0;
+ }
+
+ //
+ // If we are the target, wait for incoming migration. Otherwise,
+ // procede with the boot.
+ //
+ if (PcdGetBool(PcdIsConfidentialMigrationTarget)) {
+ DebugPrint (DEBUG_INFO,"Waiting for incoming confidential migration.\n");
+ DisableInterrupts ();
+ CpuDeadLoop ();
+ }
+
+ return 0;
+}
--
2.20.1


[RFC PATCH 03/14] OvmfPkg/PlatformDxe: Add support for SEV live migration.

Tobin Feldman-Fitzthum <tobin@...>
 

From: Ashish Kalra <ashish.kalra@...>

Detect for KVM hypervisor and check for SEV live migration
feature support via KVM_FEATURE_CPUID, if detected setup a new
UEFI enviroment variable to indicate OVMF support for SEV
live migration.

Signed-off-by: Ashish Kalra <ashish.kalra@...>
---
OvmfPkg/OvmfPkg.dec | 1 +
OvmfPkg/PlatformDxe/Platform.inf | 2 +
OvmfPkg/Include/Guid/MemEncryptLib.h | 16 +++++
OvmfPkg/PlatformDxe/PlatformConfig.h | 5 ++
OvmfPkg/PlatformDxe/AmdSev.c | 99 ++++++++++++++++++++++++++++
OvmfPkg/PlatformDxe/Platform.c | 6 ++
6 files changed, 129 insertions(+)
create mode 100644 OvmfPkg/Include/Guid/MemEncryptLib.h
create mode 100644 OvmfPkg/PlatformDxe/AmdSev.c

diff --git a/OvmfPkg/OvmfPkg.dec b/OvmfPkg/OvmfPkg.dec
index 4348bb45c6..4450d78b91 100644
--- a/OvmfPkg/OvmfPkg.dec
+++ b/OvmfPkg/OvmfPkg.dec
@@ -122,6 +122,7 @@
gQemuKernelLoaderFsMediaGuid = {0x1428f772, 0xb64a, 0x441e, {0xb8, 0xc3, 0x9e, 0xbd, 0xd7, 0xf8, 0x93, 0xc7}}
gGrubFileGuid = {0xb5ae312c, 0xbc8a, 0x43b1, {0x9c, 0x62, 0xeb, 0xb8, 0x26, 0xdd, 0x5d, 0x07}}
gConfidentialComputingSecretGuid = {0xadf956ad, 0xe98c, 0x484c, {0xae, 0x11, 0xb5, 0x1c, 0x7d, 0x33, 0x64, 0x47}}
+ gMemEncryptGuid = {0x0cf29b71, 0x9e51, 0x433a, {0xa3, 0xb7, 0x81, 0xf3, 0xab, 0x16, 0xb8, 0x75}}

[Ppis]
# PPI whose presence in the PPI database signals that the TPM base address
diff --git a/OvmfPkg/PlatformDxe/Platform.inf b/OvmfPkg/PlatformDxe/Platform.inf
index 14727c1220..2896f0a1d1 100644
--- a/OvmfPkg/PlatformDxe/Platform.inf
+++ b/OvmfPkg/PlatformDxe/Platform.inf
@@ -24,6 +24,7 @@
PlatformConfig.c
PlatformConfig.h
PlatformForms.vfr
+ AmdSev.c

[Packages]
MdePkg/MdePkg.dec
@@ -56,6 +57,7 @@
[Guids]
gEfiIfrTianoGuid
gOvmfPlatformConfigGuid
+ gMemEncryptGuid

[Depex]
gEfiHiiConfigRoutingProtocolGuid AND
diff --git a/OvmfPkg/Include/Guid/MemEncryptLib.h b/OvmfPkg/Include/Guid/MemEncryptLib.h
new file mode 100644
index 0000000000..8264a647af
--- /dev/null
+++ b/OvmfPkg/Include/Guid/MemEncryptLib.h
@@ -0,0 +1,16 @@
+/** @file
+ AMD Memory Encryption GUID, define a new GUID for defining
+ new UEFI enviroment variables assocaiated with SEV Memory Encryption.
+ Copyright (c) 2020, AMD Inc. All rights reserved.<BR>
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef __MEMENCRYPT_LIB_H__
+#define __MEMENCRYPT_LIB_H__
+
+#define MEMENCRYPT_GUID \
+{0x0cf29b71, 0x9e51, 0x433a, {0xa3, 0xb7, 0x81, 0xf3, 0xab, 0x16, 0xb8, 0x75}}
+
+extern EFI_GUID gMemEncryptGuid;
+
+#endif
diff --git a/OvmfPkg/PlatformDxe/PlatformConfig.h b/OvmfPkg/PlatformDxe/PlatformConfig.h
index 716514da21..4f662aafa4 100644
--- a/OvmfPkg/PlatformDxe/PlatformConfig.h
+++ b/OvmfPkg/PlatformDxe/PlatformConfig.h
@@ -44,6 +44,11 @@ PlatformConfigLoad (
OUT UINT64 *OptionalElements
);

+VOID
+AmdSevSetConfig(
+ VOID
+ );
+
//
// Feature flags for OptionalElements.
//
diff --git a/OvmfPkg/PlatformDxe/AmdSev.c b/OvmfPkg/PlatformDxe/AmdSev.c
new file mode 100644
index 0000000000..1f804984b7
--- /dev/null
+++ b/OvmfPkg/PlatformDxe/AmdSev.c
@@ -0,0 +1,99 @@
+/**@file
+ Detect KVM hypervisor support for SEV live migration and if
+ detected, setup a new UEFI enviroment variable indicating
+ OVMF support for SEV live migration.
+ Copyright (c) 2020, Advanced Micro Devices. All rights reserved.<BR>
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+//
+// The package level header files this module uses
+//
+
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UefiRuntimeServicesTableLib.h>
+#include <Guid/MemEncryptLib.h>
+
+/**
+ Figures out if we are running inside KVM HVM and
+ KVM HVM supports SEV Live Migration feature.
+ @retval TRUE KVM was detected and Live Migration supported
+ @retval FALSE KVM was not detected or Live Migration not supported
+**/
+BOOLEAN
+KvmDetectSevLiveMigrationFeature(
+ VOID
+ )
+{
+ UINT8 Signature[13];
+ UINT32 mKvmLeaf = 0;
+ UINT32 RegEax, RegEbx, RegEcx, RegEdx;
+
+ Signature[12] = '\0';
+ for (mKvmLeaf = 0x40000000; mKvmLeaf < 0x40010000; mKvmLeaf += 0x100) {
+ AsmCpuid (mKvmLeaf,
+ NULL,
+ (UINT32 *) &Signature[0],
+ (UINT32 *) &Signature[4],
+ (UINT32 *) &Signature[8]);
+
+ if (!AsciiStrCmp ((CHAR8 *) Signature, "KVMKVMKVM\0\0\0")) {
+ DEBUG ((
+ DEBUG_ERROR,
+ "%a: KVM Detected, signature = %s\n",
+ __FUNCTION__,
+ Signature
+ ));
+
+ RegEax = 0x40000001;
+ RegEcx = 0;
+ AsmCpuid (0x40000001, &RegEax, &RegEbx, &RegEcx, &RegEdx);
+ if (RegEax & (1 << 14)) {
+ DEBUG ((
+ DEBUG_ERROR,
+ "%a: Live Migration feature supported\n",
+ __FUNCTION__
+ ));
+ return TRUE;
+ }
+ }
+ }
+
+ return FALSE;
+}
+
+/**
+ Function checks if SEV Live Migration support is available, if present then it sets
+ a UEFI enviroment variable to be queried later using Runtime services.
+ **/
+VOID
+AmdSevSetConfig(
+ VOID
+ )
+{
+ EFI_STATUS Status;
+ BOOLEAN SevLiveMigrationEnabled;
+
+ SevLiveMigrationEnabled = KvmDetectSevLiveMigrationFeature();
+
+ if (SevLiveMigrationEnabled) {
+ Status = gRT->SetVariable (
+ L"SevLiveMigrationEnabled",
+ &gMemEncryptGuid,
+ EFI_VARIABLE_NON_VOLATILE |
+ EFI_VARIABLE_BOOTSERVICE_ACCESS |
+ EFI_VARIABLE_RUNTIME_ACCESS,
+ sizeof (BOOLEAN),
+ &SevLiveMigrationEnabled
+ );
+
+ DEBUG ((
+ DEBUG_ERROR,
+ "%a: Setting SevLiveMigrationEnabled variable, status = %lx\n",
+ __FUNCTION__,
+ Status
+ ));
+ }
+}
diff --git a/OvmfPkg/PlatformDxe/Platform.c b/OvmfPkg/PlatformDxe/Platform.c
index f2e51960ce..9a19b9f6b1 100644
--- a/OvmfPkg/PlatformDxe/Platform.c
+++ b/OvmfPkg/PlatformDxe/Platform.c
@@ -763,6 +763,12 @@ PlatformInit (
{
EFI_STATUS Status;

+ //
+ // Set Amd Sev configuation
+ //
+ AmdSevSetConfig();
+
+
ExecutePlatformConfig ();

mConfigAccess.ExtractConfig = &ExtractConfig;
--
2.20.1