public inbox for devel@edk2.groups.io
 help / color / mirror / Atom feed
From: "Brijesh Singh" <brijesh.singh@amd.com>
To: devel@edk2.groups.io
Cc: 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>,
	Ard Biesheuvel <ardb+tianocore@kernel.org>,
	Laszlo Ersek <lersek@redhat.com>,
	Erdem Aktas <erdemaktas@google.com>,
	Eric Dong <eric.dong@intel.com>, Ray Ni <ray.ni@intel.com>,
	Rahul Kumar <rahul1.kumar@intel.com>,
	Michael D Kinney <michael.d.kinney@intel.com>,
	Liming Gao <gaoliming@byosoft.com.cn>,
	Zhiguang Liu <zhiguang.liu@intel.com>,
	Michael Roth <Michael.Roth@amd.com>,
	Brijesh Singh <brijesh.singh@amd.com>
Subject: [RFC PATCH v5 09/28] OvmfPkg/ResetVector: check the vmpl level
Date: Wed, 30 Jun 2021 07:53:02 -0500	[thread overview]
Message-ID: <20210630125321.30278-10-brijesh.singh@amd.com> (raw)
In-Reply-To: <20210630125321.30278-1-brijesh.singh@amd.com>

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

Virtual Machine Privilege Level (VMPL) is an optional feature in the
SEV-SNP architecture, which allows a guest VM to divide its address space
into four levels. The level can be used to provide the hardware isolated
abstraction layers with a VM. The VMPL0 is the highest privilege, and
VMPL3 is the least privilege. Certain operations must be done by the VMPL0
software, such as:

* Validate or invalidate memory range (PVALIDATE instruction)
* Allocate VMSA page (RMPADJUST instruction when VMSA=1)

The initial SEV-SNP support assumes that it's running on VMPL0. Let's add
a check to make sure that we are running at VMPL0 before continuing the
boot. There is no easy method to query the current VMPL level. One simple
approach is to call PVALIDATE instruction and if the instruction causes
a #GP then its SEV-SNP guest is not booted under VMPL0. See the AMD APL
volume 3 (PVALIDATE) for additional information on the PVALIDATE.

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/AmdSev.asm | 89 ++++++++++++++++++++++++++++-
 1 file changed, 87 insertions(+), 2 deletions(-)

diff --git a/OvmfPkg/ResetVector/Ia32/AmdSev.asm b/OvmfPkg/ResetVector/Ia32/AmdSev.asm
index b6f33d049a43..a9101ca8b8b2 100644
--- a/OvmfPkg/ResetVector/Ia32/AmdSev.asm
+++ b/OvmfPkg/ResetVector/Ia32/AmdSev.asm
@@ -53,6 +53,12 @@ BITS    32
 ; Hypervisor does not support SEV-SNP feature
 %define TERM_HV_UNSUPPORTED_FEATURE 4
 
+; SEV-SNP guest is not launched at VMPL-0
+%define TERM_SNP_NOT_VMPL0          5
+
+; The #VC is not for PVALIDATE
+%define TERM_VC_NOT_PVALIDATE       6
+
 ; GHCB SEV Information MSR protocol
 %define GHCB_SEV_INFORMATION_REQUEST        2
 %define GHCB_SEV_INFORMATION_RESPONSE       1
@@ -139,6 +145,25 @@ BITS    32
 SevEsUnexpectedRespTerminate:
     TerminateVmgExit    TERM_UNEXPECTED_RESP_CODE
 
+; Check whether we're booted under the VMPL-0.
+;
+; There is no straightforward way to query the current VMPL level. The simplest
+; method is to use the PVALIDATE instruction to change the page state. If its
+; not a VMPL-0 guest then PVALIDATE will cause #GP.
+;
+CheckSnpVmpl0:
+    ; This routine is part of the ROM, and should have been validated by the SNP
+    ; guest launch sequence. So its safe to re-validate the page containing
+    ; this routine.
+    mov     eax, ADDR_OF(CheckSnpVmpl0)
+    mov     ecx, 0
+    mov     edx, 1
+    PVALIDATE
+
+    ; We will reach here only if we are running at VMPL-0.
+
+    OneTimeCallRet    CheckSnpVmpl0
+
 ; Check if Secure Encrypted Virtualization (SEV) features are enabled.
 ;
 ; Register usage is tight in this routine, so multiple calls for the
@@ -193,6 +218,17 @@ CheckSevFeatures:
     bt        eax, 0
     jnc       NoSev
 
+    ; Check if we're SEV-SNP guest and booted under VMPL-0.
+    ;
+    ; This check should happen here because the PVALIDATE instruction
+    ; used in the check will cause an exception. The IDT is active
+    ; during the CheckSevFeatures only.
+    ;
+    bt        eax, 2
+    jnc       SkipCheckSnpVmpl0
+    OneTimeCall     CheckSnpVmpl0
+
+SkipCheckSnpVmpl0:
     ; Check for SEV-ES memory encryption feature:
     ; CPUID  Fn8000_001F[EAX] - Bit 3
     ;   CPUID raises a #VC exception if running as an SEV-ES guest
@@ -393,6 +429,36 @@ IsSevEsEnabled:
 SevEsDisabled:
     OneTimeCallRet IsSevEsEnabled
 
+; Start handling of #GP exception handling routines
+;
+SevEsIdtNotPvalidate:
+    TerminateVmgExit TERM_VC_NOT_PVALIDATE
+    iret
+
+SevSnpGpException:
+    ;
+    ; If we're here, then we are an SEV-SNP guest and this
+    ; was triggered by a PVALIDATE instruction.
+    ;
+    ; Verify that its an PVALIDATE instruction
+    ; The exception stack looks like this:
+    ;     +---------+
+    ;     | ....    |
+    ;     | eip     |
+    ;     | err code|
+    ;     +---------+
+    pop     ebx
+    pop     ebx
+    mov     ecx, [ebx]
+    cmp     ecx, 0xff010ff2       ; Compare EIP with PVALIDATE menomics
+    jne     SevEsIdtNotPvalidate
+
+    ; The #GP was triggered by the PVALIDATE instruction, this will happen
+    ; only when we're not running at VMPL-0
+    ;
+    TerminateVmgExit TERM_SNP_NOT_VMPL0
+    iret
+
 ; Start of #VC exception handling routines
 ;
 
@@ -522,15 +588,34 @@ ALIGN   16
 ;
 IDT_BASE:
 ;
-; Vectors 0 - 28 (No handlers)
+; Vectors 0 - 12 (No handlers)
 ;
-%rep 29
+%rep 13
     dw      0                                    ; Offset low bits 15..0
     dw      0x10                                 ; Selector
     db      0                                    ; Reserved
     db      0x8E                                 ; Gate Type (IA32_IDT_GATE_TYPE_INTERRUPT_32)
     dw      0                                    ; Offset high bits 31..16
 %endrep
+;
+; Vector 13 (GP Exception)
+;
+    dw      (ADDR_OF(SevSnpGpException) & 0xffff)  ; Offset low bits 15..0
+    dw      0x10                                 ; Selector
+    db      0                                    ; Reserved
+    db      0x8E                                 ; Gate Type (IA32_IDT_GATE_TYPE_INTERRUPT_32)
+    dw      (ADDR_OF(SevSnpGpException) >> 16)   ; Offset high bits 31..16
+;
+; Vectors 14 - 28 (No handlers)
+;
+%rep 15
+    dw      0                                    ; Offset low bits 15..0
+    dw      0x10                                 ; Selector
+    db      0                                    ; Reserved
+    db      0x8E                                 ; Gate Type (IA32_IDT_GATE_TYPE_INTERRUPT_32)
+    dw      0                                    ; Offset high bits 31..16
+%endrep
+
 ;
 ; Vector 29 (VMM Communication Exception)
 ;
-- 
2.17.1


  parent reply	other threads:[~2021-06-30 12:54 UTC|newest]

Thread overview: 32+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-06-30 12:52 [RFC PATCH v5 00/28] Add AMD Secure Nested Paging (SEV-SNP) support Brijesh Singh
2021-06-30 12:52 ` [RFC PATCH v5 01/28] OvmfPkg/ResetVector: move SEV specific code in a separate file Brijesh Singh
2021-06-30 12:52 ` [RFC PATCH v5 02/28] OvmfPkg/ResetVector: add the macro to invoke MSR protocol based VMGEXIT Brijesh Singh
2021-06-30 12:52 ` [RFC PATCH v5 03/28] OvmfPkg/ResetVector: add the macro to request guest termination Brijesh Singh
2021-06-30 12:52 ` [RFC PATCH v5 04/28] OvmfPkg: reserve SNP secrets page Brijesh Singh
2021-06-30 12:52 ` [RFC PATCH v5 05/28] OvmfPkg: reserve CPUID page for SEV-SNP Brijesh Singh
2021-06-30 12:52 ` [RFC PATCH v5 06/28] OvmfPkg/ResetVector: introduce SEV-SNP boot block GUID Brijesh Singh
2021-06-30 12:53 ` [RFC PATCH v5 07/28] OvmfPkg/ResetVector: pre-validate the data pages used in SEC phase Brijesh Singh
2021-07-31  8:44   ` Erdem Aktas
2021-08-03 15:10     ` Brijesh Singh
2021-06-30 12:53 ` [RFC PATCH v5 08/28] OvmfPkg/ResetVector: invalidate the GHCB page Brijesh Singh
2021-06-30 12:53 ` Brijesh Singh [this message]
2021-06-30 12:53 ` [RFC PATCH v5 10/28] UefiCpuPkg: Define the SEV-SNP specific dynamic PCDs Brijesh Singh
2021-06-30 12:53 ` [RFC PATCH v5 11/28] OvmfPkg/MemEncryptSevLib: add MemEncryptSevSnpEnabled() Brijesh Singh
2021-06-30 12:53 ` [RFC PATCH v5 12/28] OvmfPkg/SecMain: register GHCB gpa for the SEV-SNP guest Brijesh Singh
2021-06-30 12:53 ` [RFC PATCH v5 13/28] OvmfPkg/PlatformPei: " Brijesh Singh
2021-06-30 12:53 ` [RFC PATCH v5 14/28] OvmfPkg/AmdSevDxe: do not use extended PCI config space Brijesh Singh
2021-06-30 12:53 ` [RFC PATCH v5 15/28] OvmfPkg/MemEncryptSevLib: add support to validate system RAM Brijesh Singh
2021-06-30 12:53 ` [RFC PATCH v5 16/28] OvmfPkg/BaseMemEncryptSevLib: skip the pre-validated " Brijesh Singh
2021-06-30 12:53 ` [RFC PATCH v5 17/28] OvmfPkg/MemEncryptSevLib: add support to validate > 4GB memory in PEI phase Brijesh Singh
2021-06-30 12:53 ` [RFC PATCH v5 18/28] OvmfPkg/SecMain: pre-validate the memory used for decompressing Fv Brijesh Singh
2021-06-30 12:53 ` [RFC PATCH v5 19/28] OvmfPkg/PlatformPei: validate the system RAM when SNP is active Brijesh Singh
2021-06-30 12:53 ` [RFC PATCH v5 20/28] OvmfPkg/PlatformPei: set the SEV-SNP enabled PCD Brijesh Singh
2021-06-30 12:53 ` [RFC PATCH v5 21/28] OvmfPkg/PlatformPei: set the Hypervisor Features PCD Brijesh Singh
2021-06-30 12:53 ` [RFC PATCH v5 22/28] MdePkg/GHCB: increase the GHCB protocol max version Brijesh Singh
2021-06-30 12:53 ` [RFC PATCH v5 23/28] UefiCpuPkg/MpLib: add support to register GHCB GPA when SEV-SNP is enabled Brijesh Singh
2021-06-30 12:53 ` [RFC PATCH v5 24/28] OvmfPkg/MemEncryptSevLib: change the page state in the RMP table Brijesh Singh
2021-06-30 12:53 ` [RFC PATCH v5 25/28] OvmfPkg/MemEncryptSevLib: skip page state change for Mmio address Brijesh Singh
2021-06-30 12:53 ` [RFC PATCH v5 26/28] UefiCpuPkg/MpInitLib: Use SEV-SNP AP Creation NAE event to launch APs Brijesh Singh
2021-06-30 12:53 ` [RFC PATCH v5 27/28] OvmfPkg/PlatformPei: mark cpuid and secrets memory reserved in EFI map Brijesh Singh
2021-06-30 12:53 ` [RFC PATCH v5 28/28] OvmfPkg/AmdSev: expose the SNP reserved pages through configuration table Brijesh Singh
2021-08-27  7:33 ` [edk2-devel] [RFC PATCH v5 00/28] Add AMD Secure Nested Paging (SEV-SNP) support Gerd Hoffmann

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-list from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20210630125321.30278-10-brijesh.singh@amd.com \
    --to=devel@edk2.groups.io \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox