public inbox for devel@edk2.groups.io
 help / color / mirror / Atom feed
* [RESEND PATCH RFC v3 00/22] Add AMD Secure Nested Paging (SEV-SNP) support
@ 2021-05-26 23:10 Brijesh Singh
  2021-05-26 23:10 ` [PATCH RFC v3 01/22] UefiCpuPkg: Define the SEV-SNP specific dynamic PCDs Brijesh Singh
                   ` (23 more replies)
  0 siblings, 24 replies; 57+ messages in thread
From: Brijesh Singh @ 2021-05-26 23:10 UTC (permalink / raw)
  To: James Bottomley, Min Xu, Jiewen Yao, Tom Lendacky, Jordan Justen,
	Laszlo Ersek, Erdem Aktas, Eric Dong, Ray Ni, Rahul Kumar, devel
  Cc: Brijesh Singh, Ard Biesheuvel

(I missed adding devel@edk2.groups.io, resending the series)

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

SEV-SNP builds upon existing SEV and SEV-ES functionality while adding
new hardware-based memory protections. SEV-SNP adds strong memory integrity
protection to help prevent malicious hypervisor-based attacks like data
replay, memory re-mapping and more in order to create an isolated memory
encryption environment.
 
This series provides the basic building blocks to support booting the SEV-SNP
VMs, it does not cover all the security enhancement introduced by the SEV-SNP
such as interrupt protection.

Many of the integrity guarantees of SEV-SNP are enforced through a new
structure called the Reverse Map Table (RMP). Adding a new page to SEV-SNP
VM requires a 2-step process. First, the hypervisor assigns a page to the
guest using the new RMPUPDATE instruction. This transitions the page to
guest-invalid. Second, the guest validates the page using the new PVALIDATE
instruction. The SEV-SNP VMs can use the new "Page State Change Request NAE"
defined in the GHCB specification to ask hypervisor to add or remove page
from the RMP table.

Each page assigned to the SEV-SNP VM can either be validated or unvalidated,
as indicated by the Validated flag in the page's RMP entry. There are two
approaches that can be taken for the page validation: Pre-validation and
Lazy Validation.

Under pre-validation, the pages are validated prior to first use. And under
lazy validation, pages are validated when first accessed. An access to a
unvalidated page results in a #VC exception, at which time the exception
handler may validate the page. Lazy validation requires careful tracking of
the validated pages to avoid validating the same GPA more than once. The
recently introduced "Unaccepted" memory type can be used to communicate the
unvalidated memory ranges to the Guest OS.

At this time we only support the pre-validation. OVMF detects all the available
system RAM in the PEI phase. When SEV-SNP is enabled, the memory is validated
before it is made available to the EDK2 core.

This series does not implements the following SEV-SNP features yet:

* CPUID filtering
* Lazy validation
* Interrupt security

The series builds on SNP pre-patch posted here: https://tinyurl.com/pu6admks

Additional resources
---------------------
SEV-SNP whitepaper
https://www.amd.com/system/files/TechDocs/SEV-SNP-strengthening-vm-isolation-with-integrity-protection-and-more.pdf

APM 2: https://www.amd.com/system/files/TechDocs/24593.pdf (section 15.36)

The complete source is available at
https://github.com/AMDESE/ovmf/tree/sev-snp-rfc-2

GHCB spec:
https://developer.amd.com/wp-content/resources/56421.pdf

SEV-SNP firmware specification:
https://developer.amd.com/sev/
	         
Cc: James Bottomley <jejb@linux.ibm.com>
Cc: Min Xu <min.m.xu@intel.com>
Cc: Jiewen Yao <jiewen.yao@intel.com>
Cc: Tom Lendacky <thomas.lendacky@amd.com>
Cc: Jordan Justen <jordan.l.justen@intel.com>
Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
Cc: Laszlo Ersek <lersek@redhat.com>
Cc: Erdem Aktas <erdemaktas@google.com>

Changes since v2:
 * Add support for the AP creation.
 * Use the module-scoping override to make AmdSevDxe use the IO port for PCI reads.
 * Use the reserved memory type for CPUID and Secrets page.
 * 
Changes since v1:
 * Drop the interval tree support to detect the pre-validated overlap region.
 * Use an array to keep track of pre-validated regions.
 * Add support to query the Hypervisor feature and verify that SNP feature is supported.
 * Introduce MemEncryptSevClearMmioPageEncMask() to clear the C-bit from MMIO ranges.
 * Pull the SevSecretDxe and SevSecretPei into OVMF package build.
 * Extend the SevSecretDxe to expose confidential computing blob location through
   EFI configuration table.

Brijesh Singh (21):
  UefiCpuPkg: Define the SEV-SNP specific dynamic PCDs
  OvmfPkg/MemEncryptSevLib: add MemEncryptSevSnpEnabled()
  OvmfPkg/MemEncryptSevLib: extend the workarea to include SNP enabled
    field
  OvmfPkg/MemEncryptSevLib: extend Es Workarea to include hv features
  OvmfPkg: reserve Secrets page in MEMFD
  OvmfPkg: reserve CPUID page for the SEV-SNP guest
  OvmfPkg/ResetVector: validate the data pages used in SEC phase
  OvmfPkg/ResetVector: invalidate the GHCB page
  OvmfPkg: add library to support registering GHCB GPA
  OvmfPkg/PlatformPei: register GHCB gpa for the SEV-SNP guest
  UefiCpuPkg/MpLib: add support to register GHCB GPA when SEV-SNP is
    enabled
  OvmfPkg/AmdSevDxe: do not use extended PCI config space
  OvmfPkg/MemEncryptSevLib: add support to validate system RAM
  OvmfPkg/BaseMemEncryptSevLib: skip the pre-validated system RAM
  OvmfPkg/MemEncryptSevLib: add support to validate > 4GB memory in PEI
    phase
  OvmfPkg/SecMain: pre-validate the memory used for decompressing Fv
  OvmfPkg/PlatformPei: validate the system RAM when SNP is active
  OvmfPkg/MemEncryptSevLib: Change the page state in the RMP table
  OvmfPkg/MemEncryptSevLib: skip page state change for Mmio address
  OvmfPkg/AmdSev: expose the SNP reserved pages through configuration
    table
  MdePkg/GHCB: increase the GHCB protocol max version

Tom Lendacky (1):
  UefiCpuPkg/MpInitLib: Use SEV-SNP AP Creation NAE event to launch APs

 OvmfPkg/OvmfPkg.dec                           |  21 ++
 UefiCpuPkg/UefiCpuPkg.dec                     |  11 +
 OvmfPkg/AmdSev/AmdSevX64.dsc                  |   5 +-
 OvmfPkg/Bhyve/BhyveX64.dsc                    |   5 +-
 OvmfPkg/OvmfPkgIa32.dsc                       |   2 +
 OvmfPkg/OvmfPkgIa32X64.dsc                    |   7 +-
 OvmfPkg/OvmfPkgX64.dsc                        |   8 +-
 OvmfPkg/OvmfXen.dsc                           |   5 +-
 OvmfPkg/OvmfPkgX64.fdf                        |  17 +-
 OvmfPkg/AmdSev/SecretDxe/SecretDxe.inf        |   4 +
 OvmfPkg/AmdSev/SecretPei/SecretPei.inf        |   1 +
 .../DxeMemEncryptSevLib.inf                   |   3 +
 .../PeiMemEncryptSevLib.inf                   |   7 +
 .../SecMemEncryptSevLib.inf                   |   3 +
 .../GhcbRegisterLib/GhcbRegisterLib.inf       |  33 +++
 OvmfPkg/PlatformPei/PlatformPei.inf           |   5 +
 OvmfPkg/ResetVector/ResetVector.inf           |   4 +
 OvmfPkg/Sec/SecMain.inf                       |   3 +
 UefiCpuPkg/Library/MpInitLib/DxeMpInitLib.inf |   4 +
 UefiCpuPkg/Library/MpInitLib/PeiMpInitLib.inf |   4 +
 MdePkg/Include/Register/Amd/Ghcb.h            |   2 +-
 .../Guid/ConfidentialComputingSecret.h        |  18 ++
 OvmfPkg/Include/Library/GhcbRegisterLib.h     |  27 ++
 OvmfPkg/Include/Library/MemEncryptSevLib.h    |  31 +-
 .../X64/SnpPageStateChange.h                  |  31 ++
 .../BaseMemEncryptSevLib/X64/VirtualMemory.h  |  19 ++
 UefiCpuPkg/Library/MpInitLib/MpLib.h          |  19 ++
 OvmfPkg/AmdSev/SecretDxe/SecretDxe.c          |  22 ++
 OvmfPkg/AmdSev/SecretPei/SecretPei.c          |  15 +-
 .../DxeMemEncryptSevLibInternal.c             |  27 ++
 .../Ia32/MemEncryptSevLib.c                   |  17 ++
 .../PeiMemEncryptSevLibInternal.c             |  27 ++
 .../SecMemEncryptSevLibInternal.c             |  19 ++
 .../X64/DxeSnpSystemRamValidate.c             |  40 +++
 .../X64/PeiDxeVirtualMemory.c                 | 167 ++++++++++-
 .../X64/PeiSnpSystemRamValidate.c             | 126 ++++++++
 .../X64/SecSnpSystemRamValidate.c             |  36 +++
 .../X64/SnpPageStateChangeInternal.c          | 230 +++++++++++++++
 .../Library/GhcbRegisterLib/GhcbRegisterLib.c |  97 +++++++
 OvmfPkg/PlatformPei/AmdSev.c                  |  81 ++++++
 OvmfPkg/PlatformPei/MemDetect.c               |  12 +
 OvmfPkg/Sec/SecMain.c                         | 106 +++++++
 UefiCpuPkg/Library/MpInitLib/DxeMpLib.c       |  11 +-
 .../MpInitLib/Ia32/SevSnpRmpAdjustInternal.c  |  31 ++
 UefiCpuPkg/Library/MpInitLib/MpLib.c          | 274 ++++++++++++++++--
 .../MpInitLib/X64/SevSnpRmpAdjustInternal.c   |  44 +++
 OvmfPkg/FvmainCompactScratchEnd.fdf.inc       |   5 +
 OvmfPkg/ResetVector/Ia16/ResetVectorVtf0.asm  |  23 ++
 OvmfPkg/ResetVector/Ia32/PageTables64.asm     | 227 +++++++++++++++
 OvmfPkg/ResetVector/ResetVector.nasmb         |   6 +
 UefiCpuPkg/Library/MpInitLib/MpEqu.inc        |   1 +
 UefiCpuPkg/Library/MpInitLib/X64/MpFuncs.nasm |  51 ++++
 52 files changed, 1956 insertions(+), 38 deletions(-)
 create mode 100644 OvmfPkg/Library/GhcbRegisterLib/GhcbRegisterLib.inf
 create mode 100644 OvmfPkg/Include/Library/GhcbRegisterLib.h
 create mode 100644 OvmfPkg/Library/BaseMemEncryptSevLib/X64/SnpPageStateChange.h
 create mode 100644 OvmfPkg/Library/BaseMemEncryptSevLib/X64/DxeSnpSystemRamValidate.c
 create mode 100644 OvmfPkg/Library/BaseMemEncryptSevLib/X64/PeiSnpSystemRamValidate.c
 create mode 100644 OvmfPkg/Library/BaseMemEncryptSevLib/X64/SecSnpSystemRamValidate.c
 create mode 100644 OvmfPkg/Library/BaseMemEncryptSevLib/X64/SnpPageStateChangeInternal.c
 create mode 100644 OvmfPkg/Library/GhcbRegisterLib/GhcbRegisterLib.c
 create mode 100644 UefiCpuPkg/Library/MpInitLib/Ia32/SevSnpRmpAdjustInternal.c
 create mode 100644 UefiCpuPkg/Library/MpInitLib/X64/SevSnpRmpAdjustInternal.c

-- 
2.17.1


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

* [PATCH RFC v3 01/22] UefiCpuPkg: Define the SEV-SNP specific dynamic PCDs
  2021-05-26 23:10 [RESEND PATCH RFC v3 00/22] Add AMD Secure Nested Paging (SEV-SNP) support Brijesh Singh
@ 2021-05-26 23:10 ` Brijesh Singh
  2021-06-03  8:15   ` [edk2-devel] " Laszlo Ersek
  2021-06-03 13:38   ` Laszlo Ersek
  2021-05-26 23:10 ` [PATCH RFC v3 02/22] OvmfPkg/MemEncryptSevLib: add MemEncryptSevSnpEnabled() Brijesh Singh
                   ` (22 subsequent siblings)
  23 siblings, 2 replies; 57+ messages in thread
From: Brijesh Singh @ 2021-05-26 23:10 UTC (permalink / raw)
  To: James Bottomley, Min Xu, Jiewen Yao, Tom Lendacky, Jordan Justen,
	Laszlo Ersek, Erdem Aktas, Eric Dong, Ray Ni, Rahul Kumar, devel
  Cc: Brijesh Singh, Ard Biesheuvel

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

Define the PCDs used by the MpLib while creating the AP when SEV-SNP is
active in the guest VMs.

Cc: James Bottomley <jejb@linux.ibm.com>
Cc: Min Xu <min.m.xu@intel.com>
Cc: Jiewen Yao <jiewen.yao@intel.com>
Cc: Tom Lendacky <thomas.lendacky@amd.com>
Cc: Jordan Justen <jordan.l.justen@intel.com>
Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
Cc: Laszlo Ersek <lersek@redhat.com>
Cc: Erdem Aktas <erdemaktas@google.com>
Signed-off-by: Brijesh Singh <brijesh.singh@amd.com>
---
 UefiCpuPkg/UefiCpuPkg.dec | 11 +++++++++++
 1 file changed, 11 insertions(+)

diff --git a/UefiCpuPkg/UefiCpuPkg.dec b/UefiCpuPkg/UefiCpuPkg.dec
index 62acb291f309..0ec25871a50f 100644
--- a/UefiCpuPkg/UefiCpuPkg.dec
+++ b/UefiCpuPkg/UefiCpuPkg.dec
@@ -396,5 +396,16 @@ [PcdsDynamic, PcdsDynamicEx]
   # @Prompt SEV-ES Status
   gUefiCpuPkgTokenSpaceGuid.PcdSevEsIsEnabled|FALSE|BOOLEAN|0x60000016
 
+  ## This dynamic PCD indicates whether SEV-SNP is enabled
+  #   TRUE  - SEV-SNP is enabled
+  #   FALSE - SEV-SNP is not enabled
+  # @Prompt SEV-SNP Status
+  gUefiCpuPkgTokenSpaceGuid.PcdSevSnpIsEnabled|FALSE|BOOLEAN|0x60000017
+
+  ## This dynamic PCD contains the hypervisor features value obtained through the GHCB HYPERVISOR
+  #  features VMGEXIT defined in the version 2 of GHCB spec.
+  # @Prompt GHCB Hypervisor Features
+  gUefiCpuPkgTokenSpaceGuid.PcdGhcbHypervisorFeatures|0x0|UINT64|0x60000018
+
 [UserExtensions.TianoCore."ExtraFiles"]
   UefiCpuPkgExtra.uni
-- 
2.17.1


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

* [PATCH RFC v3 02/22] OvmfPkg/MemEncryptSevLib: add MemEncryptSevSnpEnabled()
  2021-05-26 23:10 [RESEND PATCH RFC v3 00/22] Add AMD Secure Nested Paging (SEV-SNP) support Brijesh Singh
  2021-05-26 23:10 ` [PATCH RFC v3 01/22] UefiCpuPkg: Define the SEV-SNP specific dynamic PCDs Brijesh Singh
@ 2021-05-26 23:10 ` Brijesh Singh
  2021-06-04 13:43   ` Laszlo Ersek
  2021-05-26 23:10 ` [PATCH RFC v3 03/22] OvmfPkg/MemEncryptSevLib: extend the workarea to include SNP enabled field Brijesh Singh
                   ` (21 subsequent siblings)
  23 siblings, 1 reply; 57+ messages in thread
From: Brijesh Singh @ 2021-05-26 23:10 UTC (permalink / raw)
  To: James Bottomley, Min Xu, Jiewen Yao, Tom Lendacky, Jordan Justen,
	Laszlo Ersek, Erdem Aktas, Eric Dong, Ray Ni, Rahul Kumar, devel
  Cc: Brijesh Singh, Ard Biesheuvel

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

Create a function that can be used to determine if VM is running as an
SEV-SNP guest.

Cc: James Bottomley <jejb@linux.ibm.com>
Cc: Min Xu <min.m.xu@intel.com>
Cc: Jiewen Yao <jiewen.yao@intel.com>
Cc: Tom Lendacky <thomas.lendacky@amd.com>
Cc: Jordan Justen <jordan.l.justen@intel.com>
Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
Cc: Laszlo Ersek <lersek@redhat.com>
Cc: Erdem Aktas <erdemaktas@google.com>
Signed-off-by: Brijesh Singh <brijesh.singh@amd.com>
---
 OvmfPkg/Include/Library/MemEncryptSevLib.h    | 12 +++++++++
 .../DxeMemEncryptSevLibInternal.c             | 27 +++++++++++++++++++
 .../PeiMemEncryptSevLibInternal.c             | 27 +++++++++++++++++++
 .../SecMemEncryptSevLibInternal.c             | 19 +++++++++++++
 4 files changed, 85 insertions(+)

diff --git a/OvmfPkg/Include/Library/MemEncryptSevLib.h b/OvmfPkg/Include/Library/MemEncryptSevLib.h
index 76d06c206c8b..2425d8ba0a36 100644
--- a/OvmfPkg/Include/Library/MemEncryptSevLib.h
+++ b/OvmfPkg/Include/Library/MemEncryptSevLib.h
@@ -66,6 +66,18 @@ typedef enum {
   MemEncryptSevAddressRangeError,
 } MEM_ENCRYPT_SEV_ADDRESS_RANGE_STATE;
 
+/**
+  Returns a boolean to indicate whether SEV-SNP is enabled
+
+  @retval TRUE           SEV-SNP is enabled
+  @retval FALSE          SEV-SNP is not enabled
+**/
+BOOLEAN
+EFIAPI
+MemEncryptSevSnpIsEnabled (
+  VOID
+  );
+
 /**
   Returns a boolean to indicate whether SEV-ES is enabled.
 
diff --git a/OvmfPkg/Library/BaseMemEncryptSevLib/DxeMemEncryptSevLibInternal.c b/OvmfPkg/Library/BaseMemEncryptSevLib/DxeMemEncryptSevLibInternal.c
index 2816f859a0c4..057129723824 100644
--- a/OvmfPkg/Library/BaseMemEncryptSevLib/DxeMemEncryptSevLibInternal.c
+++ b/OvmfPkg/Library/BaseMemEncryptSevLib/DxeMemEncryptSevLibInternal.c
@@ -19,6 +19,7 @@
 
 STATIC BOOLEAN mSevStatus = FALSE;
 STATIC BOOLEAN mSevEsStatus = FALSE;
+STATIC BOOLEAN mSevSnpStatus = FALSE;
 STATIC BOOLEAN mSevStatusChecked = FALSE;
 
 STATIC UINT64  mSevEncryptionMask = 0;
@@ -82,11 +83,37 @@ InternalMemEncryptSevStatus (
     if (Msr.Bits.SevEsBit) {
       mSevEsStatus = TRUE;
     }
+
+    //
+    // Check MSR_0xC0010131 Bit 2 (Sev-Snp Enabled)
+    //
+    if (Msr.Bits.SevSnpBit) {
+      mSevSnpStatus = TRUE;
+    }
   }
 
   mSevStatusChecked = TRUE;
 }
 
+/**
+  Returns a boolean to indicate whether SEV-SNP is enabled.
+
+  @retval TRUE           SEV-SNP is enabled
+  @retval FALSE          SEV-SNP is not enabled
+**/
+BOOLEAN
+EFIAPI
+MemEncryptSevSnpIsEnabled (
+  VOID
+  )
+{
+  if (!mSevStatusChecked) {
+    InternalMemEncryptSevStatus ();
+  }
+
+  return mSevSnpStatus;
+}
+
 /**
   Returns a boolean to indicate whether SEV-ES is enabled.
 
diff --git a/OvmfPkg/Library/BaseMemEncryptSevLib/PeiMemEncryptSevLibInternal.c b/OvmfPkg/Library/BaseMemEncryptSevLib/PeiMemEncryptSevLibInternal.c
index e2fd109d120f..b561f211f577 100644
--- a/OvmfPkg/Library/BaseMemEncryptSevLib/PeiMemEncryptSevLibInternal.c
+++ b/OvmfPkg/Library/BaseMemEncryptSevLib/PeiMemEncryptSevLibInternal.c
@@ -19,6 +19,7 @@
 
 STATIC BOOLEAN mSevStatus = FALSE;
 STATIC BOOLEAN mSevEsStatus = FALSE;
+STATIC BOOLEAN mSevSnpStatus = FALSE;
 STATIC BOOLEAN mSevStatusChecked = FALSE;
 
 STATIC UINT64  mSevEncryptionMask = 0;
@@ -82,11 +83,37 @@ InternalMemEncryptSevStatus (
     if (Msr.Bits.SevEsBit) {
       mSevEsStatus = TRUE;
     }
+
+    //
+    // Check MSR_0xC0010131 Bit 2 (Sev-Snp Enabled)
+    //
+    if (Msr.Bits.SevSnpBit) {
+      mSevSnpStatus = TRUE;
+    }
   }
 
   mSevStatusChecked = TRUE;
 }
 
+/**
+  Returns a boolean to indicate whether SEV-SNP is enabled.
+
+  @retval TRUE           SEV-SNP is enabled
+  @retval FALSE          SEV-SNP is not enabled
+**/
+BOOLEAN
+EFIAPI
+MemEncryptSevSnpIsEnabled (
+  VOID
+  )
+{
+  if (!mSevStatusChecked) {
+    InternalMemEncryptSevStatus ();
+  }
+
+  return mSevSnpStatus;
+}
+
 /**
   Returns a boolean to indicate whether SEV-ES is enabled.
 
diff --git a/OvmfPkg/Library/BaseMemEncryptSevLib/SecMemEncryptSevLibInternal.c b/OvmfPkg/Library/BaseMemEncryptSevLib/SecMemEncryptSevLibInternal.c
index 56d8f3f3183f..69852779e2ff 100644
--- a/OvmfPkg/Library/BaseMemEncryptSevLib/SecMemEncryptSevLibInternal.c
+++ b/OvmfPkg/Library/BaseMemEncryptSevLib/SecMemEncryptSevLibInternal.c
@@ -62,6 +62,25 @@ InternalMemEncryptSevStatus (
   return ReadSevMsr ? AsmReadMsr32 (MSR_SEV_STATUS) : 0;
 }
 
+/**
+  Returns a boolean to indicate whether SEV-SNP is enabled.
+
+  @retval TRUE           SEV-SNP is enabled
+  @retval FALSE          SEV-SNP is not enabled
+**/
+BOOLEAN
+EFIAPI
+MemEncryptSevSnpIsEnabled (
+  VOID
+  )
+{
+  MSR_SEV_STATUS_REGISTER           Msr;
+
+  Msr.Uint32 = InternalMemEncryptSevStatus ();
+
+  return Msr.Bits.SevSnpBit ? TRUE : FALSE;
+}
+
 /**
   Returns a boolean to indicate whether SEV-ES is enabled.
 
-- 
2.17.1


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

* [PATCH RFC v3 03/22] OvmfPkg/MemEncryptSevLib: extend the workarea to include SNP enabled field
  2021-05-26 23:10 [RESEND PATCH RFC v3 00/22] Add AMD Secure Nested Paging (SEV-SNP) support Brijesh Singh
  2021-05-26 23:10 ` [PATCH RFC v3 01/22] UefiCpuPkg: Define the SEV-SNP specific dynamic PCDs Brijesh Singh
  2021-05-26 23:10 ` [PATCH RFC v3 02/22] OvmfPkg/MemEncryptSevLib: add MemEncryptSevSnpEnabled() Brijesh Singh
@ 2021-05-26 23:10 ` Brijesh Singh
  2021-06-04 14:15   ` Laszlo Ersek
  2021-05-26 23:11 ` [PATCH RFC v3 04/22] OvmfPkg/MemEncryptSevLib: extend Es Workarea to include hv features Brijesh Singh
                   ` (20 subsequent siblings)
  23 siblings, 1 reply; 57+ messages in thread
From: Brijesh Singh @ 2021-05-26 23:10 UTC (permalink / raw)
  To: James Bottomley, Min Xu, Jiewen Yao, Tom Lendacky, Jordan Justen,
	Laszlo Ersek, Erdem Aktas, Eric Dong, Ray Ni, Rahul Kumar, devel
  Cc: Brijesh Singh, Ard Biesheuvel

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

Extend the workarea to include the SEV-SNP enabled fields. This will be set
when SEV-SNP is active in the guest VM.

Cc: James Bottomley <jejb@linux.ibm.com>
Cc: Min Xu <min.m.xu@intel.com>
Cc: Jiewen Yao <jiewen.yao@intel.com>
Cc: Tom Lendacky <thomas.lendacky@amd.com>
Cc: Jordan Justen <jordan.l.justen@intel.com>
Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
Cc: Laszlo Ersek <lersek@redhat.com>
Cc: Erdem Aktas <erdemaktas@google.com>
Signed-off-by: Brijesh Singh <brijesh.singh@amd.com>
---
 OvmfPkg/PlatformPei/PlatformPei.inf        |  1 +
 OvmfPkg/Include/Library/MemEncryptSevLib.h |  3 ++-
 OvmfPkg/PlatformPei/AmdSev.c               | 26 ++++++++++++++++++++++
 OvmfPkg/ResetVector/Ia32/PageTables64.asm  | 12 ++++++++++
 OvmfPkg/ResetVector/ResetVector.nasmb      |  1 +
 5 files changed, 42 insertions(+), 1 deletion(-)

diff --git a/OvmfPkg/PlatformPei/PlatformPei.inf b/OvmfPkg/PlatformPei/PlatformPei.inf
index 6ef77ba7bb21..bc1dcac48343 100644
--- a/OvmfPkg/PlatformPei/PlatformPei.inf
+++ b/OvmfPkg/PlatformPei/PlatformPei.inf
@@ -110,6 +110,7 @@ [Pcd]
   gUefiCpuPkgTokenSpaceGuid.PcdCpuBootLogicalProcessorNumber
   gUefiCpuPkgTokenSpaceGuid.PcdCpuApStackSize
   gUefiCpuPkgTokenSpaceGuid.PcdSevEsIsEnabled
+  gUefiCpuPkgTokenSpaceGuid.PcdSevSnpIsEnabled
 
 [FixedPcd]
   gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseAddress
diff --git a/OvmfPkg/Include/Library/MemEncryptSevLib.h b/OvmfPkg/Include/Library/MemEncryptSevLib.h
index 2425d8ba0a36..24507de55c5d 100644
--- a/OvmfPkg/Include/Library/MemEncryptSevLib.h
+++ b/OvmfPkg/Include/Library/MemEncryptSevLib.h
@@ -49,7 +49,8 @@ typedef struct {
 //
 typedef struct _SEC_SEV_ES_WORK_AREA {
   UINT8    SevEsEnabled;
-  UINT8    Reserved1[7];
+  UINT8    SevSnpEnabled;
+  UINT8    Reserved2[6];
 
   UINT64   RandomData;
 
diff --git a/OvmfPkg/PlatformPei/AmdSev.c b/OvmfPkg/PlatformPei/AmdSev.c
index a8bf610022ba..67b78fd5fa36 100644
--- a/OvmfPkg/PlatformPei/AmdSev.c
+++ b/OvmfPkg/PlatformPei/AmdSev.c
@@ -22,6 +22,27 @@
 
 #include "Platform.h"
 
+/**
+
+  Initialize SEV-SNP support if running as an SEV-SNP guest.
+
+  **/
+STATIC
+VOID
+AmdSevSnpInitialize (
+  VOID
+  )
+{
+  RETURN_STATUS        PcdStatus;
+
+  if (!MemEncryptSevSnpIsEnabled ()) {
+    return;
+  }
+
+  PcdStatus = PcdSetBoolS (PcdSevSnpIsEnabled, TRUE);
+  ASSERT_RETURN_ERROR (PcdStatus);
+}
+
 /**
 
   Initialize SEV-ES support if running as an SEV-ES guest.
@@ -209,4 +230,9 @@ AmdSevInitialize (
   // Check and perform SEV-ES initialization if required.
   //
   AmdSevEsInitialize ();
+
+  //
+  // Check and perform SEV-SNP initialization if required.
+  //
+  AmdSevSnpInitialize ();
 }
diff --git a/OvmfPkg/ResetVector/Ia32/PageTables64.asm b/OvmfPkg/ResetVector/Ia32/PageTables64.asm
index 5fae8986d9da..6838cdeec9c3 100644
--- a/OvmfPkg/ResetVector/Ia32/PageTables64.asm
+++ b/OvmfPkg/ResetVector/Ia32/PageTables64.asm
@@ -81,6 +81,11 @@ CheckSevFeatures:
     ; the MSR check below will set the first byte of the workarea to one.
     mov     byte[SEV_ES_WORK_AREA], 0
 
+    ; Set the SevSnpEnabled field in workarea to zero to communicate to the SEC
+    ; phase that SEV-SNP is not enabled. If SEV-SNP is enabled, this function
+    ; will set it to 1.
+    mov       byte[SEV_ES_WORK_AREA_SNP], 0
+
     ;
     ; Set up exception handlers to check for SEV-ES
     ;   Load temporary RAM stack based on PCDs (see SevEsIdtVmmComm for
@@ -136,6 +141,13 @@ CheckSevFeatures:
     ; phase that SEV-ES is enabled.
     mov       byte[SEV_ES_WORK_AREA], 1
 
+    bt        eax, 2
+    jnc       GetSevEncBit
+
+    ; Set the second byte of the workarea to one to communicate to the SEC
+    ; phase that the SEV-SNP is enabled
+    mov       byte[SEV_ES_WORK_AREA_SNP], 1
+
 GetSevEncBit:
     ; Get pte bit position to enable memory encryption
     ; CPUID Fn8000_001F[EBX] - Bits 5:0
diff --git a/OvmfPkg/ResetVector/ResetVector.nasmb b/OvmfPkg/ResetVector/ResetVector.nasmb
index 5fbacaed5f9d..1971557b1c00 100644
--- a/OvmfPkg/ResetVector/ResetVector.nasmb
+++ b/OvmfPkg/ResetVector/ResetVector.nasmb
@@ -73,6 +73,7 @@
   %define GHCB_BASE (FixedPcdGet32 (PcdOvmfSecGhcbBase))
   %define GHCB_SIZE (FixedPcdGet32 (PcdOvmfSecGhcbSize))
   %define SEV_ES_WORK_AREA (FixedPcdGet32 (PcdSevEsWorkAreaBase))
+  %define SEV_ES_WORK_AREA_SNP (FixedPcdGet32 (PcdSevEsWorkAreaBase) + 1)
   %define SEV_ES_WORK_AREA_RDRAND (FixedPcdGet32 (PcdSevEsWorkAreaBase) + 8)
   %define SEV_ES_WORK_AREA_ENC_MASK (FixedPcdGet32 (PcdSevEsWorkAreaBase) + 16)
   %define SEV_ES_VC_TOP_OF_STACK (FixedPcdGet32 (PcdOvmfSecPeiTempRamBase) + FixedPcdGet32 (PcdOvmfSecPeiTempRamSize))
-- 
2.17.1


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

* [PATCH RFC v3 04/22] OvmfPkg/MemEncryptSevLib: extend Es Workarea to include hv features
  2021-05-26 23:10 [RESEND PATCH RFC v3 00/22] Add AMD Secure Nested Paging (SEV-SNP) support Brijesh Singh
                   ` (2 preceding siblings ...)
  2021-05-26 23:10 ` [PATCH RFC v3 03/22] OvmfPkg/MemEncryptSevLib: extend the workarea to include SNP enabled field Brijesh Singh
@ 2021-05-26 23:11 ` Brijesh Singh
  2021-06-07 11:54   ` [edk2-devel] " Laszlo Ersek
  2021-05-26 23:11 ` [PATCH RFC v3 05/22] OvmfPkg: reserve Secrets page in MEMFD Brijesh Singh
                   ` (19 subsequent siblings)
  23 siblings, 1 reply; 57+ messages in thread
From: Brijesh Singh @ 2021-05-26 23:11 UTC (permalink / raw)
  To: James Bottomley, Min Xu, Jiewen Yao, Tom Lendacky, Jordan Justen,
	Laszlo Ersek, Erdem Aktas, Eric Dong, Ray Ni, Rahul Kumar, devel
  Cc: Brijesh Singh, Ard Biesheuvel

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

The GHCB Version 2 introduces advertisement of features that are supported
by the hypervisor. The features value is saved in the SevEs workarea. Save
the value in the PCD for the later use.

Cc: James Bottomley <jejb@linux.ibm.com>
Cc: Min Xu <min.m.xu@intel.com>
Cc: Jiewen Yao <jiewen.yao@intel.com>
Cc: Tom Lendacky <thomas.lendacky@amd.com>
Cc: Jordan Justen <jordan.l.justen@intel.com>
Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
Cc: Laszlo Ersek <lersek@redhat.com>
Cc: Erdem Aktas <erdemaktas@google.com>
Signed-off-by: Brijesh Singh <brijesh.singh@amd.com>
---
 OvmfPkg/PlatformPei/PlatformPei.inf        |   1 +
 OvmfPkg/Include/Library/MemEncryptSevLib.h |   2 +
 OvmfPkg/PlatformPei/AmdSev.c               |  26 +++++
 OvmfPkg/ResetVector/Ia32/PageTables64.asm  | 122 +++++++++++++++++++++
 OvmfPkg/ResetVector/ResetVector.nasmb      |   1 +
 5 files changed, 152 insertions(+)

diff --git a/OvmfPkg/PlatformPei/PlatformPei.inf b/OvmfPkg/PlatformPei/PlatformPei.inf
index bc1dcac48343..3256ccfe88d8 100644
--- a/OvmfPkg/PlatformPei/PlatformPei.inf
+++ b/OvmfPkg/PlatformPei/PlatformPei.inf
@@ -111,6 +111,7 @@ [Pcd]
   gUefiCpuPkgTokenSpaceGuid.PcdCpuApStackSize
   gUefiCpuPkgTokenSpaceGuid.PcdSevEsIsEnabled
   gUefiCpuPkgTokenSpaceGuid.PcdSevSnpIsEnabled
+  gUefiCpuPkgTokenSpaceGuid.PcdGhcbHypervisorFeatures
 
 [FixedPcd]
   gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseAddress
diff --git a/OvmfPkg/Include/Library/MemEncryptSevLib.h b/OvmfPkg/Include/Library/MemEncryptSevLib.h
index 24507de55c5d..dd1c97d4a9a3 100644
--- a/OvmfPkg/Include/Library/MemEncryptSevLib.h
+++ b/OvmfPkg/Include/Library/MemEncryptSevLib.h
@@ -55,6 +55,8 @@ typedef struct _SEC_SEV_ES_WORK_AREA {
   UINT64   RandomData;
 
   UINT64   EncryptionMask;
+
+  UINT64   HypervisorFeatures;
 } SEC_SEV_ES_WORK_AREA;
 
 //
diff --git a/OvmfPkg/PlatformPei/AmdSev.c b/OvmfPkg/PlatformPei/AmdSev.c
index 67b78fd5fa36..81e40e0889aa 100644
--- a/OvmfPkg/PlatformPei/AmdSev.c
+++ b/OvmfPkg/PlatformPei/AmdSev.c
@@ -43,6 +43,27 @@ AmdSevSnpInitialize (
   ASSERT_RETURN_ERROR (PcdStatus);
 }
 
+/**
+
+  Function to set the PcdHypervisorFeatures.
+**/
+STATIC
+VOID
+AmdSevHypervisorFeatures (
+  VOID
+  )
+{
+  SEC_SEV_ES_WORK_AREA  *SevEsWorkArea;
+  RETURN_STATUS         PcdStatus;
+
+  SevEsWorkArea = (SEC_SEV_ES_WORK_AREA *) FixedPcdGet32 (PcdSevEsWorkAreaBase);
+
+  PcdStatus = PcdSet64S (PcdGhcbHypervisorFeatures, SevEsWorkArea->HypervisorFeatures);
+  ASSERT_RETURN_ERROR (PcdStatus);
+
+  DEBUG ((DEBUG_INFO, "GHCB Hypervisor Features=0x%Lx\n", SevEsWorkArea->HypervisorFeatures));
+}
+
 /**
 
   Initialize SEV-ES support if running as an SEV-ES guest.
@@ -73,6 +94,11 @@ AmdSevEsInitialize (
   PcdStatus = PcdSetBoolS (PcdSevEsIsEnabled, TRUE);
   ASSERT_RETURN_ERROR (PcdStatus);
 
+  //
+  // Set the hypervisor features PCD.
+  //
+  AmdSevHypervisorFeatures ();
+
   //
   // Allocate GHCB and per-CPU variable pages.
   //   Since the pages must survive across the UEFI to OS transition
diff --git a/OvmfPkg/ResetVector/Ia32/PageTables64.asm b/OvmfPkg/ResetVector/Ia32/PageTables64.asm
index 6838cdeec9c3..75e63d2a0561 100644
--- a/OvmfPkg/ResetVector/Ia32/PageTables64.asm
+++ b/OvmfPkg/ResetVector/Ia32/PageTables64.asm
@@ -62,6 +62,16 @@ BITS    32
 %define GHCB_CPUID_REGISTER_SHIFT  30
 %define CPUID_INSN_LEN              2
 
+; GHCB SEV Information MSR protocol
+%define GHCB_SEV_INFORMATION_REQUEST    2
+%define GHCB_SEV_INFORMATION_RESPONSE   1
+
+; GHCB Hypervisor features MSR protocol
+%define GHCB_HYPERVISOR_FEATURES_REQUEST    128
+%define GHCB_HYPERVISOR_FEATURES_RESPONSE   129
+
+; GHCB request to terminate protocol values
+%define GHCB_GENERAL_TERMINATE_REQUEST    255
 
 ; Check if Secure Encrypted Virtualization (SEV) features are enabled.
 ;
@@ -86,6 +96,13 @@ CheckSevFeatures:
     ; will set it to 1.
     mov       byte[SEV_ES_WORK_AREA_SNP], 0
 
+    ; Set the Hypervisor features field in the workarea to zero to communicate
+    ; to the hypervisor features to the SEC phase. The hypervisor feature is
+    ; filled during the call to CheckHypervisorFeatures.
+    mov     eax, 0
+    mov     dword[SEV_ES_WORK_AREA_HYPERVISOR_FEATURES], eax
+    mov     dword[SEV_ES_WORK_AREA_HYPERVISOR_FEATURES + 4], eax
+
     ;
     ; Set up exception handlers to check for SEV-ES
     ;   Load temporary RAM stack based on PCDs (see SevEsIdtVmmComm for
@@ -225,6 +242,106 @@ IsSevEsEnabled:
 SevEsDisabled:
     OneTimeCallRet IsSevEsEnabled
 
+; The version 2 of GHCB specification added the support to query the hypervisor features.
+; If the GHCB version is >=2 then read the hypervisor features.
+;
+; Modified:  EAX, EBX, ECX, EDX
+;
+CheckHypervisorFeatures:
+    ; Get the SEV Information
+    ; Setup GHCB MSR
+    ;   GHCB_MSR[11:0]  = SEV information request
+    ;
+    mov     edx, 0
+    mov     eax, GHCB_SEV_INFORMATION_REQUEST
+    mov     ecx, 0xc0010130
+    wrmsr
+
+    ;
+    ; Issue VMGEXIT - NASM doesn't support the vmmcall instruction in 32-bit
+    ; mode, so work around this by temporarily switching to 64-bit mode.
+    ;
+BITS    64
+    rep     vmmcall
+BITS    32
+
+    ;
+    ; SEV Information Response GHCB MSR
+    ;   GHCB_MSR[63:48] = Maximum protocol version
+    ;   GHCB_MSR[47:32] = Minimum protocol version
+    ;   GHCB_MSR[11:0]  = SEV information response
+    ;
+    mov     ecx, 0xc0010130
+    rdmsr
+    and     eax, 0xfff
+    cmp     eax, GHCB_SEV_INFORMATION_RESPONSE
+    jnz     TerminateSevGuestLaunch
+    shr     edx, 16
+    cmp     edx, 2
+    jl      CheckHypervisorFeaturesDone
+
+    ; Get the hypervisor features
+    ; Setup GHCB MSR
+    ;   GHCB_MSR[11:0]  = Hypervisor features request
+    ;
+    mov     edx, 0
+    mov     eax, GHCB_HYPERVISOR_FEATURES_REQUEST
+    mov     ecx, 0xc0010130
+    wrmsr
+
+    ;
+    ; Issue VMGEXIT - NASM doesn't support the vmmcall instruction in 32-bit
+    ; mode, so work around this by temporarily switching to 64-bit mode.
+    ;
+BITS    64
+    rep     vmmcall
+BITS    32
+
+    ;
+    ; Hypervisor features reponse
+    ;   GHCB_MSR[63:12] = Features bitmap
+    ;   GHCB_MSR[11:0]  = Hypervisor features response
+    ;
+    mov     ecx, 0xc0010130
+    rdmsr
+    mov     ebx, eax
+    and     eax, 0xfff
+    cmp     eax, GHCB_HYPERVISOR_FEATURES_RESPONSE
+    jnz     TerminateSevGuestLaunch
+
+    shr     ebx, 12
+    mov     dword[SEV_ES_WORK_AREA_HYPERVISOR_FEATURES], ebx
+    mov     dword[SEV_ES_WORK_AREA_HYPERVISOR_FEATURES + 4], edx
+
+    jmp     CheckHypervisorFeaturesDone
+TerminateSevGuestLaunch:
+    ;
+    ; Setup GHCB MSR
+    ;   GHCB_MSR[23:16] = 0
+    ;   GHCB_MSR[15:12] = 0
+    ;   GHCB_MSR[11:0]  = Terminate Request
+    ;
+    mov     edx, 0
+    mov     eax, GHCB_GENERAL_TERMINATE_REQUEST
+    mov     ecx, 0xc0010130
+    wrmsr
+
+    ;
+    ; Issue VMGEXIT - NASM doesn't support the vmmcall instruction in 32-bit
+    ; mode, so work around this by temporarily switching to 64-bit mode.
+    ;
+BITS    64
+    rep     vmmcall
+BITS    32
+
+TerminateSevGuestLaunchHlt:
+    cli
+    hlt
+    jmp     TerminateSevGuestLaunchHlt
+
+CheckHypervisorFeaturesDone:
+    OneTimeCallRet CheckHypervisorFeatures
+
 ;
 ; Modified:  EAX, EBX, ECX, EDX
 ;
@@ -328,6 +445,11 @@ clearGhcbMemoryLoop:
     mov     dword[ecx * 4 + GHCB_BASE - 4], eax
     loop    clearGhcbMemoryLoop
 
+    ;
+    ; It is SEV-ES guest, query the Hypervisor features
+    ;
+    OneTimeCall   CheckHypervisorFeatures
+
 SetCr3:
     ;
     ; Set CR3 now that the paging structures are available
diff --git a/OvmfPkg/ResetVector/ResetVector.nasmb b/OvmfPkg/ResetVector/ResetVector.nasmb
index 1971557b1c00..5beba3ecb290 100644
--- a/OvmfPkg/ResetVector/ResetVector.nasmb
+++ b/OvmfPkg/ResetVector/ResetVector.nasmb
@@ -76,6 +76,7 @@
   %define SEV_ES_WORK_AREA_SNP (FixedPcdGet32 (PcdSevEsWorkAreaBase) + 1)
   %define SEV_ES_WORK_AREA_RDRAND (FixedPcdGet32 (PcdSevEsWorkAreaBase) + 8)
   %define SEV_ES_WORK_AREA_ENC_MASK (FixedPcdGet32 (PcdSevEsWorkAreaBase) + 16)
+  %define SEV_ES_WORK_AREA_HYPERVISOR_FEATURES (FixedPcdGet32 (PcdSevEsWorkAreaBase) + 24)
   %define SEV_ES_VC_TOP_OF_STACK (FixedPcdGet32 (PcdOvmfSecPeiTempRamBase) + FixedPcdGet32 (PcdOvmfSecPeiTempRamSize))
 %include "Ia32/Flat32ToFlat64.asm"
 %include "Ia32/PageTables64.asm"
-- 
2.17.1


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

* [PATCH RFC v3 05/22] OvmfPkg: reserve Secrets page in MEMFD
  2021-05-26 23:10 [RESEND PATCH RFC v3 00/22] Add AMD Secure Nested Paging (SEV-SNP) support Brijesh Singh
                   ` (3 preceding siblings ...)
  2021-05-26 23:11 ` [PATCH RFC v3 04/22] OvmfPkg/MemEncryptSevLib: extend Es Workarea to include hv features Brijesh Singh
@ 2021-05-26 23:11 ` Brijesh Singh
  2021-06-07 12:26   ` Laszlo Ersek
  2021-05-26 23:11 ` [PATCH RFC v3 06/22] OvmfPkg: reserve CPUID page for the SEV-SNP guest Brijesh Singh
                   ` (18 subsequent siblings)
  23 siblings, 1 reply; 57+ messages in thread
From: Brijesh Singh @ 2021-05-26 23:11 UTC (permalink / raw)
  To: James Bottomley, Min Xu, Jiewen Yao, Tom Lendacky, Jordan Justen,
	Laszlo Ersek, Erdem Aktas, Eric Dong, Ray Ni, Rahul Kumar, devel
  Cc: Brijesh Singh, Ard Biesheuvel

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

When AMD SEV is enabled in the guest VM, a hypervisor need to insert a
secrets page.

When SEV-SNP is enabled, the secrets page contains the VM platform
communication keys. The guest BIOS and OS can use this key to communicate
with the SEV firmware to get attesation report. See the SEV-SNP firmware
spec for more details for the content of the secrets page.

When SEV and SEV-ES is enabled, the secrets page contains the information
provided by the guest owner after the attestation. See the SEV
LAUNCH_SECRET command for more details.

Cc: James Bottomley <jejb@linux.ibm.com>
Cc: Min Xu <min.m.xu@intel.com>
Cc: Jiewen Yao <jiewen.yao@intel.com>
Cc: Tom Lendacky <thomas.lendacky@amd.com>
Cc: Jordan Justen <jordan.l.justen@intel.com>
Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
Cc: Laszlo Ersek <lersek@redhat.com>
Cc: Erdem Aktas <erdemaktas@google.com>
Signed-off-by: Brijesh Singh <brijesh.singh@amd.com>
---
 OvmfPkg/OvmfPkgX64.dsc                 |  2 ++
 OvmfPkg/OvmfPkgX64.fdf                 |  5 +++++
 OvmfPkg/AmdSev/SecretPei/SecretPei.inf |  1 +
 OvmfPkg/AmdSev/SecretPei/SecretPei.c   | 15 ++++++++++++++-
 4 files changed, 22 insertions(+), 1 deletion(-)

diff --git a/OvmfPkg/OvmfPkgX64.dsc b/OvmfPkg/OvmfPkgX64.dsc
index 999738dc39cd..ea08e1fabc65 100644
--- a/OvmfPkg/OvmfPkgX64.dsc
+++ b/OvmfPkg/OvmfPkgX64.dsc
@@ -716,6 +716,7 @@ [Components]
   OvmfPkg/SmmAccess/SmmAccessPei.inf
 !endif
   UefiCpuPkg/CpuMpPei/CpuMpPei.inf
+  OvmfPkg/AmdSev/SecretPei/SecretPei.inf
 
 !if $(TPM_ENABLE) == TRUE
   OvmfPkg/Tcg/TpmMmioSevDecryptPei/TpmMmioSevDecryptPei.inf
@@ -966,6 +967,7 @@ [Components]
   OvmfPkg/PlatformDxe/Platform.inf
   OvmfPkg/AmdSevDxe/AmdSevDxe.inf
   OvmfPkg/IoMmuDxe/IoMmuDxe.inf
+  OvmfPkg/AmdSev/SecretDxe/SecretDxe.inf
 
 !if $(SMM_REQUIRE) == TRUE
   OvmfPkg/SmmAccess/SmmAccess2Dxe.inf
diff --git a/OvmfPkg/OvmfPkgX64.fdf b/OvmfPkg/OvmfPkgX64.fdf
index d6be798fcadd..9126b8eb5014 100644
--- a/OvmfPkg/OvmfPkgX64.fdf
+++ b/OvmfPkg/OvmfPkgX64.fdf
@@ -88,6 +88,9 @@ [FD.MEMFD]
 0x00C000|0x001000
 gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecGhcbBackupBase|gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecGhcbBackupSize
 
+0x00D000|0x001000
+gUefiOvmfPkgTokenSpaceGuid.PcdSevLaunchSecretBase|gUefiOvmfPkgTokenSpaceGuid.PcdSevLaunchSecretSize
+
 0x010000|0x010000
 gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecPeiTempRamBase|gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecPeiTempRamSize
 
@@ -179,6 +182,7 @@ [FV.PEIFV]
 INF  SecurityPkg/Tcg/TcgPei/TcgPei.inf
 INF  SecurityPkg/Tcg/Tcg2Pei/Tcg2Pei.inf
 !endif
+INF  OvmfPkg/AmdSev/SecretPei/SecretPei.inf
 
 ################################################################################
 
@@ -314,6 +318,7 @@ [FV.DXEFV]
 INF  ShellPkg/Application/Shell/Shell.inf
 
 INF MdeModulePkg/Logo/LogoDxe.inf
+INF OvmfPkg/AmdSev/SecretDxe/SecretDxe.inf
 
 #
 # Network modules
diff --git a/OvmfPkg/AmdSev/SecretPei/SecretPei.inf b/OvmfPkg/AmdSev/SecretPei/SecretPei.inf
index 08be156c4bc0..9265f8adee12 100644
--- a/OvmfPkg/AmdSev/SecretPei/SecretPei.inf
+++ b/OvmfPkg/AmdSev/SecretPei/SecretPei.inf
@@ -26,6 +26,7 @@ [LibraryClasses]
   HobLib
   PeimEntryPoint
   PcdLib
+  MemEncryptSevLib
 
 [FixedPcd]
   gUefiOvmfPkgTokenSpaceGuid.PcdSevLaunchSecretBase
diff --git a/OvmfPkg/AmdSev/SecretPei/SecretPei.c b/OvmfPkg/AmdSev/SecretPei/SecretPei.c
index ad491515dd5d..51eb094555aa 100644
--- a/OvmfPkg/AmdSev/SecretPei/SecretPei.c
+++ b/OvmfPkg/AmdSev/SecretPei/SecretPei.c
@@ -7,6 +7,7 @@
 #include <PiPei.h>
 #include <Library/HobLib.h>
 #include <Library/PcdLib.h>
+#include <Library/MemEncryptSevLib.h>
 
 EFI_STATUS
 EFIAPI
@@ -15,10 +16,22 @@ InitializeSecretPei (
   IN CONST EFI_PEI_SERVICES     **PeiServices
   )
 {
+  UINTN   Type;
+
+  //
+  // The location of the secret page should be marked reserved so that guest OS
+  // does not treated as a system RAM.
+  //
+  if (MemEncryptSevSnpIsEnabled ()) {
+    Type = EfiReservedMemoryType;
+  } else {
+    Type = EfiBootServicesData;
+  }
+
   BuildMemoryAllocationHob (
     PcdGet32 (PcdSevLaunchSecretBase),
     PcdGet32 (PcdSevLaunchSecretSize),
-    EfiBootServicesData
+    Type
     );
 
   return EFI_SUCCESS;
-- 
2.17.1


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

* [PATCH RFC v3 06/22] OvmfPkg: reserve CPUID page for the SEV-SNP guest
  2021-05-26 23:10 [RESEND PATCH RFC v3 00/22] Add AMD Secure Nested Paging (SEV-SNP) support Brijesh Singh
                   ` (4 preceding siblings ...)
  2021-05-26 23:11 ` [PATCH RFC v3 05/22] OvmfPkg: reserve Secrets page in MEMFD Brijesh Singh
@ 2021-05-26 23:11 ` Brijesh Singh
  2021-05-26 23:11 ` [PATCH RFC v3 07/22] OvmfPkg/ResetVector: validate the data pages used in SEC phase Brijesh Singh
                   ` (17 subsequent siblings)
  23 siblings, 0 replies; 57+ messages in thread
From: Brijesh Singh @ 2021-05-26 23:11 UTC (permalink / raw)
  To: James Bottomley, Min Xu, Jiewen Yao, Tom Lendacky, Jordan Justen,
	Laszlo Ersek, Erdem Aktas, Eric Dong, Ray Ni, Rahul Kumar, devel
  Cc: Brijesh Singh, Ard Biesheuvel

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

During the SEV-SNP guest launch sequence, two special pages need to be
inserted, the secrets and CPUID. The secrets page, contain the VM
platform communication keys. The guest BIOS and/or OS can use this key
to communicate with the SEV firmware to get the attestation report.
The CPUID page, contain the CPUIDs entries filtered through the AMD-SEV
firmware.

OvmfPkg already reserves the memory for the Secrets Page in the MEMFD.
Extend the MEMFD to reserve the memory for the CPUID page.

See SEV-SNP spec for more information on the content layout of the secrets
and CPUID page, and how it can be used by the SEV-SNP guest VM.

Cc: James Bottomley <jejb@linux.ibm.com>
Cc: Min Xu <min.m.xu@intel.com>
Cc: Jiewen Yao <jiewen.yao@intel.com>
Cc: Tom Lendacky <thomas.lendacky@amd.com>
Cc: Jordan Justen <jordan.l.justen@intel.com>
Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
Cc: Laszlo Ersek <lersek@redhat.com>
Cc: Erdem Aktas <erdemaktas@google.com>
Signed-off-by: Brijesh Singh <brijesh.singh@amd.com>
---
 OvmfPkg/OvmfPkg.dec                          |  6 ++++++
 OvmfPkg/OvmfPkgX64.fdf                       |  3 +++
 OvmfPkg/PlatformPei/PlatformPei.inf          |  2 ++
 OvmfPkg/ResetVector/ResetVector.inf          |  2 ++
 OvmfPkg/PlatformPei/MemDetect.c              | 12 ++++++++++++
 OvmfPkg/ResetVector/Ia16/ResetVectorVtf0.asm | 18 ++++++++++++++++++
 OvmfPkg/ResetVector/ResetVector.nasmb        |  2 ++
 7 files changed, 45 insertions(+)

diff --git a/OvmfPkg/OvmfPkg.dec b/OvmfPkg/OvmfPkg.dec
index 6ae733f6e39f..fdb5dacdc7fa 100644
--- a/OvmfPkg/OvmfPkg.dec
+++ b/OvmfPkg/OvmfPkg.dec
@@ -321,6 +321,12 @@ [PcdsFixedAtBuild]
   gUefiOvmfPkgTokenSpaceGuid.PcdSevLaunchSecretBase|0x0|UINT32|0x42
   gUefiOvmfPkgTokenSpaceGuid.PcdSevLaunchSecretSize|0x0|UINT32|0x43
 
+  ## The base address and size of the SEV-SNP CPUID Area provisioned by the
+  #  SEV-SNP firmware. If this is set in the .fdf, the platform
+  #  is responsible for protecting the area from DXE phase overwrites.
+  gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSnpCpuidBase|0x0|UINT32|0x47
+  gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSnpCpuidSize|0x0|UINT32|0x48
+
 [PcdsDynamic, PcdsDynamicEx]
   gUefiOvmfPkgTokenSpaceGuid.PcdEmuVariableEvent|0|UINT64|2
   gUefiOvmfPkgTokenSpaceGuid.PcdOvmfFlashVariablesEnable|FALSE|BOOLEAN|0x10
diff --git a/OvmfPkg/OvmfPkgX64.fdf b/OvmfPkg/OvmfPkgX64.fdf
index 9126b8eb5014..1300af666c49 100644
--- a/OvmfPkg/OvmfPkgX64.fdf
+++ b/OvmfPkg/OvmfPkgX64.fdf
@@ -91,6 +91,9 @@ [FD.MEMFD]
 0x00D000|0x001000
 gUefiOvmfPkgTokenSpaceGuid.PcdSevLaunchSecretBase|gUefiOvmfPkgTokenSpaceGuid.PcdSevLaunchSecretSize
 
+0x00E000|0x001000
+gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSnpCpuidBase|gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSnpCpuidSize
+
 0x010000|0x010000
 gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecPeiTempRamBase|gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecPeiTempRamSize
 
diff --git a/OvmfPkg/PlatformPei/PlatformPei.inf b/OvmfPkg/PlatformPei/PlatformPei.inf
index 3256ccfe88d8..89c8e9627c86 100644
--- a/OvmfPkg/PlatformPei/PlatformPei.inf
+++ b/OvmfPkg/PlatformPei/PlatformPei.inf
@@ -120,6 +120,8 @@ [FixedPcd]
   gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiReservedMemoryType
   gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiRuntimeServicesCode
   gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiRuntimeServicesData
+  gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSnpCpuidBase
+  gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSnpCpuidSize
   gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecGhcbBackupBase
   gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecGhcbBackupSize
   gUefiCpuPkgTokenSpaceGuid.PcdSevEsWorkAreaBase
diff --git a/OvmfPkg/ResetVector/ResetVector.inf b/OvmfPkg/ResetVector/ResetVector.inf
index dc38f68919cd..8e52265602c3 100644
--- a/OvmfPkg/ResetVector/ResetVector.inf
+++ b/OvmfPkg/ResetVector/ResetVector.inf
@@ -45,5 +45,7 @@ [Pcd]
   gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecPeiTempRamSize
 
 [FixedPcd]
+  gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSnpCpuidBase
+  gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSnpCpuidSize
   gUefiOvmfPkgTokenSpaceGuid.PcdSevLaunchSecretBase
   gUefiOvmfPkgTokenSpaceGuid.PcdSevLaunchSecretSize
diff --git a/OvmfPkg/PlatformPei/MemDetect.c b/OvmfPkg/PlatformPei/MemDetect.c
index c08aa2e45a53..483e92af8219 100644
--- a/OvmfPkg/PlatformPei/MemDetect.c
+++ b/OvmfPkg/PlatformPei/MemDetect.c
@@ -894,6 +894,18 @@ InitializeRamRegions (
         EfiACPIMemoryNVS
         );
     }
+
+    if (MemEncryptSevSnpIsEnabled ()) {
+      //
+      // If SEV-SNP is enabled, reserve the CPUID page. The memory range should
+      // not be treated as a RAM by the guest OS, so, mark it as reserved.
+      //
+      BuildMemoryAllocationHob (
+        (EFI_PHYSICAL_ADDRESS)(UINTN) PcdGet32 (PcdOvmfSnpCpuidBase),
+        (UINT64)(UINTN) PcdGet32 (PcdOvmfSnpCpuidSize),
+        EfiReservedMemoryType
+      );
+    }
 #endif
   }
 
diff --git a/OvmfPkg/ResetVector/Ia16/ResetVectorVtf0.asm b/OvmfPkg/ResetVector/Ia16/ResetVectorVtf0.asm
index 9c0b5853a46f..05c7e32f46a0 100644
--- a/OvmfPkg/ResetVector/Ia16/ResetVectorVtf0.asm
+++ b/OvmfPkg/ResetVector/Ia16/ResetVectorVtf0.asm
@@ -47,6 +47,24 @@ TIMES (15 - ((guidedStructureEnd - guidedStructureStart + 15) % 16)) DB 0
 ;
 guidedStructureStart:
 
+;
+; SEV-SNP boot support
+;
+; sevSnpBlock:
+;   For the initial boot of SEV-SNP guest, a CPUID page must be reserved by
+;   the BIOS at a RAM area defined by SEV_SNP_CPUID_BASE. A hypervisor will
+;   locate this information using the SEV-SNP boot block GUID.
+;
+; GUID (SEV-SNP boot block): bd39c0c2-2f8e-4243-83e8-1b74cebcb7d9
+;
+sevSnpBootBlockStart:
+    DD      SNP_CPUID_BASE
+    DD      SNP_CPUID_SIZE
+    DW      sevSnpBootBlockEnd - sevSnpBootBlockStart
+    DB      0xC2, 0xC0, 0x39, 0xBD, 0x8e, 0x2F, 0x43, 0x42
+    DB      0x83, 0xE8, 0x1B, 0x74, 0xCE, 0xBC, 0xB7, 0xD9
+sevSnpBootBlockEnd:
+
 ;
 ; SEV Secret block
 ;
diff --git a/OvmfPkg/ResetVector/ResetVector.nasmb b/OvmfPkg/ResetVector/ResetVector.nasmb
index 5beba3ecb290..36739096e7e1 100644
--- a/OvmfPkg/ResetVector/ResetVector.nasmb
+++ b/OvmfPkg/ResetVector/ResetVector.nasmb
@@ -90,5 +90,7 @@
   %define SEV_ES_AP_RESET_IP  FixedPcdGet32 (PcdSevEsWorkAreaBase)
   %define SEV_LAUNCH_SECRET_BASE  FixedPcdGet32 (PcdSevLaunchSecretBase)
   %define SEV_LAUNCH_SECRET_SIZE  FixedPcdGet32 (PcdSevLaunchSecretSize)
+  %define SNP_CPUID_BASE  FixedPcdGet32 (PcdOvmfSnpCpuidBase)
+  %define SNP_CPUID_SIZE  FixedPcdGet32 (PcdOvmfSnpCpuidSize)
 %include "Ia16/ResetVectorVtf0.asm"
 
-- 
2.17.1


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

* [PATCH RFC v3 07/22] OvmfPkg/ResetVector: validate the data pages used in SEC phase
  2021-05-26 23:10 [RESEND PATCH RFC v3 00/22] Add AMD Secure Nested Paging (SEV-SNP) support Brijesh Singh
                   ` (5 preceding siblings ...)
  2021-05-26 23:11 ` [PATCH RFC v3 06/22] OvmfPkg: reserve CPUID page for the SEV-SNP guest Brijesh Singh
@ 2021-05-26 23:11 ` Brijesh Singh
  2021-05-26 23:11 ` [PATCH RFC v3 08/22] OvmfPkg/ResetVector: invalidate the GHCB page Brijesh Singh
                   ` (16 subsequent siblings)
  23 siblings, 0 replies; 57+ messages in thread
From: Brijesh Singh @ 2021-05-26 23:11 UTC (permalink / raw)
  To: James Bottomley, Min Xu, Jiewen Yao, Tom Lendacky, Jordan Justen,
	Laszlo Ersek, Erdem Aktas, Eric Dong, Ray Ni, Rahul Kumar, devel
  Cc: Brijesh Singh, Ard Biesheuvel

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

An SEV-SNP guest requires that private memory (aka pages mapped 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.

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

diff --git a/OvmfPkg/OvmfPkg.dec b/OvmfPkg/OvmfPkg.dec
index fdb5dacdc7fa..e00f8159f317 100644
--- a/OvmfPkg/OvmfPkg.dec
+++ b/OvmfPkg/OvmfPkg.dec
@@ -327,6 +327,11 @@ [PcdsFixedAtBuild]
   gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSnpCpuidBase|0x0|UINT32|0x47
   gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSnpCpuidSize|0x0|UINT32|0x48
 
+  ## The start and end of pre-validated memory region by the hypervisor
+  #  through the SEV-SNP firmware.
+  gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSnpHypervisorPreValidatedStart|0x0|UINT32|0x49
+  gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSnpHypervisorPreValidatedEnd|0x0|UINT32|0x50
+
 [PcdsDynamic, PcdsDynamicEx]
   gUefiOvmfPkgTokenSpaceGuid.PcdEmuVariableEvent|0|UINT64|2
   gUefiOvmfPkgTokenSpaceGuid.PcdOvmfFlashVariablesEnable|FALSE|BOOLEAN|0x10
diff --git a/OvmfPkg/OvmfPkgX64.fdf b/OvmfPkg/OvmfPkgX64.fdf
index 1300af666c49..4c59001fb750 100644
--- a/OvmfPkg/OvmfPkgX64.fdf
+++ b/OvmfPkg/OvmfPkgX64.fdf
@@ -105,7 +105,14 @@ [FD.MEMFD]
 gUefiOvmfPkgTokenSpaceGuid.PcdOvmfDxeMemFvBase|gUefiOvmfPkgTokenSpaceGuid.PcdOvmfDxeMemFvSize
 FV = DXEFV
 
-################################################################################
+##########################################################################################
+#
+# The range of the pages pre-validated through the SEV-SNP firmware while creating SEV-SNP guest
+#
+SET gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSnpHypervisorPreValidatedStart = $(MEMFD_BASE_ADDRESS) + gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecPageTablesBase
+
+SET gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSnpHypervisorPreValidatedEnd = $(MEMFD_BASE_ADDRESS) + gUefiOvmfPkgTokenSpaceGuid.PcdOvmfPeiMemFvBase
+##########################################################################################
 
 [FV.SECFV]
 FvNameGuid         = 763BED0D-DE9F-48F5-81F1-3E90E1B1A015
diff --git a/OvmfPkg/ResetVector/ResetVector.inf b/OvmfPkg/ResetVector/ResetVector.inf
index 8e52265602c3..2a75e909c769 100644
--- a/OvmfPkg/ResetVector/ResetVector.inf
+++ b/OvmfPkg/ResetVector/ResetVector.inf
@@ -49,3 +49,5 @@ [FixedPcd]
   gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSnpCpuidSize
   gUefiOvmfPkgTokenSpaceGuid.PcdSevLaunchSecretBase
   gUefiOvmfPkgTokenSpaceGuid.PcdSevLaunchSecretSize
+  gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSnpHypervisorPreValidatedStart
+  gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSnpHypervisorPreValidatedEnd
diff --git a/OvmfPkg/ResetVector/Ia16/ResetVectorVtf0.asm b/OvmfPkg/ResetVector/Ia16/ResetVectorVtf0.asm
index 05c7e32f46a0..769dd0bccfd9 100644
--- a/OvmfPkg/ResetVector/Ia16/ResetVectorVtf0.asm
+++ b/OvmfPkg/ResetVector/Ia16/ResetVectorVtf0.asm
@@ -55,11 +55,16 @@ guidedStructureStart:
 ;   the BIOS at a RAM area defined by SEV_SNP_CPUID_BASE. A hypervisor will
 ;   locate this information using the SEV-SNP boot block GUID.
 ;
+;   In order to boot the SEV-SNP guest the hypervisor must pre-validated the
+;   memory range from SNP_HV_VALIDATED_START to SNP_HV_VALIDATED_END.
+;
 ; GUID (SEV-SNP boot block): bd39c0c2-2f8e-4243-83e8-1b74cebcb7d9
 ;
 sevSnpBootBlockStart:
     DD      SNP_CPUID_BASE
     DD      SNP_CPUID_SIZE
+    DD      SNP_HV_VALIDATED_START
+    DD      SNP_HV_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.nasmb b/OvmfPkg/ResetVector/ResetVector.nasmb
index 36739096e7e1..465038e39de3 100644
--- a/OvmfPkg/ResetVector/ResetVector.nasmb
+++ b/OvmfPkg/ResetVector/ResetVector.nasmb
@@ -92,5 +92,7 @@
   %define SEV_LAUNCH_SECRET_SIZE  FixedPcdGet32 (PcdSevLaunchSecretSize)
   %define SNP_CPUID_BASE  FixedPcdGet32 (PcdOvmfSnpCpuidBase)
   %define SNP_CPUID_SIZE  FixedPcdGet32 (PcdOvmfSnpCpuidSize)
+  %define SNP_HV_VALIDATED_START FixedPcdGet32 (PcdOvmfSnpHypervisorPreValidatedStart)
+  %define SNP_HV_VALIDATED_END FixedPcdGet32 (PcdOvmfSnpHypervisorPreValidatedEnd)
 %include "Ia16/ResetVectorVtf0.asm"
 
-- 
2.17.1


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

* [PATCH RFC v3 08/22] OvmfPkg/ResetVector: invalidate the GHCB page
  2021-05-26 23:10 [RESEND PATCH RFC v3 00/22] Add AMD Secure Nested Paging (SEV-SNP) support Brijesh Singh
                   ` (6 preceding siblings ...)
  2021-05-26 23:11 ` [PATCH RFC v3 07/22] OvmfPkg/ResetVector: validate the data pages used in SEC phase Brijesh Singh
@ 2021-05-26 23:11 ` Brijesh Singh
  2021-05-26 23:11 ` [PATCH RFC v3 09/22] OvmfPkg: add library to support registering GHCB GPA Brijesh Singh
                   ` (15 subsequent siblings)
  23 siblings, 0 replies; 57+ messages in thread
From: Brijesh Singh @ 2021-05-26 23:11 UTC (permalink / raw)
  To: James Bottomley, Min Xu, Jiewen Yao, Tom Lendacky, Jordan Justen,
	Laszlo Ersek, Erdem Aktas, Eric Dong, Ray Ni, Rahul Kumar, devel
  Cc: Brijesh Singh, Ard Biesheuvel

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

When SEV-SNP is active, the GHCB page is mapped un-encrypted in the
initial page table built by the reset vector code. Just clearing the
encryption attribute from the page table is not enough. The page also
needs to be added as shared in the RMP table.

The GHCB page was part of the pre-validated memory range specified
through the SnpBootBlock GUID. To maintain the security guarantees,
we must invalidate the GHCB page before clearing the encryption
attribute from the page table, and add the page shared in the RMP
table.

Cc: James Bottomley <jejb@linux.ibm.com>
Cc: Min Xu <min.m.xu@intel.com>
Cc: Jiewen Yao <jiewen.yao@intel.com>
Cc: Tom Lendacky <thomas.lendacky@amd.com>
Cc: Jordan Justen <jordan.l.justen@intel.com>
Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
Cc: Laszlo Ersek <lersek@redhat.com>
Cc: Erdem Aktas <erdemaktas@google.com>
Signed-off-by: Brijesh Singh <brijesh.singh@amd.com>
---
 OvmfPkg/ResetVector/Ia32/PageTables64.asm | 93 +++++++++++++++++++++++
 1 file changed, 93 insertions(+)

diff --git a/OvmfPkg/ResetVector/Ia32/PageTables64.asm b/OvmfPkg/ResetVector/Ia32/PageTables64.asm
index 75e63d2a0561..f764825755f0 100644
--- a/OvmfPkg/ResetVector/Ia32/PageTables64.asm
+++ b/OvmfPkg/ResetVector/Ia32/PageTables64.asm
@@ -10,6 +10,8 @@
 
 BITS    32
 
+%include "Nasm.inc"
+
 %define PAGE_PRESENT            0x01
 %define PAGE_READ_WRITE         0x02
 %define PAGE_USER_SUPERVISOR    0x04
@@ -70,9 +72,87 @@ BITS    32
 %define GHCB_HYPERVISOR_FEATURES_REQUEST    128
 %define GHCB_HYPERVISOR_FEATURES_RESPONSE   129
 
+; GHCB Page Invalidate request and response protocol values
+;
+%define GHCB_PAGE_STATE_CHANGE_REQUEST    20
+%define GHCB_PAGE_STATE_CHANGE_RESPONSE   21
+%define GHCB_PAGE_STATE_SHARED            2
+
 ; GHCB request to terminate protocol values
 %define GHCB_GENERAL_TERMINATE_REQUEST    255
 
+; If its an SEV-SNP guest then use the page state change VMGEXIT to invalidate
+; the GHCB page.
+;
+; Modified:  EAX, EBX, ECX, EDX
+;
+InvalidateGHCBPage:
+    ; Check if it is SEV-SNP guest.
+    cmp     byte[SEV_ES_WORK_AREA_SNP], 1
+    jne     InvalidateGHCBPageDone
+
+    ; Check whether hypervisor features has SEV-SNP (BIT0) set to indicate that
+    ; hypervisor supports the page state change.
+    mov     eax, dword[SEV_ES_WORK_AREA_HYPERVISOR_FEATURES]
+    bt      eax, 0
+    jnc     TerminateSevGuestLaunch
+
+    ; Use PVALIDATE instruction to invalidate the page
+    mov     eax, GHCB_BASE
+    mov     ecx, 0
+    mov     edx, 0
+    PVALIDATE
+
+    ; Save the carry flag to be use later.
+    setc    dl
+
+    ; If PVALIDATE fail then abort the launch.
+    cmp     eax, 0
+    jne     TerminateSevGuestLaunch
+
+    ; Check the carry flag to determine if RMP entry was updated.
+    cmp     dl, 0
+    jne     TerminateSevGuestLaunch
+
+    ; Ask hypervisor to change the page state to shared using the
+    ; Page State Change VMGEXIT.
+    ;
+    ; Setup GHCB MSR
+    ;   GHCB_MSR[55:52] = Page Operation
+    ;   GHCB_MSR[51:12] = Guest Physical Frame Number
+    ;   GHCB_MSR[11:0]  = Page State Change Request
+    ;
+    mov     eax, (GHCB_BASE >> 12)
+    shl     eax, 12
+    or      eax, GHCB_PAGE_STATE_CHANGE_REQUEST
+    mov     edx, (GHCB_PAGE_STATE_SHARED << 20)
+    mov     ecx, 0xc0010130
+    wrmsr
+
+    ;
+    ; Issue VMGEXIT - NASM doesn't support the vmmcall instruction in 32-bit
+    ; mode, so work around this by temporarily switching to 64-bit mode.
+    ;
+BITS    64
+    rep     vmmcall
+BITS    32
+
+    ;
+    ; Response GHCB MSR
+    ;   GHCB_MSR[51:12] = Guest Physical Frame Number
+    ;   GHCB_MSR[11:0]  = Page State Change Response
+    ;
+    mov     ecx, 0xc0010130
+    rdmsr
+    and     eax, 0xfff
+    cmp     eax, GHCB_PAGE_STATE_CHANGE_RESPONSE
+    jnz     TerminateSevGuestLaunch
+    cmp     edx, 0
+    jnz     TerminateSevGuestLaunch
+
+InvalidateGHCBPageDone:
+    OneTimeCallRet InvalidateGHCBPage
+
 ; Check if Secure Encrypted Virtualization (SEV) features are enabled.
 ;
 ; Register usage is tight in this routine, so multiple calls for the
@@ -450,6 +530,19 @@ clearGhcbMemoryLoop:
     ;
     OneTimeCall   CheckHypervisorFeatures
 
+    ;
+    ; The page table built above cleared the memory encryption mask from the
+    ; GHCB_BASE (aka made it shared). When SEV-SNP is enabled, to maintain
+    ; the security guarantees, the page state transition from private to
+    ; shared must go through the page invalidation steps. Invalidate the
+    ; memory range before loading the page table below.
+    ;
+    ; NOTE: the invalidation must happen after zeroing the GHCB memory. This
+    ;       is because, in the 32-bit mode all the access are considered private.
+    ;       The invalidation before the zero'ing will cause a #VC.
+    ;
+    OneTimeCall  InvalidateGHCBPage
+
 SetCr3:
     ;
     ; Set CR3 now that the paging structures are available
-- 
2.17.1


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

* [PATCH RFC v3 09/22] OvmfPkg: add library to support registering GHCB GPA
  2021-05-26 23:10 [RESEND PATCH RFC v3 00/22] Add AMD Secure Nested Paging (SEV-SNP) support Brijesh Singh
                   ` (7 preceding siblings ...)
  2021-05-26 23:11 ` [PATCH RFC v3 08/22] OvmfPkg/ResetVector: invalidate the GHCB page Brijesh Singh
@ 2021-05-26 23:11 ` Brijesh Singh
  2021-05-26 23:11 ` [PATCH RFC v3 10/22] OvmfPkg/PlatformPei: register GHCB gpa for the SEV-SNP guest Brijesh Singh
                   ` (14 subsequent siblings)
  23 siblings, 0 replies; 57+ messages in thread
From: Brijesh Singh @ 2021-05-26 23:11 UTC (permalink / raw)
  To: James Bottomley, Min Xu, Jiewen Yao, Tom Lendacky, Jordan Justen,
	Laszlo Ersek, Erdem Aktas, Eric Dong, Ray Ni, Rahul Kumar, devel
  Cc: Brijesh Singh, Ard Biesheuvel

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

An SEV-SNP guest us required to perform GHCB GPA registration before
using a GHCB. See the GHCB spec section 2.5.2 for more details.

Add a library that can be called to perform the GHCB GPA registration.

Cc: James Bottomley <jejb@linux.ibm.com>
Cc: Min Xu <min.m.xu@intel.com>
Cc: Jiewen Yao <jiewen.yao@intel.com>
Cc: Tom Lendacky <thomas.lendacky@amd.com>
Cc: Jordan Justen <jordan.l.justen@intel.com>
Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
Cc: Laszlo Ersek <lersek@redhat.com>
Cc: Erdem Aktas <erdemaktas@google.com>
Signed-off-by: Brijesh Singh <brijesh.singh@amd.com>
---
 OvmfPkg/OvmfPkg.dec                           |  4 +
 OvmfPkg/OvmfPkgIa32.dsc                       |  1 +
 OvmfPkg/OvmfPkgIa32X64.dsc                    |  1 +
 OvmfPkg/OvmfPkgX64.dsc                        |  1 +
 .../GhcbRegisterLib/GhcbRegisterLib.inf       | 33 +++++++
 OvmfPkg/Include/Library/GhcbRegisterLib.h     | 27 ++++++
 .../Library/GhcbRegisterLib/GhcbRegisterLib.c | 97 +++++++++++++++++++
 7 files changed, 164 insertions(+)
 create mode 100644 OvmfPkg/Library/GhcbRegisterLib/GhcbRegisterLib.inf
 create mode 100644 OvmfPkg/Include/Library/GhcbRegisterLib.h
 create mode 100644 OvmfPkg/Library/GhcbRegisterLib/GhcbRegisterLib.c

diff --git a/OvmfPkg/OvmfPkg.dec b/OvmfPkg/OvmfPkg.dec
index e00f8159f317..3886d43bd3de 100644
--- a/OvmfPkg/OvmfPkg.dec
+++ b/OvmfPkg/OvmfPkg.dec
@@ -106,6 +106,10 @@ [LibraryClasses]
   #
   XenPlatformLib|Include/Library/XenPlatformLib.h
 
+  ##  @libraryclass  Register GHCB GPA
+  #
+  GhcbRegisterLib|Include/Library/GhcbRegisterLib.h
+
 [Guids]
   gUefiOvmfPkgTokenSpaceGuid            = {0x93bb96af, 0xb9f2, 0x4eb8, {0x94, 0x62, 0xe0, 0xba, 0x74, 0x56, 0x42, 0x36}}
   gEfiXenInfoGuid                       = {0xd3b46f3b, 0xd441, 0x1244, {0x9a, 0x12, 0x0, 0x12, 0x27, 0x3f, 0xc1, 0x4d}}
diff --git a/OvmfPkg/OvmfPkgIa32.dsc b/OvmfPkg/OvmfPkgIa32.dsc
index 33fbd767903e..7cbef8e82282 100644
--- a/OvmfPkg/OvmfPkgIa32.dsc
+++ b/OvmfPkg/OvmfPkgIa32.dsc
@@ -243,6 +243,7 @@ [LibraryClasses]
 [LibraryClasses.common]
   BaseCryptLib|CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf
   VmgExitLib|UefiCpuPkg/Library/VmgExitLibNull/VmgExitLibNull.inf
+  GhcbRegisterLib|OvmfPkg/Library/GhcbRegisterLib/GhcbRegisterLib.inf
 
 [LibraryClasses.common.SEC]
   TimerLib|OvmfPkg/Library/AcpiTimerLib/BaseRomAcpiTimerLib.inf
diff --git a/OvmfPkg/OvmfPkgIa32X64.dsc b/OvmfPkg/OvmfPkgIa32X64.dsc
index b13e5cfd9047..6b0bc02bd536 100644
--- a/OvmfPkg/OvmfPkgIa32X64.dsc
+++ b/OvmfPkg/OvmfPkgIa32X64.dsc
@@ -247,6 +247,7 @@ [LibraryClasses]
 [LibraryClasses.common]
   BaseCryptLib|CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf
   VmgExitLib|UefiCpuPkg/Library/VmgExitLibNull/VmgExitLibNull.inf
+  GhcbRegisterLib|OvmfPkg/Library/GhcbRegisterLib/GhcbRegisterLib.inf
 
 [LibraryClasses.common.SEC]
   TimerLib|OvmfPkg/Library/AcpiTimerLib/BaseRomAcpiTimerLib.inf
diff --git a/OvmfPkg/OvmfPkgX64.dsc b/OvmfPkg/OvmfPkgX64.dsc
index ea08e1fabc65..8d9a0a077601 100644
--- a/OvmfPkg/OvmfPkgX64.dsc
+++ b/OvmfPkg/OvmfPkgX64.dsc
@@ -247,6 +247,7 @@ [LibraryClasses]
 [LibraryClasses.common]
   BaseCryptLib|CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf
   VmgExitLib|OvmfPkg/Library/VmgExitLib/VmgExitLib.inf
+  GhcbRegisterLib|OvmfPkg/Library/GhcbRegisterLib/GhcbRegisterLib.inf
 
 [LibraryClasses.common.SEC]
   TimerLib|OvmfPkg/Library/AcpiTimerLib/BaseRomAcpiTimerLib.inf
diff --git a/OvmfPkg/Library/GhcbRegisterLib/GhcbRegisterLib.inf b/OvmfPkg/Library/GhcbRegisterLib/GhcbRegisterLib.inf
new file mode 100644
index 000000000000..8cc39ef7153b
--- /dev/null
+++ b/OvmfPkg/Library/GhcbRegisterLib/GhcbRegisterLib.inf
@@ -0,0 +1,33 @@
+## @file
+#  GHCBRegisterLib Support Library.
+#
+#  Copyright (C) 2021, Advanced Micro Devices, Inc. All rights reserved.<BR>
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = GhcbRegisterLib
+  FILE_GUID                      = 0e913c15-12cd-430b-8714-ffe85672a77b
+  MODULE_TYPE                    = BASE
+  VERSION_STRING                 = 1.0
+  LIBRARY_CLASS                  = GhcbRegisterLib
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+#  VALID_ARCHITECTURES           = X64
+#
+
+[Sources.common]
+  GhcbRegisterLib.c
+
+[Packages]
+  MdePkg/MdePkg.dec
+  OvmfPkg/OvmfPkg.dec
+  UefiCpuPkg/UefiCpuPkg.dec
+
+[LibraryClasses]
+  BaseLib
+  BaseMemoryLib
diff --git a/OvmfPkg/Include/Library/GhcbRegisterLib.h b/OvmfPkg/Include/Library/GhcbRegisterLib.h
new file mode 100644
index 000000000000..7d98b6eb36f8
--- /dev/null
+++ b/OvmfPkg/Include/Library/GhcbRegisterLib.h
@@ -0,0 +1,27 @@
+/** @file
+
+  Declarations of utility functions used for GHCB GPA registration.
+
+  Copyright (C) 2021, AMD Inc, All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef _GHCB_REGISTER_LIB_H_
+#define _GHCB_REGISTER_LIB_H_
+
+/**
+
+  This function can be used to register the GHCB GPA.
+
+  @param[in]  Address           The physical address to registered.
+
+**/
+VOID
+EFIAPI
+GhcbRegister (
+  IN  EFI_PHYSICAL_ADDRESS   Address
+  );
+
+#endif // _GHCB_REGISTER_LIB_H_
diff --git a/OvmfPkg/Library/GhcbRegisterLib/GhcbRegisterLib.c b/OvmfPkg/Library/GhcbRegisterLib/GhcbRegisterLib.c
new file mode 100644
index 000000000000..7fe0aad75a1a
--- /dev/null
+++ b/OvmfPkg/Library/GhcbRegisterLib/GhcbRegisterLib.c
@@ -0,0 +1,97 @@
+/** @file
+  GHCBRegister Support Library.
+
+  Copyright (C) 2021, Advanced Micro Devices, Inc. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <Base.h>
+#include <Uefi.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/VmgExitLib.h>
+#include <Library/GhcbRegisterLib.h>
+#include <Register/Amd/Msr.h>
+
+/**
+  Handle an SEV-SNP/GHCB protocol check failure.
+
+  Notify the hypervisor using the VMGEXIT instruction that the SEV-SNP guest
+  wishes to be terminated.
+
+  @param[in] ReasonCode  Reason code to provide to the hypervisor for the
+                         termination request.
+
+**/
+STATIC
+VOID
+SevEsProtocolFailure (
+  IN UINT8  ReasonCode
+  )
+{
+  MSR_SEV_ES_GHCB_REGISTER  Msr;
+
+  //
+  // Use the GHCB MSR Protocol to request termination by the hypervisor
+  //
+  Msr.GhcbPhysicalAddress = 0;
+  Msr.GhcbTerminate.Function = GHCB_INFO_TERMINATE_REQUEST;
+  Msr.GhcbTerminate.ReasonCodeSet = GHCB_TERMINATE_GHCB;
+  Msr.GhcbTerminate.ReasonCode = ReasonCode;
+  AsmWriteMsr64 (MSR_SEV_ES_GHCB, Msr.GhcbPhysicalAddress);
+
+  AsmVmgExit ();
+
+  ASSERT (FALSE);
+  CpuDeadLoop ();
+}
+
+/**
+
+  This function can be used to register the GHCB GPA.
+
+  @param[in]  Address           The physical address to be registered.
+
+**/
+VOID
+EFIAPI
+GhcbRegister (
+  IN  EFI_PHYSICAL_ADDRESS   Address
+  )
+{
+  MSR_SEV_ES_GHCB_REGISTER  Msr;
+  MSR_SEV_ES_GHCB_REGISTER  CurrentMsr;
+  EFI_PHYSICAL_ADDRESS      GuestFrameNumber;
+
+  GuestFrameNumber = Address >> EFI_PAGE_SHIFT;
+
+  //
+  // Save the current MSR Value
+  //
+  CurrentMsr.GhcbPhysicalAddress = AsmReadMsr64 (MSR_SEV_ES_GHCB);
+
+  //
+  // Use the GHCB MSR Protocol to request to register the GPA.
+  //
+  Msr.GhcbPhysicalAddress = 0;
+  Msr.GhcbGpaRegister.Function = GHCB_INFO_GHCB_GPA_REGISTER_REQUEST;
+  Msr.GhcbGpaRegister.GuestFrameNumber = GuestFrameNumber;
+  AsmWriteMsr64 (MSR_SEV_ES_GHCB, Msr.GhcbPhysicalAddress);
+
+  AsmVmgExit ();
+
+  Msr.GhcbPhysicalAddress = AsmReadMsr64 (MSR_SEV_ES_GHCB);
+
+  //
+  // If hypervisor responded with a different GPA than requested then fail.
+  //
+  if ((Msr.GhcbGpaRegister.Function != GHCB_INFO_GHCB_GPA_REGISTER_RESPONSE) ||
+      (Msr.GhcbGpaRegister.GuestFrameNumber != GuestFrameNumber)) {
+    SevEsProtocolFailure (GHCB_TERMINATE_GHCB_GENERAL);
+  }
+
+  //
+  // Restore the MSR
+  //
+  AsmWriteMsr64 (MSR_SEV_ES_GHCB, CurrentMsr.GhcbPhysicalAddress);
+}
-- 
2.17.1


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

* [PATCH RFC v3 10/22] OvmfPkg/PlatformPei: register GHCB gpa for the SEV-SNP guest
  2021-05-26 23:10 [RESEND PATCH RFC v3 00/22] Add AMD Secure Nested Paging (SEV-SNP) support Brijesh Singh
                   ` (8 preceding siblings ...)
  2021-05-26 23:11 ` [PATCH RFC v3 09/22] OvmfPkg: add library to support registering GHCB GPA Brijesh Singh
@ 2021-05-26 23:11 ` Brijesh Singh
  2021-05-26 23:11 ` [PATCH RFC v3 11/22] UefiCpuPkg/MpLib: add support to register GHCB GPA when SEV-SNP is enabled Brijesh Singh
                   ` (13 subsequent siblings)
  23 siblings, 0 replies; 57+ messages in thread
From: Brijesh Singh @ 2021-05-26 23:11 UTC (permalink / raw)
  To: James Bottomley, Min Xu, Jiewen Yao, Tom Lendacky, Jordan Justen,
	Laszlo Ersek, Erdem Aktas, Eric Dong, Ray Ni, Rahul Kumar, devel
  Cc: Brijesh Singh, Ard Biesheuvel

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

The SEV-SNP guest requires that GHCB GPA must be registered before using.
The GHCB GPA can be registred using the GhcbGPARegister().

Cc: James Bottomley <jejb@linux.ibm.com>
Cc: Min Xu <min.m.xu@intel.com>
Cc: Jiewen Yao <jiewen.yao@intel.com>
Cc: Tom Lendacky <thomas.lendacky@amd.com>
Cc: Jordan Justen <jordan.l.justen@intel.com>
Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
Cc: Laszlo Ersek <lersek@redhat.com>
Cc: Erdem Aktas <erdemaktas@google.com>
Signed-off-by: Brijesh Singh <brijesh.singh@amd.com>
---
 OvmfPkg/PlatformPei/PlatformPei.inf |  1 +
 OvmfPkg/PlatformPei/AmdSev.c        |  8 +++
 OvmfPkg/Sec/SecMain.c               | 79 +++++++++++++++++++++++++++++
 3 files changed, 88 insertions(+)

diff --git a/OvmfPkg/PlatformPei/PlatformPei.inf b/OvmfPkg/PlatformPei/PlatformPei.inf
index 89c8e9627c86..e9a10146effd 100644
--- a/OvmfPkg/PlatformPei/PlatformPei.inf
+++ b/OvmfPkg/PlatformPei/PlatformPei.inf
@@ -52,6 +52,7 @@ [LibraryClasses]
   BaseLib
   CacheMaintenanceLib
   DebugLib
+  GhcbRegisterLib
   HobLib
   IoLib
   PciLib
diff --git a/OvmfPkg/PlatformPei/AmdSev.c b/OvmfPkg/PlatformPei/AmdSev.c
index 81e40e0889aa..54b07622b4dd 100644
--- a/OvmfPkg/PlatformPei/AmdSev.c
+++ b/OvmfPkg/PlatformPei/AmdSev.c
@@ -14,6 +14,7 @@
 #include <Library/DebugLib.h>
 #include <Library/HobLib.h>
 #include <Library/MemEncryptSevLib.h>
+#include <Library/GhcbRegisterLib.h>
 #include <Library/MemoryAllocationLib.h>
 #include <Library/PcdLib.h>
 #include <PiPei.h>
@@ -156,6 +157,13 @@ AmdSevEsInitialize (
     "SEV-ES is enabled, %lu GHCB backup pages allocated starting at 0x%p\n",
     (UINT64)GhcbBackupPageCount, GhcbBackupBase));
 
+  if (MemEncryptSevSnpIsEnabled ()) {
+    //
+    // SEV-SNP guest requires that GHCB GPA must be registered before using it.
+    //
+    GhcbRegister (GhcbBasePa);
+  }
+
   AsmWriteMsr64 (MSR_SEV_ES_GHCB, GhcbBasePa);
 
   //
diff --git a/OvmfPkg/Sec/SecMain.c b/OvmfPkg/Sec/SecMain.c
index 9db67e17b2aa..faa6891cca79 100644
--- a/OvmfPkg/Sec/SecMain.c
+++ b/OvmfPkg/Sec/SecMain.c
@@ -750,6 +750,74 @@ SevEsProtocolFailure (
   CpuDeadLoop ();
 }
 
+/**
+  Determine if SEV-SNP is active.
+
+  @retval TRUE   SEV-SNP is enabled
+  @retval FALSE  SEV-SNP is not enabled
+
+**/
+STATIC
+BOOLEAN
+SevSnpIsEnabled (
+  VOID
+  )
+{
+  SEC_SEV_ES_WORK_AREA  *SevEsWorkArea;
+
+  SevEsWorkArea = (SEC_SEV_ES_WORK_AREA *) FixedPcdGet32 (PcdSevEsWorkAreaBase);
+
+  return ((SevEsWorkArea != NULL) && (SevEsWorkArea->SevSnpEnabled != 0));
+}
+
+/**
+ The GHCB GPA registeration need to be done before the ProcessLibraryConstructorList()
+ is called. So use a local implementation instead of including the GhcbRegisterLib.
+
+ */
+STATIC
+VOID
+SevSnpGhcbRegister (
+  UINTN   Address
+  )
+{
+  MSR_SEV_ES_GHCB_REGISTER  Msr;
+  MSR_SEV_ES_GHCB_REGISTER  CurrentMsr;
+  EFI_PHYSICAL_ADDRESS      GuestFrameNumber;
+
+  GuestFrameNumber = Address >> EFI_PAGE_SHIFT;
+
+  //
+  // Save the current MSR Value
+  //
+  CurrentMsr.GhcbPhysicalAddress = AsmReadMsr64 (MSR_SEV_ES_GHCB);
+
+  //
+  // Use the GHCB MSR Protocol to request to register the GPA.
+  //
+  Msr.GhcbPhysicalAddress = 0;
+  Msr.GhcbGpaRegister.Function = GHCB_INFO_GHCB_GPA_REGISTER_REQUEST;
+  Msr.GhcbGpaRegister.GuestFrameNumber = GuestFrameNumber;
+  AsmWriteMsr64 (MSR_SEV_ES_GHCB, Msr.GhcbPhysicalAddress);
+
+  AsmVmgExit ();
+
+  Msr.GhcbPhysicalAddress = AsmReadMsr64 (MSR_SEV_ES_GHCB);
+
+  //
+  // If hypervisor responded with a different GPA than requested then fail.
+  //
+  if ((Msr.GhcbGpaRegister.Function != GHCB_INFO_GHCB_GPA_REGISTER_RESPONSE) ||
+      (Msr.GhcbGpaRegister.GuestFrameNumber != GuestFrameNumber)) {
+    SevEsProtocolFailure (GHCB_TERMINATE_GHCB_GENERAL);
+  }
+
+  //
+  // Restore the MSR
+  //
+  AsmWriteMsr64 (MSR_SEV_ES_GHCB, CurrentMsr.GhcbPhysicalAddress);
+}
+
 /**
   Validate the SEV-ES/GHCB protocol level.
 
@@ -791,6 +859,17 @@ SevEsProtocolCheck (
     SevEsProtocolFailure (GHCB_TERMINATE_GHCB_PROTOCOL);
   }
 
+  //
+  // We cannot use the MemEncryptSevSnpIsEnabled () because the
+  // ProcessLibraryConstructorList () is not called yet.
+  //
+  if (SevSnpIsEnabled ()) {
+    //
+    // SEV-SNP guest requires that GHCB GPA must be registered before using it.
+    //
+    SevSnpGhcbRegister (FixedPcdGet32 (PcdOvmfSecGhcbBase));
+  }
+
   //
   // SEV-ES protocol checking succeeded, set the initial GHCB address
   //
-- 
2.17.1


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

* [PATCH RFC v3 11/22] UefiCpuPkg/MpLib: add support to register GHCB GPA when SEV-SNP is enabled
  2021-05-26 23:10 [RESEND PATCH RFC v3 00/22] Add AMD Secure Nested Paging (SEV-SNP) support Brijesh Singh
                   ` (9 preceding siblings ...)
  2021-05-26 23:11 ` [PATCH RFC v3 10/22] OvmfPkg/PlatformPei: register GHCB gpa for the SEV-SNP guest Brijesh Singh
@ 2021-05-26 23:11 ` Brijesh Singh
  2021-05-26 23:11 ` [PATCH RFC v3 12/22] OvmfPkg/AmdSevDxe: do not use extended PCI config space Brijesh Singh
                   ` (12 subsequent siblings)
  23 siblings, 0 replies; 57+ messages in thread
From: Brijesh Singh @ 2021-05-26 23:11 UTC (permalink / raw)
  To: James Bottomley, Min Xu, Jiewen Yao, Tom Lendacky, Jordan Justen,
	Laszlo Ersek, Erdem Aktas, Eric Dong, Ray Ni, Rahul Kumar, devel
  Cc: Brijesh Singh, Ard Biesheuvel

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

An SEV-SNP guest requires that the physical address of the GHCB must
be registered with the hypervisor before using it. See the GHCB
specification for the futher detail.

Cc: James Bottomley <jejb@linux.ibm.com>
Cc: Min Xu <min.m.xu@intel.com>
Cc: Jiewen Yao <jiewen.yao@intel.com>
Cc: Tom Lendacky <thomas.lendacky@amd.com>
Cc: Jordan Justen <jordan.l.justen@intel.com>
Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
Cc: Laszlo Ersek <lersek@redhat.com>
Cc: Erdem Aktas <erdemaktas@google.com>
Signed-off-by: Brijesh Singh <brijesh.singh@amd.com>
---
 UefiCpuPkg/Library/MpInitLib/DxeMpInitLib.inf |  1 +
 UefiCpuPkg/Library/MpInitLib/PeiMpInitLib.inf |  1 +
 UefiCpuPkg/Library/MpInitLib/MpLib.h          |  2 +
 UefiCpuPkg/Library/MpInitLib/MpLib.c          |  2 +
 UefiCpuPkg/Library/MpInitLib/MpEqu.inc        |  1 +
 UefiCpuPkg/Library/MpInitLib/X64/MpFuncs.nasm | 51 +++++++++++++++++++
 6 files changed, 58 insertions(+)

diff --git a/UefiCpuPkg/Library/MpInitLib/DxeMpInitLib.inf b/UefiCpuPkg/Library/MpInitLib/DxeMpInitLib.inf
index d34419c2a524..48d7dfa4450f 100644
--- a/UefiCpuPkg/Library/MpInitLib/DxeMpInitLib.inf
+++ b/UefiCpuPkg/Library/MpInitLib/DxeMpInitLib.inf
@@ -76,3 +76,4 @@ [Pcd]
   gUefiCpuPkgTokenSpaceGuid.PcdSevEsWorkAreaBase                       ## SOMETIMES_CONSUMES
   gEfiMdeModulePkgTokenSpaceGuid.PcdCpuStackGuard                      ## CONSUMES
   gEfiMdeModulePkgTokenSpaceGuid.PcdGhcbBase                           ## CONSUMES
+  gUefiCpuPkgTokenSpaceGuid.PcdSevSnpIsEnabled                         ## CONSUMES
diff --git a/UefiCpuPkg/Library/MpInitLib/PeiMpInitLib.inf b/UefiCpuPkg/Library/MpInitLib/PeiMpInitLib.inf
index 36fcb96b5852..ab8279df596f 100644
--- a/UefiCpuPkg/Library/MpInitLib/PeiMpInitLib.inf
+++ b/UefiCpuPkg/Library/MpInitLib/PeiMpInitLib.inf
@@ -65,6 +65,7 @@ [Pcd]
   gUefiCpuPkgTokenSpaceGuid.PcdSevEsIsEnabled                      ## CONSUMES
   gUefiCpuPkgTokenSpaceGuid.PcdSevEsWorkAreaBase                   ## SOMETIMES_CONSUMES
   gEfiMdeModulePkgTokenSpaceGuid.PcdGhcbBase                       ## CONSUMES
+  gUefiCpuPkgTokenSpaceGuid.PcdSevSnpIsEnabled                     ## CONSUMES
 
 [Ppis]
   gEdkiiPeiShadowMicrocodePpiGuid        ## SOMETIMES_CONSUMES
diff --git a/UefiCpuPkg/Library/MpInitLib/MpLib.h b/UefiCpuPkg/Library/MpInitLib/MpLib.h
index e88a5355c983..4abaa2243d0a 100644
--- a/UefiCpuPkg/Library/MpInitLib/MpLib.h
+++ b/UefiCpuPkg/Library/MpInitLib/MpLib.h
@@ -218,6 +218,7 @@ typedef struct {
   //
   BOOLEAN               Enable5LevelPaging;
   BOOLEAN               SevEsIsEnabled;
+  BOOLEAN               SevSnpIsEnabled;
   UINTN                 GhcbBase;
 } MP_CPU_EXCHANGE_INFO;
 
@@ -287,6 +288,7 @@ struct _CPU_MP_DATA {
   BOOLEAN                        WakeUpByInitSipiSipi;
 
   BOOLEAN                        SevEsIsEnabled;
+  BOOLEAN                        SevSnpIsEnabled;
   UINTN                          SevEsAPBuffer;
   UINTN                          SevEsAPResetStackStart;
   CPU_MP_DATA                    *NewCpuMpData;
diff --git a/UefiCpuPkg/Library/MpInitLib/MpLib.c b/UefiCpuPkg/Library/MpInitLib/MpLib.c
index dc2a54aa31e8..7cbcce101414 100644
--- a/UefiCpuPkg/Library/MpInitLib/MpLib.c
+++ b/UefiCpuPkg/Library/MpInitLib/MpLib.c
@@ -1040,6 +1040,7 @@ FillExchangeInfoData (
   DEBUG ((DEBUG_INFO, "%a: 5-Level Paging = %d\n", gEfiCallerBaseName, ExchangeInfo->Enable5LevelPaging));
 
   ExchangeInfo->SevEsIsEnabled  = CpuMpData->SevEsIsEnabled;
+  ExchangeInfo->SevSnpIsEnabled = CpuMpData->SevSnpIsEnabled;
   ExchangeInfo->GhcbBase        = (UINTN) CpuMpData->GhcbBase;
 
   //
@@ -2016,6 +2017,7 @@ MpInitLibInitialize (
   CpuMpData->CpuInfoInHob     = (UINT64) (UINTN) (CpuMpData->CpuData + MaxLogicalProcessorNumber);
   InitializeSpinLock(&CpuMpData->MpLock);
   CpuMpData->SevEsIsEnabled = PcdGetBool (PcdSevEsIsEnabled);
+  CpuMpData->SevSnpIsEnabled = PcdGetBool (PcdSevSnpIsEnabled);
   CpuMpData->SevEsAPBuffer  = (UINTN) -1;
   CpuMpData->GhcbBase       = PcdGet64 (PcdGhcbBase);
 
diff --git a/UefiCpuPkg/Library/MpInitLib/MpEqu.inc b/UefiCpuPkg/Library/MpInitLib/MpEqu.inc
index 2e9368a374a4..01668638f245 100644
--- a/UefiCpuPkg/Library/MpInitLib/MpEqu.inc
+++ b/UefiCpuPkg/Library/MpInitLib/MpEqu.inc
@@ -92,6 +92,7 @@ struc MP_CPU_EXCHANGE_INFO
   .ModeHighSegment:              CTYPE_UINT16 1
   .Enable5LevelPaging:           CTYPE_BOOLEAN 1
   .SevEsIsEnabled:               CTYPE_BOOLEAN 1
+  .SevSnpIsEnabled               CTYPE_BOOLEAN 1
   .GhcbBase:                     CTYPE_UINTN 1
 endstruc
 
diff --git a/UefiCpuPkg/Library/MpInitLib/X64/MpFuncs.nasm b/UefiCpuPkg/Library/MpInitLib/X64/MpFuncs.nasm
index 50df802d1fca..19939c093d2e 100644
--- a/UefiCpuPkg/Library/MpInitLib/X64/MpFuncs.nasm
+++ b/UefiCpuPkg/Library/MpInitLib/X64/MpFuncs.nasm
@@ -194,9 +194,60 @@ LongModeStart:
     mov        rdx, rax
     shr        rdx, 32
     mov        rcx, 0xc0010130
+
+    ;
+    ; Register GHCB GPA when SEV-SNP is enabled
+    ;
+    lea        edi, [esi + MP_CPU_EXCHANGE_INFO_FIELD (SevSnpIsEnabled)]
+    cmp        byte [edi], 1        ; SevSnpIsEnabled
+    jne        SetGhcbAddress
+
+    ; Save the rdi and rsi to used for later comparison
+    push       rdi
+    push       rsi
+    mov        edi, eax
+    mov        esi, edx
+    or         eax, 18              ; Ghcb registration request
+    wrmsr
+    rep vmmcall
+    rdmsr
+    mov        r12, rax
+    and        r12, 0fffh
+    cmp        r12, 19              ; Ghcb registration response
+    jne        GhcbGpaRegisterFailure
+
+    ; Verify that GPA is not changed
+    and        eax, 0fffff000h
+    cmp        edi, eax
+    jne        GhcbGpaRegisterFailure
+    cmp        esi, edx
+    jne        GhcbGpaRegisterFailure
+    pop        rsi
+    pop        rdi
+
+    ;
+    ; Program GHCB
+    ;
+SetGhcbAddress:
     wrmsr
     jmp        CProcedureInvoke
 
+    ;
+    ; Request the guest termination
+    ;
+GhcbGpaRegisterFailure:
+    xor        edx, edx
+    mov        eax, 256             ; GHCB terminate
+    wrmsr
+    rep vmmcall
+
+    ; We should not return from the above terminate request, but if we do
+    ; then enter into the hlt loop.
+DoHltLoop:
+    cli
+    hlt
+    jmp        DoHltLoop
+
 GetApicId:
     lea        edi, [esi + MP_CPU_EXCHANGE_INFO_FIELD (SevEsIsEnabled)]
     cmp        byte [edi], 1        ; SevEsIsEnabled
-- 
2.17.1


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

* [PATCH RFC v3 12/22] OvmfPkg/AmdSevDxe: do not use extended PCI config space
  2021-05-26 23:10 [RESEND PATCH RFC v3 00/22] Add AMD Secure Nested Paging (SEV-SNP) support Brijesh Singh
                   ` (10 preceding siblings ...)
  2021-05-26 23:11 ` [PATCH RFC v3 11/22] UefiCpuPkg/MpLib: add support to register GHCB GPA when SEV-SNP is enabled Brijesh Singh
@ 2021-05-26 23:11 ` Brijesh Singh
  2021-05-26 23:11 ` [PATCH RFC v3 13/22] OvmfPkg/MemEncryptSevLib: add support to validate system RAM Brijesh Singh
                   ` (11 subsequent siblings)
  23 siblings, 0 replies; 57+ messages in thread
From: Brijesh Singh @ 2021-05-26 23:11 UTC (permalink / raw)
  To: James Bottomley, Min Xu, Jiewen Yao, Tom Lendacky, Jordan Justen,
	Laszlo Ersek, Erdem Aktas, Eric Dong, Ray Ni, Rahul Kumar, devel
  Cc: Brijesh Singh, Ard Biesheuvel

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

Commit 85b8eac59b8c5bd9c7eb9afdb64357ce1aa2e803 added support to ensure
that MMIO is only performed against the un-encrypted memory. If MMIO
is performed against encrypted memory, a #GP is raised.

The AmdSevDxe uses the functions provided by the MemEncryptSevLib to
clear the memory encryption mask from the page table. If the
MemEncryptSevLib is extended to include VmgExitLib then depedency
chain will look like this:

OvmfPkg/AmdSevDxe/AmdSevDxe.inf
-----> MemEncryptSevLib                    class
-----> "OvmfPkg/BaseMemEncryptSevLib/DxeMemEncryptSevLib.inf"   instance
-----> VmgExitLib                          class
-----> "OvmfPkg/VmgExitLib"    instance
-----> LocalApicLib                        class
-----> "UefiCpuPkg/BaseXApicX2ApicLib/BaseXApicX2ApicLib.inf" instance
-----> TimerLib                            class
-----> "OvmfPkg/AcpiTimerLib/DxeAcpiTimerLib.inf"   instance
-----> PciLib                                           class
-----> "OvmfPkg/DxePciLibI440FxQ35/DxePciLibI440FxQ35.inf"    instance
-----> PciExpressLib                                          class
-----> "MdePkg/BasePciExpressLib/BasePciExpressLib.inf"  instance

The LocalApicLib provides a constructor that gets called before the
AmdSevDxe can clear the memory encryption mask from the MMIO regions.

When running under the Q35 machine type, the call chain looks like this:

AcpiTimerLibConstructor ()  [AcpiTimerLib]
  PciRead32 ()              [DxePciLibI440FxQ35]
   PciExpressRead32 ()      [PciExpressLib]

The PciExpressRead32 () reads the MMIO region. The MMIO regions are not
yet mapped un-encrypted, so the check introduced in the commit
85b8eac59b8c5bd9c7eb9afdb64357ce1aa2e803 raises a #GP.

The AmdSevDxe driver does not require the access to the extended PCI
config space. Accessing a normal PCI config space, via IO port should be
sufficent. Use the module-scope override to make the AmdSevDxe use the
BasePciLib instead of BasePciExpressLib so that PciRead32 () uses the
IO ports instead of the extended config space.

Cc: James Bottomley <jejb@linux.ibm.com>
Cc: Min Xu <min.m.xu@intel.com>
Cc: Jiewen Yao <jiewen.yao@intel.com>
Cc: Tom Lendacky <thomas.lendacky@amd.com>
Cc: Jordan Justen <jordan.l.justen@intel.com>
Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
Cc: Laszlo Ersek <lersek@redhat.com>
Cc: Erdem Aktas <erdemaktas@google.com>
Suggested-by: Laszlo Ersek <lersek@redhat.com>
Signed-off-by: Brijesh Singh <brijesh.singh@amd.com>
---
 OvmfPkg/AmdSev/AmdSevX64.dsc | 5 ++++-
 OvmfPkg/Bhyve/BhyveX64.dsc   | 5 ++++-
 OvmfPkg/OvmfPkgIa32X64.dsc   | 5 ++++-
 OvmfPkg/OvmfPkgX64.dsc       | 5 ++++-
 OvmfPkg/OvmfXen.dsc          | 5 ++++-
 5 files changed, 20 insertions(+), 5 deletions(-)

diff --git a/OvmfPkg/AmdSev/AmdSevX64.dsc b/OvmfPkg/AmdSev/AmdSevX64.dsc
index 66bbbc80cd18..4ef3d71877fa 100644
--- a/OvmfPkg/AmdSev/AmdSevX64.dsc
+++ b/OvmfPkg/AmdSev/AmdSevX64.dsc
@@ -814,7 +814,10 @@ [Components]
 !endif
 
   OvmfPkg/PlatformDxe/Platform.inf
-  OvmfPkg/AmdSevDxe/AmdSevDxe.inf
+  OvmfPkg/AmdSevDxe/AmdSevDxe.inf {
+    <LibraryClasses>
+    PciLib|MdePkg/Library/BasePciLibCf8/BasePciLibCf8.inf
+  }
   OvmfPkg/IoMmuDxe/IoMmuDxe.inf
 
   #
diff --git a/OvmfPkg/Bhyve/BhyveX64.dsc b/OvmfPkg/Bhyve/BhyveX64.dsc
index 7d9e88040000..b8a7128b310e 100644
--- a/OvmfPkg/Bhyve/BhyveX64.dsc
+++ b/OvmfPkg/Bhyve/BhyveX64.dsc
@@ -824,7 +824,10 @@ [Components]
 !endif
 
   OvmfPkg/PlatformDxe/Platform.inf
-  OvmfPkg/AmdSevDxe/AmdSevDxe.inf
+  OvmfPkg/AmdSevDxe/AmdSevDxe.inf {
+    <LibraryClasses>
+    PciLib|MdePkg/Library/BasePciLibCf8/BasePciLibCf8.inf
+  }
   OvmfPkg/IoMmuDxe/IoMmuDxe.inf
 
 
diff --git a/OvmfPkg/OvmfPkgIa32X64.dsc b/OvmfPkg/OvmfPkgIa32X64.dsc
index 6b0bc02bd536..75f87d311454 100644
--- a/OvmfPkg/OvmfPkgIa32X64.dsc
+++ b/OvmfPkg/OvmfPkgIa32X64.dsc
@@ -967,7 +967,10 @@ [Components.X64]
 !endif
 
   OvmfPkg/PlatformDxe/Platform.inf
-  OvmfPkg/AmdSevDxe/AmdSevDxe.inf
+  OvmfPkg/AmdSevDxe/AmdSevDxe.inf {
+    <LibraryClasses>
+    PciLib|MdePkg/Library/BasePciLibCf8/BasePciLibCf8.inf
+  }
   OvmfPkg/IoMmuDxe/IoMmuDxe.inf
 
 !if $(SMM_REQUIRE) == TRUE
diff --git a/OvmfPkg/OvmfPkgX64.dsc b/OvmfPkg/OvmfPkgX64.dsc
index 8d9a0a077601..7f72f4150440 100644
--- a/OvmfPkg/OvmfPkgX64.dsc
+++ b/OvmfPkg/OvmfPkgX64.dsc
@@ -966,7 +966,10 @@ [Components]
 !endif
 
   OvmfPkg/PlatformDxe/Platform.inf
-  OvmfPkg/AmdSevDxe/AmdSevDxe.inf
+  OvmfPkg/AmdSevDxe/AmdSevDxe.inf {
+    <LibraryClasses>
+    PciLib|MdePkg/Library/BasePciLibCf8/BasePciLibCf8.inf
+  }
   OvmfPkg/IoMmuDxe/IoMmuDxe.inf
   OvmfPkg/AmdSev/SecretDxe/SecretDxe.inf
 
diff --git a/OvmfPkg/OvmfXen.dsc b/OvmfPkg/OvmfXen.dsc
index e535503e385d..d549f1b14378 100644
--- a/OvmfPkg/OvmfXen.dsc
+++ b/OvmfPkg/OvmfXen.dsc
@@ -727,7 +727,10 @@ [Components]
   }
 
   OvmfPkg/PlatformDxe/Platform.inf
-  OvmfPkg/AmdSevDxe/AmdSevDxe.inf
+  OvmfPkg/AmdSevDxe/AmdSevDxe.inf {
+    <LibraryClasses>
+    PciLib|MdePkg/Library/BasePciLibCf8/BasePciLibCf8.inf
+  }
   OvmfPkg/IoMmuDxe/IoMmuDxe.inf
 
   #
-- 
2.17.1


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

* [PATCH RFC v3 13/22] OvmfPkg/MemEncryptSevLib: add support to validate system RAM
  2021-05-26 23:10 [RESEND PATCH RFC v3 00/22] Add AMD Secure Nested Paging (SEV-SNP) support Brijesh Singh
                   ` (11 preceding siblings ...)
  2021-05-26 23:11 ` [PATCH RFC v3 12/22] OvmfPkg/AmdSevDxe: do not use extended PCI config space Brijesh Singh
@ 2021-05-26 23:11 ` Brijesh Singh
  2021-05-26 23:11 ` [PATCH RFC v3 14/22] OvmfPkg/BaseMemEncryptSevLib: skip the pre-validated " Brijesh Singh
                   ` (10 subsequent siblings)
  23 siblings, 0 replies; 57+ messages in thread
From: Brijesh Singh @ 2021-05-26 23:11 UTC (permalink / raw)
  To: James Bottomley, Min Xu, Jiewen Yao, Tom Lendacky, Jordan Justen,
	Laszlo Ersek, Erdem Aktas, Eric Dong, Ray Ni, Rahul Kumar, devel
  Cc: Brijesh Singh, Ard Biesheuvel

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

Many of the integrity guarantees of SEV-SNP are enforced through the
Reverse Map Table (RMP). Each RMP entry contains the GPA at which a
particular page of DRAM should be mapped. The guest can request the
hypervisor to add pages in the RMP table via the Page State Change VMGEXIT
defined in the GHCB specification section 2.5.1 and 4.1.6. Inside each RMP
entry is a Validated flag; this flag is automatically cleared to 0 by the
CPU hardware when a new RMP entry is created for a guest. Each VM page
can be either validated or invalidated, as indicated by the Validated
flag in the RMP entry. Memory access to a private page that is not
validated generates a #VC. A VM can use the PVALIDATE instruction to
validate the private page before using it.

During the guest creation, the boot ROM memory is pre-validated by the
AMD-SEV firmware. The MemEncryptSevSnpValidateSystemRam() can be called
during the SEC and PEI phase to validate the detected system RAM.

One of the fields in the Page State Change NAE is the RMP page size. The
page size input parameter indicates that either a 4KB or 2MB page should
be used while adding the RMP entry. During the validation, when possible,
the MemEncryptSevSnpValidateSystemRam() will use the 2MB entry. A
hypervisor backing the memory may choose to use the different page size
in the RMP entry. In those cases, the PVALIDATE instruction should return
SIZEMISMATCH. If a SIZEMISMATCH is detected, then validate all 512-pages
constituting a 2MB region.

Upon completion, the PVALIDATE instruction sets the rFLAGS.CF to 0 if
instruction changed the RMP entry and to 1 if the instruction did not
change the RMP entry. The rFlags.CF will be 1 only when a memory region
is already validated. We should not double validate a memory
as it could lead to a security compromise. If double validation is
detected, terminate the boot.

Cc: James Bottomley <jejb@linux.ibm.com>
Cc: Min Xu <min.m.xu@intel.com>
Cc: Jiewen Yao <jiewen.yao@intel.com>
Cc: Tom Lendacky <thomas.lendacky@amd.com>
Cc: Jordan Justen <jordan.l.justen@intel.com>
Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
Cc: Laszlo Ersek <lersek@redhat.com>
Cc: Erdem Aktas <erdemaktas@google.com>
Signed-off-by: Brijesh Singh <brijesh.singh@amd.com>
---
 OvmfPkg/OvmfPkgIa32.dsc                       |   1 +
 OvmfPkg/OvmfPkgIa32X64.dsc                    |   1 +
 .../DxeMemEncryptSevLib.inf                   |   3 +
 .../PeiMemEncryptSevLib.inf                   |   3 +
 .../SecMemEncryptSevLib.inf                   |   3 +
 OvmfPkg/Include/Library/MemEncryptSevLib.h    |  14 ++
 .../X64/SnpPageStateChange.h                  |  31 +++
 .../Ia32/MemEncryptSevLib.c                   |  17 ++
 .../X64/DxeSnpSystemRamValidate.c             |  40 +++
 .../X64/PeiSnpSystemRamValidate.c             |  36 +++
 .../X64/SecSnpSystemRamValidate.c             |  36 +++
 .../X64/SnpPageStateChangeInternal.c          | 230 ++++++++++++++++++
 12 files changed, 415 insertions(+)
 create mode 100644 OvmfPkg/Library/BaseMemEncryptSevLib/X64/SnpPageStateChange.h
 create mode 100644 OvmfPkg/Library/BaseMemEncryptSevLib/X64/DxeSnpSystemRamValidate.c
 create mode 100644 OvmfPkg/Library/BaseMemEncryptSevLib/X64/PeiSnpSystemRamValidate.c
 create mode 100644 OvmfPkg/Library/BaseMemEncryptSevLib/X64/SecSnpSystemRamValidate.c
 create mode 100644 OvmfPkg/Library/BaseMemEncryptSevLib/X64/SnpPageStateChangeInternal.c

diff --git a/OvmfPkg/OvmfPkgIa32.dsc b/OvmfPkg/OvmfPkgIa32.dsc
index 7cbef8e82282..9ffe9e3159d4 100644
--- a/OvmfPkg/OvmfPkgIa32.dsc
+++ b/OvmfPkg/OvmfPkgIa32.dsc
@@ -267,6 +267,7 @@ [LibraryClasses.common.SEC]
 !else
   CpuExceptionHandlerLib|UefiCpuPkg/Library/CpuExceptionHandlerLib/SecPeiCpuExceptionHandlerLib.inf
 !endif
+  MemEncryptSevLib|OvmfPkg/Library/BaseMemEncryptSevLib/SecMemEncryptSevLib.inf
 
 [LibraryClasses.common.PEI_CORE]
   HobLib|MdePkg/Library/PeiHobLib/PeiHobLib.inf
diff --git a/OvmfPkg/OvmfPkgIa32X64.dsc b/OvmfPkg/OvmfPkgIa32X64.dsc
index 75f87d311454..aeb603d87f13 100644
--- a/OvmfPkg/OvmfPkgIa32X64.dsc
+++ b/OvmfPkg/OvmfPkgIa32X64.dsc
@@ -271,6 +271,7 @@ [LibraryClasses.common.SEC]
 !else
   CpuExceptionHandlerLib|UefiCpuPkg/Library/CpuExceptionHandlerLib/SecPeiCpuExceptionHandlerLib.inf
 !endif
+  MemEncryptSevLib|OvmfPkg/Library/BaseMemEncryptSevLib/SecMemEncryptSevLib.inf
 
 [LibraryClasses.common.PEI_CORE]
   HobLib|MdePkg/Library/PeiHobLib/PeiHobLib.inf
diff --git a/OvmfPkg/Library/BaseMemEncryptSevLib/DxeMemEncryptSevLib.inf b/OvmfPkg/Library/BaseMemEncryptSevLib/DxeMemEncryptSevLib.inf
index f2e162d68076..f613bb314f5f 100644
--- a/OvmfPkg/Library/BaseMemEncryptSevLib/DxeMemEncryptSevLib.inf
+++ b/OvmfPkg/Library/BaseMemEncryptSevLib/DxeMemEncryptSevLib.inf
@@ -34,8 +34,10 @@ [Sources]
   PeiDxeMemEncryptSevLibInternal.c
 
 [Sources.X64]
+  X64/DxeSnpSystemRamValidate.c
   X64/MemEncryptSevLib.c
   X64/PeiDxeVirtualMemory.c
+  X64/SnpPageStateChangeInternal.c
   X64/VirtualMemory.c
   X64/VirtualMemory.h
 
@@ -49,6 +51,7 @@ [LibraryClasses]
   DebugLib
   MemoryAllocationLib
   PcdLib
+  VmgExitLib
 
 [FeaturePcd]
   gUefiOvmfPkgTokenSpaceGuid.PcdSmmSmramRequire
diff --git a/OvmfPkg/Library/BaseMemEncryptSevLib/PeiMemEncryptSevLib.inf b/OvmfPkg/Library/BaseMemEncryptSevLib/PeiMemEncryptSevLib.inf
index 03a78c32df28..0402e49a1028 100644
--- a/OvmfPkg/Library/BaseMemEncryptSevLib/PeiMemEncryptSevLib.inf
+++ b/OvmfPkg/Library/BaseMemEncryptSevLib/PeiMemEncryptSevLib.inf
@@ -36,6 +36,8 @@ [Sources]
 [Sources.X64]
   X64/MemEncryptSevLib.c
   X64/PeiDxeVirtualMemory.c
+  X64/PeiSnpSystemRamValidate.c
+  X64/SnpPageStateChangeInternal.c
   X64/VirtualMemory.c
   X64/VirtualMemory.h
 
@@ -49,6 +51,7 @@ [LibraryClasses]
   DebugLib
   MemoryAllocationLib
   PcdLib
+  VmgExitLib
 
 [FeaturePcd]
   gUefiOvmfPkgTokenSpaceGuid.PcdSmmSmramRequire
diff --git a/OvmfPkg/Library/BaseMemEncryptSevLib/SecMemEncryptSevLib.inf b/OvmfPkg/Library/BaseMemEncryptSevLib/SecMemEncryptSevLib.inf
index 279c38bfbc2c..939af0a91ea4 100644
--- a/OvmfPkg/Library/BaseMemEncryptSevLib/SecMemEncryptSevLib.inf
+++ b/OvmfPkg/Library/BaseMemEncryptSevLib/SecMemEncryptSevLib.inf
@@ -35,6 +35,8 @@ [Sources]
 [Sources.X64]
   X64/MemEncryptSevLib.c
   X64/SecVirtualMemory.c
+  X64/SecSnpSystemRamValidate.c
+  X64/SnpPageStateChangeInternal.c
   X64/VirtualMemory.c
   X64/VirtualMemory.h
 
@@ -46,6 +48,7 @@ [LibraryClasses]
   CpuLib
   DebugLib
   PcdLib
+  VmgExitLib
 
 [FixedPcd]
   gUefiCpuPkgTokenSpaceGuid.PcdSevEsWorkAreaBase
diff --git a/OvmfPkg/Include/Library/MemEncryptSevLib.h b/OvmfPkg/Include/Library/MemEncryptSevLib.h
index dd1c97d4a9a3..eec80474c8fb 100644
--- a/OvmfPkg/Include/Library/MemEncryptSevLib.h
+++ b/OvmfPkg/Include/Library/MemEncryptSevLib.h
@@ -237,4 +237,18 @@ MemEncryptSevClearMmioPageEncMask (
   IN UINTN                    NumPages
   );
 
+/**
+  Pre-validate the system RAM when SEV-SNP is enabled in the guest VM.
+
+  @param[in]  BaseAddress             Base address
+  @param[in]  NumPages                Number of pages starting from the base address
+
+**/
+VOID
+EFIAPI
+MemEncryptSevSnpPreValidateSystemRam (
+  IN PHYSICAL_ADDRESS           BaseAddress,
+  IN UINTN                      NumPages
+  );
+
 #endif // _MEM_ENCRYPT_SEV_LIB_H_
diff --git a/OvmfPkg/Library/BaseMemEncryptSevLib/X64/SnpPageStateChange.h b/OvmfPkg/Library/BaseMemEncryptSevLib/X64/SnpPageStateChange.h
new file mode 100644
index 000000000000..8bbdf06468b9
--- /dev/null
+++ b/OvmfPkg/Library/BaseMemEncryptSevLib/X64/SnpPageStateChange.h
@@ -0,0 +1,31 @@
+/** @file
+
+  SEV-SNP Page Validation functions.
+
+  Copyright (c) 2021 AMD Incorporated. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef SNP_PAGE_STATE_INTERNAL_H_
+#define SNP_PAGE_STATE_INTERNAL_H_
+
+//
+// SEV-SNP Page states
+//
+typedef enum {
+  SevSnpPagePrivate,
+  SevSnpPageShared,
+
+} SEV_SNP_PAGE_STATE;
+
+VOID
+InternalSetPageState (
+  IN EFI_PHYSICAL_ADDRESS             BaseAddress,
+  IN UINTN                            NumPages,
+  IN SEV_SNP_PAGE_STATE               State,
+  IN BOOLEAN                          UseLargeEntry
+  );
+
+#endif
diff --git a/OvmfPkg/Library/BaseMemEncryptSevLib/Ia32/MemEncryptSevLib.c b/OvmfPkg/Library/BaseMemEncryptSevLib/Ia32/MemEncryptSevLib.c
index be260e0d1014..df5e4d61513d 100644
--- a/OvmfPkg/Library/BaseMemEncryptSevLib/Ia32/MemEncryptSevLib.c
+++ b/OvmfPkg/Library/BaseMemEncryptSevLib/Ia32/MemEncryptSevLib.c
@@ -136,3 +136,20 @@ MemEncryptSevClearMmioPageEncMask (
   //
   return RETURN_UNSUPPORTED;
 }
+
+/**
+  Pre-validate the system RAM when SEV-SNP is enabled in the guest VM.
+
+  @param[in]  BaseAddress             Base address
+  @param[in]  NumPages                Number of pages starting from the base address
+
+**/
+VOID
+EFIAPI
+MemEncryptSevSnpPreValidateSystemRam (
+  IN PHYSICAL_ADDRESS           BaseAddress,
+  IN UINTN                      NumPages
+  )
+{
+  ASSERT (FALSE);
+}
diff --git a/OvmfPkg/Library/BaseMemEncryptSevLib/X64/DxeSnpSystemRamValidate.c b/OvmfPkg/Library/BaseMemEncryptSevLib/X64/DxeSnpSystemRamValidate.c
new file mode 100644
index 000000000000..ad8d8b388dc8
--- /dev/null
+++ b/OvmfPkg/Library/BaseMemEncryptSevLib/X64/DxeSnpSystemRamValidate.c
@@ -0,0 +1,40 @@
+/** @file
+
+  SEV-SNP Page Validation functions.
+
+  Copyright (c) 2021 AMD Incorporated. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <Uefi/UefiBaseType.h>
+#include <Library/BaseLib.h>
+#include <Library/DebugLib.h>
+#include <Library/MemEncryptSevLib.h>
+
+#include "SnpPageStateChange.h"
+
+/**
+  Pre-validate the system RAM when SEV-SNP is enabled in the guest VM.
+
+  @param[in]  BaseAddress             Base address
+  @param[in]  NumPages                Number of pages starting from the base address
+
+**/
+VOID
+EFIAPI
+MemEncryptSevSnpPreValidateSystemRam (
+  IN PHYSICAL_ADDRESS                   BaseAddress,
+  IN UINTN                              NumPages
+  )
+{
+  if (!MemEncryptSevSnpIsEnabled ()) {
+    return;
+  }
+
+  //
+  // All the pre-validation must be completed in the PEI phase.
+  //
+  ASSERT (FALSE);
+}
diff --git a/OvmfPkg/Library/BaseMemEncryptSevLib/X64/PeiSnpSystemRamValidate.c b/OvmfPkg/Library/BaseMemEncryptSevLib/X64/PeiSnpSystemRamValidate.c
new file mode 100644
index 000000000000..64aab7f45b6d
--- /dev/null
+++ b/OvmfPkg/Library/BaseMemEncryptSevLib/X64/PeiSnpSystemRamValidate.c
@@ -0,0 +1,36 @@
+/** @file
+
+  SEV-SNP Page Validation functions.
+
+  Copyright (c) 2021 AMD Incorporated. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <Uefi/UefiBaseType.h>
+#include <Library/BaseLib.h>
+#include <Library/MemEncryptSevLib.h>
+
+#include "SnpPageStateChange.h"
+
+/**
+  Pre-validate the system RAM when SEV-SNP is enabled in the guest VM.
+
+  @param[in]  BaseAddress             Base address
+  @param[in]  NumPages                Number of pages starting from the base address
+
+**/
+VOID
+EFIAPI
+MemEncryptSevSnpPreValidateSystemRam (
+  IN PHYSICAL_ADDRESS                   BaseAddress,
+  IN UINTN                              NumPages
+  )
+{
+  if (!MemEncryptSevSnpIsEnabled ()) {
+    return;
+  }
+
+  InternalSetPageState (BaseAddress, NumPages, SevSnpPagePrivate, TRUE);
+}
diff --git a/OvmfPkg/Library/BaseMemEncryptSevLib/X64/SecSnpSystemRamValidate.c b/OvmfPkg/Library/BaseMemEncryptSevLib/X64/SecSnpSystemRamValidate.c
new file mode 100644
index 000000000000..64aab7f45b6d
--- /dev/null
+++ b/OvmfPkg/Library/BaseMemEncryptSevLib/X64/SecSnpSystemRamValidate.c
@@ -0,0 +1,36 @@
+/** @file
+
+  SEV-SNP Page Validation functions.
+
+  Copyright (c) 2021 AMD Incorporated. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <Uefi/UefiBaseType.h>
+#include <Library/BaseLib.h>
+#include <Library/MemEncryptSevLib.h>
+
+#include "SnpPageStateChange.h"
+
+/**
+  Pre-validate the system RAM when SEV-SNP is enabled in the guest VM.
+
+  @param[in]  BaseAddress             Base address
+  @param[in]  NumPages                Number of pages starting from the base address
+
+**/
+VOID
+EFIAPI
+MemEncryptSevSnpPreValidateSystemRam (
+  IN PHYSICAL_ADDRESS                   BaseAddress,
+  IN UINTN                              NumPages
+  )
+{
+  if (!MemEncryptSevSnpIsEnabled ()) {
+    return;
+  }
+
+  InternalSetPageState (BaseAddress, NumPages, SevSnpPagePrivate, TRUE);
+}
diff --git a/OvmfPkg/Library/BaseMemEncryptSevLib/X64/SnpPageStateChangeInternal.c b/OvmfPkg/Library/BaseMemEncryptSevLib/X64/SnpPageStateChangeInternal.c
new file mode 100644
index 000000000000..fb8b50eab661
--- /dev/null
+++ b/OvmfPkg/Library/BaseMemEncryptSevLib/X64/SnpPageStateChangeInternal.c
@@ -0,0 +1,230 @@
+/** @file
+
+  SEV-SNP Page Validation functions.
+
+  Copyright (c) 2021 AMD Incorporated. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <Uefi/UefiBaseType.h>
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/MemEncryptSevLib.h>
+#include <Library/DebugLib.h>
+#include <Library/VmgExitLib.h>
+
+#include <Register/Amd/Ghcb.h>
+#include <Register/Amd/Msr.h>
+
+#include "SnpPageStateChange.h"
+
+#define IS_ALIGNED(x, y)        ((((x) & (y - 1)) == 0))
+#define PAGES_PER_LARGE_ENTRY   512
+
+STATIC
+UINTN
+MemoryStateToGhcbOp (
+  IN SEV_SNP_PAGE_STATE   State
+  )
+{
+  UINTN Cmd;
+
+  switch (State) {
+    case SevSnpPageShared: Cmd = SNP_PAGE_STATE_SHARED; break;
+    case SevSnpPagePrivate: Cmd = SNP_PAGE_STATE_PRIVATE; break;
+    default: ASSERT(0);
+  }
+
+  return Cmd;
+}
+
+STATIC
+VOID
+SnpPageStateFailureTerminate (
+  VOID
+  )
+{
+  MSR_SEV_ES_GHCB_REGISTER  Msr;
+
+  //
+  // Use the GHCB MSR Protocol to request termination by the hypervisor
+  //
+  Msr.GhcbPhysicalAddress = 0;
+  Msr.GhcbTerminate.Function = GHCB_INFO_TERMINATE_REQUEST;
+  Msr.GhcbTerminate.ReasonCodeSet = GHCB_TERMINATE_GHCB;
+  Msr.GhcbTerminate.ReasonCode = GHCB_TERMINATE_GHCB_GENERAL;
+  AsmWriteMsr64 (MSR_SEV_ES_GHCB, Msr.GhcbPhysicalAddress);
+
+  AsmVmgExit ();
+
+  ASSERT (FALSE);
+  CpuDeadLoop ();
+}
+
+/**
+ This function issues the PVALIDATE instruction to validate or invalidate the memory
+ range specified. If PVALIDATE returns size mismatch then it retry validating with
+ smaller page size.
+
+ */
+STATIC
+VOID
+PvalidateRange (
+  IN  SNP_PAGE_STATE_CHANGE_INFO    *Info,
+  IN  UINTN                         StartIndex,
+  IN  UINTN                         EndIndex,
+  IN  BOOLEAN                       Validate
+  )
+{
+  UINTN         Address, RmpPageSize, Ret, i;
+
+  for (; StartIndex < EndIndex; StartIndex++) {
+    //
+    // Get the address and the page size from the Info.
+    //
+    Address = Info->Entry[StartIndex].GuestFrameNumber << EFI_PAGE_SHIFT;
+    RmpPageSize = Info->Entry[StartIndex].PageSize;
+
+    Ret = AsmPvalidate (RmpPageSize, Validate, Address);
+
+    //
+    // If we fail to validate due to size mismatch then try with the
+    // smaller page size. This senario will occur if the backing page in
+    // the RMP entry is 4K and we are validating it as a 2MB.
+    //
+    if ((Ret == PVALIDATE_RET_SIZE_MISMATCH) && (RmpPageSize == PvalidatePageSize2MB)) {
+      for (i = 0; i < PAGES_PER_LARGE_ENTRY; i++) {
+        Ret = AsmPvalidate (PvalidatePageSize4K, Validate, Address);
+        if (Ret) {
+          break;
+        }
+
+        Address = Address + EFI_PAGE_SIZE;
+      }
+    }
+
+    //
+    // If validation failed then do not continue.
+    //
+    if (Ret) {
+      DEBUG ((
+        DEBUG_ERROR, "%a:%a: Failed to %a address 0x%Lx Error code %d\n",
+        gEfiCallerBaseName,
+        __FUNCTION__,
+        Validate ? "Validate" : "Invalidate",
+        Address,
+        Ret
+        ));
+      SnpPageStateFailureTerminate ();
+    }
+  }
+}
+
+/**
+ The function is used to set the page state when SEV-SNP is active. The page state
+ transition consist of changing the page ownership in the RMP table, and using the
+ PVALIDATE instruction to update the Validated bit in RMP table.
+
+ When the UseLargeEntry is set to TRUE, then function will try to use the large RMP
+ entry (whevever possible).
+ */
+VOID
+InternalSetPageState (
+  IN EFI_PHYSICAL_ADDRESS             BaseAddress,
+  IN UINTN                            NumPages,
+  IN SEV_SNP_PAGE_STATE               State,
+  IN BOOLEAN                          UseLargeEntry
+  )
+{
+  EFI_STATUS                      Status;
+  GHCB                            *Ghcb;
+  EFI_PHYSICAL_ADDRESS            NextAddress, EndAddress;
+  MSR_SEV_ES_GHCB_REGISTER        Msr;
+  BOOLEAN                         InterruptState;
+  SNP_PAGE_STATE_CHANGE_INFO      *Info;
+  UINTN                           i, RmpPageSize;
+
+  Msr.GhcbPhysicalAddress = AsmReadMsr64 (MSR_SEV_ES_GHCB);
+  Ghcb = Msr.Ghcb;
+
+  EndAddress = BaseAddress + EFI_PAGES_TO_SIZE (NumPages);
+
+  DEBUG ((
+    DEBUG_VERBOSE, "%a:%a Address 0x%Lx - 0x%Lx State = %a LargeEntry = %d\n",
+    gEfiCallerBaseName,
+    __FUNCTION__,
+    BaseAddress,
+    EndAddress,
+    State == SevSnpPageShared ? "Shared" : "Private",
+    UseLargeEntry
+    ));
+
+  for (; BaseAddress < EndAddress; BaseAddress = NextAddress) {
+    //
+    // Initialize the GHCB and setup scratch sw to point to shared buffer.
+    //
+    VmgInit (Ghcb, &InterruptState);
+    Info = (SNP_PAGE_STATE_CHANGE_INFO *) Ghcb->SharedBuffer;
+
+    SetMem (Info, sizeof (*Info), 0);
+
+    //
+    // Build page state change buffer
+    //
+    for (i = 0; (EndAddress > BaseAddress) && i < SNP_PAGE_STATE_MAX_ENTRY;
+        BaseAddress = NextAddress, i++) {
+      //
+      // Is this a 2MB aligned page? Check if we can use the Large RMP entry.
+      //
+      if (UseLargeEntry && IS_ALIGNED (BaseAddress, SIZE_2MB) &&
+        ((EndAddress - BaseAddress) >= SIZE_2MB)) {
+        RmpPageSize = PvalidatePageSize2MB;
+        NextAddress = BaseAddress + SIZE_2MB;
+      } else {
+        RmpPageSize = PvalidatePageSize4K;
+        NextAddress = BaseAddress + EFI_PAGE_SIZE;
+      }
+
+      Info->Entry[i].GuestFrameNumber = BaseAddress >> EFI_PAGE_SHIFT;
+      Info->Entry[i].PageSize = RmpPageSize;
+      Info->Entry[i].Operation = MemoryStateToGhcbOp (State);
+      Info->Entry[i].CurrentPage = 0;
+    }
+
+    Info->Header.CurrentEntry = 0;
+    Info->Header.EndEntry = i - 1;
+
+    //
+    // If the request page state change is shared then invalidate the pages before
+    // adding the page in the RMP table.
+    //
+    if (State == SevSnpPageShared) {
+      PvalidateRange (Info, 0, i, FALSE);
+    }
+
+    //
+    // Issue the VMGEXIT and retry if hypervisor failed to process all the entries.
+    //
+    while (Info->Header.CurrentEntry <= Info->Header.EndEntry) {
+      Ghcb->SaveArea.SwScratch = (UINT64) Ghcb->SharedBuffer;
+      VmgSetOffsetValid (Ghcb, GhcbSwScratch);
+
+      Status = VmgExit (Ghcb, SVM_EXIT_SNP_PAGE_STATE_CHANGE, 0, 0);
+      if ((Status != 0) || (Ghcb->SaveArea.SwExitInfo2)) {
+        SnpPageStateFailureTerminate ();
+      }
+    }
+
+    //
+    // If the request page state change is shared then invalidate the pages before
+    // adding the page in the RMP table.
+    //
+    if (State == SevSnpPagePrivate) {
+      PvalidateRange (Info, 0, i, TRUE);
+    }
+
+    VmgDone (Ghcb, InterruptState);
+  }
+}
-- 
2.17.1


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

* [PATCH RFC v3 14/22] OvmfPkg/BaseMemEncryptSevLib: skip the pre-validated system RAM
  2021-05-26 23:10 [RESEND PATCH RFC v3 00/22] Add AMD Secure Nested Paging (SEV-SNP) support Brijesh Singh
                   ` (12 preceding siblings ...)
  2021-05-26 23:11 ` [PATCH RFC v3 13/22] OvmfPkg/MemEncryptSevLib: add support to validate system RAM Brijesh Singh
@ 2021-05-26 23:11 ` Brijesh Singh
  2021-05-26 23:11 ` [PATCH RFC v3 15/22] OvmfPkg/MemEncryptSevLib: add support to validate > 4GB memory in PEI phase Brijesh Singh
                   ` (9 subsequent siblings)
  23 siblings, 0 replies; 57+ messages in thread
From: Brijesh Singh @ 2021-05-26 23:11 UTC (permalink / raw)
  To: James Bottomley, Min Xu, Jiewen Yao, Tom Lendacky, Jordan Justen,
	Laszlo Ersek, Erdem Aktas, Eric Dong, Ray Ni, Rahul Kumar, devel
  Cc: Brijesh Singh, Ard Biesheuvel

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

The MemEncryptSevSnpPreValidateSystemRam() is used for pre-validating the
system RAM. As the boot progress, each phase validates a fixed region of
the RAM. In the PEI phase, the PlatformPei detects all the available RAM
and calls to pre-validate the detected system RAM.

While validating the system RAM in PEI phase, we must skip previously
validated system RAM to avoid the double validation.

Cc: James Bottomley <jejb@linux.ibm.com>
Cc: Min Xu <min.m.xu@intel.com>
Cc: Jiewen Yao <jiewen.yao@intel.com>
Cc: Tom Lendacky <thomas.lendacky@amd.com>
Cc: Jordan Justen <jordan.l.justen@intel.com>
Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
Cc: Laszlo Ersek <lersek@redhat.com>
Cc: Erdem Aktas <erdemaktas@google.com>
Signed-off-by: Brijesh Singh <brijesh.singh@amd.com>
---
 .../PeiMemEncryptSevLib.inf                   |  2 +
 .../X64/PeiSnpSystemRamValidate.c             | 65 ++++++++++++++++++-
 2 files changed, 66 insertions(+), 1 deletion(-)

diff --git a/OvmfPkg/Library/BaseMemEncryptSevLib/PeiMemEncryptSevLib.inf b/OvmfPkg/Library/BaseMemEncryptSevLib/PeiMemEncryptSevLib.inf
index 0402e49a1028..f4058911e7b6 100644
--- a/OvmfPkg/Library/BaseMemEncryptSevLib/PeiMemEncryptSevLib.inf
+++ b/OvmfPkg/Library/BaseMemEncryptSevLib/PeiMemEncryptSevLib.inf
@@ -58,3 +58,5 @@ [FeaturePcd]
 
 [FixedPcd]
   gUefiCpuPkgTokenSpaceGuid.PcdSevEsWorkAreaBase
+  gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSnpHypervisorPreValidatedEnd
+  gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSnpHypervisorPreValidatedStart
diff --git a/OvmfPkg/Library/BaseMemEncryptSevLib/X64/PeiSnpSystemRamValidate.c b/OvmfPkg/Library/BaseMemEncryptSevLib/X64/PeiSnpSystemRamValidate.c
index 64aab7f45b6d..3e692a3b869d 100644
--- a/OvmfPkg/Library/BaseMemEncryptSevLib/X64/PeiSnpSystemRamValidate.c
+++ b/OvmfPkg/Library/BaseMemEncryptSevLib/X64/PeiSnpSystemRamValidate.c
@@ -14,6 +14,44 @@
 
 #include "SnpPageStateChange.h"
 
+typedef struct {
+  UINT64    StartAddress;
+  UINT64    EndAddress;
+} SNP_PRE_VALIDATED_RANGE;
+
+STATIC SNP_PRE_VALIDATED_RANGE mPreValidatedRange[] = {
+  // This range is pre-validated by the Hypervisor.
+  {
+    FixedPcdGet32 (PcdOvmfSnpHypervisorPreValidatedStart),
+    FixedPcdGet32 (PcdOvmfSnpHypervisorPreValidatedEnd)
+  }
+};
+
+STATIC
+BOOLEAN
+DetectPreValidatedOverLap (
+  IN    PHYSICAL_ADDRESS            StartAddress,
+  IN    PHYSICAL_ADDRESS            EndAddress,
+  OUT   SNP_PRE_VALIDATED_RANGE     *OverlapRange
+  )
+{
+  UINTN               i;
+
+  //
+  // Check if the specified address range exist in pre-validated array.
+  //
+  for (i = 0; i < ARRAY_SIZE (mPreValidatedRange); i++) {
+    if ((mPreValidatedRange[i].StartAddress < EndAddress) &&
+        (StartAddress < mPreValidatedRange[i].EndAddress)) {
+      OverlapRange->StartAddress = mPreValidatedRange[i].StartAddress;
+      OverlapRange->EndAddress = mPreValidatedRange[i].EndAddress;
+      return TRUE;
+    }
+  }
+
+  return FALSE;
+}
+
 /**
   Pre-validate the system RAM when SEV-SNP is enabled in the guest VM.
 
@@ -28,9 +66,34 @@ MemEncryptSevSnpPreValidateSystemRam (
   IN UINTN                              NumPages
   )
 {
+  PHYSICAL_ADDRESS          EndAddress;
+  SNP_PRE_VALIDATED_RANGE   OverlapRange;
+
   if (!MemEncryptSevSnpIsEnabled ()) {
     return;
   }
 
-  InternalSetPageState (BaseAddress, NumPages, SevSnpPagePrivate, TRUE);
+  EndAddress = BaseAddress + EFI_PAGES_TO_SIZE (NumPages);
+
+  while (BaseAddress < EndAddress) {
+    //
+    // Check if the range overlaps with the pre-validated ranges.
+    //
+    if (DetectPreValidatedOverLap (BaseAddress, EndAddress, &OverlapRange)) {
+      // Validate the non-overlap regions.
+      if (BaseAddress < OverlapRange.StartAddress) {
+        NumPages = EFI_SIZE_TO_PAGES (OverlapRange.StartAddress - BaseAddress);
+
+        InternalSetPageState (BaseAddress, NumPages, SevSnpPagePrivate, TRUE);
+      }
+
+      BaseAddress = OverlapRange.EndAddress;
+      continue;
+    }
+
+    // Validate the remaining pages.
+    NumPages = EFI_SIZE_TO_PAGES (EndAddress - BaseAddress);
+    InternalSetPageState (BaseAddress, NumPages, SevSnpPagePrivate, TRUE);
+    BaseAddress = EndAddress;
+  }
 }
-- 
2.17.1


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

* [PATCH RFC v3 15/22] OvmfPkg/MemEncryptSevLib: add support to validate > 4GB memory in PEI phase
  2021-05-26 23:10 [RESEND PATCH RFC v3 00/22] Add AMD Secure Nested Paging (SEV-SNP) support Brijesh Singh
                   ` (13 preceding siblings ...)
  2021-05-26 23:11 ` [PATCH RFC v3 14/22] OvmfPkg/BaseMemEncryptSevLib: skip the pre-validated " Brijesh Singh
@ 2021-05-26 23:11 ` Brijesh Singh
  2021-05-26 23:11 ` [PATCH RFC v3 16/22] OvmfPkg/SecMain: pre-validate the memory used for decompressing Fv Brijesh Singh
                   ` (8 subsequent siblings)
  23 siblings, 0 replies; 57+ messages in thread
From: Brijesh Singh @ 2021-05-26 23:11 UTC (permalink / raw)
  To: James Bottomley, Min Xu, Jiewen Yao, Tom Lendacky, Jordan Justen,
	Laszlo Ersek, Erdem Aktas, Eric Dong, Ray Ni, Rahul Kumar, devel
  Cc: Brijesh Singh, Ard Biesheuvel

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

The initial page built during the SEC phase is used by the
MemEncryptSevSnpValidateSystemRam() for the system RAM validation. The
page validation process requires using the PVALIDATE instruction;  the
instruction accepts a virtual address of the memory region that needs
to be validated. If hardware encounters a page table walk failure (due
to page-not-present) then it raises #GP.

The initial page table built in SEC phase address up to 4GB. Add an
internal function to extend the page table to cover > 4GB. The function
builds 1GB entries in the page table for access > 4GB. This will provide
the support to call PVALIDATE instruction for the virtual address >
4GB in PEI phase.

Cc: James Bottomley <jejb@linux.ibm.com>
Cc: Min Xu <min.m.xu@intel.com>
Cc: Jiewen Yao <jiewen.yao@intel.com>
Cc: Tom Lendacky <thomas.lendacky@amd.com>
Cc: Jordan Justen <jordan.l.justen@intel.com>
Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
Cc: Laszlo Ersek <lersek@redhat.com>
Cc: Erdem Aktas <erdemaktas@google.com>
Signed-off-by: Brijesh Singh <brijesh.singh@amd.com>
---
 .../BaseMemEncryptSevLib/X64/VirtualMemory.h  |  19 +++
 .../X64/PeiDxeVirtualMemory.c                 | 115 ++++++++++++++++++
 .../X64/PeiSnpSystemRamValidate.c             |  22 ++++
 3 files changed, 156 insertions(+)

diff --git a/OvmfPkg/Library/BaseMemEncryptSevLib/X64/VirtualMemory.h b/OvmfPkg/Library/BaseMemEncryptSevLib/X64/VirtualMemory.h
index 21bbbd1c4f9c..aefef68c30c0 100644
--- a/OvmfPkg/Library/BaseMemEncryptSevLib/X64/VirtualMemory.h
+++ b/OvmfPkg/Library/BaseMemEncryptSevLib/X64/VirtualMemory.h
@@ -143,4 +143,23 @@ InternalMemEncryptSevClearMmioPageEncMask (
   IN  PHYSICAL_ADDRESS        PhysicalAddress,
   IN  UINTN                   Length
   );
+
+/**
+  Create 1GB identity mapping for the specified virtual address range.
+
+  @param[in]  Cr3BaseAddress          Cr3 Base Address (if zero then use
+                                      current CR3)
+  @param[in]  VirtualAddress          Virtual address
+  @param[in]  Length                  Length of virtual address range
+
+  @retval RETURN_INVALID_PARAMETER    Number of pages is zero.
+
+**/
+RETURN_STATUS
+EFIAPI
+InternalMemEncryptSevCreateIdentityMap1G (
+  IN    PHYSICAL_ADDRESS      Cr3BaseAddress,
+  IN    PHYSICAL_ADDRESS      PhysicalAddress,
+  IN    UINTN                 Length
+  );
 #endif
diff --git a/OvmfPkg/Library/BaseMemEncryptSevLib/X64/PeiDxeVirtualMemory.c b/OvmfPkg/Library/BaseMemEncryptSevLib/X64/PeiDxeVirtualMemory.c
index c696745f9d26..f146f6d61cc5 100644
--- a/OvmfPkg/Library/BaseMemEncryptSevLib/X64/PeiDxeVirtualMemory.c
+++ b/OvmfPkg/Library/BaseMemEncryptSevLib/X64/PeiDxeVirtualMemory.c
@@ -536,6 +536,121 @@ EnableReadOnlyPageWriteProtect (
   AsmWriteCr0 (AsmReadCr0() | BIT16);
 }
 
+RETURN_STATUS
+EFIAPI
+InternalMemEncryptSevCreateIdentityMap1G (
+  IN    PHYSICAL_ADDRESS      Cr3BaseAddress,
+  IN    PHYSICAL_ADDRESS      PhysicalAddress,
+  IN    UINTN                 Length
+  )
+{
+  PAGE_MAP_AND_DIRECTORY_POINTER *PageMapLevel4Entry;
+  PAGE_TABLE_1G_ENTRY            *PageDirectory1GEntry;
+  UINT64                         PgTableMask;
+  UINT64                         AddressEncMask;
+  BOOLEAN                        IsWpEnabled;
+  RETURN_STATUS                  Status;
+
+  //
+  // Set PageMapLevel4Entry to suppress incorrect compiler/analyzer warnings.
+  //
+  PageMapLevel4Entry = NULL;
+
+  DEBUG ((
+    DEBUG_VERBOSE,
+    "%a:%a: Cr3Base=0x%Lx Physical=0x%Lx Length=0x%Lx\n",
+    gEfiCallerBaseName,
+    __FUNCTION__,
+    Cr3BaseAddress,
+    PhysicalAddress,
+    (UINT64)Length
+    ));
+
+  if (Length == 0) {
+    return RETURN_INVALID_PARAMETER;
+  }
+
+  //
+  // Check if we have a valid memory encryption mask
+  //
+  AddressEncMask = InternalGetMemEncryptionAddressMask ();
+  if (!AddressEncMask) {
+    return RETURN_ACCESS_DENIED;
+  }
+
+  PgTableMask = AddressEncMask | EFI_PAGE_MASK;
+
+
+  //
+  // Make sure that the page table is changeable.
+  //
+  IsWpEnabled = IsReadOnlyPageWriteProtected ();
+  if (IsWpEnabled) {
+    DisableReadOnlyPageWriteProtect ();
+  }
+
+  Status = EFI_SUCCESS;
+
+  while (Length)
+  {
+    //
+    // If Cr3BaseAddress is not specified then read the current CR3
+    //
+    if (Cr3BaseAddress == 0) {
+      Cr3BaseAddress = AsmReadCr3();
+    }
+
+    PageMapLevel4Entry = (VOID*) (Cr3BaseAddress & ~PgTableMask);
+    PageMapLevel4Entry += PML4_OFFSET(PhysicalAddress);
+    if (!PageMapLevel4Entry->Bits.Present) {
+      DEBUG ((
+        DEBUG_ERROR,
+        "%a:%a: bad PML4 for Physical=0x%Lx\n",
+        gEfiCallerBaseName,
+        __FUNCTION__,
+        PhysicalAddress
+        ));
+      Status = RETURN_NO_MAPPING;
+      goto Done;
+    }
+
+    PageDirectory1GEntry = (VOID *)(
+                             (PageMapLevel4Entry->Bits.PageTableBaseAddress <<
+                              12) & ~PgTableMask
+                             );
+    PageDirectory1GEntry += PDP_OFFSET(PhysicalAddress);
+    if (!PageDirectory1GEntry->Bits.Present) {
+      PageDirectory1GEntry->Bits.Present = 1;
+      PageDirectory1GEntry->Bits.MustBe1 = 1;
+      PageDirectory1GEntry->Bits.MustBeZero = 0;
+      PageDirectory1GEntry->Bits.ReadWrite = 1;
+      PageDirectory1GEntry->Uint64 |= (UINT64)PhysicalAddress | AddressEncMask;
+    }
+
+    if (Length <= BIT30) {
+      Length = 0;
+    } else {
+      Length -= BIT30;
+    }
+
+    PhysicalAddress += BIT30;
+  }
+
+  //
+  // Flush TLB
+  //
+  CpuFlushTlb();
+
+Done:
+  //
+  // Restore page table write protection, if any.
+  //
+  if (IsWpEnabled) {
+    EnableReadOnlyPageWriteProtect ();
+  }
+
+  return Status;
+}
 
 /**
   This function either sets or clears memory encryption bit for the memory
diff --git a/OvmfPkg/Library/BaseMemEncryptSevLib/X64/PeiSnpSystemRamValidate.c b/OvmfPkg/Library/BaseMemEncryptSevLib/X64/PeiSnpSystemRamValidate.c
index 3e692a3b869d..69ffb79633c4 100644
--- a/OvmfPkg/Library/BaseMemEncryptSevLib/X64/PeiSnpSystemRamValidate.c
+++ b/OvmfPkg/Library/BaseMemEncryptSevLib/X64/PeiSnpSystemRamValidate.c
@@ -10,9 +10,12 @@
 
 #include <Uefi/UefiBaseType.h>
 #include <Library/BaseLib.h>
+#include <Library/PcdLib.h>
+#include <Library/DebugLib.h>
 #include <Library/MemEncryptSevLib.h>
 
 #include "SnpPageStateChange.h"
+#include "VirtualMemory.h"
 
 typedef struct {
   UINT64    StartAddress;
@@ -68,6 +71,7 @@ MemEncryptSevSnpPreValidateSystemRam (
 {
   PHYSICAL_ADDRESS          EndAddress;
   SNP_PRE_VALIDATED_RANGE   OverlapRange;
+  EFI_STATUS                Status;
 
   if (!MemEncryptSevSnpIsEnabled ()) {
     return;
@@ -75,6 +79,24 @@ MemEncryptSevSnpPreValidateSystemRam (
 
   EndAddress = BaseAddress + EFI_PAGES_TO_SIZE (NumPages);
 
+  //
+  // The page table used in PEI can address up to 4GB memory. If we are asked to
+  // validate a range above the 4GB, then create an identity mapping so that the
+  // PVALIDATE instruction can execute correctly. If the page table entry is not
+  // present then PVALIDATE will #GP.
+  //
+  if (BaseAddress >= SIZE_4GB) {
+    Status = InternalMemEncryptSevCreateIdentityMap1G (
+                0,
+                BaseAddress,
+                EFI_PAGES_TO_SIZE (NumPages)
+                );
+    if (EFI_ERROR (Status)) {
+      ASSERT (FALSE);
+      CpuDeadLoop ();
+    }
+  }
+
   while (BaseAddress < EndAddress) {
     //
     // Check if the range overlaps with the pre-validated ranges.
-- 
2.17.1


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

* [PATCH RFC v3 16/22] OvmfPkg/SecMain: pre-validate the memory used for decompressing Fv
  2021-05-26 23:10 [RESEND PATCH RFC v3 00/22] Add AMD Secure Nested Paging (SEV-SNP) support Brijesh Singh
                   ` (14 preceding siblings ...)
  2021-05-26 23:11 ` [PATCH RFC v3 15/22] OvmfPkg/MemEncryptSevLib: add support to validate > 4GB memory in PEI phase Brijesh Singh
@ 2021-05-26 23:11 ` Brijesh Singh
  2021-05-26 23:11 ` [PATCH RFC v3 17/22] OvmfPkg/PlatformPei: validate the system RAM when SNP is active Brijesh Singh
                   ` (7 subsequent siblings)
  23 siblings, 0 replies; 57+ messages in thread
From: Brijesh Singh @ 2021-05-26 23:11 UTC (permalink / raw)
  To: James Bottomley, Min Xu, Jiewen Yao, Tom Lendacky, Jordan Justen,
	Laszlo Ersek, Erdem Aktas, Eric Dong, Ray Ni, Rahul Kumar, devel
  Cc: Brijesh Singh, Ard Biesheuvel

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

The VMM launch sequence should have pre-validated all the data pages used
in the Reset vector. The range does not cover the data pages used during
the SEC phase (mainly PEI and DXE firmware volume decompression memory).

When SEV-SNP is active, the memory must be pre-validated before the access.
Add support to pre-validate the memory range from SnpSecPreValidatedStart
to SnpSecPreValidatedEnd. This should be sufficent to enter into the PEI
phase.

Cc: James Bottomley <jejb@linux.ibm.com>
Cc: Min Xu <min.m.xu@intel.com>
Cc: Jiewen Yao <jiewen.yao@intel.com>
Cc: Tom Lendacky <thomas.lendacky@amd.com>
Cc: Jordan Justen <jordan.l.justen@intel.com>
Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
Cc: Laszlo Ersek <lersek@redhat.com>
Cc: Erdem Aktas <erdemaktas@google.com>
Signed-off-by: Brijesh Singh <brijesh.singh@amd.com>
---
 OvmfPkg/OvmfPkg.dec                           |  5 ++++
 .../PeiMemEncryptSevLib.inf                   |  2 ++
 OvmfPkg/Sec/SecMain.inf                       |  3 +++
 .../X64/PeiSnpSystemRamValidate.c             |  5 ++++
 OvmfPkg/Sec/SecMain.c                         | 27 +++++++++++++++++++
 OvmfPkg/FvmainCompactScratchEnd.fdf.inc       |  5 ++++
 6 files changed, 47 insertions(+)

diff --git a/OvmfPkg/OvmfPkg.dec b/OvmfPkg/OvmfPkg.dec
index 3886d43bd3de..4da2d2de9df0 100644
--- a/OvmfPkg/OvmfPkg.dec
+++ b/OvmfPkg/OvmfPkg.dec
@@ -336,6 +336,11 @@ [PcdsFixedAtBuild]
   gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSnpHypervisorPreValidatedStart|0x0|UINT32|0x49
   gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSnpHypervisorPreValidatedEnd|0x0|UINT32|0x50
 
+  ## The range of memory that need to be pre-validated in the SEC phase
+  #  when SEV-SNP is active in the guest VM.
+  gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSnpSecPreValidatedStart|0|UINT32|0x51
+  gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSnpSecPreValidatedEnd|0|UINT32|0x52
+
 [PcdsDynamic, PcdsDynamicEx]
   gUefiOvmfPkgTokenSpaceGuid.PcdEmuVariableEvent|0|UINT64|2
   gUefiOvmfPkgTokenSpaceGuid.PcdOvmfFlashVariablesEnable|FALSE|BOOLEAN|0x10
diff --git a/OvmfPkg/Library/BaseMemEncryptSevLib/PeiMemEncryptSevLib.inf b/OvmfPkg/Library/BaseMemEncryptSevLib/PeiMemEncryptSevLib.inf
index f4058911e7b6..2b60920f4b25 100644
--- a/OvmfPkg/Library/BaseMemEncryptSevLib/PeiMemEncryptSevLib.inf
+++ b/OvmfPkg/Library/BaseMemEncryptSevLib/PeiMemEncryptSevLib.inf
@@ -58,5 +58,7 @@ [FeaturePcd]
 
 [FixedPcd]
   gUefiCpuPkgTokenSpaceGuid.PcdSevEsWorkAreaBase
+  gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSnpSecPreValidatedEnd
+  gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSnpSecPreValidatedStart
   gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSnpHypervisorPreValidatedEnd
   gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSnpHypervisorPreValidatedStart
diff --git a/OvmfPkg/Sec/SecMain.inf b/OvmfPkg/Sec/SecMain.inf
index 7f78dcee2772..8144b1d115cf 100644
--- a/OvmfPkg/Sec/SecMain.inf
+++ b/OvmfPkg/Sec/SecMain.inf
@@ -50,6 +50,7 @@ [LibraryClasses]
   PeCoffExtraActionLib
   ExtractGuidedSectionLib
   LocalApicLib
+  MemEncryptSevLib
   CpuExceptionHandlerLib
 
 [Ppis]
@@ -70,6 +71,8 @@ [Pcd]
   gUefiOvmfPkgTokenSpaceGuid.PcdGuidedExtractHandlerTableSize
   gUefiOvmfPkgTokenSpaceGuid.PcdOvmfDecompressionScratchEnd
   gEfiMdeModulePkgTokenSpaceGuid.PcdInitValueInTempStack
+  gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSnpSecPreValidatedStart
+  gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSnpSecPreValidatedEnd
 
 [FeaturePcd]
   gUefiOvmfPkgTokenSpaceGuid.PcdSmmSmramRequire
diff --git a/OvmfPkg/Library/BaseMemEncryptSevLib/X64/PeiSnpSystemRamValidate.c b/OvmfPkg/Library/BaseMemEncryptSevLib/X64/PeiSnpSystemRamValidate.c
index 69ffb79633c4..253d42073907 100644
--- a/OvmfPkg/Library/BaseMemEncryptSevLib/X64/PeiSnpSystemRamValidate.c
+++ b/OvmfPkg/Library/BaseMemEncryptSevLib/X64/PeiSnpSystemRamValidate.c
@@ -27,6 +27,11 @@ STATIC SNP_PRE_VALIDATED_RANGE mPreValidatedRange[] = {
   {
     FixedPcdGet32 (PcdOvmfSnpHypervisorPreValidatedStart),
     FixedPcdGet32 (PcdOvmfSnpHypervisorPreValidatedEnd)
+  },
+  // This range is pre-validated by the Sec/SecMain.c
+  {
+    FixedPcdGet32 (PcdOvmfSnpSecPreValidatedStart),
+    FixedPcdGet32 (PcdOvmfSnpSecPreValidatedEnd)
   }
 };
 
diff --git a/OvmfPkg/Sec/SecMain.c b/OvmfPkg/Sec/SecMain.c
index faa6891cca79..532574fa3095 100644
--- a/OvmfPkg/Sec/SecMain.c
+++ b/OvmfPkg/Sec/SecMain.c
@@ -910,6 +910,26 @@ SevEsIsEnabled (
   return ((SevEsWorkArea != NULL) && (SevEsWorkArea->SevEsEnabled != 0));
 }
 
+/**
+ Pre-validate System RAM used for decompressing the PEI and DXE firmware volumes
+ when SEV-SNP is active. The PCDs SecPreValidatedStart and SecPreValidatedEnd are
+ set in OvmfPkg/FvmainCompactScratchEnd.fdf.inc.
+
+**/
+STATIC
+VOID
+SevSnpSecPreValidateSystemRam (
+  VOID
+  )
+{
+  PHYSICAL_ADDRESS        Start, End;
+
+  Start = (EFI_PHYSICAL_ADDRESS) PcdGet32 (PcdOvmfSnpSecPreValidatedStart);
+  End = (EFI_PHYSICAL_ADDRESS) PcdGet32 (PcdOvmfSnpSecPreValidatedEnd);
+
+  MemEncryptSevSnpPreValidateSystemRam (Start, EFI_SIZE_TO_PAGES (End - Start));
+}
+
 VOID
 EFIAPI
 SecCoreStartupWithStack (
@@ -1041,6 +1061,13 @@ SecCoreStartupWithStack (
   SecCoreData.BootFirmwareVolumeBase = BootFv;
   SecCoreData.BootFirmwareVolumeSize = (UINTN) BootFv->FvLength;
 
+  if (SevSnpIsEnabled ()) {
+    //
+    // Pre-validate the System RAM used in the SEC Phase
+    //
+    SevSnpSecPreValidateSystemRam ();
+  }
+
   //
   // Make sure the 8259 is masked before initializing the Debug Agent and the debug timer is enabled
   //
diff --git a/OvmfPkg/FvmainCompactScratchEnd.fdf.inc b/OvmfPkg/FvmainCompactScratchEnd.fdf.inc
index 46f52583297c..b560fb0b8e4f 100644
--- a/OvmfPkg/FvmainCompactScratchEnd.fdf.inc
+++ b/OvmfPkg/FvmainCompactScratchEnd.fdf.inc
@@ -63,3 +63,8 @@
 DEFINE DECOMP_SCRATCH_BASE           = (($(DECOMP_SCRATCH_BASE_UNALIGNED) + $(DECOMP_SCRATCH_BASE_ALIGNMENT)) & $(DECOMP_SCRATCH_BASE_MASK))
 
 SET gUefiOvmfPkgTokenSpaceGuid.PcdOvmfDecompressionScratchEnd = $(DECOMP_SCRATCH_BASE) + $(DECOMP_SCRATCH_SIZE)
+
+#
+# The range of pages that should be pre-validated during the SEC phase when SEV-SNP is active in the guest VM.
+SET gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSnpSecPreValidatedStart = $(MEMFD_BASE_ADDRESS) + gUefiOvmfPkgTokenSpaceGuid.PcdOvmfPeiMemFvBase
+SET gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSnpSecPreValidatedEnd = $(DECOMP_SCRATCH_BASE) + $(DECOMP_SCRATCH_SIZE)
-- 
2.17.1


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

* [PATCH RFC v3 17/22] OvmfPkg/PlatformPei: validate the system RAM when SNP is active
  2021-05-26 23:10 [RESEND PATCH RFC v3 00/22] Add AMD Secure Nested Paging (SEV-SNP) support Brijesh Singh
                   ` (15 preceding siblings ...)
  2021-05-26 23:11 ` [PATCH RFC v3 16/22] OvmfPkg/SecMain: pre-validate the memory used for decompressing Fv Brijesh Singh
@ 2021-05-26 23:11 ` Brijesh Singh
  2021-05-26 23:11 ` [PATCH RFC v3 18/22] OvmfPkg/MemEncryptSevLib: Change the page state in the RMP table Brijesh Singh
                   ` (6 subsequent siblings)
  23 siblings, 0 replies; 57+ messages in thread
From: Brijesh Singh @ 2021-05-26 23:11 UTC (permalink / raw)
  To: James Bottomley, Min Xu, Jiewen Yao, Tom Lendacky, Jordan Justen,
	Laszlo Ersek, Erdem Aktas, Eric Dong, Ray Ni, Rahul Kumar, devel
  Cc: Brijesh Singh, Ard Biesheuvel

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

When SEV-SNP is active, a memory region mapped encrypted in the page
table must be validated before access. There are two approaches that
can be taken to validate the system RAM detected during the PEI phase:

1) Validate on-demand
OR
2) Validate before access

On-demand
=========
If memory is not validated before access, it will cause a #VC
exception with the page-not-validated error code. The VC exception
handler can perform the validation steps.

The pages that have been validated will need to be tracked to avoid
the double validation scenarios. The range of memory that has not
been validated will need to be communicated to the OS through the
recently introduced unaccepted memory type
https://github.com/microsoft/mu_basecore/pull/66, so that OS can
validate those ranges before using them.

Validate before access
======================
Since the PEI phase detects all the available system RAM, use the
MemEncryptSevSnpValidateSystemRam() function to pre-validate the
system RAM in the PEI phase.

For now, choose option 2 due to the dependency and the complexity
of the on-demand validation.

Cc: James Bottomley <jejb@linux.ibm.com>
Cc: Min Xu <min.m.xu@intel.com>
Cc: Jiewen Yao <jiewen.yao@intel.com>
Cc: Tom Lendacky <thomas.lendacky@amd.com>
Cc: Jordan Justen <jordan.l.justen@intel.com>
Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
Cc: Laszlo Ersek <lersek@redhat.com>
Cc: Erdem Aktas <erdemaktas@google.com>
Signed-off-by: Brijesh Singh <brijesh.singh@amd.com>
---
 OvmfPkg/PlatformPei/AmdSev.c | 33 +++++++++++++++++++++++++++------
 1 file changed, 27 insertions(+), 6 deletions(-)

diff --git a/OvmfPkg/PlatformPei/AmdSev.c b/OvmfPkg/PlatformPei/AmdSev.c
index 54b07622b4dd..9a20165db79e 100644
--- a/OvmfPkg/PlatformPei/AmdSev.c
+++ b/OvmfPkg/PlatformPei/AmdSev.c
@@ -34,7 +34,9 @@ AmdSevSnpInitialize (
   VOID
   )
 {
-  RETURN_STATUS        PcdStatus;
+  RETURN_STATUS                 PcdStatus;
+  EFI_PEI_HOB_POINTERS          Hob;
+  EFI_HOB_RESOURCE_DESCRIPTOR   *ResourceHob;
 
   if (!MemEncryptSevSnpIsEnabled ()) {
     return;
@@ -42,6 +44,22 @@ AmdSevSnpInitialize (
 
   PcdStatus = PcdSetBoolS (PcdSevSnpIsEnabled, TRUE);
   ASSERT_RETURN_ERROR (PcdStatus);
+
+  //
+  // Iterate through the system RAM and validate it.
+  //
+  for (Hob.Raw = GetHobList (); !END_OF_HOB_LIST (Hob); Hob.Raw = GET_NEXT_HOB (Hob)) {
+    if (Hob.Raw != NULL && GET_HOB_TYPE (Hob) == EFI_HOB_TYPE_RESOURCE_DESCRIPTOR) {
+      ResourceHob = Hob.ResourceDescriptor;
+
+      if (ResourceHob->ResourceType == EFI_RESOURCE_SYSTEM_MEMORY) {
+        MemEncryptSevSnpPreValidateSystemRam (
+          ResourceHob->PhysicalStart,
+          EFI_SIZE_TO_PAGES ((UINTN) ResourceHob->ResourceLength)
+          );
+      }
+    }
+  }
 }
 
 /**
@@ -204,6 +222,14 @@ AmdSevInitialize (
     return;
   }
 
+  //
+  // Check and perform SEV-SNP initialization if required. This need to be
+  // done before the GHCB page is made shared in the current page table. This
+  // is because the system RAM must be validated before it is made shared.
+  // The AmdSevSnpInitialize() validates the system RAM.
+  //
+  AmdSevSnpInitialize ();
+
   //
   // Set Memory Encryption Mask PCD
   //
@@ -264,9 +290,4 @@ AmdSevInitialize (
   // Check and perform SEV-ES initialization if required.
   //
   AmdSevEsInitialize ();
-
-  //
-  // Check and perform SEV-SNP initialization if required.
-  //
-  AmdSevSnpInitialize ();
 }
-- 
2.17.1


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

* [PATCH RFC v3 18/22] OvmfPkg/MemEncryptSevLib: Change the page state in the RMP table
  2021-05-26 23:10 [RESEND PATCH RFC v3 00/22] Add AMD Secure Nested Paging (SEV-SNP) support Brijesh Singh
                   ` (16 preceding siblings ...)
  2021-05-26 23:11 ` [PATCH RFC v3 17/22] OvmfPkg/PlatformPei: validate the system RAM when SNP is active Brijesh Singh
@ 2021-05-26 23:11 ` Brijesh Singh
  2021-05-26 23:11 ` [PATCH RFC v3 19/22] OvmfPkg/MemEncryptSevLib: skip page state change for Mmio address Brijesh Singh
                   ` (5 subsequent siblings)
  23 siblings, 0 replies; 57+ messages in thread
From: Brijesh Singh @ 2021-05-26 23:11 UTC (permalink / raw)
  To: James Bottomley, Min Xu, Jiewen Yao, Tom Lendacky, Jordan Justen,
	Laszlo Ersek, Erdem Aktas, Eric Dong, Ray Ni, Rahul Kumar, devel
  Cc: Brijesh Singh, Ard Biesheuvel

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

The MemEncryptSev{Set,Clear}PageEncMask() functions are used to set or
clear the memory encryption attribute in the page table. When SEV-SNP
is active, we also need to change the page state in the RMP table so that
it is in sync with the memory encryption attribute change.

Cc: James Bottomley <jejb@linux.ibm.com>
Cc: Min Xu <min.m.xu@intel.com>
Cc: Jiewen Yao <jiewen.yao@intel.com>
Cc: Tom Lendacky <thomas.lendacky@amd.com>
Cc: Jordan Justen <jordan.l.justen@intel.com>
Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
Cc: Laszlo Ersek <lersek@redhat.com>
Cc: Erdem Aktas <erdemaktas@google.com>
Signed-off-by: Brijesh Singh <brijesh.singh@amd.com>
---
 .../X64/PeiDxeVirtualMemory.c                 | 34 +++++++++++++++++++
 1 file changed, 34 insertions(+)

diff --git a/OvmfPkg/Library/BaseMemEncryptSevLib/X64/PeiDxeVirtualMemory.c b/OvmfPkg/Library/BaseMemEncryptSevLib/X64/PeiDxeVirtualMemory.c
index f146f6d61cc5..56db1e4b6ecf 100644
--- a/OvmfPkg/Library/BaseMemEncryptSevLib/X64/PeiDxeVirtualMemory.c
+++ b/OvmfPkg/Library/BaseMemEncryptSevLib/X64/PeiDxeVirtualMemory.c
@@ -17,6 +17,7 @@
 #include <Register/Cpuid.h>
 
 #include "VirtualMemory.h"
+#include "SnpPageStateChange.h"
 
 STATIC BOOLEAN mAddressEncMaskChecked = FALSE;
 STATIC UINT64  mAddressEncMask;
@@ -695,10 +696,12 @@ SetMemoryEncDec (
   PAGE_MAP_AND_DIRECTORY_POINTER *PageDirectoryPointerEntry;
   PAGE_TABLE_1G_ENTRY            *PageDirectory1GEntry;
   PAGE_TABLE_ENTRY               *PageDirectory2MEntry;
+  PHYSICAL_ADDRESS               OrigPhysicalAddress;
   PAGE_TABLE_4K_ENTRY            *PageTableEntry;
   UINT64                         PgTableMask;
   UINT64                         AddressEncMask;
   BOOLEAN                        IsWpEnabled;
+  UINTN                          OrigLength;
   RETURN_STATUS                  Status;
 
   //
@@ -751,6 +754,22 @@ SetMemoryEncDec (
 
   Status = EFI_SUCCESS;
 
+  //
+  // To maintain the security gurantees we must set the page to shared in the RMP
+  // table before clearing the memory encryption mask from the current page table.
+  //
+  // The InternalSetPageState() is used for setting the page state in the RMP table.
+  //
+  if ((Mode == ClearCBit) && MemEncryptSevSnpIsEnabled ()) {
+    InternalSetPageState (PhysicalAddress, EFI_SIZE_TO_PAGES (Length), SevSnpPageShared, FALSE);
+  }
+
+  //
+  // Save the specified length and physical address (we need it later).
+  //
+  OrigLength = Length;
+  OrigPhysicalAddress = PhysicalAddress;
+
   while (Length != 0)
   {
     //
@@ -923,6 +942,21 @@ SetMemoryEncDec (
   //
   CpuFlushTlb();
 
+  //
+  // SEV-SNP requires that all the private pages (i.e pages mapped encrypted) must be
+  // added in the RMP table before the access.
+  //
+  // The InternalSetPageState() is used for setting the page state in the RMP table.
+  //
+  if ((Mode == SetCBit) && MemEncryptSevSnpIsEnabled ()) {
+    InternalSetPageState (
+      OrigPhysicalAddress,
+      EFI_SIZE_TO_PAGES (OrigLength),
+      SevSnpPagePrivate,
+      FALSE
+      );
+  }
+
 Done:
   //
   // Restore page table write protection, if any.
-- 
2.17.1


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

* [PATCH RFC v3 19/22] OvmfPkg/MemEncryptSevLib: skip page state change for Mmio address
  2021-05-26 23:10 [RESEND PATCH RFC v3 00/22] Add AMD Secure Nested Paging (SEV-SNP) support Brijesh Singh
                   ` (17 preceding siblings ...)
  2021-05-26 23:11 ` [PATCH RFC v3 18/22] OvmfPkg/MemEncryptSevLib: Change the page state in the RMP table Brijesh Singh
@ 2021-05-26 23:11 ` Brijesh Singh
  2021-05-26 23:11 ` [PATCH RFC v3 20/22] OvmfPkg/AmdSev: expose the SNP reserved pages through configuration table Brijesh Singh
                   ` (4 subsequent siblings)
  23 siblings, 0 replies; 57+ messages in thread
From: Brijesh Singh @ 2021-05-26 23:11 UTC (permalink / raw)
  To: James Bottomley, Min Xu, Jiewen Yao, Tom Lendacky, Jordan Justen,
	Laszlo Ersek, Erdem Aktas, Eric Dong, Ray Ni, Rahul Kumar, devel
  Cc: Brijesh Singh, Ard Biesheuvel

The SetMemoryEncDec() is used by the higher level routines to set or clear
the page encryption mask for system RAM and Mmio address. When SEV-SNP is
active, in addition to set/clear page mask it also updates the RMP table.
The RMP table updates are required for the system RAM address and not
the Mmio address.

Add a new parameter in SetMemoryEncDec() to tell whether the specified
address is Mmio. If its Mmio then skip the page state change in the RMP
table.

Cc: James Bottomley <jejb@linux.ibm.com>
Cc: Min Xu <min.m.xu@intel.com>
Cc: Jiewen Yao <jiewen.yao@intel.com>
Cc: Tom Lendacky <thomas.lendacky@amd.com>
Cc: Jordan Justen <jordan.l.justen@intel.com>
Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
Cc: Laszlo Ersek <lersek@redhat.com>
Cc: Erdem Aktas <erdemaktas@google.com>
Signed-off-by: Brijesh Singh <brijesh.singh@amd.com>
---
 .../X64/PeiDxeVirtualMemory.c                 | 20 ++++++++++++-------
 1 file changed, 13 insertions(+), 7 deletions(-)

diff --git a/OvmfPkg/Library/BaseMemEncryptSevLib/X64/PeiDxeVirtualMemory.c b/OvmfPkg/Library/BaseMemEncryptSevLib/X64/PeiDxeVirtualMemory.c
index 56db1e4b6ecf..0bb86d768017 100644
--- a/OvmfPkg/Library/BaseMemEncryptSevLib/X64/PeiDxeVirtualMemory.c
+++ b/OvmfPkg/Library/BaseMemEncryptSevLib/X64/PeiDxeVirtualMemory.c
@@ -673,6 +673,7 @@ InternalMemEncryptSevCreateIdentityMap1G (
   @param[in]  Mode                    Set or Clear mode
   @param[in]  CacheFlush              Flush the caches before applying the
                                       encryption mask
+  @param[in]  Mmio                    The physical address specified is Mmio
 
   @retval RETURN_SUCCESS              The attributes were cleared for the
                                       memory region.
@@ -688,7 +689,8 @@ SetMemoryEncDec (
   IN    PHYSICAL_ADDRESS         PhysicalAddress,
   IN    UINTN                    Length,
   IN    MAP_RANGE_MODE           Mode,
-  IN    BOOLEAN                  CacheFlush
+  IN    BOOLEAN                  CacheFlush,
+  IN    BOOLEAN                  Mmio
   )
 {
   PAGE_MAP_AND_DIRECTORY_POINTER *PageMapLevel4Entry;
@@ -711,14 +713,15 @@ SetMemoryEncDec (
 
   DEBUG ((
     DEBUG_VERBOSE,
-    "%a:%a: Cr3Base=0x%Lx Physical=0x%Lx Length=0x%Lx Mode=%a CacheFlush=%u\n",
+    "%a:%a: Cr3Base=0x%Lx Physical=0x%Lx Length=0x%Lx Mode=%a CacheFlush=%u Mmio=%u\n",
     gEfiCallerBaseName,
     __FUNCTION__,
     Cr3BaseAddress,
     PhysicalAddress,
     (UINT64)Length,
     (Mode == SetCBit) ? "Encrypt" : "Decrypt",
-    (UINT32)CacheFlush
+    (UINT32)CacheFlush,
+    (UINT32)Mmio
     ));
 
   //
@@ -760,7 +763,7 @@ SetMemoryEncDec (
   //
   // The InternalSetPageState() is used for setting the page state in the RMP table.
   //
-  if ((Mode == ClearCBit) && MemEncryptSevSnpIsEnabled ()) {
+  if (!Mmio && (Mode == ClearCBit) && MemEncryptSevSnpIsEnabled ()) {
     InternalSetPageState (PhysicalAddress, EFI_SIZE_TO_PAGES (Length), SevSnpPageShared, FALSE);
   }
 
@@ -998,7 +1001,8 @@ InternalMemEncryptSevSetMemoryDecrypted (
            PhysicalAddress,
            Length,
            ClearCBit,
-           TRUE
+           TRUE,
+           FALSE
            );
 }
 
@@ -1031,7 +1035,8 @@ InternalMemEncryptSevSetMemoryEncrypted (
            PhysicalAddress,
            Length,
            SetCBit,
-           TRUE
+           TRUE,
+           FALSE
            );
 }
 
@@ -1064,6 +1069,7 @@ InternalMemEncryptSevClearMmioPageEncMask (
            PhysicalAddress,
            Length,
            ClearCBit,
-           FALSE
+           FALSE,
+           TRUE
            );
 }
-- 
2.17.1


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

* [PATCH RFC v3 20/22] OvmfPkg/AmdSev: expose the SNP reserved pages through configuration table
  2021-05-26 23:10 [RESEND PATCH RFC v3 00/22] Add AMD Secure Nested Paging (SEV-SNP) support Brijesh Singh
                   ` (18 preceding siblings ...)
  2021-05-26 23:11 ` [PATCH RFC v3 19/22] OvmfPkg/MemEncryptSevLib: skip page state change for Mmio address Brijesh Singh
@ 2021-05-26 23:11 ` Brijesh Singh
  2021-05-26 23:11 ` [PATCH RFC v3 21/22] UefiCpuPkg/MpInitLib: Use SEV-SNP AP Creation NAE event to launch APs Brijesh Singh
                   ` (3 subsequent siblings)
  23 siblings, 0 replies; 57+ messages in thread
From: Brijesh Singh @ 2021-05-26 23:11 UTC (permalink / raw)
  To: James Bottomley, Min Xu, Jiewen Yao, Tom Lendacky, Jordan Justen,
	Laszlo Ersek, Erdem Aktas, Eric Dong, Ray Ni, Rahul Kumar, devel
  Cc: Brijesh Singh, Ard Biesheuvel

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

Now that both the secrets and cpuid pages are reserved in the HOB,
extract the location details through fixed PCD and make it available
to the guest OS through the configuration table.

Cc: James Bottomley <jejb@linux.ibm.com>
Cc: Min Xu <min.m.xu@intel.com>
Cc: Jiewen Yao <jiewen.yao@intel.com>
Cc: Tom Lendacky <thomas.lendacky@amd.com>
Cc: Jordan Justen <jordan.l.justen@intel.com>
Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
Cc: Laszlo Ersek <lersek@redhat.com>
Cc: Erdem Aktas <erdemaktas@google.com>
Signed-off-by: Brijesh Singh <brijesh.singh@amd.com>
---
 OvmfPkg/OvmfPkg.dec                           |  1 +
 OvmfPkg/AmdSev/SecretDxe/SecretDxe.inf        |  4 ++++
 .../Guid/ConfidentialComputingSecret.h        | 18 +++++++++++++++
 OvmfPkg/AmdSev/SecretDxe/SecretDxe.c          | 22 +++++++++++++++++++
 4 files changed, 45 insertions(+)

diff --git a/OvmfPkg/OvmfPkg.dec b/OvmfPkg/OvmfPkg.dec
index 4da2d2de9df0..89476c6a68d2 100644
--- a/OvmfPkg/OvmfPkg.dec
+++ b/OvmfPkg/OvmfPkg.dec
@@ -126,6 +126,7 @@ [Guids]
   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}}
+  gConfidentialComputingBlobGuid        = {0x067b1f5f, 0xcf26, 0x44c5, {0x85, 0x54, 0x93, 0xd7, 0x77, 0x91, 0x2d, 0x42}}
 
 [Ppis]
   # PPI whose presence in the PPI database signals that the TPM base address
diff --git a/OvmfPkg/AmdSev/SecretDxe/SecretDxe.inf b/OvmfPkg/AmdSev/SecretDxe/SecretDxe.inf
index 40bda7ff846c..d15194b368f5 100644
--- a/OvmfPkg/AmdSev/SecretDxe/SecretDxe.inf
+++ b/OvmfPkg/AmdSev/SecretDxe/SecretDxe.inf
@@ -23,13 +23,17 @@ [Packages]
   MdePkg/MdePkg.dec
 
 [LibraryClasses]
+  MemEncryptSevLib
   UefiBootServicesTableLib
   UefiDriverEntryPoint
 
 [Guids]
   gConfidentialComputingSecretGuid
+  gConfidentialComputingBlobGuid
 
 [FixedPcd]
+  gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSnpCpuidBase
+  gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSnpCpuidSize
   gUefiOvmfPkgTokenSpaceGuid.PcdSevLaunchSecretBase
   gUefiOvmfPkgTokenSpaceGuid.PcdSevLaunchSecretSize
 
diff --git a/OvmfPkg/Include/Guid/ConfidentialComputingSecret.h b/OvmfPkg/Include/Guid/ConfidentialComputingSecret.h
index 7026fc5b089f..aa1a3b015437 100644
--- a/OvmfPkg/Include/Guid/ConfidentialComputingSecret.h
+++ b/OvmfPkg/Include/Guid/ConfidentialComputingSecret.h
@@ -18,11 +18,29 @@
     { 0xae, 0x11, 0xb5, 0x1c, 0x7d, 0x33, 0x64, 0x47 }, \
   }
 
+#define CONFIDENTIAL_COMPUTING_BLOB_GUID                \
+  { 0x067b1f5f,                                         \
+    0xcf26,                                             \
+    0x44c5,                                             \
+    { 0x85, 0x54, 0x93, 0xd7, 0x77, 0x91, 0x2d, 0x42 }, \
+  }
+
 typedef struct {
   UINT64 Base;
   UINT64 Size;
 } CONFIDENTIAL_COMPUTING_SECRET_LOCATION;
 
+typedef struct {
+  UINT32  Header;
+  UINT16  Version;
+  UINT16  Reserved1;
+  UINT64  SecretsPhysicalAddress;
+  UINT32  SecretsSize;
+  UINT64  CpuidPhysicalAddress;
+  UINT32  CpuidLSize;
+} CONFIDENTIAL_COMPUTING_BLOB_LOCATION;
+
 extern EFI_GUID gConfidentialComputingSecretGuid;
+extern EFI_GUID gConfidentialComputingBlobGuid;
 
 #endif // SEV_LAUNCH_SECRET_H_
diff --git a/OvmfPkg/AmdSev/SecretDxe/SecretDxe.c b/OvmfPkg/AmdSev/SecretDxe/SecretDxe.c
index 308022b5b25e..0c0f511d4ca0 100644
--- a/OvmfPkg/AmdSev/SecretDxe/SecretDxe.c
+++ b/OvmfPkg/AmdSev/SecretDxe/SecretDxe.c
@@ -6,6 +6,7 @@
 **/
 #include <PiDxe.h>
 #include <Library/UefiBootServicesTableLib.h>
+#include <Library/MemEncryptSevLib.h>
 #include <Guid/ConfidentialComputingSecret.h>
 
 STATIC CONFIDENTIAL_COMPUTING_SECRET_LOCATION mSecretDxeTable = {
@@ -13,6 +14,16 @@ STATIC CONFIDENTIAL_COMPUTING_SECRET_LOCATION mSecretDxeTable = {
   FixedPcdGet32 (PcdSevLaunchSecretSize),
 };
 
+STATIC CONFIDENTIAL_COMPUTING_BLOB_LOCATION mSnpBootDxeTable = {
+  SIGNATURE_32('A','M','D','E'),
+  1,
+  0,
+  (UINT64)(UINTN) FixedPcdGet32 (PcdSevLaunchSecretBase),
+  FixedPcdGet32 (PcdSevLaunchSecretSize),
+  (UINT64)(UINTN) FixedPcdGet32 (PcdOvmfSnpCpuidBase),
+  FixedPcdGet32 (PcdOvmfSnpCpuidSize),
+};
+
 EFI_STATUS
 EFIAPI
 InitializeSecretDxe(
@@ -20,6 +31,17 @@ InitializeSecretDxe(
   IN EFI_SYSTEM_TABLE     *SystemTable
   )
 {
+  //
+  // If its SEV-SNP active guest then install the CONFIDENTIAL_COMPUTING_BLOB.
+  // It contains the location for both the Secrets and CPUID page.
+  //
+  if (MemEncryptSevSnpIsEnabled ()) {
+    return gBS->InstallConfigurationTable (
+                  &gConfidentialComputingBlobGuid,
+                  &mSnpBootDxeTable
+                  );
+  }
+
   return gBS->InstallConfigurationTable (
                 &gConfidentialComputingSecretGuid,
                 &mSecretDxeTable
-- 
2.17.1


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

* [PATCH RFC v3 21/22] UefiCpuPkg/MpInitLib: Use SEV-SNP AP Creation NAE event to launch APs
  2021-05-26 23:10 [RESEND PATCH RFC v3 00/22] Add AMD Secure Nested Paging (SEV-SNP) support Brijesh Singh
                   ` (19 preceding siblings ...)
  2021-05-26 23:11 ` [PATCH RFC v3 20/22] OvmfPkg/AmdSev: expose the SNP reserved pages through configuration table Brijesh Singh
@ 2021-05-26 23:11 ` Brijesh Singh
  2021-05-26 23:11 ` [PATCH RFC v3 22/22] MdePkg/GHCB: increase the GHCB protocol max version Brijesh Singh
                   ` (2 subsequent siblings)
  23 siblings, 0 replies; 57+ messages in thread
From: Brijesh Singh @ 2021-05-26 23:11 UTC (permalink / raw)
  To: James Bottomley, Min Xu, Jiewen Yao, Tom Lendacky, Jordan Justen,
	Laszlo Ersek, Erdem Aktas, Eric Dong, Ray Ni, Rahul Kumar, devel

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

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

Use the SEV-SNP AP Creation NAE event to create and launch APs under
SEV-SNP. This capability will be advertised in the SEV Hypervisor
Feature Support PCD (PcdSevEsHypervisorFeatures).

Cc: Eric Dong <eric.dong@intel.com>
Cc: Ray Ni <ray.ni@intel.com>
Cc: Laszlo Ersek <lersek@redhat.com>
Cc: Rahul Kumar <rahul1.kumar@intel.com>
Signed-off-by: Tom Lendacky <thomas.lendacky@amd.com>
---
 UefiCpuPkg/Library/MpInitLib/DxeMpInitLib.inf |   3 +
 UefiCpuPkg/Library/MpInitLib/PeiMpInitLib.inf |   5 +-
 UefiCpuPkg/Library/MpInitLib/MpLib.h          |  17 ++
 UefiCpuPkg/Library/MpInitLib/DxeMpLib.c       |  11 +-
 .../MpInitLib/Ia32/SevSnpRmpAdjustInternal.c  |  31 ++
 UefiCpuPkg/Library/MpInitLib/MpLib.c          | 274 ++++++++++++++++--
 .../MpInitLib/X64/SevSnpRmpAdjustInternal.c   |  44 +++
 7 files changed, 360 insertions(+), 25 deletions(-)
 create mode 100644 UefiCpuPkg/Library/MpInitLib/Ia32/SevSnpRmpAdjustInternal.c
 create mode 100644 UefiCpuPkg/Library/MpInitLib/X64/SevSnpRmpAdjustInternal.c

diff --git a/UefiCpuPkg/Library/MpInitLib/DxeMpInitLib.inf b/UefiCpuPkg/Library/MpInitLib/DxeMpInitLib.inf
index 48d7dfa4450f..b9ce05e81b54 100644
--- a/UefiCpuPkg/Library/MpInitLib/DxeMpInitLib.inf
+++ b/UefiCpuPkg/Library/MpInitLib/DxeMpInitLib.inf
@@ -23,9 +23,11 @@ [Defines]
 
 [Sources.IA32]
   Ia32/MpFuncs.nasm
+  Ia32/SevSnpRmpAdjustInternal.c
 
 [Sources.X64]
   X64/MpFuncs.nasm
+  X64/SevSnpRmpAdjustInternal.c
 
 [Sources.common]
   MpEqu.inc
@@ -72,6 +74,7 @@ [Pcd]
   gUefiCpuPkgTokenSpaceGuid.PcdCpuApLoopMode                           ## CONSUMES
   gUefiCpuPkgTokenSpaceGuid.PcdCpuApTargetCstate                       ## SOMETIMES_CONSUMES
   gUefiCpuPkgTokenSpaceGuid.PcdCpuApStatusCheckIntervalInMicroSeconds  ## CONSUMES
+  gUefiCpuPkgTokenSpaceGuid.PcdGhcbHypervisorFeatures                  ## CONSUMES
   gUefiCpuPkgTokenSpaceGuid.PcdSevEsIsEnabled                          ## CONSUMES
   gUefiCpuPkgTokenSpaceGuid.PcdSevEsWorkAreaBase                       ## SOMETIMES_CONSUMES
   gEfiMdeModulePkgTokenSpaceGuid.PcdCpuStackGuard                      ## CONSUMES
diff --git a/UefiCpuPkg/Library/MpInitLib/PeiMpInitLib.inf b/UefiCpuPkg/Library/MpInitLib/PeiMpInitLib.inf
index ab8279df596f..35057ac07cbb 100644
--- a/UefiCpuPkg/Library/MpInitLib/PeiMpInitLib.inf
+++ b/UefiCpuPkg/Library/MpInitLib/PeiMpInitLib.inf
@@ -23,9 +23,11 @@ [Defines]
 
 [Sources.IA32]
   Ia32/MpFuncs.nasm
+  Ia32/SevSnpRmpAdjustInternal.c
 
 [Sources.X64]
   X64/MpFuncs.nasm
+  X64/SevSnpRmpAdjustInternal.c
 
 [Sources.common]
   MpEqu.inc
@@ -62,10 +64,11 @@ [Pcd]
   gUefiCpuPkgTokenSpaceGuid.PcdCpuMicrocodePatchRegionSize         ## CONSUMES
   gUefiCpuPkgTokenSpaceGuid.PcdCpuApLoopMode                       ## CONSUMES
   gUefiCpuPkgTokenSpaceGuid.PcdCpuApTargetCstate                   ## SOMETIMES_CONSUMES
+  gUefiCpuPkgTokenSpaceGuid.PcdGhcbHypervisorFeatures              ## CONSUMES
   gUefiCpuPkgTokenSpaceGuid.PcdSevEsIsEnabled                      ## CONSUMES
   gUefiCpuPkgTokenSpaceGuid.PcdSevEsWorkAreaBase                   ## SOMETIMES_CONSUMES
-  gEfiMdeModulePkgTokenSpaceGuid.PcdGhcbBase                       ## CONSUMES
   gUefiCpuPkgTokenSpaceGuid.PcdSevSnpIsEnabled                     ## CONSUMES
+  gEfiMdeModulePkgTokenSpaceGuid.PcdGhcbBase                       ## CONSUMES
 
 [Ppis]
   gEdkiiPeiShadowMicrocodePpiGuid        ## SOMETIMES_CONSUMES
diff --git a/UefiCpuPkg/Library/MpInitLib/MpLib.h b/UefiCpuPkg/Library/MpInitLib/MpLib.h
index 4abaa2243d0a..b49a60ac0ce5 100644
--- a/UefiCpuPkg/Library/MpInitLib/MpLib.h
+++ b/UefiCpuPkg/Library/MpInitLib/MpLib.h
@@ -15,6 +15,7 @@
 
 #include <Register/Intel/Cpuid.h>
 #include <Register/Amd/Cpuid.h>
+#include <Register/Amd/Ghcb.h>
 #include <Register/Intel/Msr.h>
 #include <Register/Intel/LocalApic.h>
 #include <Register/Intel/Microcode.h>
@@ -146,6 +147,7 @@ typedef struct {
   UINT8                          PlatformId;
   UINT64                         MicrocodeEntryAddr;
   UINT32                         MicrocodeRevision;
+  SEV_ES_SAVE_AREA               *SevEsSaveArea;
 } CPU_AP_DATA;
 
 //
@@ -289,6 +291,7 @@ struct _CPU_MP_DATA {
 
   BOOLEAN                        SevEsIsEnabled;
   BOOLEAN                        SevSnpIsEnabled;
+  BOOLEAN                        UseSevEsAPMethod;
   UINTN                          SevEsAPBuffer;
   UINTN                          SevEsAPResetStackStart;
   CPU_MP_DATA                    *NewCpuMpData;
@@ -743,5 +746,19 @@ PlatformShadowMicrocode (
   IN OUT CPU_MP_DATA             *CpuMpData
   );
 
+/**
+  Issue RMPADJUST to adjust the attributes of an SEV-SNP page.
+
+  @param[in]  PageAddress
+  @param[in]  VmsaPage
+
+  @return  RMPADJUST return value
+**/
+UINT32
+SevSnpRmpAdjust (
+  IN  EFI_PHYSICAL_ADDRESS  PageAddress,
+  IN  BOOLEAN               VmsaPage
+  );
+
 #endif
 
diff --git a/UefiCpuPkg/Library/MpInitLib/DxeMpLib.c b/UefiCpuPkg/Library/MpInitLib/DxeMpLib.c
index 7839c249760e..1e3e71766611 100644
--- a/UefiCpuPkg/Library/MpInitLib/DxeMpLib.c
+++ b/UefiCpuPkg/Library/MpInitLib/DxeMpLib.c
@@ -88,7 +88,12 @@ GetWakeupBuffer (
   EFI_PHYSICAL_ADDRESS    StartAddress;
   EFI_MEMORY_TYPE         MemoryType;
 
-  if (PcdGetBool (PcdSevEsIsEnabled)) {
+  //
+  // An SEV-ES-only guest requires the memory to be reserved. SEV-SNP, which
+  // is also considered SEV-ES, uses a different AP startup method, though,
+  // which does not have the same requirement.
+  //
+  if (PcdGetBool (PcdSevEsIsEnabled) && !PcdGetBool (PcdSevSnpIsEnabled)) {
     MemoryType = EfiReservedMemoryType;
   } else {
     MemoryType = EfiBootServicesData;
@@ -356,7 +361,7 @@ RelocateApLoop (
   MpInitLibWhoAmI (&ProcessorNumber);
   CpuMpData    = GetCpuMpData ();
   MwaitSupport = IsMwaitSupport ();
-  if (CpuMpData->SevEsIsEnabled) {
+  if (CpuMpData->UseSevEsAPMethod) {
     StackStart = CpuMpData->SevEsAPResetStackStart;
   } else {
     StackStart = mReservedTopOfApStack;
@@ -405,7 +410,7 @@ MpInitChangeApLoopCallback (
     CpuPause ();
   }
 
-  if (CpuMpData->SevEsIsEnabled && (CpuMpData->WakeupBuffer != (UINTN) -1)) {
+  if (CpuMpData->UseSevEsAPMethod && (CpuMpData->WakeupBuffer != (UINTN) -1)) {
     //
     // There are APs present. Re-use reserved memory area below 1MB from
     // WakeupBuffer as the area to be used for transitioning to 16-bit mode
diff --git a/UefiCpuPkg/Library/MpInitLib/Ia32/SevSnpRmpAdjustInternal.c b/UefiCpuPkg/Library/MpInitLib/Ia32/SevSnpRmpAdjustInternal.c
new file mode 100644
index 000000000000..167628b696f2
--- /dev/null
+++ b/UefiCpuPkg/Library/MpInitLib/Ia32/SevSnpRmpAdjustInternal.c
@@ -0,0 +1,31 @@
+/** @file
+
+  RMPADJUST helper function.
+
+  Copyright (c) 2021, AMD Incorporated. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include "MpLib.h"
+
+/**
+  Issue RMPADJUST to adjust the attributes of an SEV-SNP page.
+
+  @param[in]  PageAddress
+  @param[in]  VmsaPage
+
+  @return  RMPADJUST return value
+**/
+UINT32
+SevSnpRmpAdjust (
+  IN  EFI_PHYSICAL_ADDRESS  PageAddress,
+  IN  BOOLEAN               VmsaPage
+  )
+{
+  //
+  // RMPADJUST is not supported in 32-bit mode
+  //
+  return RETURN_UNSUPPORTED;
+}
diff --git a/UefiCpuPkg/Library/MpInitLib/MpLib.c b/UefiCpuPkg/Library/MpInitLib/MpLib.c
index 7cbcce101414..5a06e21a2830 100644
--- a/UefiCpuPkg/Library/MpInitLib/MpLib.c
+++ b/UefiCpuPkg/Library/MpInitLib/MpLib.c
@@ -15,7 +15,6 @@
 
 EFI_GUID mCpuInitMpLibHobGuid = CPU_INIT_MP_LIB_HOB_GUID;
 
-
 /**
   The function will check if BSP Execute Disable is enabled.
 
@@ -297,8 +296,8 @@ GetApLoopMode (
 
     if (PcdGetBool (PcdSevEsIsEnabled)) {
       //
-      // For SEV-ES, force AP in Hlt-loop mode in order to use the GHCB
-      // protocol for starting APs
+      // For SEV-ES (SEV-SNP is also considered SEV-ES), force AP in Hlt-loop
+      // mode in order to use the GHCB protocol for starting APs
       //
       ApLoopMode = ApInHltLoop;
     }
@@ -869,7 +868,7 @@ ApWakeupFunction (
       // to allow the APs to issue an AP_RESET_HOLD before the BSP possibly
       // performs another INIT-SIPI-SIPI sequence.
       //
-      if (!CpuMpData->SevEsIsEnabled) {
+      if (!CpuMpData->UseSevEsAPMethod) {
         InterlockedDecrement ((UINT32 *) &CpuMpData->MpCpuExchangeInfo->NumApsExecuting);
       }
     }
@@ -883,7 +882,7 @@ ApWakeupFunction (
       //
       while (TRUE) {
         DisableInterrupts ();
-        if (CpuMpData->SevEsIsEnabled) {
+        if (CpuMpData->UseSevEsAPMethod) {
           MSR_SEV_ES_GHCB_REGISTER  Msr;
           GHCB                      *Ghcb;
           UINT64                    Status;
@@ -1167,9 +1166,11 @@ GetApResetVectorSize (
 
   //
   // The AP reset stack is only used by SEV-ES guests. Do not add to the
-  // allocation if SEV-ES is not enabled.
+  // allocation if SEV-ES is not enabled. An SEV-SNP guest is also considered
+  // an SEV-ES guest, but uses a different method of AP startup, eliminating
+  // the need for the allocation.
   //
-  if (PcdGetBool (PcdSevEsIsEnabled)) {
+  if (PcdGetBool (PcdSevEsIsEnabled) && !PcdGetBool (PcdSevSnpIsEnabled)) {
     //
     // Stack location is based on APIC ID, so use the total number of
     // processors for calculating the total stack area.
@@ -1231,7 +1232,7 @@ FreeResetVector (
   // perform the restore as this will overwrite memory which has data
   // needed by SEV-ES.
   //
-  if (!CpuMpData->SevEsIsEnabled) {
+  if (!CpuMpData->UseSevEsAPMethod) {
     RestoreWakeupBuffer (CpuMpData);
   }
 }
@@ -1248,7 +1249,7 @@ AllocateSevEsAPMemory (
 {
   if (CpuMpData->SevEsAPBuffer == (UINTN) -1) {
     CpuMpData->SevEsAPBuffer =
-      CpuMpData->SevEsIsEnabled ? GetSevEsAPMemory () : 0;
+      CpuMpData->UseSevEsAPMethod ? GetSevEsAPMemory () : 0;
   }
 }
 
@@ -1301,6 +1302,222 @@ SetSevEsJumpTable (
   JmpFar->Segment = (UINT16) (SipiVector >> 4);
 }
 
+/**
+  Create an SEV-SNP AP save area (VMSA) for use in running the vCPU.
+
+  @param[in]  CpuMpData        Pointer to CPU MP Data
+  @param[in]  CpuData          Pointer to CPU AP Data
+  @param[in]  ApicId           APIC ID of the vCPU
+**/
+STATIC
+VOID
+SevSnpCreateSaveArea (
+  IN CPU_MP_DATA               *CpuMpData,
+  IN CPU_AP_DATA               *CpuData,
+  UINT32                       ApicId
+  )
+{
+  SEV_ES_SAVE_AREA          *SaveArea;
+  IA32_CR0                  ApCr0;
+  IA32_CR0                  ResetCr0;
+  IA32_CR4                  ApCr4;
+  IA32_CR4                  ResetCr4;
+  UINTN                     StartIp;
+  UINT8                     SipiVector;
+  UINT32                    RmpAdjustStatus;
+  UINT64                    VmgExitStatus;
+  MSR_SEV_ES_GHCB_REGISTER  Msr;
+  GHCB                      *Ghcb;
+  BOOLEAN                   InterruptState;
+  UINT64                    ExitInfo1;
+  UINT64                    ExitInfo2;
+
+  //
+  // Allocate a single page for the SEV-ES Save Area and initialize it.
+  //
+  SaveArea = AllocateReservedPages (1);
+  if (!SaveArea) {
+    return;
+  }
+  ZeroMem (SaveArea, EFI_PAGE_SIZE);
+
+  //
+  // Propogate the CR0.NW and CR0.CD setting to the AP
+  //
+  ResetCr0.UintN = 0x00000010;
+  ApCr0.UintN = CpuData->VolatileRegisters.Cr0;
+  if (ApCr0.Bits.NW) {
+    ResetCr0.Bits.NW = 1;
+  }
+  if (ApCr0.Bits.CD) {
+    ResetCr0.Bits.CD = 1;
+  }
+
+  //
+  // Propagate the CR4.MCE setting to the AP
+  //
+  ResetCr4.UintN = 0;
+  ApCr4.UintN = CpuData->VolatileRegisters.Cr4;
+  if (ApCr4.Bits.MCE) {
+    ResetCr4.Bits.MCE = 1;
+  }
+
+  //
+  // Convert the start IP into a SIPI Vector
+  //
+  StartIp = CpuMpData->MpCpuExchangeInfo->BufferStart;
+  SipiVector = (UINT8) (StartIp >> 12);
+
+  //
+  // Set the CS:RIP value based on the start IP
+  //
+  SaveArea->Cs.Base = SipiVector << 12;
+  SaveArea->Cs.Selector = SipiVector << 8;
+  SaveArea->Cs.Limit = 0xFFFF;
+  SaveArea->Cs.Attributes.Bits.Present = 1;
+  SaveArea->Cs.Attributes.Bits.Sbit = 1;
+  SaveArea->Cs.Attributes.Bits.Type = SEV_ES_RESET_CODE_SEGMENT_TYPE;
+  SaveArea->Rip = StartIp & 0xFFF;
+
+  //
+  // Set the remaining values as defined in APM for INIT
+  //
+  SaveArea->Ds.Limit = 0xFFFF;
+  SaveArea->Ds.Attributes.Bits.Present = 1;
+  SaveArea->Ds.Attributes.Bits.Sbit = 1;
+  SaveArea->Ds.Attributes.Bits.Type = SEV_ES_RESET_DATA_SEGMENT_TYPE;
+  SaveArea->Es = SaveArea->Ds;
+  SaveArea->Fs = SaveArea->Ds;
+  SaveArea->Gs = SaveArea->Ds;
+  SaveArea->Ss = SaveArea->Ds;
+
+  SaveArea->Gdtr.Limit = 0xFFFF;
+  SaveArea->Ldtr.Limit = 0xFFFF;
+  SaveArea->Ldtr.Attributes.Bits.Present = 1;
+  SaveArea->Ldtr.Attributes.Bits.Type = SEV_ES_RESET_LDT_TYPE;
+  SaveArea->Idtr.Limit = 0xFFFF;
+  SaveArea->Tr.Limit = 0xFFFF;
+  SaveArea->Ldtr.Attributes.Bits.Present = 1;
+  SaveArea->Ldtr.Attributes.Bits.Type = SEV_ES_RESET_TSS_TYPE;
+
+  SaveArea->Efer   = 0x1000;
+  SaveArea->Cr4    = ResetCr4.UintN;
+  SaveArea->Cr0    = ResetCr0.UintN;
+  SaveArea->Dr7    = 0x0400;
+  SaveArea->Dr6    = 0xFFFF0FF0;
+  SaveArea->Rflags = 0x0002;
+  SaveArea->GPat   = 0x0007040600070406ULL;
+  SaveArea->XCr0   = 0x0001;
+  SaveArea->Mxcsr  = 0x1F80;
+  SaveArea->X87Ftw = 0x5555;
+  SaveArea->X87Fcw = 0x0040;
+
+  //
+  // Set the SEV-SNP specific fields for the save area:
+  //   VMPL - always VMPL0
+  //   SEV_FEATURES - equivalent to the SEV_STATUS MSR right shifted 2 bits
+  //
+  SaveArea->Vmpl        = 0;
+  SaveArea->SevFeatures = AsmReadMsr64 (MSR_SEV_STATUS) >> 2;
+
+  //
+  // To turn the page into a recognized VMSA page, issue RMPADJUST:
+  //   Target VMPL but numerically higher than current VMPL
+  //   Target PermissionMask is not used
+  //
+  RmpAdjustStatus = SevSnpRmpAdjust (
+                      (EFI_PHYSICAL_ADDRESS) (UINTN) SaveArea,
+                      TRUE
+                      );
+  ASSERT (RmpAdjustStatus == 0);
+
+  ExitInfo1 = (UINT64) ApicId << 32;
+  ExitInfo1 |= SVM_VMGEXIT_SNP_AP_CREATE;
+  ExitInfo2 = (UINT64) (UINTN) SaveArea;
+
+  Msr.GhcbPhysicalAddress = AsmReadMsr64 (MSR_SEV_ES_GHCB);
+  Ghcb = Msr.Ghcb;
+
+  VmgInit (Ghcb, &InterruptState);
+  Ghcb->SaveArea.Rax = SaveArea->SevFeatures;
+  VmgSetOffsetValid (Ghcb, GhcbRax);
+  VmgExitStatus = VmgExit (
+                    Ghcb,
+                    SVM_EXIT_SNP_AP_CREATION,
+                    ExitInfo1,
+                    ExitInfo2
+                    );
+  VmgDone (Ghcb, InterruptState);
+
+  ASSERT (VmgExitStatus == 0);
+  if (VmgExitStatus != 0) {
+    RmpAdjustStatus = SevSnpRmpAdjust (
+                        (EFI_PHYSICAL_ADDRESS) (UINTN) SaveArea,
+                        FALSE
+                        );
+    if (RmpAdjustStatus == 0) {
+      FreePages (SaveArea, 1);
+    } else {
+      DEBUG ((DEBUG_INFO, "SEV-SNP: RMPADJUST failed, leaking VMSA page\n"));
+    }
+
+    SaveArea = NULL;
+  }
+
+  if (CpuData->SevEsSaveArea) {
+    RmpAdjustStatus = SevSnpRmpAdjust (
+                        (EFI_PHYSICAL_ADDRESS) (UINTN) CpuData->SevEsSaveArea,
+                        FALSE
+                        );
+    if (RmpAdjustStatus == 0) {
+      FreePages (CpuData->SevEsSaveArea, 1);
+    } else {
+      DEBUG ((DEBUG_INFO, "SEV-SNP: RMPADJUST failed, leaking VMSA page\n"));
+    }
+  }
+
+  CpuData->SevEsSaveArea = SaveArea;
+}
+
+/**
+  Create SEV-SNP APs.
+
+  @param[in]  CpuMpData        Pointer to CPU MP Data
+  @param[in]  ProcessorNumber  The handle number of specified processor
+                               (-1 for all APs)
+**/
+STATIC
+VOID
+SevSnpCreateAP (
+  IN CPU_MP_DATA               *CpuMpData,
+  IN INTN                      ProcessorNumber
+  )
+{
+  CPU_INFO_IN_HOB  *CpuInfoInHob;
+  CPU_AP_DATA      *CpuData;
+  UINTN            Index;
+  UINT32           ApicId;
+
+  ASSERT (CpuMpData->MpCpuExchangeInfo->BufferStart < 0x100000);
+
+  CpuInfoInHob = (CPU_INFO_IN_HOB *) (UINTN) CpuMpData->CpuInfoInHob;
+
+  if (ProcessorNumber < 0) {
+    for (Index = 0; Index < CpuMpData->CpuCount; Index++) {
+      if (Index != CpuMpData->BspNumber) {
+        CpuData = &CpuMpData->CpuData[Index];
+        ApicId = CpuInfoInHob[Index].ApicId,
+        SevSnpCreateSaveArea (CpuMpData, CpuData, ApicId);
+      }
+    }
+  } else {
+    Index = (UINTN) ProcessorNumber;
+    CpuData = &CpuMpData->CpuData[Index];
+    ApicId = CpuInfoInHob[ProcessorNumber].ApicId,
+    SevSnpCreateSaveArea (CpuMpData, CpuData, ApicId);
+  }
+}
+
 /**
   This function will be called by BSP to wakeup AP.
 
@@ -1332,7 +1549,7 @@ WakeUpAP (
   ResetVectorRequired = FALSE;
 
   if (CpuMpData->WakeUpByInitSipiSipi ||
-      CpuMpData->InitFlag   != ApInitDone) {
+      CpuMpData->InitFlag != ApInitDone) {
     ResetVectorRequired = TRUE;
     AllocateResetVector (CpuMpData);
     AllocateSevEsAPMemory (CpuMpData);
@@ -1373,7 +1590,7 @@ WakeUpAP (
     }
     if (ResetVectorRequired) {
       //
-      // For SEV-ES, the initial AP boot address will be defined by
+      // For SEV-ES and SEV-SNP, the initial AP boot address will be defined by
       // PcdSevEsWorkAreaBase. The Segment/Rip must be the jump address
       // from the original INIT-SIPI-SIPI.
       //
@@ -1383,8 +1600,14 @@ WakeUpAP (
 
       //
       // Wakeup all APs
+      //   Must use the INIT-SIPI-SIPI method for initial configuration in
+      //   order to obtain the APIC ID.
       //
-      SendInitSipiSipiAllExcludingSelf ((UINT32) ExchangeInfo->BufferStart);
+      if (CpuMpData->SevSnpIsEnabled && CpuMpData->InitFlag != ApInitConfig) {
+        SevSnpCreateAP (CpuMpData, -1);
+      } else {
+        SendInitSipiSipiAllExcludingSelf ((UINT32) ExchangeInfo->BufferStart);
+      }
     }
     if (CpuMpData->InitFlag == ApInitConfig) {
       if (PcdGet32 (PcdCpuBootLogicalProcessorNumber) > 0) {
@@ -1474,7 +1697,7 @@ WakeUpAP (
       CpuInfoInHob = (CPU_INFO_IN_HOB *) (UINTN) CpuMpData->CpuInfoInHob;
 
       //
-      // For SEV-ES, the initial AP boot address will be defined by
+      // For SEV-ES and SEV-SNP, the initial AP boot address will be defined by
       // PcdSevEsWorkAreaBase. The Segment/Rip must be the jump address
       // from the original INIT-SIPI-SIPI.
       //
@@ -1482,10 +1705,14 @@ WakeUpAP (
         SetSevEsJumpTable (ExchangeInfo->BufferStart);
       }
 
-      SendInitSipiSipi (
-        CpuInfoInHob[ProcessorNumber].ApicId,
-        (UINT32) ExchangeInfo->BufferStart
-        );
+      if (CpuMpData->SevSnpIsEnabled && CpuMpData->InitFlag != ApInitConfig) {
+        SevSnpCreateAP (CpuMpData, (INTN) ProcessorNumber);
+      } else {
+        SendInitSipiSipi (
+          CpuInfoInHob[ProcessorNumber].ApicId,
+          (UINT32) ExchangeInfo->BufferStart
+          );
+      }
     }
     //
     // Wait specified AP waken up
@@ -2016,10 +2243,15 @@ MpInitLibInitialize (
   CpuMpData->CpuData          = (CPU_AP_DATA *) (CpuMpData + 1);
   CpuMpData->CpuInfoInHob     = (UINT64) (UINTN) (CpuMpData->CpuData + MaxLogicalProcessorNumber);
   InitializeSpinLock(&CpuMpData->MpLock);
-  CpuMpData->SevEsIsEnabled = PcdGetBool (PcdSevEsIsEnabled);
-  CpuMpData->SevSnpIsEnabled = PcdGetBool (PcdSevSnpIsEnabled);
-  CpuMpData->SevEsAPBuffer  = (UINTN) -1;
-  CpuMpData->GhcbBase       = PcdGet64 (PcdGhcbBase);
+  CpuMpData->SevEsIsEnabled   = PcdGetBool (PcdSevEsIsEnabled);
+  CpuMpData->SevSnpIsEnabled  = PcdGetBool (PcdSevSnpIsEnabled);
+  CpuMpData->SevEsAPBuffer    = (UINTN) -1;
+  CpuMpData->GhcbBase         = PcdGet64 (PcdGhcbBase);
+  CpuMpData->UseSevEsAPMethod = CpuMpData->SevEsIsEnabled && !CpuMpData->SevSnpIsEnabled;
+
+  if (CpuMpData->SevSnpIsEnabled) {
+    ASSERT ((PcdGet64 (PcdGhcbHypervisorFeatures) & GHCB_HV_FEATURES_SNP_AP_CREATE) == GHCB_HV_FEATURES_SNP_AP_CREATE);
+  }
 
   //
   // Make sure no memory usage outside of the allocated buffer.
diff --git a/UefiCpuPkg/Library/MpInitLib/X64/SevSnpRmpAdjustInternal.c b/UefiCpuPkg/Library/MpInitLib/X64/SevSnpRmpAdjustInternal.c
new file mode 100644
index 000000000000..0716a4623e38
--- /dev/null
+++ b/UefiCpuPkg/Library/MpInitLib/X64/SevSnpRmpAdjustInternal.c
@@ -0,0 +1,44 @@
+/** @file
+
+  RMPADJUST helper function.
+
+  Copyright (c) 2021, AMD Incorporated. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include "MpLib.h"
+
+/**
+  Issue RMPADJUST to adjust the attributes of an SEV-SNP page.
+
+  @param[in]  PageAddress
+  @param[in]  VmsaPage
+
+  @return  RMPADJUST return value
+**/
+UINT32
+SevSnpRmpAdjust (
+  IN  EFI_PHYSICAL_ADDRESS  PageAddress,
+  IN  BOOLEAN               VmsaPage
+  )
+{
+  UINT64  Rdx;
+  UINT8   Vmpl;
+  UINT8   PermissionMask;
+
+  //
+  // Use the highest VMPL level.
+  //
+  PermissionMask = 0;
+  Vmpl = RMPADJUST_VMPL_MAX;
+
+  Rdx = (Vmpl & RMPADJUST_VMPL_MASK) << RMPADJUST_VMPL_SHIFT;
+  Rdx |= (PermissionMask & RMPADJUST_PERMISSION_MASK_MASK) << RMPADJUST_PERMISSION_MASK_SHIFT;
+  if (VmsaPage) {
+    Rdx |= RMPADJUST_VMSA_PAGE_BIT;
+  }
+
+  return AsmRmpAdjust ((UINT64) PageAddress, 0, Rdx);
+}
-- 
2.17.1


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

* [PATCH RFC v3 22/22] MdePkg/GHCB: increase the GHCB protocol max version
  2021-05-26 23:10 [RESEND PATCH RFC v3 00/22] Add AMD Secure Nested Paging (SEV-SNP) support Brijesh Singh
                   ` (20 preceding siblings ...)
  2021-05-26 23:11 ` [PATCH RFC v3 21/22] UefiCpuPkg/MpInitLib: Use SEV-SNP AP Creation NAE event to launch APs Brijesh Singh
@ 2021-05-26 23:11 ` Brijesh Singh
  2021-06-03 13:08   ` [edk2-devel] " Laszlo Ersek
  2021-05-27  9:42 ` [edk2-devel] [RESEND PATCH RFC v3 00/22] Add AMD Secure Nested Paging (SEV-SNP) support Laszlo Ersek
  2021-06-04  9:32 ` Laszlo Ersek
  23 siblings, 1 reply; 57+ messages in thread
From: Brijesh Singh @ 2021-05-26 23:11 UTC (permalink / raw)
  To: James Bottomley, Min Xu, Jiewen Yao, Tom Lendacky, Jordan Justen,
	Laszlo Ersek, Erdem Aktas, Eric Dong, Ray Ni, Rahul Kumar, devel
  Cc: Brijesh Singh, Ard Biesheuvel

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

Now that OvmfPkg supports version 2 of the GHCB specification, bump the
protocol version.

Cc: James Bottomley <jejb@linux.ibm.com>
Cc: Min Xu <min.m.xu@intel.com>
Cc: Jiewen Yao <jiewen.yao@intel.com>
Cc: Tom Lendacky <thomas.lendacky@amd.com>
Cc: Jordan Justen <jordan.l.justen@intel.com>
Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
Cc: Laszlo Ersek <lersek@redhat.com>
Cc: Erdem Aktas <erdemaktas@google.com>
Signed-off-by: Brijesh Singh <brijesh.singh@amd.com>
---
 MdePkg/Include/Register/Amd/Ghcb.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/MdePkg/Include/Register/Amd/Ghcb.h b/MdePkg/Include/Register/Amd/Ghcb.h
index 4d1ee29e0a5e..191fd0876060 100644
--- a/MdePkg/Include/Register/Amd/Ghcb.h
+++ b/MdePkg/Include/Register/Amd/Ghcb.h
@@ -24,7 +24,7 @@
 #define VC_EXCEPTION 29
 
 #define GHCB_VERSION_MIN     1
-#define GHCB_VERSION_MAX     1
+#define GHCB_VERSION_MAX     2
 
 #define GHCB_STANDARD_USAGE  0
 
-- 
2.17.1


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

* Re: [edk2-devel] [RESEND PATCH RFC v3 00/22] Add AMD Secure Nested Paging (SEV-SNP) support
  2021-05-26 23:10 [RESEND PATCH RFC v3 00/22] Add AMD Secure Nested Paging (SEV-SNP) support Brijesh Singh
                   ` (21 preceding siblings ...)
  2021-05-26 23:11 ` [PATCH RFC v3 22/22] MdePkg/GHCB: increase the GHCB protocol max version Brijesh Singh
@ 2021-05-27  9:42 ` Laszlo Ersek
  2021-06-02 17:09   ` Laszlo Ersek
  2021-06-04  9:32 ` Laszlo Ersek
  23 siblings, 1 reply; 57+ messages in thread
From: Laszlo Ersek @ 2021-05-27  9:42 UTC (permalink / raw)
  To: devel, brijesh.singh, James Bottomley, Min Xu, Jiewen Yao,
	Tom Lendacky, Jordan Justen, Erdem Aktas, Eric Dong, Ray Ni,
	Rahul Kumar
  Cc: Ard Biesheuvel

On 05/27/21 01:10, Brijesh Singh wrote:
> (I missed adding devel@edk2.groups.io, resending the series)
> 
> BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=3275
> 
> SEV-SNP builds upon existing SEV and SEV-ES functionality while adding
> new hardware-based memory protections. SEV-SNP adds strong memory integrity
> protection to help prevent malicious hypervisor-based attacks like data
> replay, memory re-mapping and more in order to create an isolated memory
> encryption environment.
>  
> This series provides the basic building blocks to support booting the SEV-SNP
> VMs, it does not cover all the security enhancement introduced by the SEV-SNP
> such as interrupt protection.
> 
> Many of the integrity guarantees of SEV-SNP are enforced through a new
> structure called the Reverse Map Table (RMP). Adding a new page to SEV-SNP
> VM requires a 2-step process. First, the hypervisor assigns a page to the
> guest using the new RMPUPDATE instruction. This transitions the page to
> guest-invalid. Second, the guest validates the page using the new PVALIDATE
> instruction. The SEV-SNP VMs can use the new "Page State Change Request NAE"
> defined in the GHCB specification to ask hypervisor to add or remove page
> from the RMP table.
> 
> Each page assigned to the SEV-SNP VM can either be validated or unvalidated,
> as indicated by the Validated flag in the page's RMP entry. There are two
> approaches that can be taken for the page validation: Pre-validation and
> Lazy Validation.
> 
> Under pre-validation, the pages are validated prior to first use. And under
> lazy validation, pages are validated when first accessed. An access to a
> unvalidated page results in a #VC exception, at which time the exception
> handler may validate the page. Lazy validation requires careful tracking of
> the validated pages to avoid validating the same GPA more than once. The
> recently introduced "Unaccepted" memory type can be used to communicate the
> unvalidated memory ranges to the Guest OS.
> 
> At this time we only support the pre-validation. OVMF detects all the available
> system RAM in the PEI phase. When SEV-SNP is enabled, the memory is validated
> before it is made available to the EDK2 core.
> 
> This series does not implements the following SEV-SNP features yet:
> 
> * CPUID filtering
> * Lazy validation
> * Interrupt security
> 
> The series builds on SNP pre-patch posted here: https://tinyurl.com/pu6admks
> 
> Additional resources
> ---------------------
> SEV-SNP whitepaper
> https://www.amd.com/system/files/TechDocs/SEV-SNP-strengthening-vm-isolation-with-integrity-protection-and-more.pdf
> 
> APM 2: https://www.amd.com/system/files/TechDocs/24593.pdf (section 15.36)
> 
> The complete source is available at
> https://github.com/AMDESE/ovmf/tree/sev-snp-rfc-2
> 
> GHCB spec:
> https://developer.amd.com/wp-content/resources/56421.pdf
> 
> SEV-SNP firmware specification:
> https://developer.amd.com/sev/
> 	         
> Cc: James Bottomley <jejb@linux.ibm.com>
> Cc: Min Xu <min.m.xu@intel.com>
> Cc: Jiewen Yao <jiewen.yao@intel.com>
> Cc: Tom Lendacky <thomas.lendacky@amd.com>
> Cc: Jordan Justen <jordan.l.justen@intel.com>
> Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
> Cc: Laszlo Ersek <lersek@redhat.com>
> Cc: Erdem Aktas <erdemaktas@google.com>
> 
> Changes since v2:
>  * Add support for the AP creation.
>  * Use the module-scoping override to make AmdSevDxe use the IO port for PCI reads.
>  * Use the reserved memory type for CPUID and Secrets page.
>  * 
> Changes since v1:
>  * Drop the interval tree support to detect the pre-validated overlap region.
>  * Use an array to keep track of pre-validated regions.
>  * Add support to query the Hypervisor feature and verify that SNP feature is supported.
>  * Introduce MemEncryptSevClearMmioPageEncMask() to clear the C-bit from MMIO ranges.
>  * Pull the SevSecretDxe and SevSecretPei into OVMF package build.
>  * Extend the SevSecretDxe to expose confidential computing blob location through
>    EFI configuration table.
> 
> Brijesh Singh (21):
>   UefiCpuPkg: Define the SEV-SNP specific dynamic PCDs
>   OvmfPkg/MemEncryptSevLib: add MemEncryptSevSnpEnabled()
>   OvmfPkg/MemEncryptSevLib: extend the workarea to include SNP enabled
>     field
>   OvmfPkg/MemEncryptSevLib: extend Es Workarea to include hv features
>   OvmfPkg: reserve Secrets page in MEMFD
>   OvmfPkg: reserve CPUID page for the SEV-SNP guest
>   OvmfPkg/ResetVector: validate the data pages used in SEC phase
>   OvmfPkg/ResetVector: invalidate the GHCB page
>   OvmfPkg: add library to support registering GHCB GPA
>   OvmfPkg/PlatformPei: register GHCB gpa for the SEV-SNP guest
>   UefiCpuPkg/MpLib: add support to register GHCB GPA when SEV-SNP is
>     enabled
>   OvmfPkg/AmdSevDxe: do not use extended PCI config space
>   OvmfPkg/MemEncryptSevLib: add support to validate system RAM
>   OvmfPkg/BaseMemEncryptSevLib: skip the pre-validated system RAM
>   OvmfPkg/MemEncryptSevLib: add support to validate > 4GB memory in PEI
>     phase
>   OvmfPkg/SecMain: pre-validate the memory used for decompressing Fv
>   OvmfPkg/PlatformPei: validate the system RAM when SNP is active
>   OvmfPkg/MemEncryptSevLib: Change the page state in the RMP table
>   OvmfPkg/MemEncryptSevLib: skip page state change for Mmio address
>   OvmfPkg/AmdSev: expose the SNP reserved pages through configuration
>     table
>   MdePkg/GHCB: increase the GHCB protocol max version
> 
> Tom Lendacky (1):
>   UefiCpuPkg/MpInitLib: Use SEV-SNP AP Creation NAE event to launch APs
> 
>  OvmfPkg/OvmfPkg.dec                           |  21 ++
>  UefiCpuPkg/UefiCpuPkg.dec                     |  11 +
>  OvmfPkg/AmdSev/AmdSevX64.dsc                  |   5 +-
>  OvmfPkg/Bhyve/BhyveX64.dsc                    |   5 +-
>  OvmfPkg/OvmfPkgIa32.dsc                       |   2 +
>  OvmfPkg/OvmfPkgIa32X64.dsc                    |   7 +-
>  OvmfPkg/OvmfPkgX64.dsc                        |   8 +-
>  OvmfPkg/OvmfXen.dsc                           |   5 +-
>  OvmfPkg/OvmfPkgX64.fdf                        |  17 +-
>  OvmfPkg/AmdSev/SecretDxe/SecretDxe.inf        |   4 +
>  OvmfPkg/AmdSev/SecretPei/SecretPei.inf        |   1 +
>  .../DxeMemEncryptSevLib.inf                   |   3 +
>  .../PeiMemEncryptSevLib.inf                   |   7 +
>  .../SecMemEncryptSevLib.inf                   |   3 +
>  .../GhcbRegisterLib/GhcbRegisterLib.inf       |  33 +++
>  OvmfPkg/PlatformPei/PlatformPei.inf           |   5 +
>  OvmfPkg/ResetVector/ResetVector.inf           |   4 +
>  OvmfPkg/Sec/SecMain.inf                       |   3 +
>  UefiCpuPkg/Library/MpInitLib/DxeMpInitLib.inf |   4 +
>  UefiCpuPkg/Library/MpInitLib/PeiMpInitLib.inf |   4 +
>  MdePkg/Include/Register/Amd/Ghcb.h            |   2 +-
>  .../Guid/ConfidentialComputingSecret.h        |  18 ++
>  OvmfPkg/Include/Library/GhcbRegisterLib.h     |  27 ++
>  OvmfPkg/Include/Library/MemEncryptSevLib.h    |  31 +-
>  .../X64/SnpPageStateChange.h                  |  31 ++
>  .../BaseMemEncryptSevLib/X64/VirtualMemory.h  |  19 ++
>  UefiCpuPkg/Library/MpInitLib/MpLib.h          |  19 ++
>  OvmfPkg/AmdSev/SecretDxe/SecretDxe.c          |  22 ++
>  OvmfPkg/AmdSev/SecretPei/SecretPei.c          |  15 +-
>  .../DxeMemEncryptSevLibInternal.c             |  27 ++
>  .../Ia32/MemEncryptSevLib.c                   |  17 ++
>  .../PeiMemEncryptSevLibInternal.c             |  27 ++
>  .../SecMemEncryptSevLibInternal.c             |  19 ++
>  .../X64/DxeSnpSystemRamValidate.c             |  40 +++
>  .../X64/PeiDxeVirtualMemory.c                 | 167 ++++++++++-
>  .../X64/PeiSnpSystemRamValidate.c             | 126 ++++++++
>  .../X64/SecSnpSystemRamValidate.c             |  36 +++
>  .../X64/SnpPageStateChangeInternal.c          | 230 +++++++++++++++
>  .../Library/GhcbRegisterLib/GhcbRegisterLib.c |  97 +++++++
>  OvmfPkg/PlatformPei/AmdSev.c                  |  81 ++++++
>  OvmfPkg/PlatformPei/MemDetect.c               |  12 +
>  OvmfPkg/Sec/SecMain.c                         | 106 +++++++
>  UefiCpuPkg/Library/MpInitLib/DxeMpLib.c       |  11 +-
>  .../MpInitLib/Ia32/SevSnpRmpAdjustInternal.c  |  31 ++
>  UefiCpuPkg/Library/MpInitLib/MpLib.c          | 274 ++++++++++++++++--
>  .../MpInitLib/X64/SevSnpRmpAdjustInternal.c   |  44 +++
>  OvmfPkg/FvmainCompactScratchEnd.fdf.inc       |   5 +
>  OvmfPkg/ResetVector/Ia16/ResetVectorVtf0.asm  |  23 ++
>  OvmfPkg/ResetVector/Ia32/PageTables64.asm     | 227 +++++++++++++++
>  OvmfPkg/ResetVector/ResetVector.nasmb         |   6 +
>  UefiCpuPkg/Library/MpInitLib/MpEqu.inc        |   1 +
>  UefiCpuPkg/Library/MpInitLib/X64/MpFuncs.nasm |  51 ++++
>  52 files changed, 1956 insertions(+), 38 deletions(-)
>  create mode 100644 OvmfPkg/Library/GhcbRegisterLib/GhcbRegisterLib.inf
>  create mode 100644 OvmfPkg/Include/Library/GhcbRegisterLib.h
>  create mode 100644 OvmfPkg/Library/BaseMemEncryptSevLib/X64/SnpPageStateChange.h
>  create mode 100644 OvmfPkg/Library/BaseMemEncryptSevLib/X64/DxeSnpSystemRamValidate.c
>  create mode 100644 OvmfPkg/Library/BaseMemEncryptSevLib/X64/PeiSnpSystemRamValidate.c
>  create mode 100644 OvmfPkg/Library/BaseMemEncryptSevLib/X64/SecSnpSystemRamValidate.c
>  create mode 100644 OvmfPkg/Library/BaseMemEncryptSevLib/X64/SnpPageStateChangeInternal.c
>  create mode 100644 OvmfPkg/Library/GhcbRegisterLib/GhcbRegisterLib.c
>  create mode 100644 UefiCpuPkg/Library/MpInitLib/Ia32/SevSnpRmpAdjustInternal.c
>  create mode 100644 UefiCpuPkg/Library/MpInitLib/X64/SevSnpRmpAdjustInternal.c
> 

I'm confirming that this series is in my review queue.

However, I may need unusually long time to get to it. Thanks for your
patience.

Thanks
Laszlo


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

* Re: [edk2-devel] [RESEND PATCH RFC v3 00/22] Add AMD Secure Nested Paging (SEV-SNP) support
  2021-05-27  9:42 ` [edk2-devel] [RESEND PATCH RFC v3 00/22] Add AMD Secure Nested Paging (SEV-SNP) support Laszlo Ersek
@ 2021-06-02 17:09   ` Laszlo Ersek
  0 siblings, 0 replies; 57+ messages in thread
From: Laszlo Ersek @ 2021-06-02 17:09 UTC (permalink / raw)
  To: devel, brijesh.singh, James Bottomley, Min Xu, Jiewen Yao,
	Tom Lendacky, Jordan Justen, Erdem Aktas, Eric Dong, Ray Ni,
	Rahul Kumar
  Cc: Ard Biesheuvel

On 05/27/21 11:42, Laszlo Ersek wrote:
> On 05/27/21 01:10, Brijesh Singh wrote:

>> Changes since v2:
>>  * Add support for the AP creation.
>>  * Use the module-scoping override to make AmdSevDxe use the IO port for PCI reads.
>>  * Use the reserved memory type for CPUID and Secrets page.

> I'm confirming that this series is in my review queue.
> 
> However, I may need unusually long time to get to it. Thanks for your
> patience.

My hope is that I can at least start reviewing this series tomorrow.
Sorry about the delay, I've been working on my todo list the best I can.

Laszlo


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

* Re: [edk2-devel] [PATCH RFC v3 01/22] UefiCpuPkg: Define the SEV-SNP specific dynamic PCDs
  2021-05-26 23:10 ` [PATCH RFC v3 01/22] UefiCpuPkg: Define the SEV-SNP specific dynamic PCDs Brijesh Singh
@ 2021-06-03  8:15   ` Laszlo Ersek
  2021-06-03 12:16     ` Brijesh Singh
  2021-06-03 13:38   ` Laszlo Ersek
  1 sibling, 1 reply; 57+ messages in thread
From: Laszlo Ersek @ 2021-06-03  8:15 UTC (permalink / raw)
  To: devel, brijesh.singh, James Bottomley, Min Xu, Jiewen Yao,
	Tom Lendacky, Jordan Justen, Erdem Aktas, Eric Dong, Ray Ni,
	Rahul Kumar
  Cc: Ard Biesheuvel

Hi Brijesh,

On 05/27/21 01:10, Brijesh Singh wrote:
> BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=3275
> 
> Define the PCDs used by the MpLib while creating the AP when SEV-SNP is
> active in the guest VMs.
> 
> Cc: James Bottomley <jejb@linux.ibm.com>
> Cc: Min Xu <min.m.xu@intel.com>
> Cc: Jiewen Yao <jiewen.yao@intel.com>
> Cc: Tom Lendacky <thomas.lendacky@amd.com>
> Cc: Jordan Justen <jordan.l.justen@intel.com>
> Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
> Cc: Laszlo Ersek <lersek@redhat.com>
> Cc: Erdem Aktas <erdemaktas@google.com>
> Signed-off-by: Brijesh Singh <brijesh.singh@amd.com>
> ---
>  UefiCpuPkg/UefiCpuPkg.dec | 11 +++++++++++
>  1 file changed, 11 insertions(+)

I'm really sorry that this is my first "actual" comment (on the 7th day
of your posting this series), but the CC list is incorrect on this
patch, and (at least) on patch#11 as well.

I'm a stickler myself for being CC'd on any patches per
"Maintainers.txt", so I'm going to request a resending of this series,
with the CC lists extended.

Please run "$EDK_TOOLS_PATH/Scripts/GetMaintainer.py" on every patch in
the series, and add the missing CC's. Manually copying all of the
"confidential computing" reviewers on all of the patches is great, but
we need to keep the usual package-level reviewers/maintainers as well.

In particular, the UefiCpuPkg patches need to be copied to Eric, Ray and
Rahul -- like you actually did in patch#21. Patch#22 also misses the
MdePkg reviewers (Michael, Liming, Zhiguang).

I'm truly sorry that this must feel like a cop-out on my part. I won't
deny that I appreciate a breather after the last two, hellishly busy,
two weeks, but I *did* resolve last night to start reviewing this series
today. (I should note that we expect reviewers to start reviewing a
patch set within a calendar week, so my feedback *is* just in time by my
count -- except, I expected to make actual patch review comments.)

If you can resend today with the CC's correct, I'll make an attempt to
start reviewing tomorrow.

Also, let me point this out: we have a nice long CC list now, by virtue
of the "confidential computing" section in "Maintainers.txt", and a
calendar week has passed -- I'd have appreciated seeing comments from
others as well!

Thanks,
Laszlo

> 
> diff --git a/UefiCpuPkg/UefiCpuPkg.dec b/UefiCpuPkg/UefiCpuPkg.dec
> index 62acb291f309..0ec25871a50f 100644
> --- a/UefiCpuPkg/UefiCpuPkg.dec
> +++ b/UefiCpuPkg/UefiCpuPkg.dec
> @@ -396,5 +396,16 @@ [PcdsDynamic, PcdsDynamicEx]
>    # @Prompt SEV-ES Status
>    gUefiCpuPkgTokenSpaceGuid.PcdSevEsIsEnabled|FALSE|BOOLEAN|0x60000016
>  
> +  ## This dynamic PCD indicates whether SEV-SNP is enabled
> +  #   TRUE  - SEV-SNP is enabled
> +  #   FALSE - SEV-SNP is not enabled
> +  # @Prompt SEV-SNP Status
> +  gUefiCpuPkgTokenSpaceGuid.PcdSevSnpIsEnabled|FALSE|BOOLEAN|0x60000017
> +
> +  ## This dynamic PCD contains the hypervisor features value obtained through the GHCB HYPERVISOR
> +  #  features VMGEXIT defined in the version 2 of GHCB spec.
> +  # @Prompt GHCB Hypervisor Features
> +  gUefiCpuPkgTokenSpaceGuid.PcdGhcbHypervisorFeatures|0x0|UINT64|0x60000018
> +
>  [UserExtensions.TianoCore."ExtraFiles"]
>    UefiCpuPkgExtra.uni
> 


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

* Re: [edk2-devel] [PATCH RFC v3 01/22] UefiCpuPkg: Define the SEV-SNP specific dynamic PCDs
  2021-06-03  8:15   ` [edk2-devel] " Laszlo Ersek
@ 2021-06-03 12:16     ` Brijesh Singh
  2021-06-03 13:07       ` Laszlo Ersek
  0 siblings, 1 reply; 57+ messages in thread
From: Brijesh Singh @ 2021-06-03 12:16 UTC (permalink / raw)
  To: Laszlo Ersek, devel, James Bottomley, Min Xu, Jiewen Yao,
	Tom Lendacky, Jordan Justen, Erdem Aktas, Eric Dong, Ray Ni,
	Rahul Kumar
  Cc: brijesh.singh, Ard Biesheuvel


On 6/3/21 3:15 AM, Laszlo Ersek wrote:
> Hi Brijesh,
>
> On 05/27/21 01:10, Brijesh Singh wrote:
>> BZ: https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Fbugzilla.tianocore.org%2Fshow_bug.cgi%3Fid%3D3275&amp;data=04%7C01%7Cbrijesh.singh%40amd.com%7Cb4d27ba148e544f984ee08d92667d860%7C3dd8961fe4884e608e11a82d994e183d%7C0%7C0%7C637583049740462496%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C1000&amp;sdata=DaecxXoG%2BK932q9T70ISC%2BAIX4%2BUrAf6is6lEJmi9co%3D&amp;reserved=0
>>
>> Define the PCDs used by the MpLib while creating the AP when SEV-SNP is
>> active in the guest VMs.
>>
>> Cc: James Bottomley <jejb@linux.ibm.com>
>> Cc: Min Xu <min.m.xu@intel.com>
>> Cc: Jiewen Yao <jiewen.yao@intel.com>
>> Cc: Tom Lendacky <thomas.lendacky@amd.com>
>> Cc: Jordan Justen <jordan.l.justen@intel.com>
>> Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
>> Cc: Laszlo Ersek <lersek@redhat.com>
>> Cc: Erdem Aktas <erdemaktas@google.com>
>> Signed-off-by: Brijesh Singh <brijesh.singh@amd.com>
>> ---
>>  UefiCpuPkg/UefiCpuPkg.dec | 11 +++++++++++
>>  1 file changed, 11 insertions(+)
> I'm really sorry that this is my first "actual" comment (on the 7th day
> of your posting this series), but the CC list is incorrect on this
> patch, and (at least) on patch#11 as well.
>
> I'm a stickler myself for being CC'd on any patches per
> "Maintainers.txt", so I'm going to request a resending of this series,
> with the CC lists extended.
>
> Please run "$EDK_TOOLS_PATH/Scripts/GetMaintainer.py" on every patch in
> the series, and add the missing CC's. Manually copying all of the
> "confidential computing" reviewers on all of the patches is great, but
> we need to keep the usual package-level reviewers/maintainers as well.
>
> In particular, the UefiCpuPkg patches need to be copied to Eric, Ray and
> Rahul -- like you actually did in patch#21. Patch#22 also misses the
> MdePkg reviewers (Michael, Liming, Zhiguang).

Actually all the UefiCpuPkg maintainers/reviewers are CC'ed in the whole
series. Its just that they are not listed in the git commit Cc tag.

Patch#22 was a single one liner which bumps the version number after the
SNP support is added. I was not sure if MdePkg maintainer will have much
comment so I tried to avoid flooding the inbox -- I guess I should have
copied them. I will resend with Cc tags updated.


> I'm truly sorry that this must feel like a cop-out on my part. I won't
> deny that I appreciate a breather after the last two, hellishly busy,
> two weeks, but I *did* resolve last night to start reviewing this series
> today. (I should note that we expect reviewers to start reviewing a
> patch set within a calendar week, so my feedback *is* just in time by my
> count -- except, I expected to make actual patch review comments.)
>
> If you can resend today with the CC's correct, I'll make an attempt to
> start reviewing tomorrow.
>
> Also, let me point this out: we have a nice long CC list now, by virtue
> of the "confidential computing" section in "Maintainers.txt", and a
> calendar week has passed -- I'd have appreciated seeing comments from
> others as well!
>
> Thanks,
> Laszlo
>
>> diff --git a/UefiCpuPkg/UefiCpuPkg.dec b/UefiCpuPkg/UefiCpuPkg.dec
>> index 62acb291f309..0ec25871a50f 100644
>> --- a/UefiCpuPkg/UefiCpuPkg.dec
>> +++ b/UefiCpuPkg/UefiCpuPkg.dec
>> @@ -396,5 +396,16 @@ [PcdsDynamic, PcdsDynamicEx]
>>    # @Prompt SEV-ES Status
>>    gUefiCpuPkgTokenSpaceGuid.PcdSevEsIsEnabled|FALSE|BOOLEAN|0x60000016
>>  
>> +  ## This dynamic PCD indicates whether SEV-SNP is enabled
>> +  #   TRUE  - SEV-SNP is enabled
>> +  #   FALSE - SEV-SNP is not enabled
>> +  # @Prompt SEV-SNP Status
>> +  gUefiCpuPkgTokenSpaceGuid.PcdSevSnpIsEnabled|FALSE|BOOLEAN|0x60000017
>> +
>> +  ## This dynamic PCD contains the hypervisor features value obtained through the GHCB HYPERVISOR
>> +  #  features VMGEXIT defined in the version 2 of GHCB spec.
>> +  # @Prompt GHCB Hypervisor Features
>> +  gUefiCpuPkgTokenSpaceGuid.PcdGhcbHypervisorFeatures|0x0|UINT64|0x60000018
>> +
>>  [UserExtensions.TianoCore."ExtraFiles"]
>>    UefiCpuPkgExtra.uni
>>

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

* Re: [edk2-devel] [PATCH RFC v3 01/22] UefiCpuPkg: Define the SEV-SNP specific dynamic PCDs
  2021-06-03 12:16     ` Brijesh Singh
@ 2021-06-03 13:07       ` Laszlo Ersek
  0 siblings, 0 replies; 57+ messages in thread
From: Laszlo Ersek @ 2021-06-03 13:07 UTC (permalink / raw)
  To: Brijesh Singh, devel, James Bottomley, Min Xu, Jiewen Yao,
	Tom Lendacky, Jordan Justen, Erdem Aktas, Eric Dong, Ray Ni,
	Rahul Kumar
  Cc: Ard Biesheuvel

On 06/03/21 14:16, Brijesh Singh wrote:
> 
> On 6/3/21 3:15 AM, Laszlo Ersek wrote:
>> Hi Brijesh,
>>
>> On 05/27/21 01:10, Brijesh Singh wrote:
>>> BZ: https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Fbugzilla.tianocore.org%2Fshow_bug.cgi%3Fid%3D3275&amp;data=04%7C01%7Cbrijesh.singh%40amd.com%7Cb4d27ba148e544f984ee08d92667d860%7C3dd8961fe4884e608e11a82d994e183d%7C0%7C0%7C637583049740462496%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C1000&amp;sdata=DaecxXoG%2BK932q9T70ISC%2BAIX4%2BUrAf6is6lEJmi9co%3D&amp;reserved=0
>>>
>>> Define the PCDs used by the MpLib while creating the AP when SEV-SNP is
>>> active in the guest VMs.
>>>
>>> Cc: James Bottomley <jejb@linux.ibm.com>
>>> Cc: Min Xu <min.m.xu@intel.com>
>>> Cc: Jiewen Yao <jiewen.yao@intel.com>
>>> Cc: Tom Lendacky <thomas.lendacky@amd.com>
>>> Cc: Jordan Justen <jordan.l.justen@intel.com>
>>> Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
>>> Cc: Laszlo Ersek <lersek@redhat.com>
>>> Cc: Erdem Aktas <erdemaktas@google.com>
>>> Signed-off-by: Brijesh Singh <brijesh.singh@amd.com>
>>> ---
>>>  UefiCpuPkg/UefiCpuPkg.dec | 11 +++++++++++
>>>  1 file changed, 11 insertions(+)
>> I'm really sorry that this is my first "actual" comment (on the 7th day
>> of your posting this series), but the CC list is incorrect on this
>> patch, and (at least) on patch#11 as well.
>>
>> I'm a stickler myself for being CC'd on any patches per
>> "Maintainers.txt", so I'm going to request a resending of this series,
>> with the CC lists extended.
>>
>> Please run "$EDK_TOOLS_PATH/Scripts/GetMaintainer.py" on every patch in
>> the series, and add the missing CC's. Manually copying all of the
>> "confidential computing" reviewers on all of the patches is great, but
>> we need to keep the usual package-level reviewers/maintainers as well.
>>
>> In particular, the UefiCpuPkg patches need to be copied to Eric, Ray and
>> Rahul -- like you actually did in patch#21. Patch#22 also misses the
>> MdePkg reviewers (Michael, Liming, Zhiguang).
> 
> Actually all the UefiCpuPkg maintainers/reviewers are CC'ed in the whole
> series. Its just that they are not listed in the git commit Cc tag.

I'm sorry for missing that -- I never use git's command line CC
switch(es), because those are easy to forget upon rebases / multiple
postings. I exclusively use the commit messages for CC's, and so I
didn't even check the actual address list on your patch email. My apologies.

> 
> Patch#22 was a single one liner which bumps the version number after the
> SNP support is added. I was not sure if MdePkg maintainer will have much
> comment so I tried to avoid flooding the inbox -- I guess I should have
> copied them. I will resend with Cc tags updated.

Assuming it's going to be me to (potentially) merge this series, I'd
never merge an MdePkg patch without MdePkg owner/reviewer approval,
regardless of content (deciding about the content's impact is up to the
MdePkg owners/reviewers too).

On the other hand, if it's really just the last patch missing some CC's,
then I'll bring in the MdePkg reviewers by replying to that patch and
keeping full context for them.

Based on the above, please don't bother with another resend, and I'm
sorry about missing the actual CC's.

Thanks,
Laszlo


> 
> 
>> I'm truly sorry that this must feel like a cop-out on my part. I won't
>> deny that I appreciate a breather after the last two, hellishly busy,
>> two weeks, but I *did* resolve last night to start reviewing this series
>> today. (I should note that we expect reviewers to start reviewing a
>> patch set within a calendar week, so my feedback *is* just in time by my
>> count -- except, I expected to make actual patch review comments.)
>>
>> If you can resend today with the CC's correct, I'll make an attempt to
>> start reviewing tomorrow.
>>
>> Also, let me point this out: we have a nice long CC list now, by virtue
>> of the "confidential computing" section in "Maintainers.txt", and a
>> calendar week has passed -- I'd have appreciated seeing comments from
>> others as well!
>>
>> Thanks,
>> Laszlo
>>
>>> diff --git a/UefiCpuPkg/UefiCpuPkg.dec b/UefiCpuPkg/UefiCpuPkg.dec
>>> index 62acb291f309..0ec25871a50f 100644
>>> --- a/UefiCpuPkg/UefiCpuPkg.dec
>>> +++ b/UefiCpuPkg/UefiCpuPkg.dec
>>> @@ -396,5 +396,16 @@ [PcdsDynamic, PcdsDynamicEx]
>>>    # @Prompt SEV-ES Status
>>>    gUefiCpuPkgTokenSpaceGuid.PcdSevEsIsEnabled|FALSE|BOOLEAN|0x60000016
>>>  
>>> +  ## This dynamic PCD indicates whether SEV-SNP is enabled
>>> +  #   TRUE  - SEV-SNP is enabled
>>> +  #   FALSE - SEV-SNP is not enabled
>>> +  # @Prompt SEV-SNP Status
>>> +  gUefiCpuPkgTokenSpaceGuid.PcdSevSnpIsEnabled|FALSE|BOOLEAN|0x60000017
>>> +
>>> +  ## This dynamic PCD contains the hypervisor features value obtained through the GHCB HYPERVISOR
>>> +  #  features VMGEXIT defined in the version 2 of GHCB spec.
>>> +  # @Prompt GHCB Hypervisor Features
>>> +  gUefiCpuPkgTokenSpaceGuid.PcdGhcbHypervisorFeatures|0x0|UINT64|0x60000018
>>> +
>>>  [UserExtensions.TianoCore."ExtraFiles"]
>>>    UefiCpuPkgExtra.uni
>>>
> 


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

* Re: [edk2-devel] [PATCH RFC v3 22/22] MdePkg/GHCB: increase the GHCB protocol max version
  2021-05-26 23:11 ` [PATCH RFC v3 22/22] MdePkg/GHCB: increase the GHCB protocol max version Brijesh Singh
@ 2021-06-03 13:08   ` Laszlo Ersek
  2021-06-08  1:17     ` 回复: " gaoliming
  0 siblings, 1 reply; 57+ messages in thread
From: Laszlo Ersek @ 2021-06-03 13:08 UTC (permalink / raw)
  To: devel
  Cc: brijesh.singh, James Bottomley, Min Xu, Jiewen Yao, Tom Lendacky,
	Jordan Justen, Erdem Aktas, Eric Dong, Ray Ni, Rahul Kumar,
	Ard Biesheuvel, Michael D Kinney, Liming Gao, Zhiguang Liu

Copying the MdePkg reviewers.

Thanks
Laszlo

On 05/27/21 01:11, Brijesh Singh wrote:
> BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=3275
> 
> Now that OvmfPkg supports version 2 of the GHCB specification, bump the
> protocol version.
> 
> Cc: James Bottomley <jejb@linux.ibm.com>
> Cc: Min Xu <min.m.xu@intel.com>
> Cc: Jiewen Yao <jiewen.yao@intel.com>
> Cc: Tom Lendacky <thomas.lendacky@amd.com>
> Cc: Jordan Justen <jordan.l.justen@intel.com>
> Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
> Cc: Laszlo Ersek <lersek@redhat.com>
> Cc: Erdem Aktas <erdemaktas@google.com>
> Signed-off-by: Brijesh Singh <brijesh.singh@amd.com>
> ---
>  MdePkg/Include/Register/Amd/Ghcb.h | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/MdePkg/Include/Register/Amd/Ghcb.h b/MdePkg/Include/Register/Amd/Ghcb.h
> index 4d1ee29e0a5e..191fd0876060 100644
> --- a/MdePkg/Include/Register/Amd/Ghcb.h
> +++ b/MdePkg/Include/Register/Amd/Ghcb.h
> @@ -24,7 +24,7 @@
>  #define VC_EXCEPTION 29
>  
>  #define GHCB_VERSION_MIN     1
> -#define GHCB_VERSION_MAX     1
> +#define GHCB_VERSION_MAX     2
>  
>  #define GHCB_STANDARD_USAGE  0
>  
> 


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

* Re: [edk2-devel] [PATCH RFC v3 01/22] UefiCpuPkg: Define the SEV-SNP specific dynamic PCDs
  2021-05-26 23:10 ` [PATCH RFC v3 01/22] UefiCpuPkg: Define the SEV-SNP specific dynamic PCDs Brijesh Singh
  2021-06-03  8:15   ` [edk2-devel] " Laszlo Ersek
@ 2021-06-03 13:38   ` Laszlo Ersek
  1 sibling, 0 replies; 57+ messages in thread
From: Laszlo Ersek @ 2021-06-03 13:38 UTC (permalink / raw)
  To: devel, brijesh.singh, James Bottomley, Min Xu, Jiewen Yao,
	Tom Lendacky, Jordan Justen, Erdem Aktas, Eric Dong, Ray Ni,
	Rahul Kumar
  Cc: Ard Biesheuvel

On 05/27/21 01:10, Brijesh Singh wrote:
> BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=3275
> 
> Define the PCDs used by the MpLib while creating the AP when SEV-SNP is
> active in the guest VMs.

(1) I think MpLib should be MpInitLib.

(2) If it's not too annoying, I'd suggest using "APs" (plural) and "VM"
(singular).

I'll have to see in the rest of the series how these PCDs are set and
read, but as a starting point, this patch looks good OK to me.

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

Thanks
Laszlo

> 
> Cc: James Bottomley <jejb@linux.ibm.com>
> Cc: Min Xu <min.m.xu@intel.com>
> Cc: Jiewen Yao <jiewen.yao@intel.com>
> Cc: Tom Lendacky <thomas.lendacky@amd.com>
> Cc: Jordan Justen <jordan.l.justen@intel.com>
> Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
> Cc: Laszlo Ersek <lersek@redhat.com>
> Cc: Erdem Aktas <erdemaktas@google.com>
> Signed-off-by: Brijesh Singh <brijesh.singh@amd.com>
> ---
>  UefiCpuPkg/UefiCpuPkg.dec | 11 +++++++++++
>  1 file changed, 11 insertions(+)
> 
> diff --git a/UefiCpuPkg/UefiCpuPkg.dec b/UefiCpuPkg/UefiCpuPkg.dec
> index 62acb291f309..0ec25871a50f 100644
> --- a/UefiCpuPkg/UefiCpuPkg.dec
> +++ b/UefiCpuPkg/UefiCpuPkg.dec
> @@ -396,5 +396,16 @@ [PcdsDynamic, PcdsDynamicEx]
>    # @Prompt SEV-ES Status
>    gUefiCpuPkgTokenSpaceGuid.PcdSevEsIsEnabled|FALSE|BOOLEAN|0x60000016
>  
> +  ## This dynamic PCD indicates whether SEV-SNP is enabled
> +  #   TRUE  - SEV-SNP is enabled
> +  #   FALSE - SEV-SNP is not enabled
> +  # @Prompt SEV-SNP Status
> +  gUefiCpuPkgTokenSpaceGuid.PcdSevSnpIsEnabled|FALSE|BOOLEAN|0x60000017
> +
> +  ## This dynamic PCD contains the hypervisor features value obtained through the GHCB HYPERVISOR
> +  #  features VMGEXIT defined in the version 2 of GHCB spec.
> +  # @Prompt GHCB Hypervisor Features
> +  gUefiCpuPkgTokenSpaceGuid.PcdGhcbHypervisorFeatures|0x0|UINT64|0x60000018
> +
>  [UserExtensions.TianoCore."ExtraFiles"]
>    UefiCpuPkgExtra.uni
> 



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

* Re: [edk2-devel] [RESEND PATCH RFC v3 00/22] Add AMD Secure Nested Paging (SEV-SNP) support
  2021-05-26 23:10 [RESEND PATCH RFC v3 00/22] Add AMD Secure Nested Paging (SEV-SNP) support Brijesh Singh
                   ` (22 preceding siblings ...)
  2021-05-27  9:42 ` [edk2-devel] [RESEND PATCH RFC v3 00/22] Add AMD Secure Nested Paging (SEV-SNP) support Laszlo Ersek
@ 2021-06-04  9:32 ` Laszlo Ersek
  2021-06-04 11:50   ` Brijesh Singh
  23 siblings, 1 reply; 57+ messages in thread
From: Laszlo Ersek @ 2021-06-04  9:32 UTC (permalink / raw)
  To: brijesh.singh
  Cc: devel, James Bottomley, Min Xu, Jiewen Yao, Tom Lendacky,
	Jordan Justen, Erdem Aktas, Eric Dong, Ray Ni, Rahul Kumar,
	Ard Biesheuvel

Hi Brijesh,

On 05/27/21 01:10, Brijesh Singh wrote:
> (I missed adding devel@edk2.groups.io, resending the series)
>
> BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=3275
>
> SEV-SNP builds upon existing SEV and SEV-ES functionality while adding
> new hardware-based memory protections. SEV-SNP adds strong memory
> integrity protection to help prevent malicious hypervisor-based
> attacks like data replay, memory re-mapping and more in order to
> create an isolated memory encryption environment.
>
> This series provides the basic building blocks to support booting the
> SEV-SNP VMs, it does not cover all the security enhancement introduced
> by the SEV-SNP such as interrupt protection.
>
> Many of the integrity guarantees of SEV-SNP are enforced through a new
> structure called the Reverse Map Table (RMP). Adding a new page to
> SEV-SNP VM requires a 2-step process. First, the hypervisor assigns a
> page to the guest using the new RMPUPDATE instruction. This
> transitions the page to guest-invalid. Second, the guest validates the
> page using the new PVALIDATE instruction. The SEV-SNP VMs can use the
> new "Page State Change Request NAE" defined in the GHCB specification
> to ask hypervisor to add or remove page from the RMP table.
>
> Each page assigned to the SEV-SNP VM can either be validated or
> unvalidated, as indicated by the Validated flag in the page's RMP
> entry. There are two approaches that can be taken for the page
> validation: Pre-validation and Lazy Validation.
>
> Under pre-validation, the pages are validated prior to first use. And
> under lazy validation, pages are validated when first accessed. An
> access to a unvalidated page results in a #VC exception, at which time
> the exception handler may validate the page. Lazy validation requires
> careful tracking of the validated pages to avoid validating the same
> GPA more than once. The recently introduced "Unaccepted" memory type
> can be used to communicate the unvalidated memory ranges to the Guest
> OS.
>
> At this time we only support the pre-validation. OVMF detects all the
> available system RAM in the PEI phase. When SEV-SNP is enabled, the
> memory is validated before it is made available to the EDK2 core.
>
> This series does not implements the following SEV-SNP features yet:
>
> * CPUID filtering
> * Lazy validation
> * Interrupt security
>
> The series builds on SNP pre-patch posted here: https://tinyurl.com/pu6admks

That series ("[PATCH v3 00/13] Add GHCBv2 macro and helpers") has been
merged at this point, as commit range dbc22a178546..adfa3327d4fc. [*]

>
> Additional resources
> ---------------------
> SEV-SNP whitepaper
> https://www.amd.com/system/files/TechDocs/SEV-SNP-strengthening-vm-isolation-with-integrity-protection-and-more.pdf
>
> APM 2: https://www.amd.com/system/files/TechDocs/24593.pdf (section 15.36)
>
> The complete source is available at
> https://github.com/AMDESE/ovmf/tree/sev-snp-rfc-2

So, I'm having trouble applying this series. I attempted to apply it in
preparation for reviewing patch#2 with a larger context, but I failed,
as follows:

- When I try applying the series with git-am, upon current master
  (c410ad4da4b7), patch#21 ("UefiCpuPkg/MpInitLib: Use SEV-SNP AP
  Creation NAE event to launch APs") does not apply.

  AFAICT, that's because your modification of GetApResetVectorSize() did
  not (could not) take into account Tom's commit dbc22a178546
  ("UefiCpuPkg/MpInitLib: Allocate a separate SEV-ES AP reset stack
  area", 2021-05-29).

- Your remote branch (with HEAD @ 2dbd79823402) is based on upstream
  commit 01c0ab90beb3 ("AzurePipelines: Add support for ArmPlatformPkg",
  2021-04-28). If I try to rebase the branch from there to current
  master (c410ad4da4b7), I get the following rebase action list:

   1  pick 570829c5a0d6 MdePkg: Expand the SEV MSR to include the SNP definition
   2  pick b9247f69bdfe MdePkg: Define the GHCB Hypervisor features
   3  pick d09ed6d44ffd MdePkg: Define the Page State Change VMGEXIT structures
   4  pick 7148b2684f87 MdePkg: Add AsmPvalidate() support
   5  pick d6a2c2a0d625 OvmfPkg/BaseMemEncryptSevLib: Introduce MemEncryptSevClearMmioPageEncMask()
   6  pick 9b1037d0d9ac OvmfPkg: Use MemEncryptSevClearMmioPageEncMask() to clear EncMask from Mmio
   7  pick 556e8fc40179 OvmfPkg/BaseMemEncryptSevLib: Remove CacheFlush parameter
   8  pick 03e27af79c61 OvmfPkg/VmgExitLib: Allow PMBASE register access in Dxe phase
   9  pick a81925eeb1c6 OvmfPkg/MemEncryptSevLib: add MemEncryptSevSnpEnabled()
  10  pick 3d443240f91c OvmfPkg: Reserve Secrets page in MEMFD
  11  pick 94dad29970b0 OvmfPkg: Reserve CPUID page for the SEV-SNP guest
  12  pick b3e3faa12b0f OvmfPkg: Validate the data pages used in the Reset vector and SEC phase
  13  pick 62290e03c79a UefiCpuPkg: Define the SEV-SNP specific dynamic PCDs
  14  pick c04e71dabf63 OvmfPkg/MemEncryptSevLib: extend the workarea to include SNP enabled field
  15  pick 76072671f367 OvmfPkg/MemEncryptSevLib: Extend Es Workarea to include hv features
  16  pick 2bf0eaf2beea OvmfPkg/ResetVector: Invalidate the GHCB page
  17  pick 2f050b2a1033 OvmfPkg: Add a library to support registering GHCB GPA
  18  pick b2681bdfbebc OvmfPkg: register GHCB gpa for the SEV-SNP guest
  19  pick d9f1abb1ff35 UefiCpuPkg/MpLib: add support to register GHCB GPA when SEV-SNP is enabled
  20  pick 814084815108 OvmfPkg/MemEncryptSevLib: Add support to validate system RAM
  21  pick ec34893c46ab OvmfPkg/BaseMemEncryptSevLib: Skip the pre-validated system RAM
  22  pick 37af54f86c3a OvmfPkg/MemEncryptSevLib: Add support to validate > 4GB memory in PEI phase
  23  pick 25891f51499e OvmfPkg/SecMain: Pre-validate the memory used for decompressing Fv
  24  pick f2f55135b562 OvmfPkg/PlatformPei: Validate the system RAM when SNP is active
  25  pick a28b66462eae OvmfPkg/MemEncryptSevLib: Change the page state in the RMP table
  26  pick b10c0e61913b OvmfPkg/AmdSev: Expose the SNP reserved pages through configuration table
  27  pick 2dbd79823402 MdePkg/GHCB: Increase the GHCB protocol max version

This is 27 patches, while your series contains 22 patches. It *seems*
like some of these 27 patches have been merged via [*] already, but it's
not easy to say which ones. In particular, I can't just drop a
contiguous *prefix* of this rebase action list, because your *posted*
patch#1 is "UefiCpuPkg: Define the SEV-SNP specific dynamic PCDs", but
on your topic branch, that's patch#13! And if I dropped the 12 patches
before that, then we'd be left with 27-12=15 patches, which obviously
doesn't match your posted series consisting of 22 patches. I assume some
of the patches may have been reordered, but I wouldn't like to guess.

I believe we have two problems here: (1) the patch set does not apply to
current master, (2) the posted patch set doesn't even match your remote
topic branch.

Problem (1) is somewhat expected (the master branch is expected to
diverge over time), but problem (2) should never occur. Please never do
this. If you provide a fetch URL + branch reference in your cover
letter, then that remote topic branch must match the posted patches
*forver*. It effectively becomes read only, same as your posted emails
are read-only. If you need to modify the branch, please create a brand
new topic branch (possibly with a new version number in the name), and
rebase that branch.

(It's also possible that you modified your local branch just before
posting, without pushing it to the <https://github.com/AMDESE/ovmf>
repository afterwards, but that's quite disruptive too.)

So... what do you want me to do?

- Are at least patches 01 through 20 (as posted to the list)
  authoritative? Should I review those?

- Or would you like to rebase and repost the entire series (this time
  keeping the posted version and the fetchable topic branch in sync)?

Thanks,
Laszlo

>
> GHCB spec:
> https://developer.amd.com/wp-content/resources/56421.pdf
>
> SEV-SNP firmware specification:
> https://developer.amd.com/sev/
>
> Cc: James Bottomley <jejb@linux.ibm.com>
> Cc: Min Xu <min.m.xu@intel.com>
> Cc: Jiewen Yao <jiewen.yao@intel.com>
> Cc: Tom Lendacky <thomas.lendacky@amd.com>
> Cc: Jordan Justen <jordan.l.justen@intel.com>
> Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
> Cc: Laszlo Ersek <lersek@redhat.com>
> Cc: Erdem Aktas <erdemaktas@google.com>
>
> Changes since v2:
>  * Add support for the AP creation.
>  * Use the module-scoping override to make AmdSevDxe use the IO port for PCI reads.
>  * Use the reserved memory type for CPUID and Secrets page.
>  *
> Changes since v1:
>  * Drop the interval tree support to detect the pre-validated overlap region.
>  * Use an array to keep track of pre-validated regions.
>  * Add support to query the Hypervisor feature and verify that SNP feature is supported.
>  * Introduce MemEncryptSevClearMmioPageEncMask() to clear the C-bit from MMIO ranges.
>  * Pull the SevSecretDxe and SevSecretPei into OVMF package build.
>  * Extend the SevSecretDxe to expose confidential computing blob location through
>    EFI configuration table.
>
> Brijesh Singh (21):
>   UefiCpuPkg: Define the SEV-SNP specific dynamic PCDs
>   OvmfPkg/MemEncryptSevLib: add MemEncryptSevSnpEnabled()
>   OvmfPkg/MemEncryptSevLib: extend the workarea to include SNP enabled
>     field
>   OvmfPkg/MemEncryptSevLib: extend Es Workarea to include hv features
>   OvmfPkg: reserve Secrets page in MEMFD
>   OvmfPkg: reserve CPUID page for the SEV-SNP guest
>   OvmfPkg/ResetVector: validate the data pages used in SEC phase
>   OvmfPkg/ResetVector: invalidate the GHCB page
>   OvmfPkg: add library to support registering GHCB GPA
>   OvmfPkg/PlatformPei: register GHCB gpa for the SEV-SNP guest
>   UefiCpuPkg/MpLib: add support to register GHCB GPA when SEV-SNP is
>     enabled
>   OvmfPkg/AmdSevDxe: do not use extended PCI config space
>   OvmfPkg/MemEncryptSevLib: add support to validate system RAM
>   OvmfPkg/BaseMemEncryptSevLib: skip the pre-validated system RAM
>   OvmfPkg/MemEncryptSevLib: add support to validate > 4GB memory in PEI
>     phase
>   OvmfPkg/SecMain: pre-validate the memory used for decompressing Fv
>   OvmfPkg/PlatformPei: validate the system RAM when SNP is active
>   OvmfPkg/MemEncryptSevLib: Change the page state in the RMP table
>   OvmfPkg/MemEncryptSevLib: skip page state change for Mmio address
>   OvmfPkg/AmdSev: expose the SNP reserved pages through configuration
>     table
>   MdePkg/GHCB: increase the GHCB protocol max version
>
> Tom Lendacky (1):
>   UefiCpuPkg/MpInitLib: Use SEV-SNP AP Creation NAE event to launch APs
>
>  OvmfPkg/OvmfPkg.dec                           |  21 ++
>  UefiCpuPkg/UefiCpuPkg.dec                     |  11 +
>  OvmfPkg/AmdSev/AmdSevX64.dsc                  |   5 +-
>  OvmfPkg/Bhyve/BhyveX64.dsc                    |   5 +-
>  OvmfPkg/OvmfPkgIa32.dsc                       |   2 +
>  OvmfPkg/OvmfPkgIa32X64.dsc                    |   7 +-
>  OvmfPkg/OvmfPkgX64.dsc                        |   8 +-
>  OvmfPkg/OvmfXen.dsc                           |   5 +-
>  OvmfPkg/OvmfPkgX64.fdf                        |  17 +-
>  OvmfPkg/AmdSev/SecretDxe/SecretDxe.inf        |   4 +
>  OvmfPkg/AmdSev/SecretPei/SecretPei.inf        |   1 +
>  .../DxeMemEncryptSevLib.inf                   |   3 +
>  .../PeiMemEncryptSevLib.inf                   |   7 +
>  .../SecMemEncryptSevLib.inf                   |   3 +
>  .../GhcbRegisterLib/GhcbRegisterLib.inf       |  33 +++
>  OvmfPkg/PlatformPei/PlatformPei.inf           |   5 +
>  OvmfPkg/ResetVector/ResetVector.inf           |   4 +
>  OvmfPkg/Sec/SecMain.inf                       |   3 +
>  UefiCpuPkg/Library/MpInitLib/DxeMpInitLib.inf |   4 +
>  UefiCpuPkg/Library/MpInitLib/PeiMpInitLib.inf |   4 +
>  MdePkg/Include/Register/Amd/Ghcb.h            |   2 +-
>  .../Guid/ConfidentialComputingSecret.h        |  18 ++
>  OvmfPkg/Include/Library/GhcbRegisterLib.h     |  27 ++
>  OvmfPkg/Include/Library/MemEncryptSevLib.h    |  31 +-
>  .../X64/SnpPageStateChange.h                  |  31 ++
>  .../BaseMemEncryptSevLib/X64/VirtualMemory.h  |  19 ++
>  UefiCpuPkg/Library/MpInitLib/MpLib.h          |  19 ++
>  OvmfPkg/AmdSev/SecretDxe/SecretDxe.c          |  22 ++
>  OvmfPkg/AmdSev/SecretPei/SecretPei.c          |  15 +-
>  .../DxeMemEncryptSevLibInternal.c             |  27 ++
>  .../Ia32/MemEncryptSevLib.c                   |  17 ++
>  .../PeiMemEncryptSevLibInternal.c             |  27 ++
>  .../SecMemEncryptSevLibInternal.c             |  19 ++
>  .../X64/DxeSnpSystemRamValidate.c             |  40 +++
>  .../X64/PeiDxeVirtualMemory.c                 | 167 ++++++++++-
>  .../X64/PeiSnpSystemRamValidate.c             | 126 ++++++++
>  .../X64/SecSnpSystemRamValidate.c             |  36 +++
>  .../X64/SnpPageStateChangeInternal.c          | 230 +++++++++++++++
>  .../Library/GhcbRegisterLib/GhcbRegisterLib.c |  97 +++++++
>  OvmfPkg/PlatformPei/AmdSev.c                  |  81 ++++++
>  OvmfPkg/PlatformPei/MemDetect.c               |  12 +
>  OvmfPkg/Sec/SecMain.c                         | 106 +++++++
>  UefiCpuPkg/Library/MpInitLib/DxeMpLib.c       |  11 +-
>  .../MpInitLib/Ia32/SevSnpRmpAdjustInternal.c  |  31 ++
>  UefiCpuPkg/Library/MpInitLib/MpLib.c          | 274 ++++++++++++++++--
>  .../MpInitLib/X64/SevSnpRmpAdjustInternal.c   |  44 +++
>  OvmfPkg/FvmainCompactScratchEnd.fdf.inc       |   5 +
>  OvmfPkg/ResetVector/Ia16/ResetVectorVtf0.asm  |  23 ++
>  OvmfPkg/ResetVector/Ia32/PageTables64.asm     | 227 +++++++++++++++
>  OvmfPkg/ResetVector/ResetVector.nasmb         |   6 +
>  UefiCpuPkg/Library/MpInitLib/MpEqu.inc        |   1 +
>  UefiCpuPkg/Library/MpInitLib/X64/MpFuncs.nasm |  51 ++++
>  52 files changed, 1956 insertions(+), 38 deletions(-)
>  create mode 100644 OvmfPkg/Library/GhcbRegisterLib/GhcbRegisterLib.inf
>  create mode 100644 OvmfPkg/Include/Library/GhcbRegisterLib.h
>  create mode 100644 OvmfPkg/Library/BaseMemEncryptSevLib/X64/SnpPageStateChange.h
>  create mode 100644 OvmfPkg/Library/BaseMemEncryptSevLib/X64/DxeSnpSystemRamValidate.c
>  create mode 100644 OvmfPkg/Library/BaseMemEncryptSevLib/X64/PeiSnpSystemRamValidate.c
>  create mode 100644 OvmfPkg/Library/BaseMemEncryptSevLib/X64/SecSnpSystemRamValidate.c
>  create mode 100644 OvmfPkg/Library/BaseMemEncryptSevLib/X64/SnpPageStateChangeInternal.c
>  create mode 100644 OvmfPkg/Library/GhcbRegisterLib/GhcbRegisterLib.c
>  create mode 100644 UefiCpuPkg/Library/MpInitLib/Ia32/SevSnpRmpAdjustInternal.c
>  create mode 100644 UefiCpuPkg/Library/MpInitLib/X64/SevSnpRmpAdjustInternal.c
>


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

* Re: [edk2-devel] [RESEND PATCH RFC v3 00/22] Add AMD Secure Nested Paging (SEV-SNP) support
  2021-06-04  9:32 ` Laszlo Ersek
@ 2021-06-04 11:50   ` Brijesh Singh
  2021-06-04 13:09     ` Laszlo Ersek
  0 siblings, 1 reply; 57+ messages in thread
From: Brijesh Singh @ 2021-06-04 11:50 UTC (permalink / raw)
  To: Laszlo Ersek
  Cc: brijesh.singh, devel, James Bottomley, Min Xu, Jiewen Yao,
	Tom Lendacky, Jordan Justen, Erdem Aktas, Eric Dong, Ray Ni,
	Rahul Kumar, Ard Biesheuvel

Hi Laszlo,

On 6/4/21 4:32 AM, Laszlo Ersek wrote:
> Hi Brijesh,
>
> On 05/27/21 01:10, Brijesh Singh wrote:
>> (I missed adding devel@edk2.groups.io, resending the series)
>>
>> BZ: https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Fbugzilla.tianocore.org%2Fshow_bug.cgi%3Fid%3D3275&amp;data=04%7C01%7Cbrijesh.singh%40amd.com%7Ccc15730c886844d4783708d9273ba4e2%7C3dd8961fe4884e608e11a82d994e183d%7C0%7C0%7C637583960920109416%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C1000&amp;sdata=iN6ph%2BfbfEyY7xIeUAQEeB5FgSAjbeg6VNrU1P6zevU%3D&amp;reserved=0
>>
>> SEV-SNP builds upon existing SEV and SEV-ES functionality while adding
>> new hardware-based memory protections. SEV-SNP adds strong memory
>> integrity protection to help prevent malicious hypervisor-based
>> attacks like data replay, memory re-mapping and more in order to
>> create an isolated memory encryption environment.
>>
>> This series provides the basic building blocks to support booting the
>> SEV-SNP VMs, it does not cover all the security enhancement introduced
>> by the SEV-SNP such as interrupt protection.
>>
>> Many of the integrity guarantees of SEV-SNP are enforced through a new
>> structure called the Reverse Map Table (RMP). Adding a new page to
>> SEV-SNP VM requires a 2-step process. First, the hypervisor assigns a
>> page to the guest using the new RMPUPDATE instruction. This
>> transitions the page to guest-invalid. Second, the guest validates the
>> page using the new PVALIDATE instruction. The SEV-SNP VMs can use the
>> new "Page State Change Request NAE" defined in the GHCB specification
>> to ask hypervisor to add or remove page from the RMP table.
>>
>> Each page assigned to the SEV-SNP VM can either be validated or
>> unvalidated, as indicated by the Validated flag in the page's RMP
>> entry. There are two approaches that can be taken for the page
>> validation: Pre-validation and Lazy Validation.
>>
>> Under pre-validation, the pages are validated prior to first use. And
>> under lazy validation, pages are validated when first accessed. An
>> access to a unvalidated page results in a #VC exception, at which time
>> the exception handler may validate the page. Lazy validation requires
>> careful tracking of the validated pages to avoid validating the same
>> GPA more than once. The recently introduced "Unaccepted" memory type
>> can be used to communicate the unvalidated memory ranges to the Guest
>> OS.
>>
>> At this time we only support the pre-validation. OVMF detects all the
>> available system RAM in the PEI phase. When SEV-SNP is enabled, the
>> memory is validated before it is made available to the EDK2 core.
>>
>> This series does not implements the following SEV-SNP features yet:
>>
>> * CPUID filtering
>> * Lazy validation
>> * Interrupt security
>>
>> The series builds on SNP pre-patch posted here: https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Ftinyurl.com%2Fpu6admks&amp;data=04%7C01%7Cbrijesh.singh%40amd.com%7Ccc15730c886844d4783708d9273ba4e2%7C3dd8961fe4884e608e11a82d994e183d%7C0%7C0%7C637583960920119403%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C1000&amp;sdata=6NGf3nC%2BmDpPIUOIkSaQ0AW0LdDylM5eAvIH7oZdXWg%3D&amp;reserved=0
> That series ("[PATCH v3 00/13] Add GHCBv2 macro and helpers") has been
> merged at this point, as commit range dbc22a178546..adfa3327d4fc. [*]
>
>> Additional resources
>> ---------------------
>> SEV-SNP whitepaper
>> https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Fwww.amd.com%2Fsystem%2Ffiles%2FTechDocs%2FSEV-SNP-strengthening-vm-isolation-with-integrity-protection-and-more.pdf&amp;data=04%7C01%7Cbrijesh.singh%40amd.com%7Ccc15730c886844d4783708d9273ba4e2%7C3dd8961fe4884e608e11a82d994e183d%7C0%7C0%7C637583960920119403%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C1000&amp;sdata=YeTxsYnwYYiONaJ%2BizikzwjH7czwLVUxR7cwDAo%2F1qA%3D&amp;reserved=0
>>
>> APM 2: https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Fwww.amd.com%2Fsystem%2Ffiles%2FTechDocs%2F24593.pdf&amp;data=04%7C01%7Cbrijesh.singh%40amd.com%7Ccc15730c886844d4783708d9273ba4e2%7C3dd8961fe4884e608e11a82d994e183d%7C0%7C0%7C637583960920119403%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C1000&amp;sdata=%2BtOsP5zw%2BFPZzCBHQYYSCXTpRdxPXW4okrJmiRNwDH4%3D&amp;reserved=0 (section 15.36)
>>
>> The complete source is available at
>> https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2FAMDESE%2Fovmf%2Ftree%2Fsev-snp-rfc-2&amp;data=04%7C01%7Cbrijesh.singh%40amd.com%7Ccc15730c886844d4783708d9273ba4e2%7C3dd8961fe4884e608e11a82d994e183d%7C0%7C0%7C637583960920119403%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C1000&amp;sdata=L8FXX8X%2FITpLvY6JnXXMbZvTQ%2Br0VLsau5DRJ4kKYN8%3D&amp;reserved=0
> So, I'm having trouble applying this series. I attempted to apply it in
> preparation for reviewing patch#2 with a larger context, but I failed,
> as follows:
>
> - When I try applying the series with git-am, upon current master
>   (c410ad4da4b7), patch#21 ("UefiCpuPkg/MpInitLib: Use SEV-SNP AP
>   Creation NAE event to launch APs") does not apply.
>
>   AFAICT, that's because your modification of GetApResetVectorSize() did
>   not (could not) take into account Tom's commit dbc22a178546
>   ("UefiCpuPkg/MpInitLib: Allocate a separate SEV-ES AP reset stack
>   area", 2021-05-29).
>
> - Your remote branch (with HEAD @ 2dbd79823402) is based on upstream
>   commit 01c0ab90beb3 ("AzurePipelines: Add support for ArmPlatformPkg",
>   2021-04-28). If I try to rebase the branch from there to current
>   master (c410ad4da4b7), I get the following rebase action list:
>
>    1  pick 570829c5a0d6 MdePkg: Expand the SEV MSR to include the SNP definition
>    2  pick b9247f69bdfe MdePkg: Define the GHCB Hypervisor features
>    3  pick d09ed6d44ffd MdePkg: Define the Page State Change VMGEXIT structures
>    4  pick 7148b2684f87 MdePkg: Add AsmPvalidate() support
>    5  pick d6a2c2a0d625 OvmfPkg/BaseMemEncryptSevLib: Introduce MemEncryptSevClearMmioPageEncMask()
>    6  pick 9b1037d0d9ac OvmfPkg: Use MemEncryptSevClearMmioPageEncMask() to clear EncMask from Mmio
>    7  pick 556e8fc40179 OvmfPkg/BaseMemEncryptSevLib: Remove CacheFlush parameter
>    8  pick 03e27af79c61 OvmfPkg/VmgExitLib: Allow PMBASE register access in Dxe phase
>    9  pick a81925eeb1c6 OvmfPkg/MemEncryptSevLib: add MemEncryptSevSnpEnabled()
>   10  pick 3d443240f91c OvmfPkg: Reserve Secrets page in MEMFD
>   11  pick 94dad29970b0 OvmfPkg: Reserve CPUID page for the SEV-SNP guest
>   12  pick b3e3faa12b0f OvmfPkg: Validate the data pages used in the Reset vector and SEC phase
>   13  pick 62290e03c79a UefiCpuPkg: Define the SEV-SNP specific dynamic PCDs
>   14  pick c04e71dabf63 OvmfPkg/MemEncryptSevLib: extend the workarea to include SNP enabled field
>   15  pick 76072671f367 OvmfPkg/MemEncryptSevLib: Extend Es Workarea to include hv features
>   16  pick 2bf0eaf2beea OvmfPkg/ResetVector: Invalidate the GHCB page
>   17  pick 2f050b2a1033 OvmfPkg: Add a library to support registering GHCB GPA
>   18  pick b2681bdfbebc OvmfPkg: register GHCB gpa for the SEV-SNP guest
>   19  pick d9f1abb1ff35 UefiCpuPkg/MpLib: add support to register GHCB GPA when SEV-SNP is enabled
>   20  pick 814084815108 OvmfPkg/MemEncryptSevLib: Add support to validate system RAM
>   21  pick ec34893c46ab OvmfPkg/BaseMemEncryptSevLib: Skip the pre-validated system RAM
>   22  pick 37af54f86c3a OvmfPkg/MemEncryptSevLib: Add support to validate > 4GB memory in PEI phase
>   23  pick 25891f51499e OvmfPkg/SecMain: Pre-validate the memory used for decompressing Fv
>   24  pick f2f55135b562 OvmfPkg/PlatformPei: Validate the system RAM when SNP is active
>   25  pick a28b66462eae OvmfPkg/MemEncryptSevLib: Change the page state in the RMP table
>   26  pick b10c0e61913b OvmfPkg/AmdSev: Expose the SNP reserved pages through configuration table
>   27  pick 2dbd79823402 MdePkg/GHCB: Increase the GHCB protocol max version
>
> This is 27 patches, while your series contains 22 patches. It *seems*
> like some of these 27 patches have been merged via [*] already, but it's
> not easy to say which ones. In particular, I can't just drop a
> contiguous *prefix* of this rebase action list, because your *posted*
> patch#1 is "UefiCpuPkg: Define the SEV-SNP specific dynamic PCDs", but
> on your topic branch, that's patch#13! And if I dropped the 12 patches
> before that, then we'd be left with 27-12=15 patches, which obviously
> doesn't match your posted series consisting of 22 patches. I assume some
> of the patches may have been reordered, but I wouldn't like to guess.
>
> I believe we have two problems here: (1) the patch set does not apply to
> current master, (2) the posted patch set doesn't even match your remote
> topic branch.
>
> Problem (1) is somewhat expected (the master branch is expected to
> diverge over time), but problem (2) should never occur. Please never do
> this. If you provide a fetch URL + branch reference in your cover
> letter, then that remote topic branch must match the posted patches
> *forver*. It effectively becomes read only, same as your posted emails
> are read-only. If you need to modify the branch, please create a brand
> new topic branch (possibly with a new version number in the name), and
> rebase that branch.
>
> (It's also possible that you modified your local branch just before
> posting, without pushing it to the <https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2FAMDESE%2Fovmf&amp;data=04%7C01%7Cbrijesh.singh%40amd.com%7Ccc15730c886844d4783708d9273ba4e2%7C3dd8961fe4884e608e11a82d994e183d%7C0%7C0%7C637583960920119403%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C1000&amp;sdata=AbSYW0DGz0m1L7Xf9tkpF33coQE%2Brg1tDHYEFk9eKfc%3D&amp;reserved=0>
> repository afterwards, but that's quite disruptive too.)
>
> So... what do you want me to do?
>
> - Are at least patches 01 through 20 (as posted to the list)
>   authoritative? Should I review those?
>
> - Or would you like to rebase and repost the entire series (this time
>   keeping the posted version and the fetchable topic branch in sync)?

The main issue is I typed wrong branch name in the cover letter. The
branch name should be "sev-snp-rfc-3" and not "sev-snp-rfc-2". I
apologies for it :(. Ray asked the branch name and I replied him with
the correct branch.

https://github.com/AMDESE/ovmf/tree/sev-snp-rfc-3

This branch was based on commit 5531fd48ded1271b8775725355ab83994e4bc77c
from the upstream. 


> Thanks,
> Laszlo
>
>> GHCB spec:
>> https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Fdeveloper.amd.com%2Fwp-content%2Fresources%2F56421.pdf&amp;data=04%7C01%7Cbrijesh.singh%40amd.com%7Ccc15730c886844d4783708d9273ba4e2%7C3dd8961fe4884e608e11a82d994e183d%7C0%7C0%7C637583960920119403%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C1000&amp;sdata=DLMzZTZIu1kQa%2BKdDWhDsBatiP%2BnHRZEBMiAPwc%2FYIo%3D&amp;reserved=0
>>
>> SEV-SNP firmware specification:
>> https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Fdeveloper.amd.com%2Fsev%2F&amp;data=04%7C01%7Cbrijesh.singh%40amd.com%7Ccc15730c886844d4783708d9273ba4e2%7C3dd8961fe4884e608e11a82d994e183d%7C0%7C0%7C637583960920119403%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C1000&amp;sdata=eVdldUsQlNqFpDHGCjwl0vbh1Wn3D3dag5CLxybdSM8%3D&amp;reserved=0
>>
>> Cc: James Bottomley <jejb@linux.ibm.com>
>> Cc: Min Xu <min.m.xu@intel.com>
>> Cc: Jiewen Yao <jiewen.yao@intel.com>
>> Cc: Tom Lendacky <thomas.lendacky@amd.com>
>> Cc: Jordan Justen <jordan.l.justen@intel.com>
>> Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
>> Cc: Laszlo Ersek <lersek@redhat.com>
>> Cc: Erdem Aktas <erdemaktas@google.com>
>>
>> Changes since v2:
>>  * Add support for the AP creation.
>>  * Use the module-scoping override to make AmdSevDxe use the IO port for PCI reads.
>>  * Use the reserved memory type for CPUID and Secrets page.
>>  *
>> Changes since v1:
>>  * Drop the interval tree support to detect the pre-validated overlap region.
>>  * Use an array to keep track of pre-validated regions.
>>  * Add support to query the Hypervisor feature and verify that SNP feature is supported.
>>  * Introduce MemEncryptSevClearMmioPageEncMask() to clear the C-bit from MMIO ranges.
>>  * Pull the SevSecretDxe and SevSecretPei into OVMF package build.
>>  * Extend the SevSecretDxe to expose confidential computing blob location through
>>    EFI configuration table.
>>
>> Brijesh Singh (21):
>>   UefiCpuPkg: Define the SEV-SNP specific dynamic PCDs
>>   OvmfPkg/MemEncryptSevLib: add MemEncryptSevSnpEnabled()
>>   OvmfPkg/MemEncryptSevLib: extend the workarea to include SNP enabled
>>     field
>>   OvmfPkg/MemEncryptSevLib: extend Es Workarea to include hv features
>>   OvmfPkg: reserve Secrets page in MEMFD
>>   OvmfPkg: reserve CPUID page for the SEV-SNP guest
>>   OvmfPkg/ResetVector: validate the data pages used in SEC phase
>>   OvmfPkg/ResetVector: invalidate the GHCB page
>>   OvmfPkg: add library to support registering GHCB GPA
>>   OvmfPkg/PlatformPei: register GHCB gpa for the SEV-SNP guest
>>   UefiCpuPkg/MpLib: add support to register GHCB GPA when SEV-SNP is
>>     enabled
>>   OvmfPkg/AmdSevDxe: do not use extended PCI config space
>>   OvmfPkg/MemEncryptSevLib: add support to validate system RAM
>>   OvmfPkg/BaseMemEncryptSevLib: skip the pre-validated system RAM
>>   OvmfPkg/MemEncryptSevLib: add support to validate > 4GB memory in PEI
>>     phase
>>   OvmfPkg/SecMain: pre-validate the memory used for decompressing Fv
>>   OvmfPkg/PlatformPei: validate the system RAM when SNP is active
>>   OvmfPkg/MemEncryptSevLib: Change the page state in the RMP table
>>   OvmfPkg/MemEncryptSevLib: skip page state change for Mmio address
>>   OvmfPkg/AmdSev: expose the SNP reserved pages through configuration
>>     table
>>   MdePkg/GHCB: increase the GHCB protocol max version
>>
>> Tom Lendacky (1):
>>   UefiCpuPkg/MpInitLib: Use SEV-SNP AP Creation NAE event to launch APs
>>
>>  OvmfPkg/OvmfPkg.dec                           |  21 ++
>>  UefiCpuPkg/UefiCpuPkg.dec                     |  11 +
>>  OvmfPkg/AmdSev/AmdSevX64.dsc                  |   5 +-
>>  OvmfPkg/Bhyve/BhyveX64.dsc                    |   5 +-
>>  OvmfPkg/OvmfPkgIa32.dsc                       |   2 +
>>  OvmfPkg/OvmfPkgIa32X64.dsc                    |   7 +-
>>  OvmfPkg/OvmfPkgX64.dsc                        |   8 +-
>>  OvmfPkg/OvmfXen.dsc                           |   5 +-
>>  OvmfPkg/OvmfPkgX64.fdf                        |  17 +-
>>  OvmfPkg/AmdSev/SecretDxe/SecretDxe.inf        |   4 +
>>  OvmfPkg/AmdSev/SecretPei/SecretPei.inf        |   1 +
>>  .../DxeMemEncryptSevLib.inf                   |   3 +
>>  .../PeiMemEncryptSevLib.inf                   |   7 +
>>  .../SecMemEncryptSevLib.inf                   |   3 +
>>  .../GhcbRegisterLib/GhcbRegisterLib.inf       |  33 +++
>>  OvmfPkg/PlatformPei/PlatformPei.inf           |   5 +
>>  OvmfPkg/ResetVector/ResetVector.inf           |   4 +
>>  OvmfPkg/Sec/SecMain.inf                       |   3 +
>>  UefiCpuPkg/Library/MpInitLib/DxeMpInitLib.inf |   4 +
>>  UefiCpuPkg/Library/MpInitLib/PeiMpInitLib.inf |   4 +
>>  MdePkg/Include/Register/Amd/Ghcb.h            |   2 +-
>>  .../Guid/ConfidentialComputingSecret.h        |  18 ++
>>  OvmfPkg/Include/Library/GhcbRegisterLib.h     |  27 ++
>>  OvmfPkg/Include/Library/MemEncryptSevLib.h    |  31 +-
>>  .../X64/SnpPageStateChange.h                  |  31 ++
>>  .../BaseMemEncryptSevLib/X64/VirtualMemory.h  |  19 ++
>>  UefiCpuPkg/Library/MpInitLib/MpLib.h          |  19 ++
>>  OvmfPkg/AmdSev/SecretDxe/SecretDxe.c          |  22 ++
>>  OvmfPkg/AmdSev/SecretPei/SecretPei.c          |  15 +-
>>  .../DxeMemEncryptSevLibInternal.c             |  27 ++
>>  .../Ia32/MemEncryptSevLib.c                   |  17 ++
>>  .../PeiMemEncryptSevLibInternal.c             |  27 ++
>>  .../SecMemEncryptSevLibInternal.c             |  19 ++
>>  .../X64/DxeSnpSystemRamValidate.c             |  40 +++
>>  .../X64/PeiDxeVirtualMemory.c                 | 167 ++++++++++-
>>  .../X64/PeiSnpSystemRamValidate.c             | 126 ++++++++
>>  .../X64/SecSnpSystemRamValidate.c             |  36 +++
>>  .../X64/SnpPageStateChangeInternal.c          | 230 +++++++++++++++
>>  .../Library/GhcbRegisterLib/GhcbRegisterLib.c |  97 +++++++
>>  OvmfPkg/PlatformPei/AmdSev.c                  |  81 ++++++
>>  OvmfPkg/PlatformPei/MemDetect.c               |  12 +
>>  OvmfPkg/Sec/SecMain.c                         | 106 +++++++
>>  UefiCpuPkg/Library/MpInitLib/DxeMpLib.c       |  11 +-
>>  .../MpInitLib/Ia32/SevSnpRmpAdjustInternal.c  |  31 ++
>>  UefiCpuPkg/Library/MpInitLib/MpLib.c          | 274 ++++++++++++++++--
>>  .../MpInitLib/X64/SevSnpRmpAdjustInternal.c   |  44 +++
>>  OvmfPkg/FvmainCompactScratchEnd.fdf.inc       |   5 +
>>  OvmfPkg/ResetVector/Ia16/ResetVectorVtf0.asm  |  23 ++
>>  OvmfPkg/ResetVector/Ia32/PageTables64.asm     | 227 +++++++++++++++
>>  OvmfPkg/ResetVector/ResetVector.nasmb         |   6 +
>>  UefiCpuPkg/Library/MpInitLib/MpEqu.inc        |   1 +
>>  UefiCpuPkg/Library/MpInitLib/X64/MpFuncs.nasm |  51 ++++
>>  52 files changed, 1956 insertions(+), 38 deletions(-)
>>  create mode 100644 OvmfPkg/Library/GhcbRegisterLib/GhcbRegisterLib.inf
>>  create mode 100644 OvmfPkg/Include/Library/GhcbRegisterLib.h
>>  create mode 100644 OvmfPkg/Library/BaseMemEncryptSevLib/X64/SnpPageStateChange.h
>>  create mode 100644 OvmfPkg/Library/BaseMemEncryptSevLib/X64/DxeSnpSystemRamValidate.c
>>  create mode 100644 OvmfPkg/Library/BaseMemEncryptSevLib/X64/PeiSnpSystemRamValidate.c
>>  create mode 100644 OvmfPkg/Library/BaseMemEncryptSevLib/X64/SecSnpSystemRamValidate.c
>>  create mode 100644 OvmfPkg/Library/BaseMemEncryptSevLib/X64/SnpPageStateChangeInternal.c
>>  create mode 100644 OvmfPkg/Library/GhcbRegisterLib/GhcbRegisterLib.c
>>  create mode 100644 UefiCpuPkg/Library/MpInitLib/Ia32/SevSnpRmpAdjustInternal.c
>>  create mode 100644 UefiCpuPkg/Library/MpInitLib/X64/SevSnpRmpAdjustInternal.c
>>

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

* Re: [edk2-devel] [RESEND PATCH RFC v3 00/22] Add AMD Secure Nested Paging (SEV-SNP) support
  2021-06-04 11:50   ` Brijesh Singh
@ 2021-06-04 13:09     ` Laszlo Ersek
  2021-06-07 12:04       ` Laszlo Ersek
  0 siblings, 1 reply; 57+ messages in thread
From: Laszlo Ersek @ 2021-06-04 13:09 UTC (permalink / raw)
  To: Brijesh Singh
  Cc: devel, James Bottomley, Min Xu, Jiewen Yao, Tom Lendacky,
	Jordan Justen, Erdem Aktas, Eric Dong, Ray Ni, Rahul Kumar,
	Ard Biesheuvel

On 06/04/21 13:50, Brijesh Singh wrote:
> Hi Laszlo,
> 
> On 6/4/21 4:32 AM, Laszlo Ersek wrote:
>> Hi Brijesh,
>>
>> On 05/27/21 01:10, Brijesh Singh wrote:
>>> (I missed adding devel@edk2.groups.io, resending the series)
>>>
>>> BZ: https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Fbugzilla.tianocore.org%2Fshow_bug.cgi%3Fid%3D3275&amp;data=04%7C01%7Cbrijesh.singh%40amd.com%7Ccc15730c886844d4783708d9273ba4e2%7C3dd8961fe4884e608e11a82d994e183d%7C0%7C0%7C637583960920109416%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C1000&amp;sdata=iN6ph%2BfbfEyY7xIeUAQEeB5FgSAjbeg6VNrU1P6zevU%3D&amp;reserved=0
>>>
>>> SEV-SNP builds upon existing SEV and SEV-ES functionality while adding
>>> new hardware-based memory protections. SEV-SNP adds strong memory
>>> integrity protection to help prevent malicious hypervisor-based
>>> attacks like data replay, memory re-mapping and more in order to
>>> create an isolated memory encryption environment.
>>>
>>> This series provides the basic building blocks to support booting the
>>> SEV-SNP VMs, it does not cover all the security enhancement introduced
>>> by the SEV-SNP such as interrupt protection.
>>>
>>> Many of the integrity guarantees of SEV-SNP are enforced through a new
>>> structure called the Reverse Map Table (RMP). Adding a new page to
>>> SEV-SNP VM requires a 2-step process. First, the hypervisor assigns a
>>> page to the guest using the new RMPUPDATE instruction. This
>>> transitions the page to guest-invalid. Second, the guest validates the
>>> page using the new PVALIDATE instruction. The SEV-SNP VMs can use the
>>> new "Page State Change Request NAE" defined in the GHCB specification
>>> to ask hypervisor to add or remove page from the RMP table.
>>>
>>> Each page assigned to the SEV-SNP VM can either be validated or
>>> unvalidated, as indicated by the Validated flag in the page's RMP
>>> entry. There are two approaches that can be taken for the page
>>> validation: Pre-validation and Lazy Validation.
>>>
>>> Under pre-validation, the pages are validated prior to first use. And
>>> under lazy validation, pages are validated when first accessed. An
>>> access to a unvalidated page results in a #VC exception, at which time
>>> the exception handler may validate the page. Lazy validation requires
>>> careful tracking of the validated pages to avoid validating the same
>>> GPA more than once. The recently introduced "Unaccepted" memory type
>>> can be used to communicate the unvalidated memory ranges to the Guest
>>> OS.
>>>
>>> At this time we only support the pre-validation. OVMF detects all the
>>> available system RAM in the PEI phase. When SEV-SNP is enabled, the
>>> memory is validated before it is made available to the EDK2 core.
>>>
>>> This series does not implements the following SEV-SNP features yet:
>>>
>>> * CPUID filtering
>>> * Lazy validation
>>> * Interrupt security
>>>
>>> The series builds on SNP pre-patch posted here: https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Ftinyurl.com%2Fpu6admks&amp;data=04%7C01%7Cbrijesh.singh%40amd.com%7Ccc15730c886844d4783708d9273ba4e2%7C3dd8961fe4884e608e11a82d994e183d%7C0%7C0%7C637583960920119403%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C1000&amp;sdata=6NGf3nC%2BmDpPIUOIkSaQ0AW0LdDylM5eAvIH7oZdXWg%3D&amp;reserved=0
>> That series ("[PATCH v3 00/13] Add GHCBv2 macro and helpers") has been
>> merged at this point, as commit range dbc22a178546..adfa3327d4fc. [*]
>>
>>> Additional resources
>>> ---------------------
>>> SEV-SNP whitepaper
>>> https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Fwww.amd.com%2Fsystem%2Ffiles%2FTechDocs%2FSEV-SNP-strengthening-vm-isolation-with-integrity-protection-and-more.pdf&amp;data=04%7C01%7Cbrijesh.singh%40amd.com%7Ccc15730c886844d4783708d9273ba4e2%7C3dd8961fe4884e608e11a82d994e183d%7C0%7C0%7C637583960920119403%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C1000&amp;sdata=YeTxsYnwYYiONaJ%2BizikzwjH7czwLVUxR7cwDAo%2F1qA%3D&amp;reserved=0
>>>
>>> APM 2: https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Fwww.amd.com%2Fsystem%2Ffiles%2FTechDocs%2F24593.pdf&amp;data=04%7C01%7Cbrijesh.singh%40amd.com%7Ccc15730c886844d4783708d9273ba4e2%7C3dd8961fe4884e608e11a82d994e183d%7C0%7C0%7C637583960920119403%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C1000&amp;sdata=%2BtOsP5zw%2BFPZzCBHQYYSCXTpRdxPXW4okrJmiRNwDH4%3D&amp;reserved=0 (section 15.36)
>>>
>>> The complete source is available at
>>> https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2FAMDESE%2Fovmf%2Ftree%2Fsev-snp-rfc-2&amp;data=04%7C01%7Cbrijesh.singh%40amd.com%7Ccc15730c886844d4783708d9273ba4e2%7C3dd8961fe4884e608e11a82d994e183d%7C0%7C0%7C637583960920119403%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C1000&amp;sdata=L8FXX8X%2FITpLvY6JnXXMbZvTQ%2Br0VLsau5DRJ4kKYN8%3D&amp;reserved=0
>> So, I'm having trouble applying this series. I attempted to apply it in
>> preparation for reviewing patch#2 with a larger context, but I failed,
>> as follows:
>>
>> - When I try applying the series with git-am, upon current master
>>   (c410ad4da4b7), patch#21 ("UefiCpuPkg/MpInitLib: Use SEV-SNP AP
>>   Creation NAE event to launch APs") does not apply.
>>
>>   AFAICT, that's because your modification of GetApResetVectorSize() did
>>   not (could not) take into account Tom's commit dbc22a178546
>>   ("UefiCpuPkg/MpInitLib: Allocate a separate SEV-ES AP reset stack
>>   area", 2021-05-29).
>>
>> - Your remote branch (with HEAD @ 2dbd79823402) is based on upstream
>>   commit 01c0ab90beb3 ("AzurePipelines: Add support for ArmPlatformPkg",
>>   2021-04-28). If I try to rebase the branch from there to current
>>   master (c410ad4da4b7), I get the following rebase action list:
>>
>>    1  pick 570829c5a0d6 MdePkg: Expand the SEV MSR to include the SNP definition
>>    2  pick b9247f69bdfe MdePkg: Define the GHCB Hypervisor features
>>    3  pick d09ed6d44ffd MdePkg: Define the Page State Change VMGEXIT structures
>>    4  pick 7148b2684f87 MdePkg: Add AsmPvalidate() support
>>    5  pick d6a2c2a0d625 OvmfPkg/BaseMemEncryptSevLib: Introduce MemEncryptSevClearMmioPageEncMask()
>>    6  pick 9b1037d0d9ac OvmfPkg: Use MemEncryptSevClearMmioPageEncMask() to clear EncMask from Mmio
>>    7  pick 556e8fc40179 OvmfPkg/BaseMemEncryptSevLib: Remove CacheFlush parameter
>>    8  pick 03e27af79c61 OvmfPkg/VmgExitLib: Allow PMBASE register access in Dxe phase
>>    9  pick a81925eeb1c6 OvmfPkg/MemEncryptSevLib: add MemEncryptSevSnpEnabled()
>>   10  pick 3d443240f91c OvmfPkg: Reserve Secrets page in MEMFD
>>   11  pick 94dad29970b0 OvmfPkg: Reserve CPUID page for the SEV-SNP guest
>>   12  pick b3e3faa12b0f OvmfPkg: Validate the data pages used in the Reset vector and SEC phase
>>   13  pick 62290e03c79a UefiCpuPkg: Define the SEV-SNP specific dynamic PCDs
>>   14  pick c04e71dabf63 OvmfPkg/MemEncryptSevLib: extend the workarea to include SNP enabled field
>>   15  pick 76072671f367 OvmfPkg/MemEncryptSevLib: Extend Es Workarea to include hv features
>>   16  pick 2bf0eaf2beea OvmfPkg/ResetVector: Invalidate the GHCB page
>>   17  pick 2f050b2a1033 OvmfPkg: Add a library to support registering GHCB GPA
>>   18  pick b2681bdfbebc OvmfPkg: register GHCB gpa for the SEV-SNP guest
>>   19  pick d9f1abb1ff35 UefiCpuPkg/MpLib: add support to register GHCB GPA when SEV-SNP is enabled
>>   20  pick 814084815108 OvmfPkg/MemEncryptSevLib: Add support to validate system RAM
>>   21  pick ec34893c46ab OvmfPkg/BaseMemEncryptSevLib: Skip the pre-validated system RAM
>>   22  pick 37af54f86c3a OvmfPkg/MemEncryptSevLib: Add support to validate > 4GB memory in PEI phase
>>   23  pick 25891f51499e OvmfPkg/SecMain: Pre-validate the memory used for decompressing Fv
>>   24  pick f2f55135b562 OvmfPkg/PlatformPei: Validate the system RAM when SNP is active
>>   25  pick a28b66462eae OvmfPkg/MemEncryptSevLib: Change the page state in the RMP table
>>   26  pick b10c0e61913b OvmfPkg/AmdSev: Expose the SNP reserved pages through configuration table
>>   27  pick 2dbd79823402 MdePkg/GHCB: Increase the GHCB protocol max version
>>
>> This is 27 patches, while your series contains 22 patches. It *seems*
>> like some of these 27 patches have been merged via [*] already, but it's
>> not easy to say which ones. In particular, I can't just drop a
>> contiguous *prefix* of this rebase action list, because your *posted*
>> patch#1 is "UefiCpuPkg: Define the SEV-SNP specific dynamic PCDs", but
>> on your topic branch, that's patch#13! And if I dropped the 12 patches
>> before that, then we'd be left with 27-12=15 patches, which obviously
>> doesn't match your posted series consisting of 22 patches. I assume some
>> of the patches may have been reordered, but I wouldn't like to guess.
>>
>> I believe we have two problems here: (1) the patch set does not apply to
>> current master, (2) the posted patch set doesn't even match your remote
>> topic branch.
>>
>> Problem (1) is somewhat expected (the master branch is expected to
>> diverge over time), but problem (2) should never occur. Please never do
>> this. If you provide a fetch URL + branch reference in your cover
>> letter, then that remote topic branch must match the posted patches
>> *forver*. It effectively becomes read only, same as your posted emails
>> are read-only. If you need to modify the branch, please create a brand
>> new topic branch (possibly with a new version number in the name), and
>> rebase that branch.
>>
>> (It's also possible that you modified your local branch just before
>> posting, without pushing it to the <https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2FAMDESE%2Fovmf&amp;data=04%7C01%7Cbrijesh.singh%40amd.com%7Ccc15730c886844d4783708d9273ba4e2%7C3dd8961fe4884e608e11a82d994e183d%7C0%7C0%7C637583960920119403%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C1000&amp;sdata=AbSYW0DGz0m1L7Xf9tkpF33coQE%2Brg1tDHYEFk9eKfc%3D&amp;reserved=0>
>> repository afterwards, but that's quite disruptive too.)
>>
>> So... what do you want me to do?
>>
>> - Are at least patches 01 through 20 (as posted to the list)
>>   authoritative? Should I review those?
>>
>> - Or would you like to rebase and repost the entire series (this time
>>   keeping the posted version and the fetchable topic branch in sync)?
> 
> The main issue is I typed wrong branch name in the cover letter. The
> branch name should be "sev-snp-rfc-3" and not "sev-snp-rfc-2". I
> apologies for it :(. Ray asked the branch name and I replied him with
> the correct branch.

Hmmm... indeed, but that discussion happened off-list, namely under the
original posting of this v3 RFC set that did not reach the list. And now
I was working with my list folder.
> 
> https://github.com/AMDESE/ovmf/tree/sev-snp-rfc-3
> 
> This branch was based on commit 5531fd48ded1271b8775725355ab83994e4bc77c
> from the upstream. 

Right, this branch indeed averts problem (2); it is in sync with the
posted series. Thanks!

Problem (1) stays the same -- git-rebase reports the same issue as
git-am above, for patch#21. So, I'm going to review this version on the
list, but I'll skip patch#21 (or perhaps I'll attempt to make useful
comments there too, if I can).

Thanks!
Laszlo


> 
> 
>> Thanks,
>> Laszlo
>>
>>> GHCB spec:
>>> https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Fdeveloper.amd.com%2Fwp-content%2Fresources%2F56421.pdf&amp;data=04%7C01%7Cbrijesh.singh%40amd.com%7Ccc15730c886844d4783708d9273ba4e2%7C3dd8961fe4884e608e11a82d994e183d%7C0%7C0%7C637583960920119403%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C1000&amp;sdata=DLMzZTZIu1kQa%2BKdDWhDsBatiP%2BnHRZEBMiAPwc%2FYIo%3D&amp;reserved=0
>>>
>>> SEV-SNP firmware specification:
>>> https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Fdeveloper.amd.com%2Fsev%2F&amp;data=04%7C01%7Cbrijesh.singh%40amd.com%7Ccc15730c886844d4783708d9273ba4e2%7C3dd8961fe4884e608e11a82d994e183d%7C0%7C0%7C637583960920119403%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C1000&amp;sdata=eVdldUsQlNqFpDHGCjwl0vbh1Wn3D3dag5CLxybdSM8%3D&amp;reserved=0
>>>
>>> Cc: James Bottomley <jejb@linux.ibm.com>
>>> Cc: Min Xu <min.m.xu@intel.com>
>>> Cc: Jiewen Yao <jiewen.yao@intel.com>
>>> Cc: Tom Lendacky <thomas.lendacky@amd.com>
>>> Cc: Jordan Justen <jordan.l.justen@intel.com>
>>> Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
>>> Cc: Laszlo Ersek <lersek@redhat.com>
>>> Cc: Erdem Aktas <erdemaktas@google.com>
>>>
>>> Changes since v2:
>>>  * Add support for the AP creation.
>>>  * Use the module-scoping override to make AmdSevDxe use the IO port for PCI reads.
>>>  * Use the reserved memory type for CPUID and Secrets page.
>>>  *
>>> Changes since v1:
>>>  * Drop the interval tree support to detect the pre-validated overlap region.
>>>  * Use an array to keep track of pre-validated regions.
>>>  * Add support to query the Hypervisor feature and verify that SNP feature is supported.
>>>  * Introduce MemEncryptSevClearMmioPageEncMask() to clear the C-bit from MMIO ranges.
>>>  * Pull the SevSecretDxe and SevSecretPei into OVMF package build.
>>>  * Extend the SevSecretDxe to expose confidential computing blob location through
>>>    EFI configuration table.
>>>
>>> Brijesh Singh (21):
>>>   UefiCpuPkg: Define the SEV-SNP specific dynamic PCDs
>>>   OvmfPkg/MemEncryptSevLib: add MemEncryptSevSnpEnabled()
>>>   OvmfPkg/MemEncryptSevLib: extend the workarea to include SNP enabled
>>>     field
>>>   OvmfPkg/MemEncryptSevLib: extend Es Workarea to include hv features
>>>   OvmfPkg: reserve Secrets page in MEMFD
>>>   OvmfPkg: reserve CPUID page for the SEV-SNP guest
>>>   OvmfPkg/ResetVector: validate the data pages used in SEC phase
>>>   OvmfPkg/ResetVector: invalidate the GHCB page
>>>   OvmfPkg: add library to support registering GHCB GPA
>>>   OvmfPkg/PlatformPei: register GHCB gpa for the SEV-SNP guest
>>>   UefiCpuPkg/MpLib: add support to register GHCB GPA when SEV-SNP is
>>>     enabled
>>>   OvmfPkg/AmdSevDxe: do not use extended PCI config space
>>>   OvmfPkg/MemEncryptSevLib: add support to validate system RAM
>>>   OvmfPkg/BaseMemEncryptSevLib: skip the pre-validated system RAM
>>>   OvmfPkg/MemEncryptSevLib: add support to validate > 4GB memory in PEI
>>>     phase
>>>   OvmfPkg/SecMain: pre-validate the memory used for decompressing Fv
>>>   OvmfPkg/PlatformPei: validate the system RAM when SNP is active
>>>   OvmfPkg/MemEncryptSevLib: Change the page state in the RMP table
>>>   OvmfPkg/MemEncryptSevLib: skip page state change for Mmio address
>>>   OvmfPkg/AmdSev: expose the SNP reserved pages through configuration
>>>     table
>>>   MdePkg/GHCB: increase the GHCB protocol max version
>>>
>>> Tom Lendacky (1):
>>>   UefiCpuPkg/MpInitLib: Use SEV-SNP AP Creation NAE event to launch APs
>>>
>>>  OvmfPkg/OvmfPkg.dec                           |  21 ++
>>>  UefiCpuPkg/UefiCpuPkg.dec                     |  11 +
>>>  OvmfPkg/AmdSev/AmdSevX64.dsc                  |   5 +-
>>>  OvmfPkg/Bhyve/BhyveX64.dsc                    |   5 +-
>>>  OvmfPkg/OvmfPkgIa32.dsc                       |   2 +
>>>  OvmfPkg/OvmfPkgIa32X64.dsc                    |   7 +-
>>>  OvmfPkg/OvmfPkgX64.dsc                        |   8 +-
>>>  OvmfPkg/OvmfXen.dsc                           |   5 +-
>>>  OvmfPkg/OvmfPkgX64.fdf                        |  17 +-
>>>  OvmfPkg/AmdSev/SecretDxe/SecretDxe.inf        |   4 +
>>>  OvmfPkg/AmdSev/SecretPei/SecretPei.inf        |   1 +
>>>  .../DxeMemEncryptSevLib.inf                   |   3 +
>>>  .../PeiMemEncryptSevLib.inf                   |   7 +
>>>  .../SecMemEncryptSevLib.inf                   |   3 +
>>>  .../GhcbRegisterLib/GhcbRegisterLib.inf       |  33 +++
>>>  OvmfPkg/PlatformPei/PlatformPei.inf           |   5 +
>>>  OvmfPkg/ResetVector/ResetVector.inf           |   4 +
>>>  OvmfPkg/Sec/SecMain.inf                       |   3 +
>>>  UefiCpuPkg/Library/MpInitLib/DxeMpInitLib.inf |   4 +
>>>  UefiCpuPkg/Library/MpInitLib/PeiMpInitLib.inf |   4 +
>>>  MdePkg/Include/Register/Amd/Ghcb.h            |   2 +-
>>>  .../Guid/ConfidentialComputingSecret.h        |  18 ++
>>>  OvmfPkg/Include/Library/GhcbRegisterLib.h     |  27 ++
>>>  OvmfPkg/Include/Library/MemEncryptSevLib.h    |  31 +-
>>>  .../X64/SnpPageStateChange.h                  |  31 ++
>>>  .../BaseMemEncryptSevLib/X64/VirtualMemory.h  |  19 ++
>>>  UefiCpuPkg/Library/MpInitLib/MpLib.h          |  19 ++
>>>  OvmfPkg/AmdSev/SecretDxe/SecretDxe.c          |  22 ++
>>>  OvmfPkg/AmdSev/SecretPei/SecretPei.c          |  15 +-
>>>  .../DxeMemEncryptSevLibInternal.c             |  27 ++
>>>  .../Ia32/MemEncryptSevLib.c                   |  17 ++
>>>  .../PeiMemEncryptSevLibInternal.c             |  27 ++
>>>  .../SecMemEncryptSevLibInternal.c             |  19 ++
>>>  .../X64/DxeSnpSystemRamValidate.c             |  40 +++
>>>  .../X64/PeiDxeVirtualMemory.c                 | 167 ++++++++++-
>>>  .../X64/PeiSnpSystemRamValidate.c             | 126 ++++++++
>>>  .../X64/SecSnpSystemRamValidate.c             |  36 +++
>>>  .../X64/SnpPageStateChangeInternal.c          | 230 +++++++++++++++
>>>  .../Library/GhcbRegisterLib/GhcbRegisterLib.c |  97 +++++++
>>>  OvmfPkg/PlatformPei/AmdSev.c                  |  81 ++++++
>>>  OvmfPkg/PlatformPei/MemDetect.c               |  12 +
>>>  OvmfPkg/Sec/SecMain.c                         | 106 +++++++
>>>  UefiCpuPkg/Library/MpInitLib/DxeMpLib.c       |  11 +-
>>>  .../MpInitLib/Ia32/SevSnpRmpAdjustInternal.c  |  31 ++
>>>  UefiCpuPkg/Library/MpInitLib/MpLib.c          | 274 ++++++++++++++++--
>>>  .../MpInitLib/X64/SevSnpRmpAdjustInternal.c   |  44 +++
>>>  OvmfPkg/FvmainCompactScratchEnd.fdf.inc       |   5 +
>>>  OvmfPkg/ResetVector/Ia16/ResetVectorVtf0.asm  |  23 ++
>>>  OvmfPkg/ResetVector/Ia32/PageTables64.asm     | 227 +++++++++++++++
>>>  OvmfPkg/ResetVector/ResetVector.nasmb         |   6 +
>>>  UefiCpuPkg/Library/MpInitLib/MpEqu.inc        |   1 +
>>>  UefiCpuPkg/Library/MpInitLib/X64/MpFuncs.nasm |  51 ++++
>>>  52 files changed, 1956 insertions(+), 38 deletions(-)
>>>  create mode 100644 OvmfPkg/Library/GhcbRegisterLib/GhcbRegisterLib.inf
>>>  create mode 100644 OvmfPkg/Include/Library/GhcbRegisterLib.h
>>>  create mode 100644 OvmfPkg/Library/BaseMemEncryptSevLib/X64/SnpPageStateChange.h
>>>  create mode 100644 OvmfPkg/Library/BaseMemEncryptSevLib/X64/DxeSnpSystemRamValidate.c
>>>  create mode 100644 OvmfPkg/Library/BaseMemEncryptSevLib/X64/PeiSnpSystemRamValidate.c
>>>  create mode 100644 OvmfPkg/Library/BaseMemEncryptSevLib/X64/SecSnpSystemRamValidate.c
>>>  create mode 100644 OvmfPkg/Library/BaseMemEncryptSevLib/X64/SnpPageStateChangeInternal.c
>>>  create mode 100644 OvmfPkg/Library/GhcbRegisterLib/GhcbRegisterLib.c
>>>  create mode 100644 UefiCpuPkg/Library/MpInitLib/Ia32/SevSnpRmpAdjustInternal.c
>>>  create mode 100644 UefiCpuPkg/Library/MpInitLib/X64/SevSnpRmpAdjustInternal.c
>>>
> 


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

* Re: [PATCH RFC v3 02/22] OvmfPkg/MemEncryptSevLib: add MemEncryptSevSnpEnabled()
  2021-05-26 23:10 ` [PATCH RFC v3 02/22] OvmfPkg/MemEncryptSevLib: add MemEncryptSevSnpEnabled() Brijesh Singh
@ 2021-06-04 13:43   ` Laszlo Ersek
  0 siblings, 0 replies; 57+ messages in thread
From: Laszlo Ersek @ 2021-06-04 13:43 UTC (permalink / raw)
  To: Brijesh Singh, James Bottomley, Min Xu, Jiewen Yao, Tom Lendacky,
	Jordan Justen, Erdem Aktas, Eric Dong, Ray Ni, Rahul Kumar, devel
  Cc: Ard Biesheuvel

On 05/27/21 01:10, Brijesh Singh wrote:
> BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=3275
> 
> Create a function that can be used to determine if VM is running as an
> SEV-SNP guest.
> 
> Cc: James Bottomley <jejb@linux.ibm.com>
> Cc: Min Xu <min.m.xu@intel.com>
> Cc: Jiewen Yao <jiewen.yao@intel.com>
> Cc: Tom Lendacky <thomas.lendacky@amd.com>
> Cc: Jordan Justen <jordan.l.justen@intel.com>
> Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
> Cc: Laszlo Ersek <lersek@redhat.com>
> Cc: Erdem Aktas <erdemaktas@google.com>
> Signed-off-by: Brijesh Singh <brijesh.singh@amd.com>
> ---
>  OvmfPkg/Include/Library/MemEncryptSevLib.h    | 12 +++++++++
>  .../DxeMemEncryptSevLibInternal.c             | 27 +++++++++++++++++++
>  .../PeiMemEncryptSevLibInternal.c             | 27 +++++++++++++++++++
>  .../SecMemEncryptSevLibInternal.c             | 19 +++++++++++++
>  4 files changed, 85 insertions(+)
> 
> diff --git a/OvmfPkg/Include/Library/MemEncryptSevLib.h b/OvmfPkg/Include/Library/MemEncryptSevLib.h
> index 76d06c206c8b..2425d8ba0a36 100644
> --- a/OvmfPkg/Include/Library/MemEncryptSevLib.h
> +++ b/OvmfPkg/Include/Library/MemEncryptSevLib.h
> @@ -66,6 +66,18 @@ typedef enum {
>    MemEncryptSevAddressRangeError,
>  } MEM_ENCRYPT_SEV_ADDRESS_RANGE_STATE;
>  
> +/**
> +  Returns a boolean to indicate whether SEV-SNP is enabled
> +
> +  @retval TRUE           SEV-SNP is enabled
> +  @retval FALSE          SEV-SNP is not enabled
> +**/
> +BOOLEAN
> +EFIAPI
> +MemEncryptSevSnpIsEnabled (
> +  VOID
> +  );
> +
>  /**
>    Returns a boolean to indicate whether SEV-ES is enabled.
>  
> diff --git a/OvmfPkg/Library/BaseMemEncryptSevLib/DxeMemEncryptSevLibInternal.c b/OvmfPkg/Library/BaseMemEncryptSevLib/DxeMemEncryptSevLibInternal.c
> index 2816f859a0c4..057129723824 100644
> --- a/OvmfPkg/Library/BaseMemEncryptSevLib/DxeMemEncryptSevLibInternal.c
> +++ b/OvmfPkg/Library/BaseMemEncryptSevLib/DxeMemEncryptSevLibInternal.c
> @@ -19,6 +19,7 @@
>  
>  STATIC BOOLEAN mSevStatus = FALSE;
>  STATIC BOOLEAN mSevEsStatus = FALSE;
> +STATIC BOOLEAN mSevSnpStatus = FALSE;
>  STATIC BOOLEAN mSevStatusChecked = FALSE;
>  
>  STATIC UINT64  mSevEncryptionMask = 0;
> @@ -82,11 +83,37 @@ InternalMemEncryptSevStatus (
>      if (Msr.Bits.SevEsBit) {
>        mSevEsStatus = TRUE;
>      }
> +
> +    //
> +    // Check MSR_0xC0010131 Bit 2 (Sev-Snp Enabled)
> +    //
> +    if (Msr.Bits.SevSnpBit) {
> +      mSevSnpStatus = TRUE;
> +    }
>    }
>  
>    mSevStatusChecked = TRUE;
>  }
>  
> +/**
> +  Returns a boolean to indicate whether SEV-SNP is enabled.
> +
> +  @retval TRUE           SEV-SNP is enabled
> +  @retval FALSE          SEV-SNP is not enabled
> +**/
> +BOOLEAN
> +EFIAPI
> +MemEncryptSevSnpIsEnabled (
> +  VOID
> +  )
> +{
> +  if (!mSevStatusChecked) {
> +    InternalMemEncryptSevStatus ();
> +  }
> +
> +  return mSevSnpStatus;
> +}
> +
>  /**
>    Returns a boolean to indicate whether SEV-ES is enabled.
>  
> diff --git a/OvmfPkg/Library/BaseMemEncryptSevLib/PeiMemEncryptSevLibInternal.c b/OvmfPkg/Library/BaseMemEncryptSevLib/PeiMemEncryptSevLibInternal.c
> index e2fd109d120f..b561f211f577 100644
> --- a/OvmfPkg/Library/BaseMemEncryptSevLib/PeiMemEncryptSevLibInternal.c
> +++ b/OvmfPkg/Library/BaseMemEncryptSevLib/PeiMemEncryptSevLibInternal.c
> @@ -19,6 +19,7 @@
>  
>  STATIC BOOLEAN mSevStatus = FALSE;
>  STATIC BOOLEAN mSevEsStatus = FALSE;
> +STATIC BOOLEAN mSevSnpStatus = FALSE;
>  STATIC BOOLEAN mSevStatusChecked = FALSE;
>  
>  STATIC UINT64  mSevEncryptionMask = 0;
> @@ -82,11 +83,37 @@ InternalMemEncryptSevStatus (
>      if (Msr.Bits.SevEsBit) {
>        mSevEsStatus = TRUE;
>      }
> +
> +    //
> +    // Check MSR_0xC0010131 Bit 2 (Sev-Snp Enabled)
> +    //
> +    if (Msr.Bits.SevSnpBit) {
> +      mSevSnpStatus = TRUE;
> +    }
>    }
>  
>    mSevStatusChecked = TRUE;
>  }
>  
> +/**
> +  Returns a boolean to indicate whether SEV-SNP is enabled.
> +
> +  @retval TRUE           SEV-SNP is enabled
> +  @retval FALSE          SEV-SNP is not enabled
> +**/
> +BOOLEAN
> +EFIAPI
> +MemEncryptSevSnpIsEnabled (
> +  VOID
> +  )
> +{
> +  if (!mSevStatusChecked) {
> +    InternalMemEncryptSevStatus ();
> +  }
> +
> +  return mSevSnpStatus;
> +}
> +
>  /**
>    Returns a boolean to indicate whether SEV-ES is enabled.
>  
> diff --git a/OvmfPkg/Library/BaseMemEncryptSevLib/SecMemEncryptSevLibInternal.c b/OvmfPkg/Library/BaseMemEncryptSevLib/SecMemEncryptSevLibInternal.c
> index 56d8f3f3183f..69852779e2ff 100644
> --- a/OvmfPkg/Library/BaseMemEncryptSevLib/SecMemEncryptSevLibInternal.c
> +++ b/OvmfPkg/Library/BaseMemEncryptSevLib/SecMemEncryptSevLibInternal.c
> @@ -62,6 +62,25 @@ InternalMemEncryptSevStatus (
>    return ReadSevMsr ? AsmReadMsr32 (MSR_SEV_STATUS) : 0;
>  }
>  
> +/**
> +  Returns a boolean to indicate whether SEV-SNP is enabled.
> +
> +  @retval TRUE           SEV-SNP is enabled
> +  @retval FALSE          SEV-SNP is not enabled
> +**/
> +BOOLEAN
> +EFIAPI
> +MemEncryptSevSnpIsEnabled (
> +  VOID
> +  )
> +{
> +  MSR_SEV_STATUS_REGISTER           Msr;
> +
> +  Msr.Uint32 = InternalMemEncryptSevStatus ();
> +
> +  return Msr.Bits.SevSnpBit ? TRUE : FALSE;

According to the edk2 coding style, this should be written as:

  return (BOOLEAN)(Msr.Bits.SevSnpBit != 0);

primarily because "Msr.Bits.SevSnpBit" does not have type BOOLEAN, so it
should not be used stand-alone in a logical context -- instead, it
should be compared with zero explicitly.

However, I see that the other two functions MemEncryptSevEsIsEnabled()
and MemEncryptSevIsEnabled() in this library instance use the same
pattern. I agree consistency is more important here. And I don't think
we should add more patches just for updating the style there. These
functions are closely located together in the same source file; if we
ever update the style, it's not a big deal to update them together.

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

Thanks
Laszlo


> +}
> +
>  /**
>    Returns a boolean to indicate whether SEV-ES is enabled.
>  
> 


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

* Re: [PATCH RFC v3 03/22] OvmfPkg/MemEncryptSevLib: extend the workarea to include SNP enabled field
  2021-05-26 23:10 ` [PATCH RFC v3 03/22] OvmfPkg/MemEncryptSevLib: extend the workarea to include SNP enabled field Brijesh Singh
@ 2021-06-04 14:15   ` Laszlo Ersek
  2021-06-07 11:20     ` [edk2-devel] " Laszlo Ersek
  0 siblings, 1 reply; 57+ messages in thread
From: Laszlo Ersek @ 2021-06-04 14:15 UTC (permalink / raw)
  To: Brijesh Singh, James Bottomley, Min Xu, Jiewen Yao, Tom Lendacky,
	Jordan Justen, Erdem Aktas, Eric Dong, Ray Ni, Rahul Kumar, devel
  Cc: Ard Biesheuvel

On 05/27/21 01:10, Brijesh Singh wrote:
> BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=3275
> 
> Extend the workarea to include the SEV-SNP enabled fields. This will be set
> when SEV-SNP is active in the guest VM.
> 
> Cc: James Bottomley <jejb@linux.ibm.com>
> Cc: Min Xu <min.m.xu@intel.com>
> Cc: Jiewen Yao <jiewen.yao@intel.com>
> Cc: Tom Lendacky <thomas.lendacky@amd.com>
> Cc: Jordan Justen <jordan.l.justen@intel.com>
> Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
> Cc: Laszlo Ersek <lersek@redhat.com>
> Cc: Erdem Aktas <erdemaktas@google.com>
> Signed-off-by: Brijesh Singh <brijesh.singh@amd.com>
> ---
>  OvmfPkg/PlatformPei/PlatformPei.inf        |  1 +
>  OvmfPkg/Include/Library/MemEncryptSevLib.h |  3 ++-
>  OvmfPkg/PlatformPei/AmdSev.c               | 26 ++++++++++++++++++++++
>  OvmfPkg/ResetVector/Ia32/PageTables64.asm  | 12 ++++++++++
>  OvmfPkg/ResetVector/ResetVector.nasmb      |  1 +
>  5 files changed, 42 insertions(+), 1 deletion(-)

(1) Please split this in two patches -- the PlatformPei changes should
be a separate patch. And, I think those should come second, the
ResetVector + header file change should come first.

> 
> diff --git a/OvmfPkg/PlatformPei/PlatformPei.inf b/OvmfPkg/PlatformPei/PlatformPei.inf
> index 6ef77ba7bb21..bc1dcac48343 100644
> --- a/OvmfPkg/PlatformPei/PlatformPei.inf
> +++ b/OvmfPkg/PlatformPei/PlatformPei.inf
> @@ -110,6 +110,7 @@ [Pcd]
>    gUefiCpuPkgTokenSpaceGuid.PcdCpuBootLogicalProcessorNumber
>    gUefiCpuPkgTokenSpaceGuid.PcdCpuApStackSize
>    gUefiCpuPkgTokenSpaceGuid.PcdSevEsIsEnabled
> +  gUefiCpuPkgTokenSpaceGuid.PcdSevSnpIsEnabled
>  
>  [FixedPcd]
>    gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseAddress
> diff --git a/OvmfPkg/Include/Library/MemEncryptSevLib.h b/OvmfPkg/Include/Library/MemEncryptSevLib.h
> index 2425d8ba0a36..24507de55c5d 100644
> --- a/OvmfPkg/Include/Library/MemEncryptSevLib.h
> +++ b/OvmfPkg/Include/Library/MemEncryptSevLib.h
> @@ -49,7 +49,8 @@ typedef struct {
>  //
>  typedef struct _SEC_SEV_ES_WORK_AREA {
>    UINT8    SevEsEnabled;
> -  UINT8    Reserved1[7];
> +  UINT8    SevSnpEnabled;
> +  UINT8    Reserved2[6];
>  
>    UINT64   RandomData;
>  
> diff --git a/OvmfPkg/PlatformPei/AmdSev.c b/OvmfPkg/PlatformPei/AmdSev.c
> index a8bf610022ba..67b78fd5fa36 100644
> --- a/OvmfPkg/PlatformPei/AmdSev.c
> +++ b/OvmfPkg/PlatformPei/AmdSev.c
> @@ -22,6 +22,27 @@
>  
>  #include "Platform.h"
>  
> +/**
> +
> +  Initialize SEV-SNP support if running as an SEV-SNP guest.
> +
> +  **/
> +STATIC
> +VOID
> +AmdSevSnpInitialize (
> +  VOID
> +  )
> +{
> +  RETURN_STATUS        PcdStatus;
> +
> +  if (!MemEncryptSevSnpIsEnabled ()) {
> +    return;
> +  }
> +
> +  PcdStatus = PcdSetBoolS (PcdSevSnpIsEnabled, TRUE);
> +  ASSERT_RETURN_ERROR (PcdStatus);
> +}
> +
>  /**
>  
>    Initialize SEV-ES support if running as an SEV-ES guest.
> @@ -209,4 +230,9 @@ AmdSevInitialize (
>    // Check and perform SEV-ES initialization if required.
>    //
>    AmdSevEsInitialize ();
> +
> +  //
> +  // Check and perform SEV-SNP initialization if required.
> +  //
> +  AmdSevSnpInitialize ();
>  }
> diff --git a/OvmfPkg/ResetVector/Ia32/PageTables64.asm b/OvmfPkg/ResetVector/Ia32/PageTables64.asm
> index 5fae8986d9da..6838cdeec9c3 100644
> --- a/OvmfPkg/ResetVector/Ia32/PageTables64.asm
> +++ b/OvmfPkg/ResetVector/Ia32/PageTables64.asm
> @@ -81,6 +81,11 @@ CheckSevFeatures:
>      ; the MSR check below will set the first byte of the workarea to one.
>      mov     byte[SEV_ES_WORK_AREA], 0
>  
> +    ; Set the SevSnpEnabled field in workarea to zero to communicate to the SEC
> +    ; phase that SEV-SNP is not enabled. If SEV-SNP is enabled, this function
> +    ; will set it to 1.
> +    mov       byte[SEV_ES_WORK_AREA_SNP], 0
> +
>      ;
>      ; Set up exception handlers to check for SEV-ES
>      ;   Load temporary RAM stack based on PCDs (see SevEsIdtVmmComm for
> @@ -136,6 +141,13 @@ CheckSevFeatures:
>      ; phase that SEV-ES is enabled.
>      mov       byte[SEV_ES_WORK_AREA], 1
>  
> +    bt        eax, 2
> +    jnc       GetSevEncBit
> +
> +    ; Set the second byte of the workarea to one to communicate to the SEC
> +    ; phase that the SEV-SNP is enabled
> +    mov       byte[SEV_ES_WORK_AREA_SNP], 1
> +
>  GetSevEncBit:
>      ; Get pte bit position to enable memory encryption
>      ; CPUID Fn8000_001F[EBX] - Bits 5:0

(2) Please mention in the commit message (of the ResetVector patch),
and/or a comment here in the code, that SEV-SNP is never enabled if
SEV-ES is disabled.

Section "15.34.10 SEV_STATUS MSR" in the APM (doc#24593 v3.37) does not
spell out this dependency.

Furthermore, the mSevStatus / mSevEsStatus / mSevSnpStatus variable
assignments in patch#2 do not form a "dependency cascade" like the one
seen here in the reset vector code.

While "SEV-ES depends on SEV" seems obvious to me (and so the related,
existent jumps in the assembly code are not surprising), the statement
"SEV-SNP depends on SEV-ES" is not *that* obvious to me. Thus a comment
would be welcome.

For *both* patches split out of this one:

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

Thanks
Laszlo

> diff --git a/OvmfPkg/ResetVector/ResetVector.nasmb b/OvmfPkg/ResetVector/ResetVector.nasmb
> index 5fbacaed5f9d..1971557b1c00 100644
> --- a/OvmfPkg/ResetVector/ResetVector.nasmb
> +++ b/OvmfPkg/ResetVector/ResetVector.nasmb
> @@ -73,6 +73,7 @@
>    %define GHCB_BASE (FixedPcdGet32 (PcdOvmfSecGhcbBase))
>    %define GHCB_SIZE (FixedPcdGet32 (PcdOvmfSecGhcbSize))
>    %define SEV_ES_WORK_AREA (FixedPcdGet32 (PcdSevEsWorkAreaBase))
> +  %define SEV_ES_WORK_AREA_SNP (FixedPcdGet32 (PcdSevEsWorkAreaBase) + 1)
>    %define SEV_ES_WORK_AREA_RDRAND (FixedPcdGet32 (PcdSevEsWorkAreaBase) + 8)
>    %define SEV_ES_WORK_AREA_ENC_MASK (FixedPcdGet32 (PcdSevEsWorkAreaBase) + 16)
>    %define SEV_ES_VC_TOP_OF_STACK (FixedPcdGet32 (PcdOvmfSecPeiTempRamBase) + FixedPcdGet32 (PcdOvmfSecPeiTempRamSize))
> 


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

* Re: [edk2-devel] [PATCH RFC v3 03/22] OvmfPkg/MemEncryptSevLib: extend the workarea to include SNP enabled field
  2021-06-04 14:15   ` Laszlo Ersek
@ 2021-06-07 11:20     ` Laszlo Ersek
  2021-06-07 13:00       ` Brijesh Singh
  0 siblings, 1 reply; 57+ messages in thread
From: Laszlo Ersek @ 2021-06-07 11:20 UTC (permalink / raw)
  To: Brijesh Singh, James Bottomley, Min Xu, Jiewen Yao, Tom Lendacky,
	Jordan Justen, Erdem Aktas, Eric Dong, Ray Ni, Rahul Kumar, devel
  Cc: Ard Biesheuvel

On 06/04/21 16:15, Laszlo Ersek wrote:
> On 05/27/21 01:10, Brijesh Singh wrote:
>> BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=3275
>>
>> Extend the workarea to include the SEV-SNP enabled fields. This will be set
>> when SEV-SNP is active in the guest VM.
>>
>> Cc: James Bottomley <jejb@linux.ibm.com>
>> Cc: Min Xu <min.m.xu@intel.com>
>> Cc: Jiewen Yao <jiewen.yao@intel.com>
>> Cc: Tom Lendacky <thomas.lendacky@amd.com>
>> Cc: Jordan Justen <jordan.l.justen@intel.com>
>> Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
>> Cc: Laszlo Ersek <lersek@redhat.com>
>> Cc: Erdem Aktas <erdemaktas@google.com>
>> Signed-off-by: Brijesh Singh <brijesh.singh@amd.com>
>> ---
>>  OvmfPkg/PlatformPei/PlatformPei.inf        |  1 +
>>  OvmfPkg/Include/Library/MemEncryptSevLib.h |  3 ++-
>>  OvmfPkg/PlatformPei/AmdSev.c               | 26 ++++++++++++++++++++++
>>  OvmfPkg/ResetVector/Ia32/PageTables64.asm  | 12 ++++++++++
>>  OvmfPkg/ResetVector/ResetVector.nasmb      |  1 +
>>  5 files changed, 42 insertions(+), 1 deletion(-)
>
> (1) Please split this in two patches -- the PlatformPei changes should
> be a separate patch. And, I think those should come second, the
> ResetVector + header file change should come first.
>
>>
>> diff --git a/OvmfPkg/PlatformPei/PlatformPei.inf b/OvmfPkg/PlatformPei/PlatformPei.inf
>> index 6ef77ba7bb21..bc1dcac48343 100644
>> --- a/OvmfPkg/PlatformPei/PlatformPei.inf
>> +++ b/OvmfPkg/PlatformPei/PlatformPei.inf
>> @@ -110,6 +110,7 @@ [Pcd]
>>    gUefiCpuPkgTokenSpaceGuid.PcdCpuBootLogicalProcessorNumber
>>    gUefiCpuPkgTokenSpaceGuid.PcdCpuApStackSize
>>    gUefiCpuPkgTokenSpaceGuid.PcdSevEsIsEnabled
>> +  gUefiCpuPkgTokenSpaceGuid.PcdSevSnpIsEnabled
>>
>>  [FixedPcd]
>>    gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseAddress
>> diff --git a/OvmfPkg/Include/Library/MemEncryptSevLib.h b/OvmfPkg/Include/Library/MemEncryptSevLib.h
>> index 2425d8ba0a36..24507de55c5d 100644
>> --- a/OvmfPkg/Include/Library/MemEncryptSevLib.h
>> +++ b/OvmfPkg/Include/Library/MemEncryptSevLib.h
>> @@ -49,7 +49,8 @@ typedef struct {
>>  //
>>  typedef struct _SEC_SEV_ES_WORK_AREA {
>>    UINT8    SevEsEnabled;
>> -  UINT8    Reserved1[7];
>> +  UINT8    SevSnpEnabled;
>> +  UINT8    Reserved2[6];
>>
>>    UINT64   RandomData;
>>
>> diff --git a/OvmfPkg/PlatformPei/AmdSev.c b/OvmfPkg/PlatformPei/AmdSev.c
>> index a8bf610022ba..67b78fd5fa36 100644
>> --- a/OvmfPkg/PlatformPei/AmdSev.c
>> +++ b/OvmfPkg/PlatformPei/AmdSev.c
>> @@ -22,6 +22,27 @@
>>
>>  #include "Platform.h"
>>
>> +/**
>> +
>> +  Initialize SEV-SNP support if running as an SEV-SNP guest.
>> +
>> +  **/
>> +STATIC
>> +VOID
>> +AmdSevSnpInitialize (
>> +  VOID
>> +  )
>> +{
>> +  RETURN_STATUS        PcdStatus;
>> +
>> +  if (!MemEncryptSevSnpIsEnabled ()) {
>> +    return;
>> +  }
>> +
>> +  PcdStatus = PcdSetBoolS (PcdSevSnpIsEnabled, TRUE);
>> +  ASSERT_RETURN_ERROR (PcdStatus);
>> +}
>> +
>>  /**
>>
>>    Initialize SEV-ES support if running as an SEV-ES guest.
>> @@ -209,4 +230,9 @@ AmdSevInitialize (
>>    // Check and perform SEV-ES initialization if required.
>>    //
>>    AmdSevEsInitialize ();
>> +
>> +  //
>> +  // Check and perform SEV-SNP initialization if required.
>> +  //
>> +  AmdSevSnpInitialize ();
>>  }
>> diff --git a/OvmfPkg/ResetVector/Ia32/PageTables64.asm b/OvmfPkg/ResetVector/Ia32/PageTables64.asm
>> index 5fae8986d9da..6838cdeec9c3 100644
>> --- a/OvmfPkg/ResetVector/Ia32/PageTables64.asm
>> +++ b/OvmfPkg/ResetVector/Ia32/PageTables64.asm
>> @@ -81,6 +81,11 @@ CheckSevFeatures:
>>      ; the MSR check below will set the first byte of the workarea to one.
>>      mov     byte[SEV_ES_WORK_AREA], 0
>>
>> +    ; Set the SevSnpEnabled field in workarea to zero to communicate to the SEC
>> +    ; phase that SEV-SNP is not enabled. If SEV-SNP is enabled, this function
>> +    ; will set it to 1.
>> +    mov       byte[SEV_ES_WORK_AREA_SNP], 0
>> +
>>      ;
>>      ; Set up exception handlers to check for SEV-ES
>>      ;   Load temporary RAM stack based on PCDs (see SevEsIdtVmmComm for
>> @@ -136,6 +141,13 @@ CheckSevFeatures:
>>      ; phase that SEV-ES is enabled.
>>      mov       byte[SEV_ES_WORK_AREA], 1
>>
>> +    bt        eax, 2
>> +    jnc       GetSevEncBit
>> +
>> +    ; Set the second byte of the workarea to one to communicate to the SEC
>> +    ; phase that the SEV-SNP is enabled
>> +    mov       byte[SEV_ES_WORK_AREA_SNP], 1
>> +
>>  GetSevEncBit:
>>      ; Get pte bit position to enable memory encryption
>>      ; CPUID Fn8000_001F[EBX] - Bits 5:0
>
> (2) Please mention in the commit message (of the ResetVector patch),
> and/or a comment here in the code, that SEV-SNP is never enabled if
> SEV-ES is disabled.
>
> Section "15.34.10 SEV_STATUS MSR" in the APM (doc#24593 v3.37) does not
> spell out this dependency.
>
> Furthermore, the mSevStatus / mSevEsStatus / mSevSnpStatus variable
> assignments in patch#2 do not form a "dependency cascade" like the one
> seen here in the reset vector code.
>
> While "SEV-ES depends on SEV" seems obvious to me (and so the related,
> existent jumps in the assembly code are not surprising), the statement
> "SEV-SNP depends on SEV-ES" is not *that* obvious to me. Thus a comment
> would be welcome.
>
> For *both* patches split out of this one:
>
> Reviewed-by: Laszlo Ersek <lersek@redhat.com>

(3) Actually, no.

This patch should be reduced to the following files only:

- OvmfPkg/PlatformPei/AmdSev.c
- OvmfPkg/PlatformPei/PlatformPei.inf

and the following changes should be dropped completely:

- OvmfPkg/Include/Library/MemEncryptSevLib.h
- OvmfPkg/ResetVector/Ia32/PageTables64.asm
- OvmfPkg/ResetVector/ResetVector.nasmb

Specifically, the "SEC_SEV_ES_WORK_AREA.SevSnpEnabled" field should
never be introduced.

The reason is apparent only from patch #10 -- "OvmfPkg/PlatformPei:
register GHCB gpa for the SEV-SNP guest".

The core idea is that in patch#10, in the SEC module, you can implement
SevSnpIsEnabled() by just reading MSR_SEV_STATUS, and checking the SNP
bit. Namely, while the SevSnpIsEnabled() call is made in
SevEsProtocolCheck(), i.e., before exception handling is set up in the
SEC module -- and so you indeed cannot call CPUID --, you don't *have*
to call CPUID at that call site. Where you call SevSnpIsEnabled() in
SevEsProtocolCheck(), you already know that SEV-ES is enabled, so it's
safe to just read the exact same SEV status MSR that the SEV-ES status
comes from in the first place, without any CPUID safety check.

(

  General request: please be explicit in the commit messages about the
  data flow between modules, and why you are doing what you are doing.
  Arriving at the above analysis took me 3+ hours this morning, when --
  while reviewing patch#4 -- I took issue with the proliferation of the
  new fields in SEC_SEV_ES_WORK_AREA. SEC_SEV_ES_WORK_AREA is *not* a
  convenience dump. We should restrict its use as much as possible.

  I double-checked how SEC_SEV_ES_WORK_AREA had evolved historically:


  * SEC_SEV_ES_WORK_AREA.SevEsEnabled:

     1  43c3df78460d OvmfPkg: Reserve a page in memory for the SEV-ES usage
     2  0731236fc108 OvmfPkg/PlatformPei: Reserve SEV-ES work area if S3 is supported
     3  8a2732186a53 OvmfPkg/ResetVector: Add support for a 32-bit SEV check
     4  13e5492bfdf3 OvmfPkg/Sec: Add #VC exception handling for Sec phase

  The "SEC_SEV_ES_WORK_AREA.SevEsEnabled" field is important for the
  following reason:

  - in an SEV-ES guest, just learning about SEV requires exception
    handling; thus, the Reset Vector sets up exception handling
    *unconditionally*,

  - in SEC, we deal with exception handling regardless of SEV-ES, but
    *how* we do that is conditional on SEV-ES.

  This means that caching the SEV-ES presence from the Reset Vector to
  SEC makes a lot of sense. Given that in the Reset Vector we have
  unconditional exception handling, and then in SEC we have a cached
  result, we are allowed to only have conditional exception handling in
  SEC.


  * SEC_SEV_ES_WORK_AREA.RandomData, SEC_SEV_ES_WORK_AREA.EncryptionMask:

     1  7cb96c47a94e OvmfPkg/ResetVector: Validate the encryption bit position for SEV/SEV-ES
     2  bd0c1c8e225b OvmfPkg/ResetVector: Perform a simple SEV-ES sanity check
     3  3b32be7e7192 OvmfPkg/ResetVector: Save the encryption mask at boot time
     4  b97dc4b92ba1 OvmfPkg/MemEncryptSevLib: Add an interface to retrieve the encryption mask

  The "RandomData" and "EncryptionMask" fields in the
  SEC_SEV_ES_WORK_AREA structure seem justified because they implement
  some serious work (which must be done as early as possible, i.e., in
  the Reset Vector), *and* caching the result of that work for the rest
  of the firmware saves significant complexity (and the result is
  security-related even).

  "SEC_SEV_ES_WORK_AREA.SevSnpEnabled" is unlike any of these three
  fields.

)

Thanks
Laszlo

>> diff --git a/OvmfPkg/ResetVector/ResetVector.nasmb b/OvmfPkg/ResetVector/ResetVector.nasmb
>> index 5fbacaed5f9d..1971557b1c00 100644
>> --- a/OvmfPkg/ResetVector/ResetVector.nasmb
>> +++ b/OvmfPkg/ResetVector/ResetVector.nasmb
>> @@ -73,6 +73,7 @@
>>    %define GHCB_BASE (FixedPcdGet32 (PcdOvmfSecGhcbBase))
>>    %define GHCB_SIZE (FixedPcdGet32 (PcdOvmfSecGhcbSize))
>>    %define SEV_ES_WORK_AREA (FixedPcdGet32 (PcdSevEsWorkAreaBase))
>> +  %define SEV_ES_WORK_AREA_SNP (FixedPcdGet32 (PcdSevEsWorkAreaBase) + 1)
>>    %define SEV_ES_WORK_AREA_RDRAND (FixedPcdGet32 (PcdSevEsWorkAreaBase) + 8)
>>    %define SEV_ES_WORK_AREA_ENC_MASK (FixedPcdGet32 (PcdSevEsWorkAreaBase) + 16)
>>    %define SEV_ES_VC_TOP_OF_STACK (FixedPcdGet32 (PcdOvmfSecPeiTempRamBase) + FixedPcdGet32 (PcdOvmfSecPeiTempRamSize))
>>
>
>
>
> 
>
>


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

* Re: [edk2-devel] [PATCH RFC v3 04/22] OvmfPkg/MemEncryptSevLib: extend Es Workarea to include hv features
  2021-05-26 23:11 ` [PATCH RFC v3 04/22] OvmfPkg/MemEncryptSevLib: extend Es Workarea to include hv features Brijesh Singh
@ 2021-06-07 11:54   ` Laszlo Ersek
  2021-06-07 13:37     ` Brijesh Singh
  0 siblings, 1 reply; 57+ messages in thread
From: Laszlo Ersek @ 2021-06-07 11:54 UTC (permalink / raw)
  To: brijesh.singh
  Cc: devel, James Bottomley, Min Xu, Jiewen Yao, Tom Lendacky,
	Jordan Justen, Erdem Aktas, Eric Dong, Ray Ni, Rahul Kumar,
	Ard Biesheuvel

Hi Brijesh,

On 05/27/21 01:11, Brijesh Singh wrote:
> BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=3275
> 
> The GHCB Version 2 introduces advertisement of features that are supported
> by the hypervisor. The features value is saved in the SevEs workarea. Save
> the value in the PCD for the later use.
> 
> Cc: James Bottomley <jejb@linux.ibm.com>
> Cc: Min Xu <min.m.xu@intel.com>
> Cc: Jiewen Yao <jiewen.yao@intel.com>
> Cc: Tom Lendacky <thomas.lendacky@amd.com>
> Cc: Jordan Justen <jordan.l.justen@intel.com>
> Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
> Cc: Laszlo Ersek <lersek@redhat.com>
> Cc: Erdem Aktas <erdemaktas@google.com>
> Signed-off-by: Brijesh Singh <brijesh.singh@amd.com>
> ---
>  OvmfPkg/PlatformPei/PlatformPei.inf        |   1 +
>  OvmfPkg/Include/Library/MemEncryptSevLib.h |   2 +
>  OvmfPkg/PlatformPei/AmdSev.c               |  26 +++++
>  OvmfPkg/ResetVector/Ia32/PageTables64.asm  | 122 +++++++++++++++++++++
>  OvmfPkg/ResetVector/ResetVector.nasmb      |   1 +
>  5 files changed, 152 insertions(+)

(1) Please split this patch: the PlatformPei changes should be in the second patch.

> 
> diff --git a/OvmfPkg/PlatformPei/PlatformPei.inf b/OvmfPkg/PlatformPei/PlatformPei.inf
> index bc1dcac48343..3256ccfe88d8 100644
> --- a/OvmfPkg/PlatformPei/PlatformPei.inf
> +++ b/OvmfPkg/PlatformPei/PlatformPei.inf
> @@ -111,6 +111,7 @@ [Pcd]
>    gUefiCpuPkgTokenSpaceGuid.PcdCpuApStackSize
>    gUefiCpuPkgTokenSpaceGuid.PcdSevEsIsEnabled
>    gUefiCpuPkgTokenSpaceGuid.PcdSevSnpIsEnabled
> +  gUefiCpuPkgTokenSpaceGuid.PcdGhcbHypervisorFeatures
>  
>  [FixedPcd]
>    gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseAddress
> diff --git a/OvmfPkg/Include/Library/MemEncryptSevLib.h b/OvmfPkg/Include/Library/MemEncryptSevLib.h
> index 24507de55c5d..dd1c97d4a9a3 100644
> --- a/OvmfPkg/Include/Library/MemEncryptSevLib.h
> +++ b/OvmfPkg/Include/Library/MemEncryptSevLib.h
> @@ -55,6 +55,8 @@ typedef struct _SEC_SEV_ES_WORK_AREA {
>    UINT64   RandomData;
>  
>    UINT64   EncryptionMask;
> +
> +  UINT64   HypervisorFeatures;
>  } SEC_SEV_ES_WORK_AREA;
>  
>  //
> diff --git a/OvmfPkg/PlatformPei/AmdSev.c b/OvmfPkg/PlatformPei/AmdSev.c
> index 67b78fd5fa36..81e40e0889aa 100644
> --- a/OvmfPkg/PlatformPei/AmdSev.c
> +++ b/OvmfPkg/PlatformPei/AmdSev.c
> @@ -43,6 +43,27 @@ AmdSevSnpInitialize (
>    ASSERT_RETURN_ERROR (PcdStatus);
>  }
>  
> +/**
> +
> +  Function to set the PcdHypervisorFeatures.
> +**/
> +STATIC
> +VOID
> +AmdSevHypervisorFeatures (
> +  VOID
> +  )
> +{
> +  SEC_SEV_ES_WORK_AREA  *SevEsWorkArea;
> +  RETURN_STATUS         PcdStatus;
> +
> +  SevEsWorkArea = (SEC_SEV_ES_WORK_AREA *) FixedPcdGet32 (PcdSevEsWorkAreaBase);
> +
> +  PcdStatus = PcdSet64S (PcdGhcbHypervisorFeatures, SevEsWorkArea->HypervisorFeatures);
> +  ASSERT_RETURN_ERROR (PcdStatus);
> +
> +  DEBUG ((DEBUG_INFO, "GHCB Hypervisor Features=0x%Lx\n", SevEsWorkArea->HypervisorFeatures));

(2) Overlong line.

Please avoid basic mistakes like this, even in an RFC series.


> +}
> +
>  /**
>  
>    Initialize SEV-ES support if running as an SEV-ES guest.
> @@ -73,6 +94,11 @@ AmdSevEsInitialize (
>    PcdStatus = PcdSetBoolS (PcdSevEsIsEnabled, TRUE);
>    ASSERT_RETURN_ERROR (PcdStatus);
>  
> +  //
> +  // Set the hypervisor features PCD.
> +  //
> +  AmdSevHypervisorFeatures ();
> +
>    //
>    // Allocate GHCB and per-CPU variable pages.
>    //   Since the pages must survive across the UEFI to OS transition
> diff --git a/OvmfPkg/ResetVector/Ia32/PageTables64.asm b/OvmfPkg/ResetVector/Ia32/PageTables64.asm
> index 6838cdeec9c3..75e63d2a0561 100644
> --- a/OvmfPkg/ResetVector/Ia32/PageTables64.asm
> +++ b/OvmfPkg/ResetVector/Ia32/PageTables64.asm
> @@ -62,6 +62,16 @@ BITS    32
>  %define GHCB_CPUID_REGISTER_SHIFT  30
>  %define CPUID_INSN_LEN              2
>  
> +; GHCB SEV Information MSR protocol
> +%define GHCB_SEV_INFORMATION_REQUEST    2
> +%define GHCB_SEV_INFORMATION_RESPONSE   1

(3) These macro names do not match the ones in "MdePkg/Include/Register/Amd/Fam17Msr.h" (GHCB_INFO_SEV_INFO_GET, GHCB_INFO_SEV_INFO, respectively).

They don't *have* to match, technically speaking, but one goal of using macros for magic numbers is so we can grep the source for them. The macros just below (for values 128 and 129) do match the header file.


> +
> +; GHCB Hypervisor features MSR protocol
> +%define GHCB_HYPERVISOR_FEATURES_REQUEST    128
> +%define GHCB_HYPERVISOR_FEATURES_RESPONSE   129
> +
> +; GHCB request to terminate protocol values
> +%define GHCB_GENERAL_TERMINATE_REQUEST    255

(4) Not only does this macro name not match the one in the header file (which is GHCB_INFO_TERMINATE_REQUEST), even the value is wrong. The header file has

#define GHCB_INFO_TERMINATE_REQUEST                 256

and I checked the GHCBv2 spec too; there is no operation defined with opcode 255.


>  
>  ; Check if Secure Encrypted Virtualization (SEV) features are enabled.
>  ;
> @@ -86,6 +96,13 @@ CheckSevFeatures:
>      ; will set it to 1.
>      mov       byte[SEV_ES_WORK_AREA_SNP], 0
>  
> +    ; Set the Hypervisor features field in the workarea to zero to communicate
> +    ; to the hypervisor features to the SEC phase. The hypervisor feature is
> +    ; filled during the call to CheckHypervisorFeatures.
> +    mov     eax, 0
> +    mov     dword[SEV_ES_WORK_AREA_HYPERVISOR_FEATURES], eax
> +    mov     dword[SEV_ES_WORK_AREA_HYPERVISOR_FEATURES + 4], eax
> +
>      ;
>      ; Set up exception handlers to check for SEV-ES
>      ;   Load temporary RAM stack based on PCDs (see SevEsIdtVmmComm for
> @@ -225,6 +242,106 @@ IsSevEsEnabled:
>  SevEsDisabled:
>      OneTimeCallRet IsSevEsEnabled
>  
> +; The version 2 of GHCB specification added the support to query the hypervisor features.
> +; If the GHCB version is >=2 then read the hypervisor features.
> +;
> +; Modified:  EAX, EBX, ECX, EDX
> +;
> +CheckHypervisorFeatures:

(5) Arguably this label name should contain "Sev".


> +    ; Get the SEV Information
> +    ; Setup GHCB MSR
> +    ;   GHCB_MSR[11:0]  = SEV information request
> +    ;
> +    mov     edx, 0
> +    mov     eax, GHCB_SEV_INFORMATION_REQUEST
> +    mov     ecx, 0xc0010130
> +    wrmsr
> +
> +    ;
> +    ; Issue VMGEXIT - NASM doesn't support the vmmcall instruction in 32-bit
> +    ; mode, so work around this by temporarily switching to 64-bit mode.
> +    ;
> +BITS    64
> +    rep     vmmcall
> +BITS    32
> +
> +    ;
> +    ; SEV Information Response GHCB MSR
> +    ;   GHCB_MSR[63:48] = Maximum protocol version
> +    ;   GHCB_MSR[47:32] = Minimum protocol version
> +    ;   GHCB_MSR[11:0]  = SEV information response
> +    ;
> +    mov     ecx, 0xc0010130
> +    rdmsr
> +    and     eax, 0xfff
> +    cmp     eax, GHCB_SEV_INFORMATION_RESPONSE
> +    jnz     TerminateSevGuestLaunch

(6) Before modifying the ResetVector module like this, please insert a refactoring patch as follows:

- A new SEV-specific assembly include file should be introduced. The majority of the "OvmfPkg/ResetVector/Ia32/PageTables64.asm" file now deals with SEV aspects, but the file-top comment still says "Sets the CR3 register for 64-bit paging". It's high time that we move SEV stuff to a file with a name that references SEV.

- We now have five (5) invocations of the GHCB MSR protocol in this file, and every one of them open-codes the same setup, the same 0xc0010130 MSR constant, the same retval check logic with possible guest termination, the same "rep vmmcall" workaround for the 32-bit limitation of NASM, and so on. this file is now borderline unreadable. At the minimum, please introduce a function-like NASM macro with two arguments (= the request & response opcodes), and extract as much as possible.



> +    shr     edx, 16
> +    cmp     edx, 2
> +    jl      CheckHypervisorFeaturesDone
> +
> +    ; Get the hypervisor features
> +    ; Setup GHCB MSR
> +    ;   GHCB_MSR[11:0]  = Hypervisor features request
> +    ;
> +    mov     edx, 0
> +    mov     eax, GHCB_HYPERVISOR_FEATURES_REQUEST
> +    mov     ecx, 0xc0010130
> +    wrmsr
> +
> +    ;
> +    ; Issue VMGEXIT - NASM doesn't support the vmmcall instruction in 32-bit
> +    ; mode, so work around this by temporarily switching to 64-bit mode.
> +    ;
> +BITS    64
> +    rep     vmmcall
> +BITS    32
> +
> +    ;
> +    ; Hypervisor features reponse
> +    ;   GHCB_MSR[63:12] = Features bitmap
> +    ;   GHCB_MSR[11:0]  = Hypervisor features response
> +    ;
> +    mov     ecx, 0xc0010130
> +    rdmsr
> +    mov     ebx, eax
> +    and     eax, 0xfff
> +    cmp     eax, GHCB_HYPERVISOR_FEATURES_RESPONSE
> +    jnz     TerminateSevGuestLaunch
> +
> +    shr     ebx, 12
> +    mov     dword[SEV_ES_WORK_AREA_HYPERVISOR_FEATURES], ebx
> +    mov     dword[SEV_ES_WORK_AREA_HYPERVISOR_FEATURES + 4], edx

(7) According to the spec, the FEATURES bitmap is a contiguous bitmap of 52 bits. The way the EDX:EAX qword is shifted right by 12 bits above is incorrect. The EAX half is shifted OK (through EBX), but the EDX half is not shifted down by 12 bits at all, it is simply stored to the most significant dword of the "HypervisorFeatures" field. This basically inserts a 12 bit wide gap in the FEATURES bitmap.


> +
> +    jmp     CheckHypervisorFeaturesDone
> +TerminateSevGuestLaunch:
> +    ;
> +    ; Setup GHCB MSR
> +    ;   GHCB_MSR[23:16] = 0
> +    ;   GHCB_MSR[15:12] = 0
> +    ;   GHCB_MSR[11:0]  = Terminate Request
> +    ;
> +    mov     edx, 0
> +    mov     eax, GHCB_GENERAL_TERMINATE_REQUEST

(8) The "MdePkg/Include/Register/Amd/Fam17Msr.h" header file introduces GHCB_TERMINATE_GHCB, GHCB_TERMINATE_GHCB_GENERAL, GHCB_TERMINATE_GHCB_PROTOCOL. Can we use some of those here (with a separate, but matching, NASM macro of course)? See SevEsProtocolFailure() in "OvmfPkg/Sec/SecMain.c".


> +    mov     ecx, 0xc0010130
> +    wrmsr
> +
> +    ;
> +    ; Issue VMGEXIT - NASM doesn't support the vmmcall instruction in 32-bit
> +    ; mode, so work around this by temporarily switching to 64-bit mode.
> +    ;
> +BITS    64
> +    rep     vmmcall
> +BITS    32
> +
> +TerminateSevGuestLaunchHlt:
> +    cli
> +    hlt
> +    jmp     TerminateSevGuestLaunchHlt
> +
> +CheckHypervisorFeaturesDone:
> +    OneTimeCallRet CheckHypervisorFeatures
> +
>  ;
>  ; Modified:  EAX, EBX, ECX, EDX
>  ;
> @@ -328,6 +445,11 @@ clearGhcbMemoryLoop:
>      mov     dword[ecx * 4 + GHCB_BASE - 4], eax
>      loop    clearGhcbMemoryLoop
>  
> +    ;
> +    ; It is SEV-ES guest, query the Hypervisor features
> +    ;
> +    OneTimeCall   CheckHypervisorFeatures
> +
>  SetCr3:
>      ;
>      ; Set CR3 now that the paging structures are available
> diff --git a/OvmfPkg/ResetVector/ResetVector.nasmb b/OvmfPkg/ResetVector/ResetVector.nasmb
> index 1971557b1c00..5beba3ecb290 100644
> --- a/OvmfPkg/ResetVector/ResetVector.nasmb
> +++ b/OvmfPkg/ResetVector/ResetVector.nasmb
> @@ -76,6 +76,7 @@
>    %define SEV_ES_WORK_AREA_SNP (FixedPcdGet32 (PcdSevEsWorkAreaBase) + 1)
>    %define SEV_ES_WORK_AREA_RDRAND (FixedPcdGet32 (PcdSevEsWorkAreaBase) + 8)
>    %define SEV_ES_WORK_AREA_ENC_MASK (FixedPcdGet32 (PcdSevEsWorkAreaBase) + 16)
> +  %define SEV_ES_WORK_AREA_HYPERVISOR_FEATURES (FixedPcdGet32 (PcdSevEsWorkAreaBase) + 24)
>    %define SEV_ES_VC_TOP_OF_STACK (FixedPcdGet32 (PcdOvmfSecPeiTempRamBase) + FixedPcdGet32 (PcdOvmfSecPeiTempRamSize))
>  %include "Ia32/Flat32ToFlat64.asm"
>  %include "Ia32/PageTables64.asm"
> 

(9) And, I'm arriving at the following assertion only now unfortunately, after spending about 4 hours on reviewing this patch, and the history of SEC_SEV_ES_WORK_AREA.

I assert that the "SEC_SEV_ES_WORK_AREA.HypervisorFeatures" field should not exist. The only read site is here, in "OvmfPkg/PlatformPei".

Instead, we should have a new MemEncryptSevLib function that outputs the FEATURES bitmask. It should be similar to MemEncryptSevGetEncryptionMask(), but it should return a RETURN_STATUS, and produce the FEATURES bitmask through an output parameter.

The SEC instance of the function should return RETURN_UNSUPPORTED.

The PEI instance should use the GHCB MSR protocol, with the help of the AsmCpuId(), AsmWriteMsr64(), AsmReadMsr64() and AsmVmgExit() BaseLib functions.

The DXE instance should read back the PCD.

And so the OvmfPkg/ResetVector hunks should be dropped from this patch.

Thanks,
Laszlo


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

* Re: [edk2-devel] [RESEND PATCH RFC v3 00/22] Add AMD Secure Nested Paging (SEV-SNP) support
  2021-06-04 13:09     ` Laszlo Ersek
@ 2021-06-07 12:04       ` Laszlo Ersek
  0 siblings, 0 replies; 57+ messages in thread
From: Laszlo Ersek @ 2021-06-07 12:04 UTC (permalink / raw)
  To: Brijesh Singh
  Cc: devel, James Bottomley, Min Xu, Jiewen Yao, Tom Lendacky,
	Jordan Justen, Erdem Aktas, Eric Dong, Ray Ni, Rahul Kumar,
	Ard Biesheuvel

On 06/04/21 15:09, Laszlo Ersek wrote:
> On 06/04/21 13:50, Brijesh Singh wrote:

>> The main issue is I typed wrong branch name in the cover letter. The
>> branch name should be "sev-snp-rfc-3" and not "sev-snp-rfc-2". I
>> apologies for it :(. Ray asked the branch name and I replied him with
>> the correct branch.
> 
> Hmmm... indeed, but that discussion happened off-list, namely under the
> original posting of this v3 RFC set that did not reach the list. And now
> I was working with my list folder.
>>
>> https://github.com/AMDESE/ovmf/tree/sev-snp-rfc-3
>>
>> This branch was based on commit 5531fd48ded1271b8775725355ab83994e4bc77c
>> from the upstream. 
> 
> Right, this branch indeed averts problem (2); it is in sync with the
> posted series. Thanks!
> 
> Problem (1) stays the same -- git-rebase reports the same issue as
> git-am above, for patch#21. So, I'm going to review this version on the
> list, but I'll skip patch#21 (or perhaps I'll attempt to make useful
> comments there too, if I can).

I re-reviewed patch #3 today, and reviewed patch #4 as well.

Because the data flow was not explained in advance, regarding the
"SevSnpEnabled" and "HypervisorFeatures" fields, I wasted a huge amount
of time reviewing ResetVector details that ultimately proved irrelevant.

Additionally, I've found that several patches modify multiple modules in
one step, typically ResetVector and PlatformPei. Honestly, this is
inexplicable to me, given the edk2 coding style. The edk2 style permits
multi-module patches only in the most exceptional cases. In a typical
producer/consumer setup, the producer module patch comes first, the
consumer module patch comes second. Breaking this edk2 rule is very
detrimental to my efficiency as a reviewer.

Either way, I'm done reviewing RFCv3; primarily because tomorrow and the
day after I have some time-sensitive work to do, and afterwards, I'm
going to disapper for a good while, to salvage the shreds of my brain
that I've been left with, after the last two weeks.

In the meantime, assuming no other reviewer wishes to comment RFCv3,
please rework this series carefully -- even if it has "RFC" status,
that's not a license to break edk2 coding style, structure patches
incorrectly, diverge from spec-dictated constants, omit detailed
explanations in commit messages (data flow!), duplicate code (assembly
code!) mindlessly, and so on.

Thanks
Laszlo


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

* Re: [PATCH RFC v3 05/22] OvmfPkg: reserve Secrets page in MEMFD
  2021-05-26 23:11 ` [PATCH RFC v3 05/22] OvmfPkg: reserve Secrets page in MEMFD Brijesh Singh
@ 2021-06-07 12:26   ` Laszlo Ersek
  2021-06-07 12:48     ` Laszlo Ersek
  2021-06-07 15:58     ` Brijesh Singh
  0 siblings, 2 replies; 57+ messages in thread
From: Laszlo Ersek @ 2021-06-07 12:26 UTC (permalink / raw)
  To: Brijesh Singh, James Bottomley, Min Xu, Jiewen Yao, Tom Lendacky,
	Jordan Justen, Erdem Aktas, Eric Dong, Ray Ni, Rahul Kumar, devel
  Cc: Ard Biesheuvel

On 05/27/21 01:11, Brijesh Singh wrote:
> BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=3275
> 
> When AMD SEV is enabled in the guest VM, a hypervisor need to insert a
> secrets page.

For pure SEV?

> 
> When SEV-SNP is enabled, the secrets page contains the VM platform
> communication keys. The guest BIOS and OS can use this key to communicate
> with the SEV firmware to get attesation report. See the SEV-SNP firmware
> spec for more details for the content of the secrets page.
> 
> When SEV and SEV-ES is enabled, the secrets page contains the information
> provided by the guest owner after the attestation. See the SEV
> LAUNCH_SECRET command for more details.
> 
> Cc: James Bottomley <jejb@linux.ibm.com>
> Cc: Min Xu <min.m.xu@intel.com>
> Cc: Jiewen Yao <jiewen.yao@intel.com>
> Cc: Tom Lendacky <thomas.lendacky@amd.com>
> Cc: Jordan Justen <jordan.l.justen@intel.com>
> Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
> Cc: Laszlo Ersek <lersek@redhat.com>
> Cc: Erdem Aktas <erdemaktas@google.com>
> Signed-off-by: Brijesh Singh <brijesh.singh@amd.com>
> ---
>  OvmfPkg/OvmfPkgX64.dsc                 |  2 ++
>  OvmfPkg/OvmfPkgX64.fdf                 |  5 +++++
>  OvmfPkg/AmdSev/SecretPei/SecretPei.inf |  1 +
>  OvmfPkg/AmdSev/SecretPei/SecretPei.c   | 15 ++++++++++++++-
>  4 files changed, 22 insertions(+), 1 deletion(-)

How is all of the above related to the "OvmfPkg/OvmfPkgX64.dsc"
platform, where remote attestation is not a goal?

What you describe makes sense to me, but only for the remote-attested
"OvmfPkg/AmdSev/AmdSevX64.dsc" platform. (Which already includes
SecretPei and SecretDxe, and sets the necessary PCDs.)

Then, even if we limit this patch only to the "OvmfPkg/AmdSev/SecretPei"
module, the commit message does not explain sufficiently why the secrets
page must be reserved for good. The "SEV-SNP firmware spec" reference is
vague at best; I'm permanently lost between the dozen PDF files I have
downloaded locally from the AMD website. Please include a specific
document number, revision number, and chapter/section identifier.

Honestly I'm getting a *rushed* vibe on this whole series. Why is that?

Assume that I'm dumb. You won't be far from the truth. Then hold my hand
through all this?

Laszlo


> 
> diff --git a/OvmfPkg/OvmfPkgX64.dsc b/OvmfPkg/OvmfPkgX64.dsc
> index 999738dc39cd..ea08e1fabc65 100644
> --- a/OvmfPkg/OvmfPkgX64.dsc
> +++ b/OvmfPkg/OvmfPkgX64.dsc
> @@ -716,6 +716,7 @@ [Components]
>    OvmfPkg/SmmAccess/SmmAccessPei.inf
>  !endif
>    UefiCpuPkg/CpuMpPei/CpuMpPei.inf
> +  OvmfPkg/AmdSev/SecretPei/SecretPei.inf
>  
>  !if $(TPM_ENABLE) == TRUE
>    OvmfPkg/Tcg/TpmMmioSevDecryptPei/TpmMmioSevDecryptPei.inf
> @@ -966,6 +967,7 @@ [Components]
>    OvmfPkg/PlatformDxe/Platform.inf
>    OvmfPkg/AmdSevDxe/AmdSevDxe.inf
>    OvmfPkg/IoMmuDxe/IoMmuDxe.inf
> +  OvmfPkg/AmdSev/SecretDxe/SecretDxe.inf
>  
>  !if $(SMM_REQUIRE) == TRUE
>    OvmfPkg/SmmAccess/SmmAccess2Dxe.inf
> diff --git a/OvmfPkg/OvmfPkgX64.fdf b/OvmfPkg/OvmfPkgX64.fdf
> index d6be798fcadd..9126b8eb5014 100644
> --- a/OvmfPkg/OvmfPkgX64.fdf
> +++ b/OvmfPkg/OvmfPkgX64.fdf
> @@ -88,6 +88,9 @@ [FD.MEMFD]
>  0x00C000|0x001000
>  gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecGhcbBackupBase|gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecGhcbBackupSize
>  
> +0x00D000|0x001000
> +gUefiOvmfPkgTokenSpaceGuid.PcdSevLaunchSecretBase|gUefiOvmfPkgTokenSpaceGuid.PcdSevLaunchSecretSize
> +
>  0x010000|0x010000
>  gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecPeiTempRamBase|gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecPeiTempRamSize
>  
> @@ -179,6 +182,7 @@ [FV.PEIFV]
>  INF  SecurityPkg/Tcg/TcgPei/TcgPei.inf
>  INF  SecurityPkg/Tcg/Tcg2Pei/Tcg2Pei.inf
>  !endif
> +INF  OvmfPkg/AmdSev/SecretPei/SecretPei.inf
>  
>  ################################################################################
>  
> @@ -314,6 +318,7 @@ [FV.DXEFV]
>  INF  ShellPkg/Application/Shell/Shell.inf
>  
>  INF MdeModulePkg/Logo/LogoDxe.inf
> +INF OvmfPkg/AmdSev/SecretDxe/SecretDxe.inf
>  
>  #
>  # Network modules
> diff --git a/OvmfPkg/AmdSev/SecretPei/SecretPei.inf b/OvmfPkg/AmdSev/SecretPei/SecretPei.inf
> index 08be156c4bc0..9265f8adee12 100644
> --- a/OvmfPkg/AmdSev/SecretPei/SecretPei.inf
> +++ b/OvmfPkg/AmdSev/SecretPei/SecretPei.inf
> @@ -26,6 +26,7 @@ [LibraryClasses]
>    HobLib
>    PeimEntryPoint
>    PcdLib
> +  MemEncryptSevLib
>  
>  [FixedPcd]
>    gUefiOvmfPkgTokenSpaceGuid.PcdSevLaunchSecretBase
> diff --git a/OvmfPkg/AmdSev/SecretPei/SecretPei.c b/OvmfPkg/AmdSev/SecretPei/SecretPei.c
> index ad491515dd5d..51eb094555aa 100644
> --- a/OvmfPkg/AmdSev/SecretPei/SecretPei.c
> +++ b/OvmfPkg/AmdSev/SecretPei/SecretPei.c
> @@ -7,6 +7,7 @@
>  #include <PiPei.h>
>  #include <Library/HobLib.h>
>  #include <Library/PcdLib.h>
> +#include <Library/MemEncryptSevLib.h>
>  
>  EFI_STATUS
>  EFIAPI
> @@ -15,10 +16,22 @@ InitializeSecretPei (
>    IN CONST EFI_PEI_SERVICES     **PeiServices
>    )
>  {
> +  UINTN   Type;
> +
> +  //
> +  // The location of the secret page should be marked reserved so that guest OS
> +  // does not treated as a system RAM.
> +  //
> +  if (MemEncryptSevSnpIsEnabled ()) {
> +    Type = EfiReservedMemoryType;
> +  } else {
> +    Type = EfiBootServicesData;
> +  }
> +
>    BuildMemoryAllocationHob (
>      PcdGet32 (PcdSevLaunchSecretBase),
>      PcdGet32 (PcdSevLaunchSecretSize),
> -    EfiBootServicesData
> +    Type
>      );
>  
>    return EFI_SUCCESS;
> 


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

* Re: [PATCH RFC v3 05/22] OvmfPkg: reserve Secrets page in MEMFD
  2021-06-07 12:26   ` Laszlo Ersek
@ 2021-06-07 12:48     ` Laszlo Ersek
  2021-06-07 17:33       ` Brijesh Singh
  2021-06-07 15:58     ` Brijesh Singh
  1 sibling, 1 reply; 57+ messages in thread
From: Laszlo Ersek @ 2021-06-07 12:48 UTC (permalink / raw)
  To: Brijesh Singh, James Bottomley, Min Xu, Jiewen Yao, Tom Lendacky,
	Jordan Justen, Erdem Aktas, Eric Dong, Ray Ni, Rahul Kumar, devel
  Cc: Ard Biesheuvel

On 06/07/21 14:26, Laszlo Ersek wrote:
> On 05/27/21 01:11, Brijesh Singh wrote:
>> BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=3275
>>
>> When AMD SEV is enabled in the guest VM, a hypervisor need to insert a
>> secrets page.
>
> For pure SEV?
>
>>
>> When SEV-SNP is enabled, the secrets page contains the VM platform
>> communication keys. The guest BIOS and OS can use this key to communicate
>> with the SEV firmware to get attesation report. See the SEV-SNP firmware
>> spec for more details for the content of the secrets page.
>>
>> When SEV and SEV-ES is enabled, the secrets page contains the information
>> provided by the guest owner after the attestation. See the SEV
>> LAUNCH_SECRET command for more details.
>>
>> Cc: James Bottomley <jejb@linux.ibm.com>
>> Cc: Min Xu <min.m.xu@intel.com>
>> Cc: Jiewen Yao <jiewen.yao@intel.com>
>> Cc: Tom Lendacky <thomas.lendacky@amd.com>
>> Cc: Jordan Justen <jordan.l.justen@intel.com>
>> Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
>> Cc: Laszlo Ersek <lersek@redhat.com>
>> Cc: Erdem Aktas <erdemaktas@google.com>
>> Signed-off-by: Brijesh Singh <brijesh.singh@amd.com>
>> ---
>>  OvmfPkg/OvmfPkgX64.dsc                 |  2 ++
>>  OvmfPkg/OvmfPkgX64.fdf                 |  5 +++++
>>  OvmfPkg/AmdSev/SecretPei/SecretPei.inf |  1 +
>>  OvmfPkg/AmdSev/SecretPei/SecretPei.c   | 15 ++++++++++++++-
>>  4 files changed, 22 insertions(+), 1 deletion(-)
>
> How is all of the above related to the "OvmfPkg/OvmfPkgX64.dsc"
> platform, where remote attestation is not a goal?
>
> What you describe makes sense to me, but only for the remote-attested
> "OvmfPkg/AmdSev/AmdSevX64.dsc" platform. (Which already includes
> SecretPei and SecretDxe, and sets the necessary PCDs.)
>
> Then, even if we limit this patch only to the "OvmfPkg/AmdSev/SecretPei"
> module, the commit message does not explain sufficiently why the secrets
> page must be reserved for good. The "SEV-SNP firmware spec" reference is
> vague at best; I'm permanently lost between the dozen PDF files I have
> downloaded locally from the AMD website. Please include a specific
> document number, revision number, and chapter/section identifier.
>
> Honestly I'm getting a *rushed* vibe on this whole series. Why is that?
>
> Assume that I'm dumb. You won't be far from the truth. Then hold my hand
> through all this?

Here's the v2 discussion:

- http://mid.mail-archive.com/9804ecb5-8afd-c56e-4982-d1a6ebad3de8@redhat.com
- https://edk2.groups.io/g/devel/message/74797
- https://listman.redhat.com/archives/edk2-devel-archive/2021-May/msg00112.html

That discussion refers to a different use case, raised by Dov. That use
case might justify reserving the area even for plain SEV. It's out of
scope for now, AIUI.

(

And even for that separate use case, James showed down-thread that *not*
reserving the page forever in the firmware is more flexible.

- http://mid.mail-archive.com/aed7d3490fe6edee74440ed8e4cd5364fb2ba4af.camel@linux.ibm.com
- https://edk2.groups.io/g/devel/message/74801
- https://listman.redhat.com/archives/edk2-devel-archive/2021-May/msg00116.html

)

AFAICT, the only effect of the v2 sub-thread on the patch has been that
we now use the Reserved memory type rather than AcpiNVS (when SEV-SNP is
in use). I have two comments on that:

- It's good that we're not mixing in the other use case raised by Dov
  (i.e., enabling the guest-kernel to read secrets from the injected
  page even under plain SEV).

- It's still unclear to me why the reservation needs to be permanent
  under SEV-SNP.

Thanks
Laszlo

>>
>> diff --git a/OvmfPkg/OvmfPkgX64.dsc b/OvmfPkg/OvmfPkgX64.dsc
>> index 999738dc39cd..ea08e1fabc65 100644
>> --- a/OvmfPkg/OvmfPkgX64.dsc
>> +++ b/OvmfPkg/OvmfPkgX64.dsc
>> @@ -716,6 +716,7 @@ [Components]
>>    OvmfPkg/SmmAccess/SmmAccessPei.inf
>>  !endif
>>    UefiCpuPkg/CpuMpPei/CpuMpPei.inf
>> +  OvmfPkg/AmdSev/SecretPei/SecretPei.inf
>>
>>  !if $(TPM_ENABLE) == TRUE
>>    OvmfPkg/Tcg/TpmMmioSevDecryptPei/TpmMmioSevDecryptPei.inf
>> @@ -966,6 +967,7 @@ [Components]
>>    OvmfPkg/PlatformDxe/Platform.inf
>>    OvmfPkg/AmdSevDxe/AmdSevDxe.inf
>>    OvmfPkg/IoMmuDxe/IoMmuDxe.inf
>> +  OvmfPkg/AmdSev/SecretDxe/SecretDxe.inf
>>
>>  !if $(SMM_REQUIRE) == TRUE
>>    OvmfPkg/SmmAccess/SmmAccess2Dxe.inf
>> diff --git a/OvmfPkg/OvmfPkgX64.fdf b/OvmfPkg/OvmfPkgX64.fdf
>> index d6be798fcadd..9126b8eb5014 100644
>> --- a/OvmfPkg/OvmfPkgX64.fdf
>> +++ b/OvmfPkg/OvmfPkgX64.fdf
>> @@ -88,6 +88,9 @@ [FD.MEMFD]
>>  0x00C000|0x001000
>>  gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecGhcbBackupBase|gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecGhcbBackupSize
>>
>> +0x00D000|0x001000
>> +gUefiOvmfPkgTokenSpaceGuid.PcdSevLaunchSecretBase|gUefiOvmfPkgTokenSpaceGuid.PcdSevLaunchSecretSize
>> +
>>  0x010000|0x010000
>>  gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecPeiTempRamBase|gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecPeiTempRamSize
>>
>> @@ -179,6 +182,7 @@ [FV.PEIFV]
>>  INF  SecurityPkg/Tcg/TcgPei/TcgPei.inf
>>  INF  SecurityPkg/Tcg/Tcg2Pei/Tcg2Pei.inf
>>  !endif
>> +INF  OvmfPkg/AmdSev/SecretPei/SecretPei.inf
>>
>>  ################################################################################
>>
>> @@ -314,6 +318,7 @@ [FV.DXEFV]
>>  INF  ShellPkg/Application/Shell/Shell.inf
>>
>>  INF MdeModulePkg/Logo/LogoDxe.inf
>> +INF OvmfPkg/AmdSev/SecretDxe/SecretDxe.inf
>>
>>  #
>>  # Network modules
>> diff --git a/OvmfPkg/AmdSev/SecretPei/SecretPei.inf b/OvmfPkg/AmdSev/SecretPei/SecretPei.inf
>> index 08be156c4bc0..9265f8adee12 100644
>> --- a/OvmfPkg/AmdSev/SecretPei/SecretPei.inf
>> +++ b/OvmfPkg/AmdSev/SecretPei/SecretPei.inf
>> @@ -26,6 +26,7 @@ [LibraryClasses]
>>    HobLib
>>    PeimEntryPoint
>>    PcdLib
>> +  MemEncryptSevLib
>>
>>  [FixedPcd]
>>    gUefiOvmfPkgTokenSpaceGuid.PcdSevLaunchSecretBase
>> diff --git a/OvmfPkg/AmdSev/SecretPei/SecretPei.c b/OvmfPkg/AmdSev/SecretPei/SecretPei.c
>> index ad491515dd5d..51eb094555aa 100644
>> --- a/OvmfPkg/AmdSev/SecretPei/SecretPei.c
>> +++ b/OvmfPkg/AmdSev/SecretPei/SecretPei.c
>> @@ -7,6 +7,7 @@
>>  #include <PiPei.h>
>>  #include <Library/HobLib.h>
>>  #include <Library/PcdLib.h>
>> +#include <Library/MemEncryptSevLib.h>
>>
>>  EFI_STATUS
>>  EFIAPI
>> @@ -15,10 +16,22 @@ InitializeSecretPei (
>>    IN CONST EFI_PEI_SERVICES     **PeiServices
>>    )
>>  {
>> +  UINTN   Type;
>> +
>> +  //
>> +  // The location of the secret page should be marked reserved so that guest OS
>> +  // does not treated as a system RAM.
>> +  //
>> +  if (MemEncryptSevSnpIsEnabled ()) {
>> +    Type = EfiReservedMemoryType;
>> +  } else {
>> +    Type = EfiBootServicesData;
>> +  }
>> +
>>    BuildMemoryAllocationHob (
>>      PcdGet32 (PcdSevLaunchSecretBase),
>>      PcdGet32 (PcdSevLaunchSecretSize),
>> -    EfiBootServicesData
>> +    Type
>>      );
>>
>>    return EFI_SUCCESS;
>>
>


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

* Re: [edk2-devel] [PATCH RFC v3 03/22] OvmfPkg/MemEncryptSevLib: extend the workarea to include SNP enabled field
  2021-06-07 11:20     ` [edk2-devel] " Laszlo Ersek
@ 2021-06-07 13:00       ` Brijesh Singh
  2021-06-08  8:17         ` Laszlo Ersek
  0 siblings, 1 reply; 57+ messages in thread
From: Brijesh Singh @ 2021-06-07 13:00 UTC (permalink / raw)
  To: devel, lersek, James Bottomley, Min Xu, Jiewen Yao, Tom Lendacky,
	Jordan Justen, Erdem Aktas, Eric Dong, Ray Ni, Rahul Kumar
  Cc: brijesh.singh, Ard Biesheuvel

Hi Laszlo,


On 6/7/21 6:20 AM, Laszlo Ersek via groups.io wrote:
> On 06/04/21 16:15, Laszlo Ersek wrote:
>> On 05/27/21 01:10, Brijesh Singh wrote:
>>> BZ: https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Fbugzilla.tianocore.org%2Fshow_bug.cgi%3Fid%3D3275&amp;data=04%7C01%7Cbrijesh.singh%40amd.com%7C4b1c71cc4cef4dd250f608d929a640cb%7C3dd8961fe4884e608e11a82d994e183d%7C0%7C0%7C637586616293720447%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C1000&amp;sdata=Wulen9mRG3lzBHDOwrwP6%2BnV6F95LgnsgDxuEadi9Ng%3D&amp;reserved=0
>>>
>>> Extend the workarea to include the SEV-SNP enabled fields. This will be set
>>> when SEV-SNP is active in the guest VM.
>>>
>>> Cc: James Bottomley <jejb@linux.ibm.com>
>>> Cc: Min Xu <min.m.xu@intel.com>
>>> Cc: Jiewen Yao <jiewen.yao@intel.com>
>>> Cc: Tom Lendacky <thomas.lendacky@amd.com>
>>> Cc: Jordan Justen <jordan.l.justen@intel.com>
>>> Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
>>> Cc: Laszlo Ersek <lersek@redhat.com>
>>> Cc: Erdem Aktas <erdemaktas@google.com>
>>> Signed-off-by: Brijesh Singh <brijesh.singh@amd.com>
>>> ---
>>>  OvmfPkg/PlatformPei/PlatformPei.inf        |  1 +
>>>  OvmfPkg/Include/Library/MemEncryptSevLib.h |  3 ++-
>>>  OvmfPkg/PlatformPei/AmdSev.c               | 26 ++++++++++++++++++++++
>>>  OvmfPkg/ResetVector/Ia32/PageTables64.asm  | 12 ++++++++++
>>>  OvmfPkg/ResetVector/ResetVector.nasmb      |  1 +
>>>  5 files changed, 42 insertions(+), 1 deletion(-)
>> (1) Please split this in two patches -- the PlatformPei changes should
>> be a separate patch. And, I think those should come second, the
>> ResetVector + header file change should come first.
>>
>>> diff --git a/OvmfPkg/PlatformPei/PlatformPei.inf b/OvmfPkg/PlatformPei/PlatformPei.inf
>>> index 6ef77ba7bb21..bc1dcac48343 100644
>>> --- a/OvmfPkg/PlatformPei/PlatformPei.inf
>>> +++ b/OvmfPkg/PlatformPei/PlatformPei.inf
>>> @@ -110,6 +110,7 @@ [Pcd]
>>>    gUefiCpuPkgTokenSpaceGuid.PcdCpuBootLogicalProcessorNumber
>>>    gUefiCpuPkgTokenSpaceGuid.PcdCpuApStackSize
>>>    gUefiCpuPkgTokenSpaceGuid.PcdSevEsIsEnabled
>>> +  gUefiCpuPkgTokenSpaceGuid.PcdSevSnpIsEnabled
>>>
>>>  [FixedPcd]
>>>    gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseAddress
>>> diff --git a/OvmfPkg/Include/Library/MemEncryptSevLib.h b/OvmfPkg/Include/Library/MemEncryptSevLib.h
>>> index 2425d8ba0a36..24507de55c5d 100644
>>> --- a/OvmfPkg/Include/Library/MemEncryptSevLib.h
>>> +++ b/OvmfPkg/Include/Library/MemEncryptSevLib.h
>>> @@ -49,7 +49,8 @@ typedef struct {
>>>  //
>>>  typedef struct _SEC_SEV_ES_WORK_AREA {
>>>    UINT8    SevEsEnabled;
>>> -  UINT8    Reserved1[7];
>>> +  UINT8    SevSnpEnabled;
>>> +  UINT8    Reserved2[6];
>>>
>>>    UINT64   RandomData;
>>>
>>> diff --git a/OvmfPkg/PlatformPei/AmdSev.c b/OvmfPkg/PlatformPei/AmdSev.c
>>> index a8bf610022ba..67b78fd5fa36 100644
>>> --- a/OvmfPkg/PlatformPei/AmdSev.c
>>> +++ b/OvmfPkg/PlatformPei/AmdSev.c
>>> @@ -22,6 +22,27 @@
>>>
>>>  #include "Platform.h"
>>>
>>> +/**
>>> +
>>> +  Initialize SEV-SNP support if running as an SEV-SNP guest.
>>> +
>>> +  **/
>>> +STATIC
>>> +VOID
>>> +AmdSevSnpInitialize (
>>> +  VOID
>>> +  )
>>> +{
>>> +  RETURN_STATUS        PcdStatus;
>>> +
>>> +  if (!MemEncryptSevSnpIsEnabled ()) {
>>> +    return;
>>> +  }
>>> +
>>> +  PcdStatus = PcdSetBoolS (PcdSevSnpIsEnabled, TRUE);
>>> +  ASSERT_RETURN_ERROR (PcdStatus);
>>> +}
>>> +
>>>  /**
>>>
>>>    Initialize SEV-ES support if running as an SEV-ES guest.
>>> @@ -209,4 +230,9 @@ AmdSevInitialize (
>>>    // Check and perform SEV-ES initialization if required.
>>>    //
>>>    AmdSevEsInitialize ();
>>> +
>>> +  //
>>> +  // Check and perform SEV-SNP initialization if required.
>>> +  //
>>> +  AmdSevSnpInitialize ();
>>>  }
>>> diff --git a/OvmfPkg/ResetVector/Ia32/PageTables64.asm b/OvmfPkg/ResetVector/Ia32/PageTables64.asm
>>> index 5fae8986d9da..6838cdeec9c3 100644
>>> --- a/OvmfPkg/ResetVector/Ia32/PageTables64.asm
>>> +++ b/OvmfPkg/ResetVector/Ia32/PageTables64.asm
>>> @@ -81,6 +81,11 @@ CheckSevFeatures:
>>>      ; the MSR check below will set the first byte of the workarea to one.
>>>      mov     byte[SEV_ES_WORK_AREA], 0
>>>
>>> +    ; Set the SevSnpEnabled field in workarea to zero to communicate to the SEC
>>> +    ; phase that SEV-SNP is not enabled. If SEV-SNP is enabled, this function
>>> +    ; will set it to 1.
>>> +    mov       byte[SEV_ES_WORK_AREA_SNP], 0
>>> +
>>>      ;
>>>      ; Set up exception handlers to check for SEV-ES
>>>      ;   Load temporary RAM stack based on PCDs (see SevEsIdtVmmComm for
>>> @@ -136,6 +141,13 @@ CheckSevFeatures:
>>>      ; phase that SEV-ES is enabled.
>>>      mov       byte[SEV_ES_WORK_AREA], 1
>>>
>>> +    bt        eax, 2
>>> +    jnc       GetSevEncBit
>>> +
>>> +    ; Set the second byte of the workarea to one to communicate to the SEC
>>> +    ; phase that the SEV-SNP is enabled
>>> +    mov       byte[SEV_ES_WORK_AREA_SNP], 1
>>> +
>>>  GetSevEncBit:
>>>      ; Get pte bit position to enable memory encryption
>>>      ; CPUID Fn8000_001F[EBX] - Bits 5:0
>> (2) Please mention in the commit message (of the ResetVector patch),
>> and/or a comment here in the code, that SEV-SNP is never enabled if
>> SEV-ES is disabled.
>>
>> Section "15.34.10 SEV_STATUS MSR" in the APM (doc#24593 v3.37) does not
>> spell out this dependency.
>>
>> Furthermore, the mSevStatus / mSevEsStatus / mSevSnpStatus variable
>> assignments in patch#2 do not form a "dependency cascade" like the one
>> seen here in the reset vector code.
>>
>> While "SEV-ES depends on SEV" seems obvious to me (and so the related,
>> existent jumps in the assembly code are not surprising), the statement
>> "SEV-SNP depends on SEV-ES" is not *that* obvious to me. Thus a comment
>> would be welcome.
>>
>> For *both* patches split out of this one:
>>
>> Reviewed-by: Laszlo Ersek <lersek@redhat.com>
> (3) Actually, no.
>
> This patch should be reduced to the following files only:
>
> - OvmfPkg/PlatformPei/AmdSev.c
> - OvmfPkg/PlatformPei/PlatformPei.inf
>
> and the following changes should be dropped completely:
>
> - OvmfPkg/Include/Library/MemEncryptSevLib.h
> - OvmfPkg/ResetVector/Ia32/PageTables64.asm
> - OvmfPkg/ResetVector/ResetVector.nasmb
>
> Specifically, the "SEC_SEV_ES_WORK_AREA.SevSnpEnabled" field should
> never be introduced.
>
> The reason is apparent only from patch #10 -- "OvmfPkg/PlatformPei:
> register GHCB gpa for the SEV-SNP guest".
>
> The core idea is that in patch#10, in the SEC module, you can implement
> SevSnpIsEnabled() by just reading MSR_SEV_STATUS, and checking the SNP
> bit. Namely, while the SevSnpIsEnabled() call is made in
> SevEsProtocolCheck(), i.e., before exception handling is set up in the
> SEC module -- and so you indeed cannot call CPUID --, you don't *have*
> to call CPUID at that call site. Where you call SevSnpIsEnabled() in
> SevEsProtocolCheck(), you already know that SEV-ES is enabled, so it's
> safe to just read the exact same SEV status MSR that the SEV-ES status
> comes from in the first place, without any CPUID safety check.
We must check the SNP Enabled inside the assembly code for the page
invalidate functions, and I decided to cache the value. A similar
SNP-enabled check is required in SEC phase before the
ProcessLibraryConstrctorList() is called. There are two options on how
we can go about doing the SNP enabled check inside the SEC phase
1. Call the SEV_STATUS MSR after reading the
SEC_SEV_ES_WORK_AREA.SevEnabled. As you said, we need to be sure that ES
is enabled before calling the SEV_STATUS MSR.
2. SEV_STATUS MSR is read in Reset vector for the SNP enabled check
purpose. Extend the SevEsWorkArea to cache the state.

 I chose #2 because it avoids checking for ES enabled before checking
the SNP enabled. I understand that in the current code path, SNP check
is called inside the SevEsProtocolCheck() -- ES is already enabled, and
its safe to call SEV_STATUS MSR. What if we need to check for the SNP
state outside the ES-specific code block in the future? Then we will
need to extend the SevEsWorkArea. So I went ahead with option #2. I have
no problem reverting to option #1 and simplify the patch. I hope you
understand that sometimes it's difficult to foresee which option will be
preferred by the community, so I, as a contributor, can do one thing
and, based on the feedback, change the course.

Thanks

> (
>
>   General request: please be explicit in the commit messages about the
>   data flow between modules, and why you are doing what you are doing.
>   Arriving at the above analysis took me 3+ hours this morning, when --
>   while reviewing patch#4 -- I took issue with the proliferation of the
>   new fields in SEC_SEV_ES_WORK_AREA. SEC_SEV_ES_WORK_AREA is *not* a
>   convenience dump. We should restrict its use as much as possible.
>
>   I double-checked how SEC_SEV_ES_WORK_AREA had evolved historically:
>
>
>   * SEC_SEV_ES_WORK_AREA.SevEsEnabled:
>
>      1  43c3df78460d OvmfPkg: Reserve a page in memory for the SEV-ES usage
>      2  0731236fc108 OvmfPkg/PlatformPei: Reserve SEV-ES work area if S3 is supported
>      3  8a2732186a53 OvmfPkg/ResetVector: Add support for a 32-bit SEV check
>      4  13e5492bfdf3 OvmfPkg/Sec: Add #VC exception handling for Sec phase
>
>   The "SEC_SEV_ES_WORK_AREA.SevEsEnabled" field is important for the
>   following reason:
>
>   - in an SEV-ES guest, just learning about SEV requires exception
>     handling; thus, the Reset Vector sets up exception handling
>     *unconditionally*,
>
>   - in SEC, we deal with exception handling regardless of SEV-ES, but
>     *how* we do that is conditional on SEV-ES.
>
>   This means that caching the SEV-ES presence from the Reset Vector to
>   SEC makes a lot of sense. Given that in the Reset Vector we have
>   unconditional exception handling, and then in SEC we have a cached
>   result, we are allowed to only have conditional exception handling in
>   SEC.
>
>
>   * SEC_SEV_ES_WORK_AREA.RandomData, SEC_SEV_ES_WORK_AREA.EncryptionMask:
>
>      1  7cb96c47a94e OvmfPkg/ResetVector: Validate the encryption bit position for SEV/SEV-ES
>      2  bd0c1c8e225b OvmfPkg/ResetVector: Perform a simple SEV-ES sanity check
>      3  3b32be7e7192 OvmfPkg/ResetVector: Save the encryption mask at boot time
>      4  b97dc4b92ba1 OvmfPkg/MemEncryptSevLib: Add an interface to retrieve the encryption mask
>
>   The "RandomData" and "EncryptionMask" fields in the
>   SEC_SEV_ES_WORK_AREA structure seem justified because they implement
>   some serious work (which must be done as early as possible, i.e., in
>   the Reset Vector), *and* caching the result of that work for the rest
>   of the firmware saves significant complexity (and the result is
>   security-related even).
>
>   "SEC_SEV_ES_WORK_AREA.SevSnpEnabled" is unlike any of these three
>   fields.
>
> )
>
> Thanks
> Laszlo
>
>>> diff --git a/OvmfPkg/ResetVector/ResetVector.nasmb b/OvmfPkg/ResetVector/ResetVector.nasmb
>>> index 5fbacaed5f9d..1971557b1c00 100644
>>> --- a/OvmfPkg/ResetVector/ResetVector.nasmb
>>> +++ b/OvmfPkg/ResetVector/ResetVector.nasmb
>>> @@ -73,6 +73,7 @@
>>>    %define GHCB_BASE (FixedPcdGet32 (PcdOvmfSecGhcbBase))
>>>    %define GHCB_SIZE (FixedPcdGet32 (PcdOvmfSecGhcbSize))
>>>    %define SEV_ES_WORK_AREA (FixedPcdGet32 (PcdSevEsWorkAreaBase))
>>> +  %define SEV_ES_WORK_AREA_SNP (FixedPcdGet32 (PcdSevEsWorkAreaBase) + 1)
>>>    %define SEV_ES_WORK_AREA_RDRAND (FixedPcdGet32 (PcdSevEsWorkAreaBase) + 8)
>>>    %define SEV_ES_WORK_AREA_ENC_MASK (FixedPcdGet32 (PcdSevEsWorkAreaBase) + 16)
>>>    %define SEV_ES_VC_TOP_OF_STACK (FixedPcdGet32 (PcdOvmfSecPeiTempRamBase) + FixedPcdGet32 (PcdOvmfSecPeiTempRamSize))
>>>
>>
>>
>>
>>
>>
>
>
> 
>
>

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

* Re: [edk2-devel] [PATCH RFC v3 04/22] OvmfPkg/MemEncryptSevLib: extend Es Workarea to include hv features
  2021-06-07 11:54   ` [edk2-devel] " Laszlo Ersek
@ 2021-06-07 13:37     ` Brijesh Singh
  2021-06-08  8:49       ` Laszlo Ersek
  0 siblings, 1 reply; 57+ messages in thread
From: Brijesh Singh @ 2021-06-07 13:37 UTC (permalink / raw)
  To: Laszlo Ersek
  Cc: brijesh.singh, devel, James Bottomley, Min Xu, Jiewen Yao,
	Tom Lendacky, Jordan Justen, Erdem Aktas, Eric Dong, Ray Ni,
	Rahul Kumar, Ard Biesheuvel

Hi Laszlo,


On 6/7/21 6:54 AM, Laszlo Ersek wrote:
> Hi Brijesh,
>
> On 05/27/21 01:11, Brijesh Singh wrote:
>> BZ: https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Fbugzilla.tianocore.org%2Fshow_bug.cgi%3Fid%3D3275&amp;data=04%7C01%7Cbrijesh.singh%40amd.com%7C107d760e06824b1b6d6d08d929aaffd3%7C3dd8961fe4884e608e11a82d994e183d%7C0%7C0%7C637586636747299845%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C1000&amp;sdata=KQ42j9fOtsJfCh2iziap1v%2BBqC%2FHfR%2BR9ZbO3JHAJaM%3D&amp;reserved=0
>>
>> The GHCB Version 2 introduces advertisement of features that are supported
>> by the hypervisor. The features value is saved in the SevEs workarea. Save
>> the value in the PCD for the later use.
>>
>> Cc: James Bottomley <jejb@linux.ibm.com>
>> Cc: Min Xu <min.m.xu@intel.com>
>> Cc: Jiewen Yao <jiewen.yao@intel.com>
>> Cc: Tom Lendacky <thomas.lendacky@amd.com>
>> Cc: Jordan Justen <jordan.l.justen@intel.com>
>> Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
>> Cc: Laszlo Ersek <lersek@redhat.com>
>> Cc: Erdem Aktas <erdemaktas@google.com>
>> Signed-off-by: Brijesh Singh <brijesh.singh@amd.com>
>> ---
>>  OvmfPkg/PlatformPei/PlatformPei.inf        |   1 +
>>  OvmfPkg/Include/Library/MemEncryptSevLib.h |   2 +
>>  OvmfPkg/PlatformPei/AmdSev.c               |  26 +++++
>>  OvmfPkg/ResetVector/Ia32/PageTables64.asm  | 122 +++++++++++++++++++++
>>  OvmfPkg/ResetVector/ResetVector.nasmb      |   1 +
>>  5 files changed, 152 insertions(+)
> (1) Please split this patch: the PlatformPei changes should be in the second patch.

Noted.


>
>> diff --git a/OvmfPkg/PlatformPei/PlatformPei.inf b/OvmfPkg/PlatformPei/PlatformPei.inf
>> index bc1dcac48343..3256ccfe88d8 100644
>> --- a/OvmfPkg/PlatformPei/PlatformPei.inf
>> +++ b/OvmfPkg/PlatformPei/PlatformPei.inf
>> @@ -111,6 +111,7 @@ [Pcd]
>>    gUefiCpuPkgTokenSpaceGuid.PcdCpuApStackSize
>>    gUefiCpuPkgTokenSpaceGuid.PcdSevEsIsEnabled
>>    gUefiCpuPkgTokenSpaceGuid.PcdSevSnpIsEnabled
>> +  gUefiCpuPkgTokenSpaceGuid.PcdGhcbHypervisorFeatures
>>  
>>  [FixedPcd]
>>    gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseAddress
>> diff --git a/OvmfPkg/Include/Library/MemEncryptSevLib.h b/OvmfPkg/Include/Library/MemEncryptSevLib.h
>> index 24507de55c5d..dd1c97d4a9a3 100644
>> --- a/OvmfPkg/Include/Library/MemEncryptSevLib.h
>> +++ b/OvmfPkg/Include/Library/MemEncryptSevLib.h
>> @@ -55,6 +55,8 @@ typedef struct _SEC_SEV_ES_WORK_AREA {
>>    UINT64   RandomData;
>>  
>>    UINT64   EncryptionMask;
>> +
>> +  UINT64   HypervisorFeatures;
>>  } SEC_SEV_ES_WORK_AREA;
>>  
>>  //
>> diff --git a/OvmfPkg/PlatformPei/AmdSev.c b/OvmfPkg/PlatformPei/AmdSev.c
>> index 67b78fd5fa36..81e40e0889aa 100644
>> --- a/OvmfPkg/PlatformPei/AmdSev.c
>> +++ b/OvmfPkg/PlatformPei/AmdSev.c
>> @@ -43,6 +43,27 @@ AmdSevSnpInitialize (
>>    ASSERT_RETURN_ERROR (PcdStatus);
>>  }
>>  
>> +/**
>> +
>> +  Function to set the PcdHypervisorFeatures.
>> +**/
>> +STATIC
>> +VOID
>> +AmdSevHypervisorFeatures (
>> +  VOID
>> +  )
>> +{
>> +  SEC_SEV_ES_WORK_AREA  *SevEsWorkArea;
>> +  RETURN_STATUS         PcdStatus;
>> +
>> +  SevEsWorkArea = (SEC_SEV_ES_WORK_AREA *) FixedPcdGet32 (PcdSevEsWorkAreaBase);
>> +
>> +  PcdStatus = PcdSet64S (PcdGhcbHypervisorFeatures, SevEsWorkArea->HypervisorFeatures);
>> +  ASSERT_RETURN_ERROR (PcdStatus);
>> +
>> +  DEBUG ((DEBUG_INFO, "GHCB Hypervisor Features=0x%Lx\n", SevEsWorkArea->HypervisorFeatures));
> (2) Overlong line.
>
> Please avoid basic mistakes like this, even in an RFC series.

I will split it, but all the checkpatch and CI stuff passed on my branch
before the submission.


>
>
>> +}
>> +
>>  /**
>>  
>>    Initialize SEV-ES support if running as an SEV-ES guest.
>> @@ -73,6 +94,11 @@ AmdSevEsInitialize (
>>    PcdStatus = PcdSetBoolS (PcdSevEsIsEnabled, TRUE);
>>    ASSERT_RETURN_ERROR (PcdStatus);
>>  
>> +  //
>> +  // Set the hypervisor features PCD.
>> +  //
>> +  AmdSevHypervisorFeatures ();
>> +
>>    //
>>    // Allocate GHCB and per-CPU variable pages.
>>    //   Since the pages must survive across the UEFI to OS transition
>> diff --git a/OvmfPkg/ResetVector/Ia32/PageTables64.asm b/OvmfPkg/ResetVector/Ia32/PageTables64.asm
>> index 6838cdeec9c3..75e63d2a0561 100644
>> --- a/OvmfPkg/ResetVector/Ia32/PageTables64.asm
>> +++ b/OvmfPkg/ResetVector/Ia32/PageTables64.asm
>> @@ -62,6 +62,16 @@ BITS    32
>>  %define GHCB_CPUID_REGISTER_SHIFT  30
>>  %define CPUID_INSN_LEN              2
>>  
>> +; GHCB SEV Information MSR protocol
>> +%define GHCB_SEV_INFORMATION_REQUEST    2
>> +%define GHCB_SEV_INFORMATION_RESPONSE   1
> (3) These macro names do not match the ones in "MdePkg/Include/Register/Amd/Fam17Msr.h" (GHCB_INFO_SEV_INFO_GET, GHCB_INFO_SEV_INFO, respectively).
>
> They don't *have* to match, technically speaking, but one goal of using macros for magic numbers is so we can grep the source for them. The macros just below (for values 128 and 129) do match the header file.

Noted, I will match them.


>
>> +
>> +; GHCB Hypervisor features MSR protocol
>> +%define GHCB_HYPERVISOR_FEATURES_REQUEST    128
>> +%define GHCB_HYPERVISOR_FEATURES_RESPONSE   129
>> +
>> +; GHCB request to terminate protocol values
>> +%define GHCB_GENERAL_TERMINATE_REQUEST    255
> (4) Not only does this macro name not match the one in the header file (which is GHCB_INFO_TERMINATE_REQUEST), even the value is wrong. The header file has
>
> #define GHCB_INFO_TERMINATE_REQUEST                 256
>
> and I checked the GHCBv2 spec too; there is no operation defined with opcode 255.
>
Ah good catch. Thanks


>>  
>>  ; Check if Secure Encrypted Virtualization (SEV) features are enabled.
>>  ;
>> @@ -86,6 +96,13 @@ CheckSevFeatures:
>>      ; will set it to 1.
>>      mov       byte[SEV_ES_WORK_AREA_SNP], 0
>>  
>> +    ; Set the Hypervisor features field in the workarea to zero to communicate
>> +    ; to the hypervisor features to the SEC phase. The hypervisor feature is
>> +    ; filled during the call to CheckHypervisorFeatures.
>> +    mov     eax, 0
>> +    mov     dword[SEV_ES_WORK_AREA_HYPERVISOR_FEATURES], eax
>> +    mov     dword[SEV_ES_WORK_AREA_HYPERVISOR_FEATURES + 4], eax
>> +
>>      ;
>>      ; Set up exception handlers to check for SEV-ES
>>      ;   Load temporary RAM stack based on PCDs (see SevEsIdtVmmComm for
>> @@ -225,6 +242,106 @@ IsSevEsEnabled:
>>  SevEsDisabled:
>>      OneTimeCallRet IsSevEsEnabled
>>  
>> +; The version 2 of GHCB specification added the support to query the hypervisor features.
>> +; If the GHCB version is >=2 then read the hypervisor features.
>> +;
>> +; Modified:  EAX, EBX, ECX, EDX
>> +;
>> +CheckHypervisorFeatures:
> (5) Arguably this label name should contain "Sev".

Noted.


>
>> +    ; Get the SEV Information
>> +    ; Setup GHCB MSR
>> +    ;   GHCB_MSR[11:0]  = SEV information request
>> +    ;
>> +    mov     edx, 0
>> +    mov     eax, GHCB_SEV_INFORMATION_REQUEST
>> +    mov     ecx, 0xc0010130
>> +    wrmsr
>> +
>> +    ;
>> +    ; Issue VMGEXIT - NASM doesn't support the vmmcall instruction in 32-bit
>> +    ; mode, so work around this by temporarily switching to 64-bit mode.
>> +    ;
>> +BITS    64
>> +    rep     vmmcall
>> +BITS    32
>> +
>> +    ;
>> +    ; SEV Information Response GHCB MSR
>> +    ;   GHCB_MSR[63:48] = Maximum protocol version
>> +    ;   GHCB_MSR[47:32] = Minimum protocol version
>> +    ;   GHCB_MSR[11:0]  = SEV information response
>> +    ;
>> +    mov     ecx, 0xc0010130
>> +    rdmsr
>> +    and     eax, 0xfff
>> +    cmp     eax, GHCB_SEV_INFORMATION_RESPONSE
>> +    jnz     TerminateSevGuestLaunch
> (6) Before modifying the ResetVector module like this, please insert a refactoring patch as follows:
>
> - A new SEV-specific assembly include file should be introduced. The majority of the "OvmfPkg/ResetVector/Ia32/PageTables64.asm" file now deals with SEV aspects, but the file-top comment still says "Sets the CR3 register for 64-bit paging". It's high time that we move SEV stuff to a file with a name that references SEV.
>
> - We now have five (5) invocations of the GHCB MSR protocol in this file, and every one of them open-codes the same setup, the same 0xc0010130 MSR constant, the same retval check logic with possible guest termination, the same "rep vmmcall" workaround for the 32-bit limitation of NASM, and so on. this file is now borderline unreadable. At the minimum, please introduce a function-like NASM macro with two arguments (= the request & response opcodes), and extract as much as possible.
>
Okay, I will try moving all the SEV specific stuff outside this file.


>
>> +    shr     edx, 16
>> +    cmp     edx, 2
>> +    jl      CheckHypervisorFeaturesDone
>> +
>> +    ; Get the hypervisor features
>> +    ; Setup GHCB MSR
>> +    ;   GHCB_MSR[11:0]  = Hypervisor features request
>> +    ;
>> +    mov     edx, 0
>> +    mov     eax, GHCB_HYPERVISOR_FEATURES_REQUEST
>> +    mov     ecx, 0xc0010130
>> +    wrmsr
>> +
>> +    ;
>> +    ; Issue VMGEXIT - NASM doesn't support the vmmcall instruction in 32-bit
>> +    ; mode, so work around this by temporarily switching to 64-bit mode.
>> +    ;
>> +BITS    64
>> +    rep     vmmcall
>> +BITS    32
>> +
>> +    ;
>> +    ; Hypervisor features reponse
>> +    ;   GHCB_MSR[63:12] = Features bitmap
>> +    ;   GHCB_MSR[11:0]  = Hypervisor features response
>> +    ;
>> +    mov     ecx, 0xc0010130
>> +    rdmsr
>> +    mov     ebx, eax
>> +    and     eax, 0xfff
>> +    cmp     eax, GHCB_HYPERVISOR_FEATURES_RESPONSE
>> +    jnz     TerminateSevGuestLaunch
>> +
>> +    shr     ebx, 12
>> +    mov     dword[SEV_ES_WORK_AREA_HYPERVISOR_FEATURES], ebx
>> +    mov     dword[SEV_ES_WORK_AREA_HYPERVISOR_FEATURES + 4], edx
> (7) According to the spec, the FEATURES bitmap is a contiguous bitmap of 52 bits. The way the EDX:EAX qword is shifted right by 12 bits above is incorrect. The EAX half is shifted OK (through EBX), but the EDX half is not shifted down by 12 bits at all, it is simply stored to the most significant dword of the "HypervisorFeatures" field. This basically inserts a 12 bit wide gap in the FEATURES bitmap.

Noted, I will fix it.


>
>> +
>> +    jmp     CheckHypervisorFeaturesDone
>> +TerminateSevGuestLaunch:
>> +    ;
>> +    ; Setup GHCB MSR
>> +    ;   GHCB_MSR[23:16] = 0
>> +    ;   GHCB_MSR[15:12] = 0
>> +    ;   GHCB_MSR[11:0]  = Terminate Request
>> +    ;
>> +    mov     edx, 0
>> +    mov     eax, GHCB_GENERAL_TERMINATE_REQUEST
> (8) The "MdePkg/Include/Register/Amd/Fam17Msr.h" header file introduces GHCB_TERMINATE_GHCB, GHCB_TERMINATE_GHCB_GENERAL, GHCB_TERMINATE_GHCB_PROTOCOL. Can we use some of those here (with a separate, but matching, NASM macro of course)? See SevEsProtocolFailure() in "OvmfPkg/Sec/SecMain.c".

Sure, while moving SEV bits in a separate file I will try to define a
matching macros for it.


>
>
>> +    mov     ecx, 0xc0010130
>> +    wrmsr
>> +
>> +    ;
>> +    ; Issue VMGEXIT - NASM doesn't support the vmmcall instruction in 32-bit
>> +    ; mode, so work around this by temporarily switching to 64-bit mode.
>> +    ;
>> +BITS    64
>> +    rep     vmmcall
>> +BITS    32
>> +
>> +TerminateSevGuestLaunchHlt:
>> +    cli
>> +    hlt
>> +    jmp     TerminateSevGuestLaunchHlt
>> +
>> +CheckHypervisorFeaturesDone:
>> +    OneTimeCallRet CheckHypervisorFeatures
>> +
>>  ;
>>  ; Modified:  EAX, EBX, ECX, EDX
>>  ;
>> @@ -328,6 +445,11 @@ clearGhcbMemoryLoop:
>>      mov     dword[ecx * 4 + GHCB_BASE - 4], eax
>>      loop    clearGhcbMemoryLoop
>>  
>> +    ;
>> +    ; It is SEV-ES guest, query the Hypervisor features
>> +    ;
>> +    OneTimeCall   CheckHypervisorFeatures
>> +
>>  SetCr3:
>>      ;
>>      ; Set CR3 now that the paging structures are available
>> diff --git a/OvmfPkg/ResetVector/ResetVector.nasmb b/OvmfPkg/ResetVector/ResetVector.nasmb
>> index 1971557b1c00..5beba3ecb290 100644
>> --- a/OvmfPkg/ResetVector/ResetVector.nasmb
>> +++ b/OvmfPkg/ResetVector/ResetVector.nasmb
>> @@ -76,6 +76,7 @@
>>    %define SEV_ES_WORK_AREA_SNP (FixedPcdGet32 (PcdSevEsWorkAreaBase) + 1)
>>    %define SEV_ES_WORK_AREA_RDRAND (FixedPcdGet32 (PcdSevEsWorkAreaBase) + 8)
>>    %define SEV_ES_WORK_AREA_ENC_MASK (FixedPcdGet32 (PcdSevEsWorkAreaBase) + 16)
>> +  %define SEV_ES_WORK_AREA_HYPERVISOR_FEATURES (FixedPcdGet32 (PcdSevEsWorkAreaBase) + 24)
>>    %define SEV_ES_VC_TOP_OF_STACK (FixedPcdGet32 (PcdOvmfSecPeiTempRamBase) + FixedPcdGet32 (PcdOvmfSecPeiTempRamSize))
>>  %include "Ia32/Flat32ToFlat64.asm"
>>  %include "Ia32/PageTables64.asm"
>>
> (9) And, I'm arriving at the following assertion only now unfortunately, after spending about 4 hours on reviewing this patch, and the history of SEC_SEV_ES_WORK_AREA.
>
> I assert that the "SEC_SEV_ES_WORK_AREA.HypervisorFeatures" field should not exist. The only read site is here, in "OvmfPkg/PlatformPei".

I choose to cache as much as I could during the reset vector time so
that we avoid the need for VmgExit later. But now I understand that you
prefer to query those information when they are needed and not use the
SevEsWorkArea as a cache for other information.

Also, I was trying to avoid the cases where the malicious hypervisor
changing the feature value after the GHCB negotiation is completed. 
e.g, during the reset vector they give us one feature value and change
them during SEC or PEI or DXE instances run. They can't break the
security of SNP by doing so, but I thought its good to avoid querying
the features on every phase.


>
> Instead, we should have a new MemEncryptSevLib function that outputs the FEATURES bitmask. It should be similar to MemEncryptSevGetEncryptionMask(), but it should return a RETURN_STATUS, and produce the FEATURES bitmask through an output parameter.

This is one of thing which I noticed last week, we are actually creating
a circular dependency. The MemEncryptSevLib provides the routines which
are used by the VmgExitLib. The MemEncryptSevLib should *not* depend on
the VmgExitLib. If we extend the MemEncryptSevLib to provide a routine
to query the features then we will be required to include the
VmgExitLib. The patch #13 extends the MemEncryptSevLib to provide
functions for the page validation and it requires the VmgExitLib. I am
trying to see what I can do to not create this circular dependency and
still keep code reuse.

Thanks

Brijesh

>
> The SEC instance of the function should return RETURN_UNSUPPORTED.
>
> The PEI instance should use the GHCB MSR protocol, with the help of the AsmCpuId(), AsmWriteMsr64(), AsmReadMsr64() and AsmVmgExit() BaseLib functions.
>
> The DXE instance should read back the PCD.
>
> And so the OvmfPkg/ResetVector hunks should be dropped from this patch.
>
> Thanks,
> Laszlo
>

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

* Re: [PATCH RFC v3 05/22] OvmfPkg: reserve Secrets page in MEMFD
  2021-06-07 12:26   ` Laszlo Ersek
  2021-06-07 12:48     ` Laszlo Ersek
@ 2021-06-07 15:58     ` Brijesh Singh
  2021-06-08  9:20       ` Laszlo Ersek
  1 sibling, 1 reply; 57+ messages in thread
From: Brijesh Singh @ 2021-06-07 15:58 UTC (permalink / raw)
  To: Laszlo Ersek, James Bottomley, Min Xu, Jiewen Yao, Tom Lendacky,
	Jordan Justen, Erdem Aktas, Eric Dong, Ray Ni, Rahul Kumar, devel
  Cc: brijesh.singh, Ard Biesheuvel


On 6/7/21 7:26 AM, Laszlo Ersek wrote:
> On 05/27/21 01:11, Brijesh Singh wrote:
>> BZ: https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Fbugzilla.tianocore.org%2Fshow_bug.cgi%3Fid%3D3275&amp;data=04%7C01%7Cbrijesh.singh%40amd.com%7C32a95d87f0984b88080708d929af878f%7C3dd8961fe4884e608e11a82d994e183d%7C0%7C0%7C637586656154129803%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C1000&amp;sdata=JyrMLVE%2BMNq%2B1sUTI7WnbxkjloKi81PcISiLvz2geLg%3D&amp;reserved=0
>>
>> When AMD SEV is enabled in the guest VM, a hypervisor need to insert a
>> secrets page.
> For pure SEV?

The secrets page is applicable to all the SEV's (SEV, SEV-ES and
SEV-SNP) but there is some difference see below.


>
>> When SEV-SNP is enabled, the secrets page contains the VM platform
>> communication keys. The guest BIOS and OS can use this key to communicate
>> with the SEV firmware to get attesation report. See the SEV-SNP firmware
>> spec for more details for the content of the secrets page.
>>
>> When SEV and SEV-ES is enabled, the secrets page contains the information
>> provided by the guest owner after the attestation. See the SEV
>> LAUNCH_SECRET command for more details.
>>
>> Cc: James Bottomley <jejb@linux.ibm.com>
>> Cc: Min Xu <min.m.xu@intel.com>
>> Cc: Jiewen Yao <jiewen.yao@intel.com>
>> Cc: Tom Lendacky <thomas.lendacky@amd.com>
>> Cc: Jordan Justen <jordan.l.justen@intel.com>
>> Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
>> Cc: Laszlo Ersek <lersek@redhat.com>
>> Cc: Erdem Aktas <erdemaktas@google.com>
>> Signed-off-by: Brijesh Singh <brijesh.singh@amd.com>
>> ---
>>  OvmfPkg/OvmfPkgX64.dsc                 |  2 ++
>>  OvmfPkg/OvmfPkgX64.fdf                 |  5 +++++
>>  OvmfPkg/AmdSev/SecretPei/SecretPei.inf |  1 +
>>  OvmfPkg/AmdSev/SecretPei/SecretPei.c   | 15 ++++++++++++++-
>>  4 files changed, 22 insertions(+), 1 deletion(-)
> How is all of the above related to the "OvmfPkg/OvmfPkgX64.dsc"
> platform, where remote attestation is not a goal?
>
> What you describe makes sense to me, but only for the remote-attested
> "OvmfPkg/AmdSev/AmdSevX64.dsc" platform. (Which already includes
> SecretPei and SecretDxe, and sets the necessary PCDs.)
>
> Then, even if we limit this patch only to the "OvmfPkg/AmdSev/SecretPei"
> module, the commit message does not explain sufficiently why the secrets
> page must be reserved for good. The "SEV-SNP firmware spec" reference is
> vague at best; I'm permanently lost between the dozen PDF files I have
> downloaded locally from the AMD website. Please include a specific
> document number, revision number, and chapter/section identifier.


There is a fundamental difference between SEV and SEV-SNP attestation
flow. In the case of SEV and SEV-ES, the attestation happens before the
VM is booted, and the secrets page contains the data provided by the
guest owner after the attestation is complete. The hypervisor injects
that data into the guest memory before booting it.  However, with
SEV-SNP, the guest uses the data from the secrets page to build a
message for the PSP. The guest can send the following message to the PSP:

1. Expand the filtered CPUID list
2. Query attestation report
2. Derive a key
3. VM export, import, and absorb -- migration specific command

See chapter 7 [1] for all possible commands that a guest can send to PSP
through the guest message request. I understand that it is confusing,
but the secrets page is *not* same as SEV/SEV-ES. But since SEV-SNP spec
calls it secrets, so I used the same name. 

In SEV-SNP, the secrets page is not tight up with just the remote
attestation. Later, the AmdSev.dsc can include a library to perform the
SEV-SNP-specific attestation. The library can use the SNP secrets page
to get the key and message counter use for constructing the guest
message to query the attestation report.

I hope it clarifies it.

[1] https://www.amd.com/system/files/TechDocs/56860.pdf


> Honestly I'm getting a *rushed* vibe on this whole series. Why is that?

I am not sure why you are getting this feel, please let me know where I
can help to clarify but the series is *rushed* at all. Its building on
existing support. It's possible that we are getting mixed with the
fundamental difference between the SEV and SEV-SNP attestation flow and
recent patches from Dov to expand the attestation to cover other aspects
of the boot flow.

In case of SEV-SNP, some folks may prefer to do all the attestation in
the OVMF and others may prefer to do the attestation in the guest OS. We
should try to not restrict one approach over the other.


>
> Assume that I'm dumb. You won't be far from the truth. Then hold my hand
> through all this?


Please let me know if the above explanation helps or I should expand more.


> Laszlo
>
>
>> diff --git a/OvmfPkg/OvmfPkgX64.dsc b/OvmfPkg/OvmfPkgX64.dsc
>> index 999738dc39cd..ea08e1fabc65 100644
>> --- a/OvmfPkg/OvmfPkgX64.dsc
>> +++ b/OvmfPkg/OvmfPkgX64.dsc
>> @@ -716,6 +716,7 @@ [Components]
>>    OvmfPkg/SmmAccess/SmmAccessPei.inf
>>  !endif
>>    UefiCpuPkg/CpuMpPei/CpuMpPei.inf
>> +  OvmfPkg/AmdSev/SecretPei/SecretPei.inf
>>  
>>  !if $(TPM_ENABLE) == TRUE
>>    OvmfPkg/Tcg/TpmMmioSevDecryptPei/TpmMmioSevDecryptPei.inf
>> @@ -966,6 +967,7 @@ [Components]
>>    OvmfPkg/PlatformDxe/Platform.inf
>>    OvmfPkg/AmdSevDxe/AmdSevDxe.inf
>>    OvmfPkg/IoMmuDxe/IoMmuDxe.inf
>> +  OvmfPkg/AmdSev/SecretDxe/SecretDxe.inf
>>  
>>  !if $(SMM_REQUIRE) == TRUE
>>    OvmfPkg/SmmAccess/SmmAccess2Dxe.inf
>> diff --git a/OvmfPkg/OvmfPkgX64.fdf b/OvmfPkg/OvmfPkgX64.fdf
>> index d6be798fcadd..9126b8eb5014 100644
>> --- a/OvmfPkg/OvmfPkgX64.fdf
>> +++ b/OvmfPkg/OvmfPkgX64.fdf
>> @@ -88,6 +88,9 @@ [FD.MEMFD]
>>  0x00C000|0x001000
>>  gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecGhcbBackupBase|gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecGhcbBackupSize
>>  
>> +0x00D000|0x001000
>> +gUefiOvmfPkgTokenSpaceGuid.PcdSevLaunchSecretBase|gUefiOvmfPkgTokenSpaceGuid.PcdSevLaunchSecretSize
>> +
>>  0x010000|0x010000
>>  gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecPeiTempRamBase|gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecPeiTempRamSize
>>  
>> @@ -179,6 +182,7 @@ [FV.PEIFV]
>>  INF  SecurityPkg/Tcg/TcgPei/TcgPei.inf
>>  INF  SecurityPkg/Tcg/Tcg2Pei/Tcg2Pei.inf
>>  !endif
>> +INF  OvmfPkg/AmdSev/SecretPei/SecretPei.inf
>>  
>>  ################################################################################
>>  
>> @@ -314,6 +318,7 @@ [FV.DXEFV]
>>  INF  ShellPkg/Application/Shell/Shell.inf
>>  
>>  INF MdeModulePkg/Logo/LogoDxe.inf
>> +INF OvmfPkg/AmdSev/SecretDxe/SecretDxe.inf
>>  
>>  #
>>  # Network modules
>> diff --git a/OvmfPkg/AmdSev/SecretPei/SecretPei.inf b/OvmfPkg/AmdSev/SecretPei/SecretPei.inf
>> index 08be156c4bc0..9265f8adee12 100644
>> --- a/OvmfPkg/AmdSev/SecretPei/SecretPei.inf
>> +++ b/OvmfPkg/AmdSev/SecretPei/SecretPei.inf
>> @@ -26,6 +26,7 @@ [LibraryClasses]
>>    HobLib
>>    PeimEntryPoint
>>    PcdLib
>> +  MemEncryptSevLib
>>  
>>  [FixedPcd]
>>    gUefiOvmfPkgTokenSpaceGuid.PcdSevLaunchSecretBase
>> diff --git a/OvmfPkg/AmdSev/SecretPei/SecretPei.c b/OvmfPkg/AmdSev/SecretPei/SecretPei.c
>> index ad491515dd5d..51eb094555aa 100644
>> --- a/OvmfPkg/AmdSev/SecretPei/SecretPei.c
>> +++ b/OvmfPkg/AmdSev/SecretPei/SecretPei.c
>> @@ -7,6 +7,7 @@
>>  #include <PiPei.h>
>>  #include <Library/HobLib.h>
>>  #include <Library/PcdLib.h>
>> +#include <Library/MemEncryptSevLib.h>
>>  
>>  EFI_STATUS
>>  EFIAPI
>> @@ -15,10 +16,22 @@ InitializeSecretPei (
>>    IN CONST EFI_PEI_SERVICES     **PeiServices
>>    )
>>  {
>> +  UINTN   Type;
>> +
>> +  //
>> +  // The location of the secret page should be marked reserved so that guest OS
>> +  // does not treated as a system RAM.
>> +  //
>> +  if (MemEncryptSevSnpIsEnabled ()) {
>> +    Type = EfiReservedMemoryType;
>> +  } else {
>> +    Type = EfiBootServicesData;
>> +  }
>> +
>>    BuildMemoryAllocationHob (
>>      PcdGet32 (PcdSevLaunchSecretBase),
>>      PcdGet32 (PcdSevLaunchSecretSize),
>> -    EfiBootServicesData
>> +    Type
>>      );
>>  
>>    return EFI_SUCCESS;
>>

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

* Re: [PATCH RFC v3 05/22] OvmfPkg: reserve Secrets page in MEMFD
  2021-06-07 12:48     ` Laszlo Ersek
@ 2021-06-07 17:33       ` Brijesh Singh
  2021-06-08  9:22         ` Laszlo Ersek
  0 siblings, 1 reply; 57+ messages in thread
From: Brijesh Singh @ 2021-06-07 17:33 UTC (permalink / raw)
  To: Laszlo Ersek, James Bottomley, Min Xu, Jiewen Yao, Tom Lendacky,
	Jordan Justen, Erdem Aktas, Eric Dong, Ray Ni, Rahul Kumar, devel
  Cc: brijesh.singh, Ard Biesheuvel


On 6/7/21 7:48 AM, Laszlo Ersek wrote:
> On 06/07/21 14:26, Laszlo Ersek wrote:
>> On 05/27/21 01:11, Brijesh Singh wrote:
>>> BZ: https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Fbugzilla.tianocore.org%2Fshow_bug.cgi%3Fid%3D3275&amp;data=04%7C01%7Cbrijesh.singh%40amd.com%7Cc7a508dbd4af461b413208d929b2a231%7C3dd8961fe4884e608e11a82d994e183d%7C0%7C0%7C637586669489236720%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C1000&amp;sdata=OjlLNpUW8U%2FykMMU7JwjddEZd9Zi%2BsHNK%2FqoQCwW3vo%3D&amp;reserved=0
>>>
>>> When AMD SEV is enabled in the guest VM, a hypervisor need to insert a
>>> secrets page.
>> For pure SEV?
>>
>>> When SEV-SNP is enabled, the secrets page contains the VM platform
>>> communication keys. The guest BIOS and OS can use this key to communicate
>>> with the SEV firmware to get attesation report. See the SEV-SNP firmware
>>> spec for more details for the content of the secrets page.
>>>
>>> When SEV and SEV-ES is enabled, the secrets page contains the information
>>> provided by the guest owner after the attestation. See the SEV
>>> LAUNCH_SECRET command for more details.
>>>
>>> Cc: James Bottomley <jejb@linux.ibm.com>
>>> Cc: Min Xu <min.m.xu@intel.com>
>>> Cc: Jiewen Yao <jiewen.yao@intel.com>
>>> Cc: Tom Lendacky <thomas.lendacky@amd.com>
>>> Cc: Jordan Justen <jordan.l.justen@intel.com>
>>> Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
>>> Cc: Laszlo Ersek <lersek@redhat.com>
>>> Cc: Erdem Aktas <erdemaktas@google.com>
>>> Signed-off-by: Brijesh Singh <brijesh.singh@amd.com>
>>> ---
>>>  OvmfPkg/OvmfPkgX64.dsc                 |  2 ++
>>>  OvmfPkg/OvmfPkgX64.fdf                 |  5 +++++
>>>  OvmfPkg/AmdSev/SecretPei/SecretPei.inf |  1 +
>>>  OvmfPkg/AmdSev/SecretPei/SecretPei.c   | 15 ++++++++++++++-
>>>  4 files changed, 22 insertions(+), 1 deletion(-)
>> How is all of the above related to the "OvmfPkg/OvmfPkgX64.dsc"
>> platform, where remote attestation is not a goal?
>>
>> What you describe makes sense to me, but only for the remote-attested
>> "OvmfPkg/AmdSev/AmdSevX64.dsc" platform. (Which already includes
>> SecretPei and SecretDxe, and sets the necessary PCDs.)
>>
>> Then, even if we limit this patch only to the "OvmfPkg/AmdSev/SecretPei"
>> module, the commit message does not explain sufficiently why the secrets
>> page must be reserved for good. The "SEV-SNP firmware spec" reference is
>> vague at best; I'm permanently lost between the dozen PDF files I have
>> downloaded locally from the AMD website. Please include a specific
>> document number, revision number, and chapter/section identifier.
>>
>> Honestly I'm getting a *rushed* vibe on this whole series. Why is that?
>>
>> Assume that I'm dumb. You won't be far from the truth. Then hold my hand
>> through all this?
> Here's the v2 discussion:
>
> - https://nam11.safelinks.protection.outlook.com/?url=http%3A%2F%2Fmid.mail-archive.com%2F9804ecb5-8afd-c56e-4982-d1a6ebad3de8%40redhat.com&amp;data=04%7C01%7Cbrijesh.singh%40amd.com%7Cc7a508dbd4af461b413208d929b2a231%7C3dd8961fe4884e608e11a82d994e183d%7C0%7C0%7C637586669489236720%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C1000&amp;sdata=K8FRcks19dQ4BM4DBOh%2F7uO4hNvIsM0eqdNvwUQzDUU%3D&amp;reserved=0
> - https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Fedk2.groups.io%2Fg%2Fdevel%2Fmessage%2F74797&amp;data=04%7C01%7Cbrijesh.singh%40amd.com%7Cc7a508dbd4af461b413208d929b2a231%7C3dd8961fe4884e608e11a82d994e183d%7C0%7C0%7C637586669489236720%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C1000&amp;sdata=8rfpRAEvBdWex0BQctCbbGnHb691gcKSIEvVA3ZKDkg%3D&amp;reserved=0
> - https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Flistman.redhat.com%2Farchives%2Fedk2-devel-archive%2F2021-May%2Fmsg00112.html&amp;data=04%7C01%7Cbrijesh.singh%40amd.com%7Cc7a508dbd4af461b413208d929b2a231%7C3dd8961fe4884e608e11a82d994e183d%7C0%7C0%7C637586669489246713%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C1000&amp;sdata=NAL8jAfiq1EApkDBOBjgL7b3NIsmjginZSDxB1NDCk8%3D&amp;reserved=0
>
> That discussion refers to a different use case, raised by Dov. That use
> case might justify reserving the area even for plain SEV. It's out of
> scope for now, AIUI.
>
> (
>
> And even for that separate use case, James showed down-thread that *not*
> reserving the page forever in the firmware is more flexible.
>
> - https://nam11.safelinks.protection.outlook.com/?url=http%3A%2F%2Fmid.mail-archive.com%2Faed7d3490fe6edee74440ed8e4cd5364fb2ba4af.camel%40linux.ibm.com&amp;data=04%7C01%7Cbrijesh.singh%40amd.com%7Cc7a508dbd4af461b413208d929b2a231%7C3dd8961fe4884e608e11a82d994e183d%7C0%7C0%7C637586669489246713%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C1000&amp;sdata=2UV6KcGYb9CoKzgIU%2FscCX2l%2F5pKaSkFYshP%2BPSWHSM%3D&amp;reserved=0
> - https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Fedk2.groups.io%2Fg%2Fdevel%2Fmessage%2F74801&amp;data=04%7C01%7Cbrijesh.singh%40amd.com%7Cc7a508dbd4af461b413208d929b2a231%7C3dd8961fe4884e608e11a82d994e183d%7C0%7C0%7C637586669489246713%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C1000&amp;sdata=jnHpYxYkijt2LtcH772m88%2BLNH3Zjfn3Zqc3uuttL1M%3D&amp;reserved=0
> - https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Flistman.redhat.com%2Farchives%2Fedk2-devel-archive%2F2021-May%2Fmsg00116.html&amp;data=04%7C01%7Cbrijesh.singh%40amd.com%7Cc7a508dbd4af461b413208d929b2a231%7C3dd8961fe4884e608e11a82d994e183d%7C0%7C0%7C637586669489246713%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C1000&amp;sdata=XzePjtTDS8blsXhBNOg52uo81uFhoYpgcNMvU4RupSI%3D&amp;reserved=0
>
> )
>
> AFAICT, the only effect of the v2 sub-thread on the patch has been that
> we now use the Reserved memory type rather than AcpiNVS (when SEV-SNP is
> in use). I have two comments on that:
>
> - It's good that we're not mixing in the other use case raised by Dov
>   (i.e., enabling the guest-kernel to read secrets from the injected
>   page even under plain SEV).
>
> - It's still unclear to me why the reservation needs to be permanent
>   under SEV-SNP.


As highlighted in the previous email, in the case of SEV, the secrets
page contains the private data provided by the guest owner to the guest.
Whereas, in SEV-SNP, the secrets page includes the key and other
metadata used by the guest (OVMF or kernel) to construct a message for
the PSP. The secrets page contains some information (e.g key and
sequence number) that must persist across kexec boots. If we mark the
SEV-SNP secrets page as "Boot Data," I believe it gets free'd on
ExitBootService(). In the kexec'ed kernel, we need to retrieve the
secret page to get the key and message counters to construct the next
PSP quest request command.


I have not looked into detail on how EFI configuration table and other
data is preserved during the kexec boot, but I thought making the
secrets reserved should ensure that memory is not free'd on
ExitBootServices() and we can reach it after the kexec. I can
investigate a bit more.

Dov/James,
 
Does kexec works with the SEV secrets page?

-Brijesh





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

* 回复: [edk2-devel] [PATCH RFC v3 22/22] MdePkg/GHCB: increase the GHCB protocol max version
  2021-06-03 13:08   ` [edk2-devel] " Laszlo Ersek
@ 2021-06-08  1:17     ` gaoliming
  0 siblings, 0 replies; 57+ messages in thread
From: gaoliming @ 2021-06-08  1:17 UTC (permalink / raw)
  To: devel, lersek
  Cc: brijesh.singh, 'James Bottomley', 'Min Xu',
	'Jiewen Yao', 'Tom Lendacky',
	'Jordan Justen', 'Erdem Aktas',
	'Eric Dong', 'Ray Ni', 'Rahul Kumar',
	'Ard Biesheuvel', 'Michael D Kinney',
	'Zhiguang Liu'

Reviewed-by: Liming Gao <gaoliming@byosoft.com.cn>

> -----邮件原件-----
> 发件人: devel@edk2.groups.io <devel@edk2.groups.io> 代表 Laszlo Ersek
> 发送时间: 2021年6月3日 21:09
> 收件人: devel@edk2.groups.io
> 抄送: brijesh.singh@amd.com; James Bottomley <jejb@linux.ibm.com>; Min
> Xu <min.m.xu@intel.com>; Jiewen Yao <jiewen.yao@intel.com>; Tom
> Lendacky <thomas.lendacky@amd.com>; Jordan Justen
> <jordan.l.justen@intel.com>; Erdem Aktas <erdemaktas@google.com>; Eric
> Dong <eric.dong@intel.com>; Ray Ni <ray.ni@intel.com>; Rahul Kumar
> <rahul1.kumar@intel.com>; Ard Biesheuvel <ardb+tianocore@kernel.org>;
> Michael D Kinney <michael.d.kinney@intel.com>; Liming Gao
> <gaoliming@byosoft.com.cn>; Zhiguang Liu <zhiguang.liu@intel.com>
> 主题: Re: [edk2-devel] [PATCH RFC v3 22/22] MdePkg/GHCB: increase the
> GHCB protocol max version
> 
> Copying the MdePkg reviewers.
> 
> Thanks
> Laszlo
> 
> On 05/27/21 01:11, Brijesh Singh wrote:
> > BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=3275
> >
> > Now that OvmfPkg supports version 2 of the GHCB specification, bump the
> > protocol version.
> >
> > Cc: James Bottomley <jejb@linux.ibm.com>
> > Cc: Min Xu <min.m.xu@intel.com>
> > Cc: Jiewen Yao <jiewen.yao@intel.com>
> > Cc: Tom Lendacky <thomas.lendacky@amd.com>
> > Cc: Jordan Justen <jordan.l.justen@intel.com>
> > Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
> > Cc: Laszlo Ersek <lersek@redhat.com>
> > Cc: Erdem Aktas <erdemaktas@google.com>
> > Signed-off-by: Brijesh Singh <brijesh.singh@amd.com>
> > ---
> >  MdePkg/Include/Register/Amd/Ghcb.h | 2 +-
> >  1 file changed, 1 insertion(+), 1 deletion(-)
> >
> > diff --git a/MdePkg/Include/Register/Amd/Ghcb.h
> b/MdePkg/Include/Register/Amd/Ghcb.h
> > index 4d1ee29e0a5e..191fd0876060 100644
> > --- a/MdePkg/Include/Register/Amd/Ghcb.h
> > +++ b/MdePkg/Include/Register/Amd/Ghcb.h
> > @@ -24,7 +24,7 @@
> >  #define VC_EXCEPTION 29
> >
> >  #define GHCB_VERSION_MIN     1
> > -#define GHCB_VERSION_MAX     1
> > +#define GHCB_VERSION_MAX     2
> >
> >  #define GHCB_STANDARD_USAGE  0
> >
> >
> 
> 
> 
> 
> 




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

* Re: [edk2-devel] [PATCH RFC v3 03/22] OvmfPkg/MemEncryptSevLib: extend the workarea to include SNP enabled field
  2021-06-07 13:00       ` Brijesh Singh
@ 2021-06-08  8:17         ` Laszlo Ersek
  2021-06-08 13:51           ` Brijesh Singh
  0 siblings, 1 reply; 57+ messages in thread
From: Laszlo Ersek @ 2021-06-08  8:17 UTC (permalink / raw)
  To: Brijesh Singh, devel, James Bottomley, Min Xu, Jiewen Yao,
	Tom Lendacky, Jordan Justen, Erdem Aktas, Eric Dong, Ray Ni,
	Rahul Kumar
  Cc: Ard Biesheuvel

On 06/07/21 15:00, Brijesh Singh wrote:
> Hi Laszlo,
> 
> 
> On 6/7/21 6:20 AM, Laszlo Ersek via groups.io wrote:
>> On 06/04/21 16:15, Laszlo Ersek wrote:
>>> On 05/27/21 01:10, Brijesh Singh wrote:
>>>> BZ: https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Fbugzilla.tianocore.org%2Fshow_bug.cgi%3Fid%3D3275&amp;data=04%7C01%7Cbrijesh.singh%40amd.com%7C4b1c71cc4cef4dd250f608d929a640cb%7C3dd8961fe4884e608e11a82d994e183d%7C0%7C0%7C637586616293720447%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C1000&amp;sdata=Wulen9mRG3lzBHDOwrwP6%2BnV6F95LgnsgDxuEadi9Ng%3D&amp;reserved=0
>>>>
>>>> Extend the workarea to include the SEV-SNP enabled fields. This will be set
>>>> when SEV-SNP is active in the guest VM.
>>>>
>>>> Cc: James Bottomley <jejb@linux.ibm.com>
>>>> Cc: Min Xu <min.m.xu@intel.com>
>>>> Cc: Jiewen Yao <jiewen.yao@intel.com>
>>>> Cc: Tom Lendacky <thomas.lendacky@amd.com>
>>>> Cc: Jordan Justen <jordan.l.justen@intel.com>
>>>> Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
>>>> Cc: Laszlo Ersek <lersek@redhat.com>
>>>> Cc: Erdem Aktas <erdemaktas@google.com>
>>>> Signed-off-by: Brijesh Singh <brijesh.singh@amd.com>
>>>> ---
>>>>  OvmfPkg/PlatformPei/PlatformPei.inf        |  1 +
>>>>  OvmfPkg/Include/Library/MemEncryptSevLib.h |  3 ++-
>>>>  OvmfPkg/PlatformPei/AmdSev.c               | 26 ++++++++++++++++++++++
>>>>  OvmfPkg/ResetVector/Ia32/PageTables64.asm  | 12 ++++++++++
>>>>  OvmfPkg/ResetVector/ResetVector.nasmb      |  1 +
>>>>  5 files changed, 42 insertions(+), 1 deletion(-)
>>> (1) Please split this in two patches -- the PlatformPei changes should
>>> be a separate patch. And, I think those should come second, the
>>> ResetVector + header file change should come first.
>>>
>>>> diff --git a/OvmfPkg/PlatformPei/PlatformPei.inf b/OvmfPkg/PlatformPei/PlatformPei.inf
>>>> index 6ef77ba7bb21..bc1dcac48343 100644
>>>> --- a/OvmfPkg/PlatformPei/PlatformPei.inf
>>>> +++ b/OvmfPkg/PlatformPei/PlatformPei.inf
>>>> @@ -110,6 +110,7 @@ [Pcd]
>>>>    gUefiCpuPkgTokenSpaceGuid.PcdCpuBootLogicalProcessorNumber
>>>>    gUefiCpuPkgTokenSpaceGuid.PcdCpuApStackSize
>>>>    gUefiCpuPkgTokenSpaceGuid.PcdSevEsIsEnabled
>>>> +  gUefiCpuPkgTokenSpaceGuid.PcdSevSnpIsEnabled
>>>>
>>>>  [FixedPcd]
>>>>    gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseAddress
>>>> diff --git a/OvmfPkg/Include/Library/MemEncryptSevLib.h b/OvmfPkg/Include/Library/MemEncryptSevLib.h
>>>> index 2425d8ba0a36..24507de55c5d 100644
>>>> --- a/OvmfPkg/Include/Library/MemEncryptSevLib.h
>>>> +++ b/OvmfPkg/Include/Library/MemEncryptSevLib.h
>>>> @@ -49,7 +49,8 @@ typedef struct {
>>>>  //
>>>>  typedef struct _SEC_SEV_ES_WORK_AREA {
>>>>    UINT8    SevEsEnabled;
>>>> -  UINT8    Reserved1[7];
>>>> +  UINT8    SevSnpEnabled;
>>>> +  UINT8    Reserved2[6];
>>>>
>>>>    UINT64   RandomData;
>>>>
>>>> diff --git a/OvmfPkg/PlatformPei/AmdSev.c b/OvmfPkg/PlatformPei/AmdSev.c
>>>> index a8bf610022ba..67b78fd5fa36 100644
>>>> --- a/OvmfPkg/PlatformPei/AmdSev.c
>>>> +++ b/OvmfPkg/PlatformPei/AmdSev.c
>>>> @@ -22,6 +22,27 @@
>>>>
>>>>  #include "Platform.h"
>>>>
>>>> +/**
>>>> +
>>>> +  Initialize SEV-SNP support if running as an SEV-SNP guest.
>>>> +
>>>> +  **/
>>>> +STATIC
>>>> +VOID
>>>> +AmdSevSnpInitialize (
>>>> +  VOID
>>>> +  )
>>>> +{
>>>> +  RETURN_STATUS        PcdStatus;
>>>> +
>>>> +  if (!MemEncryptSevSnpIsEnabled ()) {
>>>> +    return;
>>>> +  }
>>>> +
>>>> +  PcdStatus = PcdSetBoolS (PcdSevSnpIsEnabled, TRUE);
>>>> +  ASSERT_RETURN_ERROR (PcdStatus);
>>>> +}
>>>> +
>>>>  /**
>>>>
>>>>    Initialize SEV-ES support if running as an SEV-ES guest.
>>>> @@ -209,4 +230,9 @@ AmdSevInitialize (
>>>>    // Check and perform SEV-ES initialization if required.
>>>>    //
>>>>    AmdSevEsInitialize ();
>>>> +
>>>> +  //
>>>> +  // Check and perform SEV-SNP initialization if required.
>>>> +  //
>>>> +  AmdSevSnpInitialize ();
>>>>  }
>>>> diff --git a/OvmfPkg/ResetVector/Ia32/PageTables64.asm b/OvmfPkg/ResetVector/Ia32/PageTables64.asm
>>>> index 5fae8986d9da..6838cdeec9c3 100644
>>>> --- a/OvmfPkg/ResetVector/Ia32/PageTables64.asm
>>>> +++ b/OvmfPkg/ResetVector/Ia32/PageTables64.asm
>>>> @@ -81,6 +81,11 @@ CheckSevFeatures:
>>>>      ; the MSR check below will set the first byte of the workarea to one.
>>>>      mov     byte[SEV_ES_WORK_AREA], 0
>>>>
>>>> +    ; Set the SevSnpEnabled field in workarea to zero to communicate to the SEC
>>>> +    ; phase that SEV-SNP is not enabled. If SEV-SNP is enabled, this function
>>>> +    ; will set it to 1.
>>>> +    mov       byte[SEV_ES_WORK_AREA_SNP], 0
>>>> +
>>>>      ;
>>>>      ; Set up exception handlers to check for SEV-ES
>>>>      ;   Load temporary RAM stack based on PCDs (see SevEsIdtVmmComm for
>>>> @@ -136,6 +141,13 @@ CheckSevFeatures:
>>>>      ; phase that SEV-ES is enabled.
>>>>      mov       byte[SEV_ES_WORK_AREA], 1
>>>>
>>>> +    bt        eax, 2
>>>> +    jnc       GetSevEncBit
>>>> +
>>>> +    ; Set the second byte of the workarea to one to communicate to the SEC
>>>> +    ; phase that the SEV-SNP is enabled
>>>> +    mov       byte[SEV_ES_WORK_AREA_SNP], 1
>>>> +
>>>>  GetSevEncBit:
>>>>      ; Get pte bit position to enable memory encryption
>>>>      ; CPUID Fn8000_001F[EBX] - Bits 5:0
>>> (2) Please mention in the commit message (of the ResetVector patch),
>>> and/or a comment here in the code, that SEV-SNP is never enabled if
>>> SEV-ES is disabled.
>>>
>>> Section "15.34.10 SEV_STATUS MSR" in the APM (doc#24593 v3.37) does not
>>> spell out this dependency.
>>>
>>> Furthermore, the mSevStatus / mSevEsStatus / mSevSnpStatus variable
>>> assignments in patch#2 do not form a "dependency cascade" like the one
>>> seen here in the reset vector code.
>>>
>>> While "SEV-ES depends on SEV" seems obvious to me (and so the related,
>>> existent jumps in the assembly code are not surprising), the statement
>>> "SEV-SNP depends on SEV-ES" is not *that* obvious to me. Thus a comment
>>> would be welcome.
>>>
>>> For *both* patches split out of this one:
>>>
>>> Reviewed-by: Laszlo Ersek <lersek@redhat.com>
>> (3) Actually, no.
>>
>> This patch should be reduced to the following files only:
>>
>> - OvmfPkg/PlatformPei/AmdSev.c
>> - OvmfPkg/PlatformPei/PlatformPei.inf
>>
>> and the following changes should be dropped completely:
>>
>> - OvmfPkg/Include/Library/MemEncryptSevLib.h
>> - OvmfPkg/ResetVector/Ia32/PageTables64.asm
>> - OvmfPkg/ResetVector/ResetVector.nasmb
>>
>> Specifically, the "SEC_SEV_ES_WORK_AREA.SevSnpEnabled" field should
>> never be introduced.
>>
>> The reason is apparent only from patch #10 -- "OvmfPkg/PlatformPei:
>> register GHCB gpa for the SEV-SNP guest".
>>
>> The core idea is that in patch#10, in the SEC module, you can implement
>> SevSnpIsEnabled() by just reading MSR_SEV_STATUS, and checking the SNP
>> bit. Namely, while the SevSnpIsEnabled() call is made in
>> SevEsProtocolCheck(), i.e., before exception handling is set up in the
>> SEC module -- and so you indeed cannot call CPUID --, you don't *have*
>> to call CPUID at that call site. Where you call SevSnpIsEnabled() in
>> SevEsProtocolCheck(), you already know that SEV-ES is enabled, so it's
>> safe to just read the exact same SEV status MSR that the SEV-ES status
>> comes from in the first place, without any CPUID safety check.
> We must check the SNP Enabled inside the assembly code for the page
> invalidate functions, and I decided to cache the value. A similar
> SNP-enabled check is required in SEC phase before the
> ProcessLibraryConstrctorList() is called. There are two options on how
> we can go about doing the SNP enabled check inside the SEC phase
> 1. Call the SEV_STATUS MSR after reading the
> SEC_SEV_ES_WORK_AREA.SevEnabled. As you said, we need to be sure that ES
> is enabled before calling the SEV_STATUS MSR.
> 2. SEV_STATUS MSR is read in Reset vector for the SNP enabled check
> purpose. Extend the SevEsWorkArea to cache the state.
> 
>  I chose #2 because it avoids checking for ES enabled before checking
> the SNP enabled. I understand that in the current code path, SNP check
> is called inside the SevEsProtocolCheck() -- ES is already enabled, and
> its safe to call SEV_STATUS MSR. What if we need to check for the SNP
> state outside the ES-specific code block in the future? Then we will
> need to extend the SevEsWorkArea.

What would be the reason for this, ever?

I think this ties in with another point (or question) I raised
elsewhere: the assembly code in the reset vector suggests *anyway* that
SNP is only available if ES is available, but I couldn't verify that
from any specs. If this dependency is an architectural fact (that is, if
ES is absent, then SNP may never be present), then I wouldn't like to
introduce a separate field for SNP presence in the SEC_SEV_ES_WORK_AREA
structure.

I consider "data" the backbone (I consider "information flow" in a
somewhat declarative, not imperative, sense). Code just organizes itself
around data.

> So I went ahead with option #2. I have
> no problem reverting to option #1 and simplify the patch. I hope you
> understand that sometimes it's difficult to foresee which option will be
> preferred by the community, so I, as a contributor, can do one thing
> and, based on the feedback, change the course.

I *entirely* agree with you that it's impossible to predict what the
community will prefer. Yet it doesn't hurt to ask questions (or propose
approaches) in natural language, when facing a (likely important) choice.

More importantly: ahead-of-time discussion is not indispensable, as long
as you present your choices in code at once, but also document your
choices in natural language, at the same time. I think I'd have been
less frustrated and exhausted if your above 2-3 paragraphs had been
included anywhere near your patches. Then, I wouldn't have had to
reverse-engineer the data flow (the declarative backbone) bottom-up from
the code, and dig down the history and original justification of
SEC_SEV_ES_WORK_AREA.

If you *did* describe all this somewhere, before, and I missed it, then
I sincerely apologize.

I do unconditionally apologize about my tone; I've been spread thin for
a long time now, and heavy context switches are virtually unbearable.
It's an explanation, but not an excuse, for sure. So please forgive me
for being rude. I'll try to remedy that with some time away from work.

Thanks
Laszlo





> 
> Thanks
> 
>> (
>>
>>   General request: please be explicit in the commit messages about the
>>   data flow between modules, and why you are doing what you are doing.
>>   Arriving at the above analysis took me 3+ hours this morning, when --
>>   while reviewing patch#4 -- I took issue with the proliferation of the
>>   new fields in SEC_SEV_ES_WORK_AREA. SEC_SEV_ES_WORK_AREA is *not* a
>>   convenience dump. We should restrict its use as much as possible.
>>
>>   I double-checked how SEC_SEV_ES_WORK_AREA had evolved historically:
>>
>>
>>   * SEC_SEV_ES_WORK_AREA.SevEsEnabled:
>>
>>      1  43c3df78460d OvmfPkg: Reserve a page in memory for the SEV-ES usage
>>      2  0731236fc108 OvmfPkg/PlatformPei: Reserve SEV-ES work area if S3 is supported
>>      3  8a2732186a53 OvmfPkg/ResetVector: Add support for a 32-bit SEV check
>>      4  13e5492bfdf3 OvmfPkg/Sec: Add #VC exception handling for Sec phase
>>
>>   The "SEC_SEV_ES_WORK_AREA.SevEsEnabled" field is important for the
>>   following reason:
>>
>>   - in an SEV-ES guest, just learning about SEV requires exception
>>     handling; thus, the Reset Vector sets up exception handling
>>     *unconditionally*,
>>
>>   - in SEC, we deal with exception handling regardless of SEV-ES, but
>>     *how* we do that is conditional on SEV-ES.
>>
>>   This means that caching the SEV-ES presence from the Reset Vector to
>>   SEC makes a lot of sense. Given that in the Reset Vector we have
>>   unconditional exception handling, and then in SEC we have a cached
>>   result, we are allowed to only have conditional exception handling in
>>   SEC.
>>
>>
>>   * SEC_SEV_ES_WORK_AREA.RandomData, SEC_SEV_ES_WORK_AREA.EncryptionMask:
>>
>>      1  7cb96c47a94e OvmfPkg/ResetVector: Validate the encryption bit position for SEV/SEV-ES
>>      2  bd0c1c8e225b OvmfPkg/ResetVector: Perform a simple SEV-ES sanity check
>>      3  3b32be7e7192 OvmfPkg/ResetVector: Save the encryption mask at boot time
>>      4  b97dc4b92ba1 OvmfPkg/MemEncryptSevLib: Add an interface to retrieve the encryption mask
>>
>>   The "RandomData" and "EncryptionMask" fields in the
>>   SEC_SEV_ES_WORK_AREA structure seem justified because they implement
>>   some serious work (which must be done as early as possible, i.e., in
>>   the Reset Vector), *and* caching the result of that work for the rest
>>   of the firmware saves significant complexity (and the result is
>>   security-related even).
>>
>>   "SEC_SEV_ES_WORK_AREA.SevSnpEnabled" is unlike any of these three
>>   fields.
>>
>> )
>>
>> Thanks
>> Laszlo
>>
>>>> diff --git a/OvmfPkg/ResetVector/ResetVector.nasmb b/OvmfPkg/ResetVector/ResetVector.nasmb
>>>> index 5fbacaed5f9d..1971557b1c00 100644
>>>> --- a/OvmfPkg/ResetVector/ResetVector.nasmb
>>>> +++ b/OvmfPkg/ResetVector/ResetVector.nasmb
>>>> @@ -73,6 +73,7 @@
>>>>    %define GHCB_BASE (FixedPcdGet32 (PcdOvmfSecGhcbBase))
>>>>    %define GHCB_SIZE (FixedPcdGet32 (PcdOvmfSecGhcbSize))
>>>>    %define SEV_ES_WORK_AREA (FixedPcdGet32 (PcdSevEsWorkAreaBase))
>>>> +  %define SEV_ES_WORK_AREA_SNP (FixedPcdGet32 (PcdSevEsWorkAreaBase) + 1)
>>>>    %define SEV_ES_WORK_AREA_RDRAND (FixedPcdGet32 (PcdSevEsWorkAreaBase) + 8)
>>>>    %define SEV_ES_WORK_AREA_ENC_MASK (FixedPcdGet32 (PcdSevEsWorkAreaBase) + 16)
>>>>    %define SEV_ES_VC_TOP_OF_STACK (FixedPcdGet32 (PcdOvmfSecPeiTempRamBase) + FixedPcdGet32 (PcdOvmfSecPeiTempRamSize))
>>>>
>>>
>>>
>>>
>>>
>>>
>>
>>
>> 
>>
>>
> 


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

* Re: [edk2-devel] [PATCH RFC v3 04/22] OvmfPkg/MemEncryptSevLib: extend Es Workarea to include hv features
  2021-06-07 13:37     ` Brijesh Singh
@ 2021-06-08  8:49       ` Laszlo Ersek
  2021-06-08 14:50         ` Brijesh Singh
  2021-06-08 21:36         ` Lendacky, Thomas
  0 siblings, 2 replies; 57+ messages in thread
From: Laszlo Ersek @ 2021-06-08  8:49 UTC (permalink / raw)
  To: Brijesh Singh
  Cc: devel, James Bottomley, Min Xu, Jiewen Yao, Tom Lendacky,
	Jordan Justen, Erdem Aktas, Eric Dong, Ray Ni, Rahul Kumar,
	Ard Biesheuvel

On 06/07/21 15:37, Brijesh Singh wrote:

> Also, I was trying to avoid the cases where the malicious hypervisor
> changing the feature value after the GHCB negotiation is completed. 
> e.g, during the reset vector they give us one feature value and change
> them during SEC or PEI or DXE instances run. They can't break the
> security of SNP by doing so, but I thought its good to avoid querying
> the features on every phase.

If there is *feasible* security problem (attack), then my "information
flow purity" criteria are irrelevant. Security trumps all.

My understanding is though (per your explanation above) that there is no
real security problem here.

Furthermore, we're not going to query the feature set in every phase.
We're going to set the PCDs in the PEI phase; there shouldn't be
hardware querying in the DXE phase. That's quite standard business in OVMF.


>> Instead, we should have a new MemEncryptSevLib function that outputs the FEATURES bitmask. It should be similar to MemEncryptSevGetEncryptionMask(), but it should return a RETURN_STATUS, and produce the FEATURES bitmask through an output parameter.
> 
> This is one of thing which I noticed last week, we are actually creating
> a circular dependency. The MemEncryptSevLib provides the routines which
> are used by the VmgExitLib. The MemEncryptSevLib should *not* depend on
> the VmgExitLib. If we extend the MemEncryptSevLib to provide a routine
> to query the features then we will be required to include the
> VmgExitLib. The patch #13 extends the MemEncryptSevLib to provide
> functions for the page validation and it requires the VmgExitLib. I am
> trying to see what I can do to not create this circular dependency and
> still keep code reuse.

As far as I remember, a circular dependency is only a problem if both
library instances in question have constructors. If a library instance
needs no construction (has no constructor), then it does not partake in
the topological sorting (for initialization) performed by BaseTools.

In this case, at the end of your RFCv3 series (minus patch#21), no INF
file in either "OvmfPkg/Library/BaseMemEncryptSevLib" or
"OvmfPkg/Library/VmgExitLib" seems to specify a CONSTRUCTOR, so purely
from the build perspective, there should be no issue.

But, I have another idea here:

>> The SEC instance of the function should return RETURN_UNSUPPORTED.
>>
>> The PEI instance should use the GHCB MSR protocol, with the help of the AsmCpuId(), AsmWriteMsr64(), AsmReadMsr64() and AsmVmgExit() BaseLib functions.
>>
>> The DXE instance should read back the PCD.

the above basically tells us that this library API would be a single-use
interface. It wouldn't work in SEC, it would do actual work in PEI
(namely, in PlatformPei), and it wouldn't do any "real work" in DXE.

To me, the boundary is not crystal clear, but the above struggles
*suggest* that we might not want this API to be a MemEncryptSevLib
function (or any library function) at all. If abstracting out the API
causes more pain than it does good, then let's just not abstract it.

Meaning, you could open-code the fetching of features (using VmgExitLib)
in PlatormPei, set the PCD, and be done with it. The only place where
the PCD (PcdGhcbHypervisorFeatures) is actually used (as far as I can
see) is patch#21, in UefiCpuPkg. We could reasonably say that the "real
API", namely the declaration of the PCD, *already exists*, namely in the
"UefiCpuPkg/UefiCpuPkg.dec" file, from your commit e6994b1d5226
("UefiCpuPkg: Define the SEV-SNP specific dynamic PCDs", 2021-06-04).

There are other examples where a cross-package PCD is set once and for
all in OvmfPkg/PlatformPei (random example:
"PcdCpuBootLogicalProcessorNumber"). We don't have to turn everything
into a lib class API, especially if it causes more pain than help.

... But maybe I just need to accept that we have to repurpose
SEC_SEV_ES_WORK_AREA, considering it a super-early "HOB list" of sorts.
Same as the PEI phase is considered the "HOB producer phase", outputting
a bunch of disparate bits of info, we could consider the SEV-ES parts of
the Reset Vector such an "early info bits" producer phase. I think this
is a very big conceptual step away from the original purpose of
SEC_SEV_ES_WORK_AREA (note the *name* of the structure: "work area"!
HOBs are not "work areas", they are effectively read-only, once
produced). But perhaps this is what we need (and then with proper
documentation).

NB however that HOBs have types, GUIDed HOBs have GUIDs, the HOB types
are specified in PI, and GUIDs are expressly declared to stand for
various purposes at least in edk2 DEC files. All that helps with
discerning the information flow. So... I'd still prefer keeping
SEC_SEV_ES_WORK_AREA as minimal as possible.

Tom, any comments?

Thank you Brijesh for raising great points!
Laszlo


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

* Re: [PATCH RFC v3 05/22] OvmfPkg: reserve Secrets page in MEMFD
  2021-06-07 15:58     ` Brijesh Singh
@ 2021-06-08  9:20       ` Laszlo Ersek
  2021-06-08 15:43         ` [edk2-devel] " Brijesh Singh
  0 siblings, 1 reply; 57+ messages in thread
From: Laszlo Ersek @ 2021-06-08  9:20 UTC (permalink / raw)
  To: Brijesh Singh, James Bottomley, Min Xu, Jiewen Yao, Tom Lendacky,
	Jordan Justen, Erdem Aktas, Eric Dong, Ray Ni, Rahul Kumar, devel
  Cc: Ard Biesheuvel

On 06/07/21 17:58, Brijesh Singh wrote:
> 
> On 6/7/21 7:26 AM, Laszlo Ersek wrote:
>> On 05/27/21 01:11, Brijesh Singh wrote:
>>> BZ: https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Fbugzilla.tianocore.org%2Fshow_bug.cgi%3Fid%3D3275&amp;data=04%7C01%7Cbrijesh.singh%40amd.com%7C32a95d87f0984b88080708d929af878f%7C3dd8961fe4884e608e11a82d994e183d%7C0%7C0%7C637586656154129803%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C1000&amp;sdata=JyrMLVE%2BMNq%2B1sUTI7WnbxkjloKi81PcISiLvz2geLg%3D&amp;reserved=0
>>>
>>> When AMD SEV is enabled in the guest VM, a hypervisor need to insert a
>>> secrets page.
>> For pure SEV?
> 
> The secrets page is applicable to all the SEV's (SEV, SEV-ES and
> SEV-SNP) but there is some difference see below.
> 
> 
>>
>>> When SEV-SNP is enabled, the secrets page contains the VM platform
>>> communication keys. The guest BIOS and OS can use this key to communicate
>>> with the SEV firmware to get attesation report. See the SEV-SNP firmware
>>> spec for more details for the content of the secrets page.
>>>
>>> When SEV and SEV-ES is enabled, the secrets page contains the information
>>> provided by the guest owner after the attestation. See the SEV
>>> LAUNCH_SECRET command for more details.
>>>
>>> Cc: James Bottomley <jejb@linux.ibm.com>
>>> Cc: Min Xu <min.m.xu@intel.com>
>>> Cc: Jiewen Yao <jiewen.yao@intel.com>
>>> Cc: Tom Lendacky <thomas.lendacky@amd.com>
>>> Cc: Jordan Justen <jordan.l.justen@intel.com>
>>> Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
>>> Cc: Laszlo Ersek <lersek@redhat.com>
>>> Cc: Erdem Aktas <erdemaktas@google.com>
>>> Signed-off-by: Brijesh Singh <brijesh.singh@amd.com>
>>> ---
>>>  OvmfPkg/OvmfPkgX64.dsc                 |  2 ++
>>>  OvmfPkg/OvmfPkgX64.fdf                 |  5 +++++
>>>  OvmfPkg/AmdSev/SecretPei/SecretPei.inf |  1 +
>>>  OvmfPkg/AmdSev/SecretPei/SecretPei.c   | 15 ++++++++++++++-
>>>  4 files changed, 22 insertions(+), 1 deletion(-)
>> How is all of the above related to the "OvmfPkg/OvmfPkgX64.dsc"
>> platform, where remote attestation is not a goal?
>>
>> What you describe makes sense to me, but only for the remote-attested
>> "OvmfPkg/AmdSev/AmdSevX64.dsc" platform. (Which already includes
>> SecretPei and SecretDxe, and sets the necessary PCDs.)
>>
>> Then, even if we limit this patch only to the "OvmfPkg/AmdSev/SecretPei"
>> module, the commit message does not explain sufficiently why the secrets
>> page must be reserved for good. The "SEV-SNP firmware spec" reference is
>> vague at best; I'm permanently lost between the dozen PDF files I have
>> downloaded locally from the AMD website. Please include a specific
>> document number, revision number, and chapter/section identifier.
> 
> 
> There is a fundamental difference between SEV and SEV-SNP attestation
> flow. In the case of SEV and SEV-ES, the attestation happens before the
> VM is booted, and the secrets page contains the data provided by the
> guest owner after the attestation is complete. The hypervisor injects
> that data into the guest memory before booting it.  However, with
> SEV-SNP, the guest uses the data from the secrets page to build a
> message for the PSP. The guest can send the following message to the PSP:
> 
> 1. Expand the filtered CPUID list
> 2. Query attestation report
> 2. Derive a key
> 3. VM export, import, and absorb -- migration specific command
> 
> See chapter 7 [1] for all possible commands that a guest can send to PSP
> through the guest message request. I understand that it is confusing,
> but the secrets page is *not* same as SEV/SEV-ES. But since SEV-SNP spec
> calls it secrets, so I used the same name. 

I thought the secrets page was entirely opaque to the guest firmware;
i.e., all the guest firmware would do with it is (a) cover it with an
allocation in SecretPei, (b) forward it to the guest OS via a UEFI
system config table in SecretDxe.

This patch uses the same PCD names ("launch secret", where I understand
the SEV-SNP case *not* to be a *launch* secret; is that right?), plus it
uses the same drivers. That's way too confusing.


So what is this "SNP secrets" page supposed to contain:

- both the previously defined SEV/SEV-ES level launch secret, and the
SNP-specific VMPCK (?)

- how are these secret bits separated from each other in the page?

- does the guest (firmware and/or OS) *write* to the new locations in
the page, possibly for secure message construction?


Either way, I think the proposed repurposing of the page, for the sake
of SNP secrets (VMPCK and maybe even secure message construction?),
breaks the current declarations of the PCDs, in "OvmfPkg.dec":

  ## The base address and size of the SEV Launch Secret Area provisioned
  #  after remote attestation.  If this is set in the .fdf, the platform
  #  is responsible for protecting the area from DXE phase overwrites.
  gUefiOvmfPkgTokenSpaceGuid.PcdSevLaunchSecretBase|0x0|UINT32|0x42
  gUefiOvmfPkgTokenSpaceGuid.PcdSevLaunchSecretSize|0x0|UINT32|0x43

> 
> In SEV-SNP, the secrets page is not tight up with just the remote
> attestation.

This is the most important statement. We need the SNP secrets page even
without remote attestation. OvmfPkgX64.dsc does not deal with remote
attestation.

But then (putting all the PCD naming confusion aside), if a driver is
promoted to "common use", from the AmdSevX64 platform to multiple
OvmfPkg platforms, then it should be lifted to the top-level OvmfPkg
directory.

> Later, the AmdSev.dsc can include a library to perform the
> SEV-SNP-specific attestation. The library can use the SNP secrets page
> to get the key and message counter use for constructing the guest
> message to query the attestation report.
> 
> I hope it clarifies it.
> 
> [1] https://www.amd.com/system/files/TechDocs/56860.pdf
> 
> 
>> Honestly I'm getting a *rushed* vibe on this whole series. Why is that?
> 
> I am not sure why you are getting this feel, please let me know where I
> can help to clarify but the series is *rushed* at all. Its building on
> existing support. It's possible that we are getting mixed with the
> fundamental difference between the SEV and SEV-SNP attestation flow and
> recent patches from Dov to expand the attestation to cover other aspects
> of the boot flow.
> 
> In case of SEV-SNP, some folks may prefer to do all the attestation in
> the OVMF and others may prefer to do the attestation in the guest OS. We
> should try to not restrict one approach over the other.
> 
> 
>>
>> Assume that I'm dumb. You won't be far from the truth. Then hold my hand
>> through all this?
> 
> 
> Please let me know if the above explanation helps or I should expand more.

You should please (a) expand your *commit messages*, (b) add a *wall* of
text in the "OvmfPkg.dec" file, where the PCDs in questions are
declared. When I grep the OvmfPkg subdirectory in two years for
"PcdSevLaunchSecretBase", I'd like to find the DEC file's comments to be
consistent with the actual uses of the PCD, and I'd like git-blame to
tell me something useful about those lines, too.


One problem is that I'm supposed to internalize about 50 pages from yet
from another technical specification, in order to get the basics of a
single patch. I can't even follow the *set* of AMD documents I should
have a local copy of. How am I supposed to interleave all that with, for
example, reviewing a 57 slide TDX design presentation?

Honestly, this has gone off the rails. The pressure that Confidential
Computing has generated for me as an OvmfPkg co-maintainer over the
course of a few months exceeds what I've been under for nearly a
*decade*, including all prior work with SEV and SEV-ES.

This makes me incredibly unhappy.

Laszlo


> 
> 
>> Laszlo
>>
>>
>>> diff --git a/OvmfPkg/OvmfPkgX64.dsc b/OvmfPkg/OvmfPkgX64.dsc
>>> index 999738dc39cd..ea08e1fabc65 100644
>>> --- a/OvmfPkg/OvmfPkgX64.dsc
>>> +++ b/OvmfPkg/OvmfPkgX64.dsc
>>> @@ -716,6 +716,7 @@ [Components]
>>>    OvmfPkg/SmmAccess/SmmAccessPei.inf
>>>  !endif
>>>    UefiCpuPkg/CpuMpPei/CpuMpPei.inf
>>> +  OvmfPkg/AmdSev/SecretPei/SecretPei.inf
>>>  
>>>  !if $(TPM_ENABLE) == TRUE
>>>    OvmfPkg/Tcg/TpmMmioSevDecryptPei/TpmMmioSevDecryptPei.inf
>>> @@ -966,6 +967,7 @@ [Components]
>>>    OvmfPkg/PlatformDxe/Platform.inf
>>>    OvmfPkg/AmdSevDxe/AmdSevDxe.inf
>>>    OvmfPkg/IoMmuDxe/IoMmuDxe.inf
>>> +  OvmfPkg/AmdSev/SecretDxe/SecretDxe.inf
>>>  
>>>  !if $(SMM_REQUIRE) == TRUE
>>>    OvmfPkg/SmmAccess/SmmAccess2Dxe.inf
>>> diff --git a/OvmfPkg/OvmfPkgX64.fdf b/OvmfPkg/OvmfPkgX64.fdf
>>> index d6be798fcadd..9126b8eb5014 100644
>>> --- a/OvmfPkg/OvmfPkgX64.fdf
>>> +++ b/OvmfPkg/OvmfPkgX64.fdf
>>> @@ -88,6 +88,9 @@ [FD.MEMFD]
>>>  0x00C000|0x001000
>>>  gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecGhcbBackupBase|gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecGhcbBackupSize
>>>  
>>> +0x00D000|0x001000
>>> +gUefiOvmfPkgTokenSpaceGuid.PcdSevLaunchSecretBase|gUefiOvmfPkgTokenSpaceGuid.PcdSevLaunchSecretSize
>>> +
>>>  0x010000|0x010000
>>>  gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecPeiTempRamBase|gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecPeiTempRamSize
>>>  
>>> @@ -179,6 +182,7 @@ [FV.PEIFV]
>>>  INF  SecurityPkg/Tcg/TcgPei/TcgPei.inf
>>>  INF  SecurityPkg/Tcg/Tcg2Pei/Tcg2Pei.inf
>>>  !endif
>>> +INF  OvmfPkg/AmdSev/SecretPei/SecretPei.inf
>>>  
>>>  ################################################################################
>>>  
>>> @@ -314,6 +318,7 @@ [FV.DXEFV]
>>>  INF  ShellPkg/Application/Shell/Shell.inf
>>>  
>>>  INF MdeModulePkg/Logo/LogoDxe.inf
>>> +INF OvmfPkg/AmdSev/SecretDxe/SecretDxe.inf
>>>  
>>>  #
>>>  # Network modules
>>> diff --git a/OvmfPkg/AmdSev/SecretPei/SecretPei.inf b/OvmfPkg/AmdSev/SecretPei/SecretPei.inf
>>> index 08be156c4bc0..9265f8adee12 100644
>>> --- a/OvmfPkg/AmdSev/SecretPei/SecretPei.inf
>>> +++ b/OvmfPkg/AmdSev/SecretPei/SecretPei.inf
>>> @@ -26,6 +26,7 @@ [LibraryClasses]
>>>    HobLib
>>>    PeimEntryPoint
>>>    PcdLib
>>> +  MemEncryptSevLib
>>>  
>>>  [FixedPcd]
>>>    gUefiOvmfPkgTokenSpaceGuid.PcdSevLaunchSecretBase
>>> diff --git a/OvmfPkg/AmdSev/SecretPei/SecretPei.c b/OvmfPkg/AmdSev/SecretPei/SecretPei.c
>>> index ad491515dd5d..51eb094555aa 100644
>>> --- a/OvmfPkg/AmdSev/SecretPei/SecretPei.c
>>> +++ b/OvmfPkg/AmdSev/SecretPei/SecretPei.c
>>> @@ -7,6 +7,7 @@
>>>  #include <PiPei.h>
>>>  #include <Library/HobLib.h>
>>>  #include <Library/PcdLib.h>
>>> +#include <Library/MemEncryptSevLib.h>
>>>  
>>>  EFI_STATUS
>>>  EFIAPI
>>> @@ -15,10 +16,22 @@ InitializeSecretPei (
>>>    IN CONST EFI_PEI_SERVICES     **PeiServices
>>>    )
>>>  {
>>> +  UINTN   Type;
>>> +
>>> +  //
>>> +  // The location of the secret page should be marked reserved so that guest OS
>>> +  // does not treated as a system RAM.
>>> +  //
>>> +  if (MemEncryptSevSnpIsEnabled ()) {
>>> +    Type = EfiReservedMemoryType;
>>> +  } else {
>>> +    Type = EfiBootServicesData;
>>> +  }
>>> +
>>>    BuildMemoryAllocationHob (
>>>      PcdGet32 (PcdSevLaunchSecretBase),
>>>      PcdGet32 (PcdSevLaunchSecretSize),
>>> -    EfiBootServicesData
>>> +    Type
>>>      );
>>>  
>>>    return EFI_SUCCESS;
>>>
> 


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

* Re: [PATCH RFC v3 05/22] OvmfPkg: reserve Secrets page in MEMFD
  2021-06-07 17:33       ` Brijesh Singh
@ 2021-06-08  9:22         ` Laszlo Ersek
  0 siblings, 0 replies; 57+ messages in thread
From: Laszlo Ersek @ 2021-06-08  9:22 UTC (permalink / raw)
  To: Brijesh Singh, James Bottomley, Min Xu, Jiewen Yao, Tom Lendacky,
	Jordan Justen, Erdem Aktas, Eric Dong, Ray Ni, Rahul Kumar, devel
  Cc: Ard Biesheuvel

On 06/07/21 19:33, Brijesh Singh wrote:
> 
> On 6/7/21 7:48 AM, Laszlo Ersek wrote:
>> On 06/07/21 14:26, Laszlo Ersek wrote:
>>> On 05/27/21 01:11, Brijesh Singh wrote:
>>>> BZ: https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Fbugzilla.tianocore.org%2Fshow_bug.cgi%3Fid%3D3275&amp;data=04%7C01%7Cbrijesh.singh%40amd.com%7Cc7a508dbd4af461b413208d929b2a231%7C3dd8961fe4884e608e11a82d994e183d%7C0%7C0%7C637586669489236720%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C1000&amp;sdata=OjlLNpUW8U%2FykMMU7JwjddEZd9Zi%2BsHNK%2FqoQCwW3vo%3D&amp;reserved=0
>>>>
>>>> When AMD SEV is enabled in the guest VM, a hypervisor need to insert a
>>>> secrets page.
>>> For pure SEV?
>>>
>>>> When SEV-SNP is enabled, the secrets page contains the VM platform
>>>> communication keys. The guest BIOS and OS can use this key to communicate
>>>> with the SEV firmware to get attesation report. See the SEV-SNP firmware
>>>> spec for more details for the content of the secrets page.
>>>>
>>>> When SEV and SEV-ES is enabled, the secrets page contains the information
>>>> provided by the guest owner after the attestation. See the SEV
>>>> LAUNCH_SECRET command for more details.
>>>>
>>>> Cc: James Bottomley <jejb@linux.ibm.com>
>>>> Cc: Min Xu <min.m.xu@intel.com>
>>>> Cc: Jiewen Yao <jiewen.yao@intel.com>
>>>> Cc: Tom Lendacky <thomas.lendacky@amd.com>
>>>> Cc: Jordan Justen <jordan.l.justen@intel.com>
>>>> Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
>>>> Cc: Laszlo Ersek <lersek@redhat.com>
>>>> Cc: Erdem Aktas <erdemaktas@google.com>
>>>> Signed-off-by: Brijesh Singh <brijesh.singh@amd.com>
>>>> ---
>>>>  OvmfPkg/OvmfPkgX64.dsc                 |  2 ++
>>>>  OvmfPkg/OvmfPkgX64.fdf                 |  5 +++++
>>>>  OvmfPkg/AmdSev/SecretPei/SecretPei.inf |  1 +
>>>>  OvmfPkg/AmdSev/SecretPei/SecretPei.c   | 15 ++++++++++++++-
>>>>  4 files changed, 22 insertions(+), 1 deletion(-)
>>> How is all of the above related to the "OvmfPkg/OvmfPkgX64.dsc"
>>> platform, where remote attestation is not a goal?
>>>
>>> What you describe makes sense to me, but only for the remote-attested
>>> "OvmfPkg/AmdSev/AmdSevX64.dsc" platform. (Which already includes
>>> SecretPei and SecretDxe, and sets the necessary PCDs.)
>>>
>>> Then, even if we limit this patch only to the "OvmfPkg/AmdSev/SecretPei"
>>> module, the commit message does not explain sufficiently why the secrets
>>> page must be reserved for good. The "SEV-SNP firmware spec" reference is
>>> vague at best; I'm permanently lost between the dozen PDF files I have
>>> downloaded locally from the AMD website. Please include a specific
>>> document number, revision number, and chapter/section identifier.
>>>
>>> Honestly I'm getting a *rushed* vibe on this whole series. Why is that?
>>>
>>> Assume that I'm dumb. You won't be far from the truth. Then hold my hand
>>> through all this?
>> Here's the v2 discussion:
>>
>> - https://nam11.safelinks.protection.outlook.com/?url=http%3A%2F%2Fmid.mail-archive.com%2F9804ecb5-8afd-c56e-4982-d1a6ebad3de8%40redhat.com&amp;data=04%7C01%7Cbrijesh.singh%40amd.com%7Cc7a508dbd4af461b413208d929b2a231%7C3dd8961fe4884e608e11a82d994e183d%7C0%7C0%7C637586669489236720%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C1000&amp;sdata=K8FRcks19dQ4BM4DBOh%2F7uO4hNvIsM0eqdNvwUQzDUU%3D&amp;reserved=0
>> - https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Fedk2.groups.io%2Fg%2Fdevel%2Fmessage%2F74797&amp;data=04%7C01%7Cbrijesh.singh%40amd.com%7Cc7a508dbd4af461b413208d929b2a231%7C3dd8961fe4884e608e11a82d994e183d%7C0%7C0%7C637586669489236720%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C1000&amp;sdata=8rfpRAEvBdWex0BQctCbbGnHb691gcKSIEvVA3ZKDkg%3D&amp;reserved=0
>> - https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Flistman.redhat.com%2Farchives%2Fedk2-devel-archive%2F2021-May%2Fmsg00112.html&amp;data=04%7C01%7Cbrijesh.singh%40amd.com%7Cc7a508dbd4af461b413208d929b2a231%7C3dd8961fe4884e608e11a82d994e183d%7C0%7C0%7C637586669489246713%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C1000&amp;sdata=NAL8jAfiq1EApkDBOBjgL7b3NIsmjginZSDxB1NDCk8%3D&amp;reserved=0
>>
>> That discussion refers to a different use case, raised by Dov. That use
>> case might justify reserving the area even for plain SEV. It's out of
>> scope for now, AIUI.
>>
>> (
>>
>> And even for that separate use case, James showed down-thread that *not*
>> reserving the page forever in the firmware is more flexible.
>>
>> - https://nam11.safelinks.protection.outlook.com/?url=http%3A%2F%2Fmid.mail-archive.com%2Faed7d3490fe6edee74440ed8e4cd5364fb2ba4af.camel%40linux.ibm.com&amp;data=04%7C01%7Cbrijesh.singh%40amd.com%7Cc7a508dbd4af461b413208d929b2a231%7C3dd8961fe4884e608e11a82d994e183d%7C0%7C0%7C637586669489246713%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C1000&amp;sdata=2UV6KcGYb9CoKzgIU%2FscCX2l%2F5pKaSkFYshP%2BPSWHSM%3D&amp;reserved=0
>> - https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Fedk2.groups.io%2Fg%2Fdevel%2Fmessage%2F74801&amp;data=04%7C01%7Cbrijesh.singh%40amd.com%7Cc7a508dbd4af461b413208d929b2a231%7C3dd8961fe4884e608e11a82d994e183d%7C0%7C0%7C637586669489246713%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C1000&amp;sdata=jnHpYxYkijt2LtcH772m88%2BLNH3Zjfn3Zqc3uuttL1M%3D&amp;reserved=0
>> - https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Flistman.redhat.com%2Farchives%2Fedk2-devel-archive%2F2021-May%2Fmsg00116.html&amp;data=04%7C01%7Cbrijesh.singh%40amd.com%7Cc7a508dbd4af461b413208d929b2a231%7C3dd8961fe4884e608e11a82d994e183d%7C0%7C0%7C637586669489246713%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C1000&amp;sdata=XzePjtTDS8blsXhBNOg52uo81uFhoYpgcNMvU4RupSI%3D&amp;reserved=0
>>
>> )
>>
>> AFAICT, the only effect of the v2 sub-thread on the patch has been that
>> we now use the Reserved memory type rather than AcpiNVS (when SEV-SNP is
>> in use). I have two comments on that:
>>
>> - It's good that we're not mixing in the other use case raised by Dov
>>   (i.e., enabling the guest-kernel to read secrets from the injected
>>   page even under plain SEV).
>>
>> - It's still unclear to me why the reservation needs to be permanent
>>   under SEV-SNP.
> 
> 
> As highlighted in the previous email, in the case of SEV, the secrets
> page contains the private data provided by the guest owner to the guest.
> Whereas, in SEV-SNP, the secrets page includes the key and other
> metadata used by the guest (OVMF or kernel) to construct a message for
> the PSP. The secrets page contains some information (e.g key and
> sequence number) that must persist across kexec boots. If we mark the
> SEV-SNP secrets page as "Boot Data," I believe it gets free'd on
> ExitBootService(). In the kexec'ed kernel, we need to retrieve the
> secret page to get the key and message counters to construct the next
> PSP quest request command.

All great information, especially the kexec bits; why not explicitly
document all this?

Thanks
Laszlo

> 
> 
> I have not looked into detail on how EFI configuration table and other
> data is preserved during the kexec boot, but I thought making the
> secrets reserved should ensure that memory is not free'd on
> ExitBootServices() and we can reach it after the kexec. I can
> investigate a bit more.
> 
> Dov/James,
>  
> Does kexec works with the SEV secrets page?
> 
> -Brijesh
> 
> 
> 
> 


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

* Re: [edk2-devel] [PATCH RFC v3 03/22] OvmfPkg/MemEncryptSevLib: extend the workarea to include SNP enabled field
  2021-06-08  8:17         ` Laszlo Ersek
@ 2021-06-08 13:51           ` Brijesh Singh
  2021-06-08 16:42             ` Laszlo Ersek
  0 siblings, 1 reply; 57+ messages in thread
From: Brijesh Singh @ 2021-06-08 13:51 UTC (permalink / raw)
  To: Laszlo Ersek, devel, James Bottomley, Min Xu, Jiewen Yao,
	Tom Lendacky, Jordan Justen, Erdem Aktas, Eric Dong, Ray Ni,
	Rahul Kumar
  Cc: brijesh.singh, Ard Biesheuvel


On 6/8/21 3:17 AM, Laszlo Ersek wrote:
>
>>> (3) Actually, no.
>>>
>>> This patch should be reduced to the following files only:
>>>
>>> - OvmfPkg/PlatformPei/AmdSev.c
>>> - OvmfPkg/PlatformPei/PlatformPei.inf
>>>
>>> and the following changes should be dropped completely:
>>>
>>> - OvmfPkg/Include/Library/MemEncryptSevLib.h
>>> - OvmfPkg/ResetVector/Ia32/PageTables64.asm
>>> - OvmfPkg/ResetVector/ResetVector.nasmb
>>>
>>> Specifically, the "SEC_SEV_ES_WORK_AREA.SevSnpEnabled" field should
>>> never be introduced.
>>>
>>> The reason is apparent only from patch #10 -- "OvmfPkg/PlatformPei:
>>> register GHCB gpa for the SEV-SNP guest".
>>>
>>> The core idea is that in patch#10, in the SEC module, you can implement
>>> SevSnpIsEnabled() by just reading MSR_SEV_STATUS, and checking the SNP
>>> bit. Namely, while the SevSnpIsEnabled() call is made in
>>> SevEsProtocolCheck(), i.e., before exception handling is set up in the
>>> SEC module -- and so you indeed cannot call CPUID --, you don't *have*
>>> to call CPUID at that call site. Where you call SevSnpIsEnabled() in
>>> SevEsProtocolCheck(), you already know that SEV-ES is enabled, so it's
>>> safe to just read the exact same SEV status MSR that the SEV-ES status
>>> comes from in the first place, without any CPUID safety check.
>> We must check the SNP Enabled inside the assembly code for the page
>> invalidate functions, and I decided to cache the value. A similar
>> SNP-enabled check is required in SEC phase before the
>> ProcessLibraryConstrctorList() is called. There are two options on how
>> we can go about doing the SNP enabled check inside the SEC phase
>> 1. Call the SEV_STATUS MSR after reading the
>> SEC_SEV_ES_WORK_AREA.SevEnabled. As you said, we need to be sure that ES
>> is enabled before calling the SEV_STATUS MSR.
>> 2. SEV_STATUS MSR is read in Reset vector for the SNP enabled check
>> purpose. Extend the SevEsWorkArea to cache the state.
>>
>>  I chose #2 because it avoids checking for ES enabled before checking
>> the SNP enabled. I understand that in the current code path, SNP check
>> is called inside the SevEsProtocolCheck() -- ES is already enabled, and
>> its safe to call SEV_STATUS MSR. What if we need to check for the SNP
>> state outside the ES-specific code block in the future? Then we will
>> need to extend the SevEsWorkArea.
> What would be the reason for this, ever?

One reason I can think of is if we ever decided validate the pages
before the SevEsProtocolCheck(). The version 2 of GHCB spec adds few new
NAE's that are SNP specific such as Page State Change. They are not
applicable to the ES guests. Currently, we do the page validation much
later and by then ProcessorConstructList() is called. Anyway, this is
not an important thing to consider right now. As I said, I will drop the
extending workarea to cache the SNP enable and Hypervisor feature values.


>
> I think this ties in with another point (or question) I raised
> elsewhere: the assembly code in the reset vector suggests *anyway* that
> SNP is only available if ES is available, but I couldn't verify that
> from any specs. If this dependency is an architectural fact (that is, if
> ES is absent, then SNP may never be present), then I wouldn't like to
> introduce a separate field for SNP presence in the SEC_SEV_ES_WORK_AREA
> structure.

The SEV-SNP builds upon existing SEV and SEV-ES support and provides an
additional protection from the hypervisor. The SEV-SNP feature requires
both the SEV and SEV-ES must be enabled. There is some text about it in
APM volume 2 [1] chapter  15.36.


[1] https://www.amd.com/system/files/TechDocs/24593.pdf


thanks


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

* Re: [edk2-devel] [PATCH RFC v3 04/22] OvmfPkg/MemEncryptSevLib: extend Es Workarea to include hv features
  2021-06-08  8:49       ` Laszlo Ersek
@ 2021-06-08 14:50         ` Brijesh Singh
  2021-06-08 21:36         ` Lendacky, Thomas
  1 sibling, 0 replies; 57+ messages in thread
From: Brijesh Singh @ 2021-06-08 14:50 UTC (permalink / raw)
  To: Laszlo Ersek
  Cc: brijesh.singh, devel, James Bottomley, Min Xu, Jiewen Yao,
	Tom Lendacky, Jordan Justen, Erdem Aktas, Eric Dong, Ray Ni,
	Rahul Kumar, Ard Biesheuvel


On 6/8/21 3:49 AM, Laszlo Ersek wrote:
> On 06/07/21 15:37, Brijesh Singh wrote:
>
>> Also, I was trying to avoid the cases where the malicious hypervisor
>> changing the feature value after the GHCB negotiation is completed. 
>> e.g, during the reset vector they give us one feature value and change
>> them during SEC or PEI or DXE instances run. They can't break the
>> security of SNP by doing so, but I thought its good to avoid querying
>> the features on every phase.
> If there is *feasible* security problem (attack), then my "information
> flow purity" criteria are irrelevant. Security trumps all.
>
> My understanding is though (per your explanation above) that there is no
> real security problem here.
>
> Furthermore, we're not going to query the feature set in every phase.
> We're going to set the PCDs in the PEI phase; there shouldn't be
> hardware querying in the DXE phase. That's quite standard business in OVMF.
>
>
>>> Instead, we should have a new MemEncryptSevLib function that outputs the FEATURES bitmask. It should be similar to MemEncryptSevGetEncryptionMask(), but it should return a RETURN_STATUS, and produce the FEATURES bitmask through an output parameter.
>> This is one of thing which I noticed last week, we are actually creating
>> a circular dependency. The MemEncryptSevLib provides the routines which
>> are used by the VmgExitLib. The MemEncryptSevLib should *not* depend on
>> the VmgExitLib. If we extend the MemEncryptSevLib to provide a routine
>> to query the features then we will be required to include the
>> VmgExitLib. The patch #13 extends the MemEncryptSevLib to provide
>> functions for the page validation and it requires the VmgExitLib. I am
>> trying to see what I can do to not create this circular dependency and
>> still keep code reuse.
> As far as I remember, a circular dependency is only a problem if both
> library instances in question have constructors. If a library instance
> needs no construction (has no constructor), then it does not partake in
> the topological sorting (for initialization) performed by BaseTools.
>
> In this case, at the end of your RFCv3 series (minus patch#21), no INF
> file in either "OvmfPkg/Library/BaseMemEncryptSevLib" or
> "OvmfPkg/Library/VmgExitLib" seems to specify a CONSTRUCTOR, so purely
> from the build perspective, there should be no issue.

I have to debug it, but it did appear that this circular dependency
caused problem for the SEV guest when SMM is enabled. If SMM is enabled,
then I get a random #UD as soon as I link the VmgExit to
MemEncryptSevLib. I will see what I find.


>
> But, I have another idea here:
>
>>> The SEC instance of the function should return RETURN_UNSUPPORTED.
>>>
>>> The PEI instance should use the GHCB MSR protocol, with the help of the AsmCpuId(), AsmWriteMsr64(), AsmReadMsr64() and AsmVmgExit() BaseLib functions.
>>>
>>> The DXE instance should read back the PCD.
> the above basically tells us that this library API would be a single-use
> interface. It wouldn't work in SEC, it would do actual work in PEI
> (namely, in PlatformPei), and it wouldn't do any "real work" in DXE.
>
> To me, the boundary is not crystal clear, but the above struggles
> *suggest* that we might not want this API to be a MemEncryptSevLib
> function (or any library function) at all. If abstracting out the API
> causes more pain than it does good, then let's just not abstract it.
>
> Meaning, you could open-code the fetching of features (using VmgExitLib)
> in PlatormPei, set the PCD, and be done with it. The only place where
> the PCD (PcdGhcbHypervisorFeatures) is actually used (as far as I can
> see) is patch#21, in UefiCpuPkg. We could reasonably say that the "real
> API", namely the declaration of the PCD, *already exists*, namely in the
> "UefiCpuPkg/UefiCpuPkg.dec" file, from your commit e6994b1d5226
> ("UefiCpuPkg: Define the SEV-SNP specific dynamic PCDs", 2021-06-04).
>
> There are other examples where a cross-package PCD is set once and for
> all in OvmfPkg/PlatformPei (random example:
> "PcdCpuBootLogicalProcessorNumber"). We don't have to turn everything
> into a lib class API, especially if it causes more pain than help.

This is much ideal, I would prefer to avoid creating a new library or
add a function into the existing library if this function is only going
to be used once during the PEI to query the feature.



> ... But maybe I just need to accept that we have to repurpose
> SEC_SEV_ES_WORK_AREA, considering it a super-early "HOB list" of sorts.
> Same as the PEI phase is considered the "HOB producer phase", outputting
> a bunch of disparate bits of info, we could consider the SEV-ES parts of
> the Reset Vector such an "early info bits" producer phase. I think this
> is a very big conceptual step away from the original purpose of
> SEC_SEV_ES_WORK_AREA (note the *name* of the structure: "work area"!
> HOBs are not "work areas", they are effectively read-only, once
> produced). But perhaps this is what we need (and then with proper
> documentation).
>
> NB however that HOBs have types, GUIDed HOBs have GUIDs, the HOB types
> are specified in PI, and GUIDs are expressly declared to stand for
> various purposes at least in edk2 DEC files. All that helps with
> discerning the information flow. So... I'd still prefer keeping
> SEC_SEV_ES_WORK_AREA as minimal as possible.
>
> Tom, any comments?
>
> Thank you Brijesh for raising great points!
> Laszlo
>

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

* Re: [edk2-devel] [PATCH RFC v3 05/22] OvmfPkg: reserve Secrets page in MEMFD
  2021-06-08  9:20       ` Laszlo Ersek
@ 2021-06-08 15:43         ` Brijesh Singh
  2021-06-08 18:01           ` Laszlo Ersek
  0 siblings, 1 reply; 57+ messages in thread
From: Brijesh Singh @ 2021-06-08 15:43 UTC (permalink / raw)
  To: devel, lersek, James Bottomley, Min Xu, Jiewen Yao, Tom Lendacky,
	Jordan Justen, Erdem Aktas, Eric Dong, Ray Ni, Rahul Kumar
  Cc: brijesh.singh, Ard Biesheuvel


On 6/8/21 4:20 AM, Laszlo Ersek via groups.io wrote:
>
> I thought the secrets page was entirely opaque to the guest firmware;
> i.e., all the guest firmware would do with it is (a) cover it with an
> allocation in SecretPei, (b) forward it to the guest OS via a UEFI
> system config table in SecretDxe.

Yes, it should be an opaque to the guest firmware. If someone wants to
do attestation inside the OVMF then they may need to know the whether
its an SEV or SEV-SNP guest. If its SEV guest then blob contains the
guest private information (such as disk key) and if its SEV-SNP guest
then blob contains the encryption key used for communicating with the PSP.


>
> This patch uses the same PCD names ("launch secret", where I understand
> the SEV-SNP case *not* to be a *launch* secret; is that right?), plus it
> uses the same drivers. That's way too confusing.

Yes, its not a launch secret. With your responses so far it seems that I
need to create a different PCD and spell out that its for SNP secrets
page, maybe something like this:

"PcdSevSnpSecretBase"

Since the code for reserving the memory type and installing the EFI
configuration table already existed in AmdSev/Secrets{Dxe,Pei} so I
decided to reuse. Now I understand that why you don't want to overload
those drivers. Those drivers are not part of OvmfPkgX64.dsc because the
generic packages do not support the attestation. I will update in v4 to
not use those drivers and reserve the memory during PEI phase and create
another driver to install the configuration table for it.

>
> So what is this "SNP secrets" page supposed to contain:
>
> - both the previously defined SEV/SEV-ES level launch secret, and the
> SNP-specific VMPCK (?)
>
> - how are these secret bits separated from each other in the page?
>
> - does the guest (firmware and/or OS) *write* to the new locations in
> the page, possibly for secure message construction?
>
>
> Either way, I think the proposed repurposing of the page, for the sake
> of SNP secrets (VMPCK and maybe even secure message construction?),
> breaks the current declarations of the PCDs, in "OvmfPkg.dec":
>
>   ## The base address and size of the SEV Launch Secret Area provisioned
>   #  after remote attestation.  If this is set in the .fdf, the platform
>   #  is responsible for protecting the area from DXE phase overwrites.
>   gUefiOvmfPkgTokenSpaceGuid.PcdSevLaunchSecretBase|0x0|UINT32|0x42
>   gUefiOvmfPkgTokenSpaceGuid.PcdSevLaunchSecretSize|0x0|UINT32|0x43
>
>> In SEV-SNP, the secrets page is not tight up with just the remote
>> attestation.
> This is the most important statement. We need the SNP secrets page even
> without remote attestation. OvmfPkgX64.dsc does not deal with remote
> attestation.
>
> But then (putting all the PCD naming confusion aside), if a driver is
> promoted to "common use", from the AmdSevX64 platform to multiple
> OvmfPkg platforms, then it should be lifted to the top-level OvmfPkg
> directory.

Now I think about it maybe we should leave the driver where it is
because OvmfPkgX64.dsc does not need to deal with the attestation etc.
But we need to create a driver that can install the EFI configuration
table for the SNP secrets page. Is that okay ?


>> Later, the AmdSev.dsc can include a library to perform the
>> SEV-SNP-specific attestation. The library can use the SNP secrets page
>> to get the key and message counter use for constructing the guest
>> message to query the attestation report.
>>
>> I hope it clarifies it.
>>
>> [1] https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Fwww.amd.com%2Fsystem%2Ffiles%2FTechDocs%2F56860.pdf&amp;data=04%7C01%7Cbrijesh.singh%40amd.com%7C972887a952cd48b090a308d92a5eb0d5%7C3dd8961fe4884e608e11a82d994e183d%7C0%7C0%7C637587409068253595%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C1000&amp;sdata=j%2FL5eTSR3%2FODJRE0IaF7R49aDVkFjDCO1JUpGsPbDwk%3D&amp;reserved=0
>>
>>
>>> Honestly I'm getting a *rushed* vibe on this whole series. Why is that?
>> I am not sure why you are getting this feel, please let me know where I
>> can help to clarify but the series is *rushed* at all. Its building on
>> existing support. It's possible that we are getting mixed with the
>> fundamental difference between the SEV and SEV-SNP attestation flow and
>> recent patches from Dov to expand the attestation to cover other aspects
>> of the boot flow.
>>
>> In case of SEV-SNP, some folks may prefer to do all the attestation in
>> the OVMF and others may prefer to do the attestation in the guest OS. We
>> should try to not restrict one approach over the other.
>>
>>
>>> Assume that I'm dumb. You won't be far from the truth. Then hold my hand
>>> through all this?
>>
>> Please let me know if the above explanation helps or I should expand more.
> You should please (a) expand your *commit messages*, (b) add a *wall* of
> text in the "OvmfPkg.dec" file, where the PCDs in questions are
> declared. When I grep the OvmfPkg subdirectory in two years for
> "PcdSevLaunchSecretBase", I'd like to find the DEC file's comments to be
> consistent with the actual uses of the PCD, and I'd like git-blame to
> tell me something useful about those lines, too.
>
I will add more comments in the patch to clarify certain things.


> One problem is that I'm supposed to internalize about 50 pages from yet
> from another technical specification, in order to get the basics of a
> single patch. I can't even follow the *set* of AMD documents I should
> have a local copy of. How am I supposed to interleave all that with, for
> example, reviewing a 57 slide TDX design presentation?

As you may have seen that myself and Tom try not to put the exact link
or  document number in the comment is because we have seen that our docs
folks change the link or they replace the old document with the new
copy. We have similar issue in kernel. The kernel maintainer now have a
bugzilla where they want us to upload the document so that they can keep
a copy and in the commits we refer to that BZ link instead of AMD URL. I
myself gets so mixed up with various version of documents. I don't like
that we replace the old docs with a new without archiving it.

thanks



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

* Re: [edk2-devel] [PATCH RFC v3 03/22] OvmfPkg/MemEncryptSevLib: extend the workarea to include SNP enabled field
  2021-06-08 13:51           ` Brijesh Singh
@ 2021-06-08 16:42             ` Laszlo Ersek
  0 siblings, 0 replies; 57+ messages in thread
From: Laszlo Ersek @ 2021-06-08 16:42 UTC (permalink / raw)
  To: Brijesh Singh, devel, James Bottomley, Min Xu, Jiewen Yao,
	Tom Lendacky, Jordan Justen, Erdem Aktas, Eric Dong, Ray Ni,
	Rahul Kumar
  Cc: Ard Biesheuvel

On 06/08/21 15:51, Brijesh Singh wrote:
> 
> On 6/8/21 3:17 AM, Laszlo Ersek wrote:
>>
>>>> (3) Actually, no.
>>>>
>>>> This patch should be reduced to the following files only:
>>>>
>>>> - OvmfPkg/PlatformPei/AmdSev.c
>>>> - OvmfPkg/PlatformPei/PlatformPei.inf
>>>>
>>>> and the following changes should be dropped completely:
>>>>
>>>> - OvmfPkg/Include/Library/MemEncryptSevLib.h
>>>> - OvmfPkg/ResetVector/Ia32/PageTables64.asm
>>>> - OvmfPkg/ResetVector/ResetVector.nasmb
>>>>
>>>> Specifically, the "SEC_SEV_ES_WORK_AREA.SevSnpEnabled" field should
>>>> never be introduced.
>>>>
>>>> The reason is apparent only from patch #10 -- "OvmfPkg/PlatformPei:
>>>> register GHCB gpa for the SEV-SNP guest".
>>>>
>>>> The core idea is that in patch#10, in the SEC module, you can implement
>>>> SevSnpIsEnabled() by just reading MSR_SEV_STATUS, and checking the SNP
>>>> bit. Namely, while the SevSnpIsEnabled() call is made in
>>>> SevEsProtocolCheck(), i.e., before exception handling is set up in the
>>>> SEC module -- and so you indeed cannot call CPUID --, you don't *have*
>>>> to call CPUID at that call site. Where you call SevSnpIsEnabled() in
>>>> SevEsProtocolCheck(), you already know that SEV-ES is enabled, so it's
>>>> safe to just read the exact same SEV status MSR that the SEV-ES status
>>>> comes from in the first place, without any CPUID safety check.
>>> We must check the SNP Enabled inside the assembly code for the page
>>> invalidate functions, and I decided to cache the value. A similar
>>> SNP-enabled check is required in SEC phase before the
>>> ProcessLibraryConstrctorList() is called. There are two options on how
>>> we can go about doing the SNP enabled check inside the SEC phase
>>> 1. Call the SEV_STATUS MSR after reading the
>>> SEC_SEV_ES_WORK_AREA.SevEnabled. As you said, we need to be sure that ES
>>> is enabled before calling the SEV_STATUS MSR.
>>> 2. SEV_STATUS MSR is read in Reset vector for the SNP enabled check
>>> purpose. Extend the SevEsWorkArea to cache the state.
>>>
>>>  I chose #2 because it avoids checking for ES enabled before checking
>>> the SNP enabled. I understand that in the current code path, SNP check
>>> is called inside the SevEsProtocolCheck() -- ES is already enabled, and
>>> its safe to call SEV_STATUS MSR. What if we need to check for the SNP
>>> state outside the ES-specific code block in the future? Then we will
>>> need to extend the SevEsWorkArea.
>> What would be the reason for this, ever?
> 
> One reason I can think of is if we ever decided validate the pages
> before the SevEsProtocolCheck(). The version 2 of GHCB spec adds few new
> NAE's that are SNP specific such as Page State Change. They are not
> applicable to the ES guests. Currently, we do the page validation much
> later and by then ProcessorConstructList() is called. Anyway, this is
> not an important thing to consider right now. As I said, I will drop the
> extending workarea to cache the SNP enable and Hypervisor feature values.

Thanks.

I agree there are conflicting goals here (and by that I don't mean my
goals conflict with yours). One goal is to avoid speculative generality,
as (in my experience) actual usage of such generality rarely
materializes, but we keep paying the price of a more complex data flow
in maintenance. The conflicting goal is to lay a future-proof foundation
(also known as "let's not code ourselves into a corner").

Personally, I'm really bad at predicting the future, while (I feel)
more-complex-than-necessary data flow tends to sound my alarm quickly.
(Perhaps because that can make debugging difficult.) I know I'm going
out on a limb here and that I might eat my words later, but right now, I
think we should not extend the work area.

Thanks for putting up with me.


> 
> 
>>
>> I think this ties in with another point (or question) I raised
>> elsewhere: the assembly code in the reset vector suggests *anyway* that
>> SNP is only available if ES is available, but I couldn't verify that
>> from any specs. If this dependency is an architectural fact (that is, if
>> ES is absent, then SNP may never be present), then I wouldn't like to
>> introduce a separate field for SNP presence in the SEC_SEV_ES_WORK_AREA
>> structure.
> 
> The SEV-SNP builds upon existing SEV and SEV-ES support and provides an
> additional protection from the hypervisor. The SEV-SNP feature requires
> both the SEV and SEV-ES must be enabled. There is some text about it in
> APM volume 2 [1] chapter  15.36.
> 
> 
> [1] https://www.amd.com/system/files/TechDocs/24593.pdf

Perfect, the first paragraph is exactly what I needed:

    The SEV-SNP features enable additional protection for encrypted VMs
    designed to achieve stronger isolation from the hypervisor. SEV-SNP
    is used with the SEV and SEV-ES features described in Section 15.34
    and Section 15.35 respectively and requires the enablement and use
    of these features.

Thanks!
Laszlo


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

* Re: [edk2-devel] [PATCH RFC v3 05/22] OvmfPkg: reserve Secrets page in MEMFD
  2021-06-08 15:43         ` [edk2-devel] " Brijesh Singh
@ 2021-06-08 18:01           ` Laszlo Ersek
  2021-06-08 18:34             ` Brijesh Singh
  0 siblings, 1 reply; 57+ messages in thread
From: Laszlo Ersek @ 2021-06-08 18:01 UTC (permalink / raw)
  To: Brijesh Singh, devel, James Bottomley, Min Xu, Jiewen Yao,
	Tom Lendacky, Jordan Justen, Erdem Aktas, Eric Dong, Ray Ni,
	Rahul Kumar
  Cc: Ard Biesheuvel

On 06/08/21 17:43, Brijesh Singh wrote:
> 
> On 6/8/21 4:20 AM, Laszlo Ersek via groups.io wrote:
>>
>> I thought the secrets page was entirely opaque to the guest firmware;
>> i.e., all the guest firmware would do with it is (a) cover it with an
>> allocation in SecretPei, (b) forward it to the guest OS via a UEFI
>> system config table in SecretDxe.
> 
> Yes, it should be an opaque to the guest firmware. If someone wants to
> do attestation inside the OVMF then they may need to know the whether
> its an SEV or SEV-SNP guest. If its SEV guest then blob contains the
> guest private information (such as disk key) and if its SEV-SNP guest
> then blob contains the encryption key used for communicating with the PSP.
> 
> 
>>
>> This patch uses the same PCD names ("launch secret", where I understand
>> the SEV-SNP case *not* to be a *launch* secret; is that right?), plus it
>> uses the same drivers. That's way too confusing.
> 
> Yes, its not a launch secret. With your responses so far it seems that I
> need to create a different PCD and spell out that its for SNP secrets
> page, maybe something like this:
> 
> "PcdSevSnpSecretBase"
> 
> Since the code for reserving the memory type and installing the EFI
> configuration table already existed in AmdSev/Secrets{Dxe,Pei} so I
> decided to reuse. Now I understand that why you don't want to overload
> those drivers. Those drivers are not part of OvmfPkgX64.dsc because the
> generic packages do not support the attestation. I will update in v4 to
> not use those drivers and reserve the memory during PEI phase and create
> another driver to install the configuration table for it.
> 
>>
>> So what is this "SNP secrets" page supposed to contain:
>>
>> - both the previously defined SEV/SEV-ES level launch secret, and the
>> SNP-specific VMPCK (?)
>>
>> - how are these secret bits separated from each other in the page?
>>
>> - does the guest (firmware and/or OS) *write* to the new locations in
>> the page, possibly for secure message construction?
>>
>>
>> Either way, I think the proposed repurposing of the page, for the sake
>> of SNP secrets (VMPCK and maybe even secure message construction?),
>> breaks the current declarations of the PCDs, in "OvmfPkg.dec":
>>
>>   ## The base address and size of the SEV Launch Secret Area provisioned
>>   #  after remote attestation.  If this is set in the .fdf, the platform
>>   #  is responsible for protecting the area from DXE phase overwrites.
>>   gUefiOvmfPkgTokenSpaceGuid.PcdSevLaunchSecretBase|0x0|UINT32|0x42
>>   gUefiOvmfPkgTokenSpaceGuid.PcdSevLaunchSecretSize|0x0|UINT32|0x43
>>
>>> In SEV-SNP, the secrets page is not tight up with just the remote
>>> attestation.
>> This is the most important statement. We need the SNP secrets page even
>> without remote attestation. OvmfPkgX64.dsc does not deal with remote
>> attestation.
>>
>> But then (putting all the PCD naming confusion aside), if a driver is
>> promoted to "common use", from the AmdSevX64 platform to multiple
>> OvmfPkg platforms, then it should be lifted to the top-level OvmfPkg
>> directory.
> 
> Now I think about it maybe we should leave the driver where it is
> because OvmfPkgX64.dsc does not need to deal with the attestation etc.
> But we need to create a driver that can install the EFI configuration
> table for the SNP secrets page. Is that okay ?

Well I'm sure I'm day-dreaming, but here's what I'd like, all at the
same time of course:

- to-the-point PCD names and explanations in the DEC file,

- minimize the new pages carved out of MEMFD,

- make sure that this new SEV-SNP secret page is reusable (at least
conceptually) in the "AmdSevX64.dsc" platform if necessary -- it may
exist at a different base address in that platform, but the mechanism
should be the same,

- I wouldn't like a new DXE driver for installing this new config table,
and I also wouldn't like to move and/or reuse SecretDxe. Instead, I
might like some new code in the existent AmdSevDxe driver, which is
already the SEV-specific platform driver (also included by the
"AmdSevX64.dsc" platform). If the config table cannot be installed in
the entry point function of the driver, can we invent a suitable
protocol notify, or other event notification callback?

> 
> 
>>> Later, the AmdSev.dsc can include a library to perform the
>>> SEV-SNP-specific attestation. The library can use the SNP secrets page
>>> to get the key and message counter use for constructing the guest
>>> message to query the attestation report.
>>>
>>> I hope it clarifies it.
>>>
>>> [1] https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Fwww.amd.com%2Fsystem%2Ffiles%2FTechDocs%2F56860.pdf&amp;data=04%7C01%7Cbrijesh.singh%40amd.com%7C972887a952cd48b090a308d92a5eb0d5%7C3dd8961fe4884e608e11a82d994e183d%7C0%7C0%7C637587409068253595%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C1000&amp;sdata=j%2FL5eTSR3%2FODJRE0IaF7R49aDVkFjDCO1JUpGsPbDwk%3D&amp;reserved=0
>>>
>>>
>>>> Honestly I'm getting a *rushed* vibe on this whole series. Why is that?
>>> I am not sure why you are getting this feel, please let me know where I
>>> can help to clarify but the series is *rushed* at all. Its building on
>>> existing support. It's possible that we are getting mixed with the
>>> fundamental difference between the SEV and SEV-SNP attestation flow and
>>> recent patches from Dov to expand the attestation to cover other aspects
>>> of the boot flow.
>>>
>>> In case of SEV-SNP, some folks may prefer to do all the attestation in
>>> the OVMF and others may prefer to do the attestation in the guest OS. We
>>> should try to not restrict one approach over the other.
>>>
>>>
>>>> Assume that I'm dumb. You won't be far from the truth. Then hold my hand
>>>> through all this?
>>>
>>> Please let me know if the above explanation helps or I should expand more.
>> You should please (a) expand your *commit messages*, (b) add a *wall* of
>> text in the "OvmfPkg.dec" file, where the PCDs in questions are
>> declared. When I grep the OvmfPkg subdirectory in two years for
>> "PcdSevLaunchSecretBase", I'd like to find the DEC file's comments to be
>> consistent with the actual uses of the PCD, and I'd like git-blame to
>> tell me something useful about those lines, too.
>>
> I will add more comments in the patch to clarify certain things.
> 
> 
>> One problem is that I'm supposed to internalize about 50 pages from yet
>> from another technical specification, in order to get the basics of a
>> single patch. I can't even follow the *set* of AMD documents I should
>> have a local copy of. How am I supposed to interleave all that with, for
>> example, reviewing a 57 slide TDX design presentation?
> 
> As you may have seen that myself and Tom try not to put the exact link
> or  document number in the comment

Huh, so that's been intentional? I didn't expect it.

> is because we have seen that our docs
> folks change the link or they replace the old document with the new
> copy.

Changing links is tolerable, as long as previously released versions
(identified by document# and revision#) remain accessible forever.

> We have similar issue in kernel. The kernel maintainer now have a
> bugzilla where they want us to upload the document so that they can keep
> a copy and in the commits we refer to that BZ link instead of AMD URL.

This is a fantastic idea from those kernel developers, and I'm scolding
myself for not thinking of the same.

If you do upload such documents to the kernel bugzilla, please feel free
to refer to the exact same (kernel bugziila) URLs in the edk2 commit
messages, and (perhaps) code comments. There's no need to upload the
(large) PDFs to the tianocore bugzilla separately; I trust the kernel
bugzilla instance to stick around.

> I
> myself gets so mixed up with various version of documents. I don't like
> that we replace the old docs with a new without archiving it.

Hm, so the old docs do disappear for good (not just the URLs but the
docs themselves). In that case, please let us go with kernel bugzilla
attachments.

Thanks!
Laszlo


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

* Re: [edk2-devel] [PATCH RFC v3 05/22] OvmfPkg: reserve Secrets page in MEMFD
  2021-06-08 18:01           ` Laszlo Ersek
@ 2021-06-08 18:34             ` Brijesh Singh
  0 siblings, 0 replies; 57+ messages in thread
From: Brijesh Singh @ 2021-06-08 18:34 UTC (permalink / raw)
  To: devel, lersek, James Bottomley, Min Xu, Jiewen Yao, Tom Lendacky,
	Jordan Justen, Erdem Aktas, Eric Dong, Ray Ni, Rahul Kumar
  Cc: brijesh.singh, Ard Biesheuvel


On 6/8/21 1:01 PM, Laszlo Ersek via groups.io wrote:
>
>> Now I think about it maybe we should leave the driver where it is
>> because OvmfPkgX64.dsc does not need to deal with the attestation etc.
>> But we need to create a driver that can install the EFI configuration
>> table for the SNP secrets page. Is that okay ?
> Well I'm sure I'm day-dreaming, but here's what I'd like, all at the
> same time of course:
>
> - to-the-point PCD names and explanations in the DEC file,
>
> - minimize the new pages carved out of MEMFD,
>
> - make sure that this new SEV-SNP secret page is reusable (at least
> conceptually) in the "AmdSevX64.dsc" platform if necessary -- it may
> exist at a different base address in that platform, but the mechanism
> should be the same,
>
> - I wouldn't like a new DXE driver for installing this new config table,
> and I also wouldn't like to move and/or reuse SecretDxe. Instead, I
> might like some new code in the existent AmdSevDxe driver, which is
> already the SEV-specific platform driver (also included by the
> "AmdSevX64.dsc" platform). If the config table cannot be installed in
> the entry point function of the driver, can we invent a suitable
> protocol notify, or other event notification callback?

Yes, I will try that approach.


>
>>
>>>> Later, the AmdSev.dsc can include a library to perform the
>>>> SEV-SNP-specific attestation. The library can use the SNP secrets page
>>>> to get the key and message counter use for constructing the guest
>>>> message to query the attestation report.
>>>>
>>>> I hope it clarifies it.
>>>>
>>>> [1] https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Fwww.amd.com%2Fsystem%2Ffiles%2FTechDocs%2F56860.pdf&amp;data=04%7C01%7Cbrijesh.singh%40amd.com%7C8db4f78aad5148606b6608d92aa789fe%7C3dd8961fe4884e608e11a82d994e183d%7C0%7C0%7C637587721344269131%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C1000&amp;sdata=roXIS4GuBJg3ftf5lQyFwItfDXQ8oHukiN0wolvd8Wg%3D&amp;reserved=0
>>>>
>>>>
>>>>> Honestly I'm getting a *rushed* vibe on this whole series. Why is that?
>>>> I am not sure why you are getting this feel, please let me know where I
>>>> can help to clarify but the series is *rushed* at all. Its building on
>>>> existing support. It's possible that we are getting mixed with the
>>>> fundamental difference between the SEV and SEV-SNP attestation flow and
>>>> recent patches from Dov to expand the attestation to cover other aspects
>>>> of the boot flow.
>>>>
>>>> In case of SEV-SNP, some folks may prefer to do all the attestation in
>>>> the OVMF and others may prefer to do the attestation in the guest OS. We
>>>> should try to not restrict one approach over the other.
>>>>
>>>>
>>>>> Assume that I'm dumb. You won't be far from the truth. Then hold my hand
>>>>> through all this?
>>>> Please let me know if the above explanation helps or I should expand more.
>>> You should please (a) expand your *commit messages*, (b) add a *wall* of
>>> text in the "OvmfPkg.dec" file, where the PCDs in questions are
>>> declared. When I grep the OvmfPkg subdirectory in two years for
>>> "PcdSevLaunchSecretBase", I'd like to find the DEC file's comments to be
>>> consistent with the actual uses of the PCD, and I'd like git-blame to
>>> tell me something useful about those lines, too.
>>>
>> I will add more comments in the patch to clarify certain things.
>>
>>
>>> One problem is that I'm supposed to internalize about 50 pages from yet
>>> from another technical specification, in order to get the basics of a
>>> single patch. I can't even follow the *set* of AMD documents I should
>>> have a local copy of. How am I supposed to interleave all that with, for
>>> example, reviewing a 57 slide TDX design presentation?
>> As you may have seen that myself and Tom try not to put the exact link
>> or  document number in the comment
> Huh, so that's been intentional? I didn't expect it.

At least I have been asked by it in the kernel ML folks to avoid using
the moving URL. So, I am doing similar thing for OVMF commit messages.


>
>> is because we have seen that our docs
>> folks change the link or they replace the old document with the new
>> copy.
> Changing links is tolerable, as long as previously released versions
> (identified by document# and revision#) remain accessible forever.
>
>> We have similar issue in kernel. The kernel maintainer now have a
>> bugzilla where they want us to upload the document so that they can keep
>> a copy and in the commits we refer to that BZ link instead of AMD URL.
> This is a fantastic idea from those kernel developers, and I'm scolding
> myself for not thinking of the same.
>
> If you do upload such documents to the kernel bugzilla, please feel free
> to refer to the exact same (kernel bugziila) URLs in the edk2 commit
> messages, and (perhaps) code comments. There's no need to upload the
> (large) PDFs to the tianocore bugzilla separately; I trust the kernel
> bugzilla instance to stick around.
>
>> I
>> myself gets so mixed up with various version of documents. I don't like
>> that we replace the old docs with a new without archiving it.
> Hm, so the old docs do disappear for good (not just the URLs but the
> docs themselves). In that case, please let us go with kernel bugzilla
> attachments.

Yes, it simply disappears hence my frustration. I have ran into cases
that during the review the doc gets updated and my code gets out of sync
with the posted spec :(. I think some of this has to do with the
feedbacks from other hypervisor folks on SNP mailing list. I am hoping
this gets stable soon. SEV-SNP FW is still in 0.9 and I hope it moves to
1.0 sooner for the stable APIs. Anyway the good part is that none of
these affect OVMF. Since early SEV days we have tried best to avoid
expanding the blobs in the guest firmware and OS. When its comes to
attestation then we have no choice but to define the Secrets page layout
to access all those keys etc. In future I am sure someone will work to
extend AmdSev package to provide attestation for the SEV-SNP and at time
they will have much stable layout to work it.

Thanks



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

* Re: [edk2-devel] [PATCH RFC v3 04/22] OvmfPkg/MemEncryptSevLib: extend Es Workarea to include hv features
  2021-06-08  8:49       ` Laszlo Ersek
  2021-06-08 14:50         ` Brijesh Singh
@ 2021-06-08 21:36         ` Lendacky, Thomas
  2021-06-09 10:50           ` Laszlo Ersek
  1 sibling, 1 reply; 57+ messages in thread
From: Lendacky, Thomas @ 2021-06-08 21:36 UTC (permalink / raw)
  To: Laszlo Ersek, Brijesh Singh
  Cc: devel, James Bottomley, Min Xu, Jiewen Yao, Jordan Justen,
	Erdem Aktas, Eric Dong, Ray Ni, Rahul Kumar, Ard Biesheuvel

On 6/8/21 3:49 AM, Laszlo Ersek wrote:
> On 06/07/21 15:37, Brijesh Singh wrote:
> 
> 
...

> ... But maybe I just need to accept that we have to repurpose
> SEC_SEV_ES_WORK_AREA, considering it a super-early "HOB list" of sorts.
> Same as the PEI phase is considered the "HOB producer phase", outputting
> a bunch of disparate bits of info, we could consider the SEV-ES parts of
> the Reset Vector such an "early info bits" producer phase. I think this
> is a very big conceptual step away from the original purpose of
> SEC_SEV_ES_WORK_AREA (note the *name* of the structure: "work area"!
> HOBs are not "work areas", they are effectively read-only, once
> produced). But perhaps this is what we need (and then with proper
> documentation).
> 
> NB however that HOBs have types, GUIDed HOBs have GUIDs, the HOB types
> are specified in PI, and GUIDs are expressly declared to stand for
> various purposes at least in edk2 DEC files. All that helps with
> discerning the information flow. So... I'd still prefer keeping
> SEC_SEV_ES_WORK_AREA as minimal as possible.
> 
> Tom, any comments?

The purpose of the work area was originally two-fold. It is used in the
reset vector code to set the SevEsEnabled bit so that we could keep the
original behavior in SecCoreStartupWithStack() - no initialization of the
exception handlers or early enabling of processor cache. The second use is
for initial AP startup, where we had a known memory address at build time
that could be used to set the initial CS:IP of APs for the first boot.

We expanded the use for the security mitigations, used by the reset vector
code and again in SEC. At the start of PEI, PCDs are then set.

So, yes, if the information can be obtained later, and in this case we're
not talking about CPUID information which would need re-validation, then
there's no need to keep it in the work area and we can keep the size and
information stored in the work area to a minimum.

Thanks,
Tom

> 
> Thank you Brijesh for raising great points!
> Laszlo
> 

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

* Re: [edk2-devel] [PATCH RFC v3 04/22] OvmfPkg/MemEncryptSevLib: extend Es Workarea to include hv features
  2021-06-08 21:36         ` Lendacky, Thomas
@ 2021-06-09 10:50           ` Laszlo Ersek
  0 siblings, 0 replies; 57+ messages in thread
From: Laszlo Ersek @ 2021-06-09 10:50 UTC (permalink / raw)
  To: Tom Lendacky, Brijesh Singh
  Cc: devel, James Bottomley, Min Xu, Jiewen Yao, Jordan Justen,
	Erdem Aktas, Eric Dong, Ray Ni, Rahul Kumar, Ard Biesheuvel

On 06/08/21 23:36, Tom Lendacky wrote:
> On 6/8/21 3:49 AM, Laszlo Ersek wrote:
>> On 06/07/21 15:37, Brijesh Singh wrote:
>>
>>
> ...
> 
>> ... But maybe I just need to accept that we have to repurpose
>> SEC_SEV_ES_WORK_AREA, considering it a super-early "HOB list" of sorts.
>> Same as the PEI phase is considered the "HOB producer phase", outputting
>> a bunch of disparate bits of info, we could consider the SEV-ES parts of
>> the Reset Vector such an "early info bits" producer phase. I think this
>> is a very big conceptual step away from the original purpose of
>> SEC_SEV_ES_WORK_AREA (note the *name* of the structure: "work area"!
>> HOBs are not "work areas", they are effectively read-only, once
>> produced). But perhaps this is what we need (and then with proper
>> documentation).
>>
>> NB however that HOBs have types, GUIDed HOBs have GUIDs, the HOB types
>> are specified in PI, and GUIDs are expressly declared to stand for
>> various purposes at least in edk2 DEC files. All that helps with
>> discerning the information flow. So... I'd still prefer keeping
>> SEC_SEV_ES_WORK_AREA as minimal as possible.
>>
>> Tom, any comments?
> 
> The purpose of the work area was originally two-fold. It is used in the
> reset vector code to set the SevEsEnabled bit so that we could keep the
> original behavior in SecCoreStartupWithStack() - no initialization of the
> exception handlers or early enabling of processor cache. The second use is
> for initial AP startup, where we had a known memory address at build time
> that could be used to set the initial CS:IP of APs for the first boot.
> 
> We expanded the use for the security mitigations, used by the reset vector
> code and again in SEC. At the start of PEI, PCDs are then set.
> 
> So, yes, if the information can be obtained later, and in this case we're
> not talking about CPUID information which would need re-validation, then
> there's no need to keep it in the work area and we can keep the size and
> information stored in the work area to a minimum.

Thank you very much!
Laszlo


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

end of thread, other threads:[~2021-06-09 10:51 UTC | newest]

Thread overview: 57+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2021-05-26 23:10 [RESEND PATCH RFC v3 00/22] Add AMD Secure Nested Paging (SEV-SNP) support Brijesh Singh
2021-05-26 23:10 ` [PATCH RFC v3 01/22] UefiCpuPkg: Define the SEV-SNP specific dynamic PCDs Brijesh Singh
2021-06-03  8:15   ` [edk2-devel] " Laszlo Ersek
2021-06-03 12:16     ` Brijesh Singh
2021-06-03 13:07       ` Laszlo Ersek
2021-06-03 13:38   ` Laszlo Ersek
2021-05-26 23:10 ` [PATCH RFC v3 02/22] OvmfPkg/MemEncryptSevLib: add MemEncryptSevSnpEnabled() Brijesh Singh
2021-06-04 13:43   ` Laszlo Ersek
2021-05-26 23:10 ` [PATCH RFC v3 03/22] OvmfPkg/MemEncryptSevLib: extend the workarea to include SNP enabled field Brijesh Singh
2021-06-04 14:15   ` Laszlo Ersek
2021-06-07 11:20     ` [edk2-devel] " Laszlo Ersek
2021-06-07 13:00       ` Brijesh Singh
2021-06-08  8:17         ` Laszlo Ersek
2021-06-08 13:51           ` Brijesh Singh
2021-06-08 16:42             ` Laszlo Ersek
2021-05-26 23:11 ` [PATCH RFC v3 04/22] OvmfPkg/MemEncryptSevLib: extend Es Workarea to include hv features Brijesh Singh
2021-06-07 11:54   ` [edk2-devel] " Laszlo Ersek
2021-06-07 13:37     ` Brijesh Singh
2021-06-08  8:49       ` Laszlo Ersek
2021-06-08 14:50         ` Brijesh Singh
2021-06-08 21:36         ` Lendacky, Thomas
2021-06-09 10:50           ` Laszlo Ersek
2021-05-26 23:11 ` [PATCH RFC v3 05/22] OvmfPkg: reserve Secrets page in MEMFD Brijesh Singh
2021-06-07 12:26   ` Laszlo Ersek
2021-06-07 12:48     ` Laszlo Ersek
2021-06-07 17:33       ` Brijesh Singh
2021-06-08  9:22         ` Laszlo Ersek
2021-06-07 15:58     ` Brijesh Singh
2021-06-08  9:20       ` Laszlo Ersek
2021-06-08 15:43         ` [edk2-devel] " Brijesh Singh
2021-06-08 18:01           ` Laszlo Ersek
2021-06-08 18:34             ` Brijesh Singh
2021-05-26 23:11 ` [PATCH RFC v3 06/22] OvmfPkg: reserve CPUID page for the SEV-SNP guest Brijesh Singh
2021-05-26 23:11 ` [PATCH RFC v3 07/22] OvmfPkg/ResetVector: validate the data pages used in SEC phase Brijesh Singh
2021-05-26 23:11 ` [PATCH RFC v3 08/22] OvmfPkg/ResetVector: invalidate the GHCB page Brijesh Singh
2021-05-26 23:11 ` [PATCH RFC v3 09/22] OvmfPkg: add library to support registering GHCB GPA Brijesh Singh
2021-05-26 23:11 ` [PATCH RFC v3 10/22] OvmfPkg/PlatformPei: register GHCB gpa for the SEV-SNP guest Brijesh Singh
2021-05-26 23:11 ` [PATCH RFC v3 11/22] UefiCpuPkg/MpLib: add support to register GHCB GPA when SEV-SNP is enabled Brijesh Singh
2021-05-26 23:11 ` [PATCH RFC v3 12/22] OvmfPkg/AmdSevDxe: do not use extended PCI config space Brijesh Singh
2021-05-26 23:11 ` [PATCH RFC v3 13/22] OvmfPkg/MemEncryptSevLib: add support to validate system RAM Brijesh Singh
2021-05-26 23:11 ` [PATCH RFC v3 14/22] OvmfPkg/BaseMemEncryptSevLib: skip the pre-validated " Brijesh Singh
2021-05-26 23:11 ` [PATCH RFC v3 15/22] OvmfPkg/MemEncryptSevLib: add support to validate > 4GB memory in PEI phase Brijesh Singh
2021-05-26 23:11 ` [PATCH RFC v3 16/22] OvmfPkg/SecMain: pre-validate the memory used for decompressing Fv Brijesh Singh
2021-05-26 23:11 ` [PATCH RFC v3 17/22] OvmfPkg/PlatformPei: validate the system RAM when SNP is active Brijesh Singh
2021-05-26 23:11 ` [PATCH RFC v3 18/22] OvmfPkg/MemEncryptSevLib: Change the page state in the RMP table Brijesh Singh
2021-05-26 23:11 ` [PATCH RFC v3 19/22] OvmfPkg/MemEncryptSevLib: skip page state change for Mmio address Brijesh Singh
2021-05-26 23:11 ` [PATCH RFC v3 20/22] OvmfPkg/AmdSev: expose the SNP reserved pages through configuration table Brijesh Singh
2021-05-26 23:11 ` [PATCH RFC v3 21/22] UefiCpuPkg/MpInitLib: Use SEV-SNP AP Creation NAE event to launch APs Brijesh Singh
2021-05-26 23:11 ` [PATCH RFC v3 22/22] MdePkg/GHCB: increase the GHCB protocol max version Brijesh Singh
2021-06-03 13:08   ` [edk2-devel] " Laszlo Ersek
2021-06-08  1:17     ` 回复: " gaoliming
2021-05-27  9:42 ` [edk2-devel] [RESEND PATCH RFC v3 00/22] Add AMD Secure Nested Paging (SEV-SNP) support Laszlo Ersek
2021-06-02 17:09   ` Laszlo Ersek
2021-06-04  9:32 ` Laszlo Ersek
2021-06-04 11:50   ` Brijesh Singh
2021-06-04 13:09     ` Laszlo Ersek
2021-06-07 12:04       ` Laszlo Ersek

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