[edk2-devel] [RFC PATCH 02/19] OvmfPkg: validate the data pages used in the SEC phase

Brijesh Singh brijesh.singh at amd.com
Wed Mar 24 15:31:58 UTC 2021


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

An SEV-SNP guest requires that private memory (aka pages mapped as
encrypted) must be validated before being accessed.

The validation process consist of the following sequence:

1) Set the memory encryption attribute in the page table (aka C-bit).
   Note: If the processor is in non-PAE mode, then all the memory accesses
   are considered private.
2) Add the memory range as private in the RMP table. This can be performed
   using the Page State Change VMGEXIT defined in the GHCB specification.
3) Use the PVALIDATE instruction to set the Validated Bit in the RMP table.

During the guest creation time, the VMM encrypts the OVMF_CODE.fd using
the SEV-SNP firmware provided LAUNCH_UPDATE_DATA command. In addition to
encrypting the content, the command also validates the memory region.
This allows us to execute the code without going through the validation
sequence.

During execution, the reset vector need to access some data pages
(such as page tables, SevESWorkarea, Sec stack). The data pages are
accessed as private memory. The data pages are not part of the
OVMF_CODE.fd, so they were not validated during the guest creation.

There are two approaches we can take to validate the data pages before
the access:

a) Enhance the OVMF reset vector code to validate the pages as described
   above (go through step 2 - 3).
OR
b) Validate the pages during the guest creation time. The SEV firmware
   provides a command which can be used by the VMM to validate the pages
   without affecting the measurement of the launch.

Approach #b seems much simpler; it does not require any changes to the
OVMF reset vector code.

Extend the SnpBootBlock to provide the range that can be pre-validated
using the SEV-SNP firmware command during the guest creation time.

At the end of the guest creation the pre-validated range looks like this:

0x800000   0x801000   (CPUID Page     [Validated + Measured])
0x801000   0x802000   (Secrets Page   [Validated + Measured])
0x802000   0x820000   (Data Pages for the SEC phase  [Validated + unmeasured])

Cc: James Bottomley <jejb at linux.ibm.com>
Cc: Min Xu <min.m.xu at intel.com>
Cc: Jiewen Yao <jiewen.yao at intel.com>
Cc: Tom Lendacky <thomas.lendacky at amd.com>
Cc: Jordan Justen <jordan.l.justen at intel.com>
Cc: Ard Biesheuvel <ardb+tianocore at kernel.org>
Cc: Laszlo Ersek <lersek at redhat.com>
Signed-off-by: Brijesh Singh <brijesh.singh at amd.com>
---
 OvmfPkg/OvmfPkg.dec                          | 4 ++++
 OvmfPkg/OvmfPkgX64.fdf                       | 9 ++++++++-
 OvmfPkg/ResetVector/Ia16/ResetVectorVtf0.asm | 5 +++++
 OvmfPkg/ResetVector/ResetVector.inf          | 1 +
 OvmfPkg/ResetVector/ResetVector.nasmb        | 2 ++
 5 files changed, 20 insertions(+), 1 deletion(-)

diff --git a/OvmfPkg/OvmfPkg.dec b/OvmfPkg/OvmfPkg.dec
index 062926772d..6fb70e2c10 100644
--- a/OvmfPkg/OvmfPkg.dec
+++ b/OvmfPkg/OvmfPkg.dec
@@ -325,6 +325,10 @@
   gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSnpSecretsBase|0|UINT32|0x50
   gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSnpSecretsSize|0|UINT32|0x51
 
+  ## The range of memory pre-validated through the SEV-SNP launch sequence
+  gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSnpLaunchValidatedStart|0|UINT32|0x52
+  gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSnpLaunchValidatedEnd|0|UINT32|0x53
+
 [PcdsDynamic, PcdsDynamicEx]
   gUefiOvmfPkgTokenSpaceGuid.PcdEmuVariableEvent|0|UINT64|2
   gUefiOvmfPkgTokenSpaceGuid.PcdOvmfFlashVariablesEnable|FALSE|BOOLEAN|0x10
diff --git a/OvmfPkg/OvmfPkgX64.fdf b/OvmfPkg/OvmfPkgX64.fdf
index ea214600be..16383453f1 100644
--- a/OvmfPkg/OvmfPkgX64.fdf
+++ b/OvmfPkg/OvmfPkgX64.fdf
@@ -105,7 +105,14 @@ FV = PEIFV
 gUefiOvmfPkgTokenSpaceGuid.PcdOvmfDxeMemFvBase|gUefiOvmfPkgTokenSpaceGuid.PcdOvmfDxeMemFvSize
 FV = DXEFV
 
-################################################################################
+##############################################################################
+#
+# The range of the pages validated through the SEV-SNP launch sequence.
+#
+SET gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSnpLaunchValidatedStart = $(MEMFD_BASE_ADDRESS)
+SET gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSnpLaunchValidatedEnd = gUefiOvmfPkgTokenSpaceGuid.PcdOvmfPeiMemFvBase
+
+###############################################################################
 
 [FV.SECFV]
 FvNameGuid         = 763BED0D-DE9F-48F5-81F1-3E90E1B1A015
diff --git a/OvmfPkg/ResetVector/Ia16/ResetVectorVtf0.asm b/OvmfPkg/ResetVector/Ia16/ResetVectorVtf0.asm
index 5456f02924..9be887c4fc 100644
--- a/OvmfPkg/ResetVector/Ia16/ResetVectorVtf0.asm
+++ b/OvmfPkg/ResetVector/Ia16/ResetVectorVtf0.asm
@@ -56,11 +56,16 @@ guidedStructureStart:
 ;   and SEV_SNP_CPUID_PAGE. A VMM will locate this information using the
 ;   SEV-SNP boot block.
 ;
+;   In addition to Secret and CPUID page, the SEV-SNP boot block also contain
+;   the range of memory that must be pre-validated by the VMM before the execution.
+;
 ; GUID (SEV-SNP boot block): bd39c0c2-2f8e-4243-83e8-1b74cebcb7d9
 ;
 sevSnpBootBlockStart:
     DD      SEV_SNP_SECRETS_PAGE
     DD      SEV_SNP_CPUID_PAGE
+    DD      SEV_SNP_LAUNCH_VALIDATED_START
+    DD      SEV_SNP_LAUNCH_VALIDATED_END
     DW      sevSnpBootBlockEnd - sevSnpBootBlockStart
     DB      0xC2, 0xC0, 0x39, 0xBD, 0x8e, 0x2F, 0x43, 0x42
     DB      0x83, 0xE8, 0x1B, 0x74, 0xCE, 0xBC, 0xB7, 0xD9
diff --git a/OvmfPkg/ResetVector/ResetVector.inf b/OvmfPkg/ResetVector/ResetVector.inf
index d890bb6b29..49a527c0b1 100644
--- a/OvmfPkg/ResetVector/ResetVector.inf
+++ b/OvmfPkg/ResetVector/ResetVector.inf
@@ -47,6 +47,7 @@
   gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecPageTablesSize
   gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecPeiTempRamBase
   gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecPeiTempRamSize
+  gUefiOvmfPkgTokenSpaceGuid.PcdOvmfPeiMemFvBase
 
 [FixedPcd]
   gUefiOvmfPkgTokenSpaceGuid.PcdSevLaunchSecretBase
diff --git a/OvmfPkg/ResetVector/ResetVector.nasmb b/OvmfPkg/ResetVector/ResetVector.nasmb
index 2c194958f4..6d399c4739 100644
--- a/OvmfPkg/ResetVector/ResetVector.nasmb
+++ b/OvmfPkg/ResetVector/ResetVector.nasmb
@@ -77,6 +77,8 @@
   %define SEV_ES_WORK_AREA_ENC_MASK (FixedPcdGet32 (PcdSevEsWorkAreaBase) + 16)
   %define SEV_SNP_SECRETS_PAGE FixedPcdGet32 (PcdOvmfSnpSecretsBase)
   %define SEV_SNP_CPUID_PAGE  FixedPcdGet32 (PcdOvmfSnpCpuidBase)
+  %define SEV_SNP_LAUNCH_VALIDATED_START FixedPcdGet32 (PcdOvmfSecPageTablesBase)
+  %define SEV_SNP_LAUNCH_VALIDATED_END FixedPcdGet32 (PcdOvmfPeiMemFvBase)
   %define SEV_ES_VC_TOP_OF_STACK (FixedPcdGet32 (PcdOvmfSecPeiTempRamBase) + FixedPcdGet32 (PcdOvmfSecPeiTempRamSize))
 %include "Ia32/Flat32ToFlat64.asm"
 %include "Ia32/PageTables64.asm"
-- 
2.17.1



-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#73218): https://edk2.groups.io/g/devel/message/73218
Mute This Topic: https://groups.io/mt/81584578/1813853
Group Owner: devel+owner at edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [edk2-devel-archive at redhat.com]
-=-=-=-=-=-=-=-=-=-=-=-





More information about the edk2-devel-archive mailing list