public inbox for devel@edk2.groups.io
 help / color / mirror / Atom feed
* [PATCH v2 0/3] Move the SEV specific changes in ResetVector in separate file
@ 2021-07-27 18:10 Brijesh Singh
  2021-07-27 18:10 ` [PATCH v2 1/3] OvmfPkg/ResetVector: move SEV specific code in a " Brijesh Singh
                   ` (3 more replies)
  0 siblings, 4 replies; 5+ messages in thread
From: Brijesh Singh @ 2021-07-27 18:10 UTC (permalink / raw)
  To: devel
  Cc: Brijesh Singh, James Bottomley, Min Xu, Jiewen Yao, Tom Lendacky,
	Jordan Justen, Ard Biesheuvel, Laszlo Ersek, Erdem Aktas

The PageTable64.asm was created to build the initial page table,
but over the time it grew to include bunch of the SEV specific code
which does not directly manipulates the pagetable. Before adding more
to it, let's move all the SEV-specific routines into a separate file.

The series is taken from SNP RFCv4. And there is no functionality change
intended. Its just moving the code from one place to another.

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>

The full branch is available at:
https://github.com/AMDESE/ovmf/pull/new/refactor-reset-vector

Changelog:
 - fix the copyright header in AmdSev.asm

Brijesh Singh (3):
  OvmfPkg/ResetVector: move SEV specific code in a separate file
  OvmfPkg/ResetVector: add the macro to invoke MSR protocol based
    VMGEXIT
  OvmfPkg/ResetVector: add the macro to request guest termination

 .../Ia32/{PageTables64.asm => AmdSev.asm}     | 297 ++++---------
 OvmfPkg/ResetVector/Ia32/PageTables64.asm     | 391 ------------------
 OvmfPkg/ResetVector/ResetVector.nasmb         |   1 +
 3 files changed, 92 insertions(+), 597 deletions(-)
 copy OvmfPkg/ResetVector/Ia32/{PageTables64.asm => AmdSev.asm} (66%)

-- 
2.17.1


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

* [PATCH v2 1/3] OvmfPkg/ResetVector: move SEV specific code in a separate file
  2021-07-27 18:10 [PATCH v2 0/3] Move the SEV specific changes in ResetVector in separate file Brijesh Singh
@ 2021-07-27 18:10 ` Brijesh Singh
  2021-07-27 18:10 ` [PATCH v2 2/3] OvmfPkg/ResetVector: add the macro to invoke MSR protocol based VMGEXIT Brijesh Singh
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 5+ messages in thread
From: Brijesh Singh @ 2021-07-27 18:10 UTC (permalink / raw)
  To: devel
  Cc: Brijesh Singh, James Bottomley, Min Xu, Jiewen Yao, Tom Lendacky,
	Jordan Justen, Ard Biesheuvel, Laszlo Ersek, Erdem Aktas

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

The PageTables64.asm was created to provide routines to set the CR3
register for 64-bit paging. During the SEV support, it grew to include a
lot of the SEV stuff. Before adding more SEV features, let's move all
the SEV-specific routines into a separate file.

No functionality change intended.

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>
Reviewed-by: Jiewen Yao <jiewen.yao@intel.com>
Acked-by: Ard Biesheuvel <ardb+tianocore@kernel.org>
Suggested-by: Laszlo Ersek <lersek@redhat.com>
Signed-off-by: Brijesh Singh <brijesh.singh@amd.com>
---
 .../Ia32/{PageTables64.asm => AmdSev.asm}     | 145 +------
 OvmfPkg/ResetVector/Ia32/PageTables64.asm     | 391 ------------------
 OvmfPkg/ResetVector/ResetVector.nasmb         |   1 +
 3 files changed, 3 insertions(+), 534 deletions(-)
 copy OvmfPkg/ResetVector/Ia32/{PageTables64.asm => AmdSev.asm} (70%)

diff --git a/OvmfPkg/ResetVector/Ia32/PageTables64.asm b/OvmfPkg/ResetVector/Ia32/AmdSev.asm
similarity index 70%
copy from OvmfPkg/ResetVector/Ia32/PageTables64.asm
copy to OvmfPkg/ResetVector/Ia32/AmdSev.asm
index 5fae8986d9da..2c9d990af55f 100644
--- a/OvmfPkg/ResetVector/Ia32/PageTables64.asm
+++ b/OvmfPkg/ResetVector/Ia32/AmdSev.asm
@@ -1,42 +1,14 @@
 ;------------------------------------------------------------------------------
 ; @file
-; Sets the CR3 register for 64-bit paging
+; Provide the functions to check whether SEV and SEV-ES is enabled.
 ;
-; Copyright (c) 2008 - 2013, Intel Corporation. All rights reserved.<BR>
-; Copyright (c) 2017 - 2020, Advanced Micro Devices, Inc. All rights reserved.<BR>
+; Copyright (c) 2017 - 2021, Advanced Micro Devices, Inc. All rights reserved.<BR>
 ; SPDX-License-Identifier: BSD-2-Clause-Patent
 ;
 ;------------------------------------------------------------------------------
 
 BITS    32
 
-%define PAGE_PRESENT            0x01
-%define PAGE_READ_WRITE         0x02
-%define PAGE_USER_SUPERVISOR    0x04
-%define PAGE_WRITE_THROUGH      0x08
-%define PAGE_CACHE_DISABLE     0x010
-%define PAGE_ACCESSED          0x020
-%define PAGE_DIRTY             0x040
-%define PAGE_PAT               0x080
-%define PAGE_GLOBAL           0x0100
-%define PAGE_2M_MBO            0x080
-%define PAGE_2M_PAT          0x01000
-
-%define PAGE_4K_PDE_ATTR (PAGE_ACCESSED + \
-                          PAGE_DIRTY + \
-                          PAGE_READ_WRITE + \
-                          PAGE_PRESENT)
-
-%define PAGE_2M_PDE_ATTR (PAGE_2M_MBO + \
-                          PAGE_ACCESSED + \
-                          PAGE_DIRTY + \
-                          PAGE_READ_WRITE + \
-                          PAGE_PRESENT)
-
-%define PAGE_PDP_ATTR (PAGE_ACCESSED + \
-                       PAGE_READ_WRITE + \
-                       PAGE_PRESENT)
-
 ;
 ; SEV-ES #VC exception handler support
 ;
@@ -213,119 +185,6 @@ IsSevEsEnabled:
 SevEsDisabled:
     OneTimeCallRet IsSevEsEnabled
 
-;
-; Modified:  EAX, EBX, ECX, EDX
-;
-SetCr3ForPageTables64:
-
-    OneTimeCall   CheckSevFeatures
-    xor     edx, edx
-    test    eax, eax
-    jz      SevNotActive
-
-    ; If SEV is enabled, C-bit is always above 31
-    sub     eax, 32
-    bts     edx, eax
-
-SevNotActive:
-
-    ;
-    ; For OVMF, build some initial page tables at
-    ; PcdOvmfSecPageTablesBase - (PcdOvmfSecPageTablesBase + 0x6000).
-    ;
-    ; This range should match with PcdOvmfSecPageTablesSize which is
-    ; declared in the FDF files.
-    ;
-    ; At the end of PEI, the pages tables will be rebuilt into a
-    ; more permanent location by DxeIpl.
-    ;
-
-    mov     ecx, 6 * 0x1000 / 4
-    xor     eax, eax
-clearPageTablesMemoryLoop:
-    mov     dword[ecx * 4 + PT_ADDR (0) - 4], eax
-    loop    clearPageTablesMemoryLoop
-
-    ;
-    ; Top level Page Directory Pointers (1 * 512GB entry)
-    ;
-    mov     dword[PT_ADDR (0)], PT_ADDR (0x1000) + PAGE_PDP_ATTR
-    mov     dword[PT_ADDR (4)], edx
-
-    ;
-    ; Next level Page Directory Pointers (4 * 1GB entries => 4GB)
-    ;
-    mov     dword[PT_ADDR (0x1000)], PT_ADDR (0x2000) + PAGE_PDP_ATTR
-    mov     dword[PT_ADDR (0x1004)], edx
-    mov     dword[PT_ADDR (0x1008)], PT_ADDR (0x3000) + PAGE_PDP_ATTR
-    mov     dword[PT_ADDR (0x100C)], edx
-    mov     dword[PT_ADDR (0x1010)], PT_ADDR (0x4000) + PAGE_PDP_ATTR
-    mov     dword[PT_ADDR (0x1014)], edx
-    mov     dword[PT_ADDR (0x1018)], PT_ADDR (0x5000) + PAGE_PDP_ATTR
-    mov     dword[PT_ADDR (0x101C)], edx
-
-    ;
-    ; Page Table Entries (2048 * 2MB entries => 4GB)
-    ;
-    mov     ecx, 0x800
-pageTableEntriesLoop:
-    mov     eax, ecx
-    dec     eax
-    shl     eax, 21
-    add     eax, PAGE_2M_PDE_ATTR
-    mov     [ecx * 8 + PT_ADDR (0x2000 - 8)], eax
-    mov     [(ecx * 8 + PT_ADDR (0x2000 - 8)) + 4], edx
-    loop    pageTableEntriesLoop
-
-    OneTimeCall   IsSevEsEnabled
-    test    eax, eax
-    jz      SetCr3
-
-    ;
-    ; The initial GHCB will live at GHCB_BASE and needs to be un-encrypted.
-    ; This requires the 2MB page for this range be broken down into 512 4KB
-    ; pages.  All will be marked encrypted, except for the GHCB.
-    ;
-    mov     ecx, (GHCB_BASE >> 21)
-    mov     eax, GHCB_PT_ADDR + PAGE_PDP_ATTR
-    mov     [ecx * 8 + PT_ADDR (0x2000)], eax
-
-    ;
-    ; Page Table Entries (512 * 4KB entries => 2MB)
-    ;
-    mov     ecx, 512
-pageTableEntries4kLoop:
-    mov     eax, ecx
-    dec     eax
-    shl     eax, 12
-    add     eax, GHCB_BASE & 0xFFE0_0000
-    add     eax, PAGE_4K_PDE_ATTR
-    mov     [ecx * 8 + GHCB_PT_ADDR - 8], eax
-    mov     [(ecx * 8 + GHCB_PT_ADDR - 8) + 4], edx
-    loop    pageTableEntries4kLoop
-
-    ;
-    ; Clear the encryption bit from the GHCB entry
-    ;
-    mov     ecx, (GHCB_BASE & 0x1F_FFFF) >> 12
-    mov     [ecx * 8 + GHCB_PT_ADDR + 4], strict dword 0
-
-    mov     ecx, GHCB_SIZE / 4
-    xor     eax, eax
-clearGhcbMemoryLoop:
-    mov     dword[ecx * 4 + GHCB_BASE - 4], eax
-    loop    clearGhcbMemoryLoop
-
-SetCr3:
-    ;
-    ; Set CR3 now that the paging structures are available
-    ;
-    mov     eax, PT_ADDR (0)
-    mov     cr3, eax
-
-    OneTimeCallRet SetCr3ForPageTables64
-
-;
 ; Start of #VC exception handling routines
 ;
 
diff --git a/OvmfPkg/ResetVector/Ia32/PageTables64.asm b/OvmfPkg/ResetVector/Ia32/PageTables64.asm
index 5fae8986d9da..eacdb69ddb9f 100644
--- a/OvmfPkg/ResetVector/Ia32/PageTables64.asm
+++ b/OvmfPkg/ResetVector/Ia32/PageTables64.asm
@@ -37,182 +37,6 @@ BITS    32
                        PAGE_READ_WRITE + \
                        PAGE_PRESENT)
 
-;
-; SEV-ES #VC exception handler support
-;
-; #VC handler local variable locations
-;
-%define VC_CPUID_RESULT_EAX         0
-%define VC_CPUID_RESULT_EBX         4
-%define VC_CPUID_RESULT_ECX         8
-%define VC_CPUID_RESULT_EDX        12
-%define VC_GHCB_MSR_EDX            16
-%define VC_GHCB_MSR_EAX            20
-%define VC_CPUID_REQUEST_REGISTER  24
-%define VC_CPUID_FUNCTION          28
-
-; #VC handler total local variable size
-;
-%define VC_VARIABLE_SIZE           32
-
-; #VC handler GHCB CPUID request/response protocol values
-;
-%define GHCB_CPUID_REQUEST          4
-%define GHCB_CPUID_RESPONSE         5
-%define GHCB_CPUID_REGISTER_SHIFT  30
-%define CPUID_INSN_LEN              2
-
-
-; Check if Secure Encrypted Virtualization (SEV) features are enabled.
-;
-; Register usage is tight in this routine, so multiple calls for the
-; same CPUID and MSR data are performed to keep things simple.
-;
-; Modified:  EAX, EBX, ECX, EDX, ESP
-;
-; If SEV is enabled then EAX will be at least 32.
-; If SEV is disabled then EAX will be zero.
-;
-CheckSevFeatures:
-    ; Set the first byte of the workarea to zero to communicate to the SEC
-    ; phase that SEV-ES is not enabled. If SEV-ES is enabled, the CPUID
-    ; instruction will trigger a #VC exception where the first byte of the
-    ; workarea will be set to one or, if CPUID is not being intercepted,
-    ; the MSR check below will set the first byte of the workarea to one.
-    mov     byte[SEV_ES_WORK_AREA], 0
-
-    ;
-    ; Set up exception handlers to check for SEV-ES
-    ;   Load temporary RAM stack based on PCDs (see SevEsIdtVmmComm for
-    ;   stack usage)
-    ;   Establish exception handlers
-    ;
-    mov       esp, SEV_ES_VC_TOP_OF_STACK
-    mov       eax, ADDR_OF(Idtr)
-    lidt      [cs:eax]
-
-    ; Check if we have a valid (0x8000_001F) CPUID leaf
-    ;   CPUID raises a #VC exception if running as an SEV-ES guest
-    mov       eax, 0x80000000
-    cpuid
-
-    ; This check should fail on Intel or Non SEV AMD CPUs. In future if
-    ; Intel CPUs supports this CPUID leaf then we are guranteed to have exact
-    ; same bit definition.
-    cmp       eax, 0x8000001f
-    jl        NoSev
-
-    ; Check for SEV memory encryption feature:
-    ; CPUID  Fn8000_001F[EAX] - Bit 1
-    ;   CPUID raises a #VC exception if running as an SEV-ES guest
-    mov       eax, 0x8000001f
-    cpuid
-    bt        eax, 1
-    jnc       NoSev
-
-    ; Check if SEV memory encryption is enabled
-    ;  MSR_0xC0010131 - Bit 0 (SEV enabled)
-    mov       ecx, 0xc0010131
-    rdmsr
-    bt        eax, 0
-    jnc       NoSev
-
-    ; 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
-    mov       eax, 0x8000001f
-    cpuid
-    bt        eax, 3
-    jnc       GetSevEncBit
-
-    ; Check if SEV-ES is enabled
-    ;  MSR_0xC0010131 - Bit 1 (SEV-ES enabled)
-    mov       ecx, 0xc0010131
-    rdmsr
-    bt        eax, 1
-    jnc       GetSevEncBit
-
-    ; Set the first byte of the workarea to one to communicate to the SEC
-    ; phase that SEV-ES is enabled.
-    mov       byte[SEV_ES_WORK_AREA], 1
-
-GetSevEncBit:
-    ; Get pte bit position to enable memory encryption
-    ; CPUID Fn8000_001F[EBX] - Bits 5:0
-    ;
-    and       ebx, 0x3f
-    mov       eax, ebx
-
-    ; The encryption bit position is always above 31
-    sub       ebx, 32
-    jns       SevSaveMask
-
-    ; Encryption bit was reported as 31 or below, enter a HLT loop
-SevEncBitLowHlt:
-    cli
-    hlt
-    jmp       SevEncBitLowHlt
-
-SevSaveMask:
-    xor       edx, edx
-    bts       edx, ebx
-
-    mov       dword[SEV_ES_WORK_AREA_ENC_MASK], 0
-    mov       dword[SEV_ES_WORK_AREA_ENC_MASK + 4], edx
-    jmp       SevExit
-
-NoSev:
-    ;
-    ; Perform an SEV-ES sanity check by seeing if a #VC exception occurred.
-    ;
-    cmp       byte[SEV_ES_WORK_AREA], 0
-    jz        NoSevPass
-
-    ;
-    ; A #VC was received, yet CPUID indicates no SEV-ES support, something
-    ; isn't right.
-    ;
-NoSevEsVcHlt:
-    cli
-    hlt
-    jmp       NoSevEsVcHlt
-
-NoSevPass:
-    xor       eax, eax
-
-SevExit:
-    ;
-    ; Clear exception handlers and stack
-    ;
-    push      eax
-    mov       eax, ADDR_OF(IdtrClear)
-    lidt      [cs:eax]
-    pop       eax
-    mov       esp, 0
-
-    OneTimeCallRet CheckSevFeatures
-
-; Check if Secure Encrypted Virtualization - Encrypted State (SEV-ES) feature
-; is enabled.
-;
-; Modified:  EAX
-;
-; If SEV-ES is enabled then EAX will be non-zero.
-; If SEV-ES is disabled then EAX will be zero.
-;
-IsSevEsEnabled:
-    xor       eax, eax
-
-    ; During CheckSevFeatures, the SEV_ES_WORK_AREA was set to 1 if
-    ; SEV-ES is enabled.
-    cmp       byte[SEV_ES_WORK_AREA], 1
-    jne       SevEsDisabled
-
-    mov       eax, 1
-
-SevEsDisabled:
-    OneTimeCallRet IsSevEsEnabled
-
 ;
 ; Modified:  EAX, EBX, ECX, EDX
 ;
@@ -324,218 +148,3 @@ SetCr3:
     mov     cr3, eax
 
     OneTimeCallRet SetCr3ForPageTables64
-
-;
-; Start of #VC exception handling routines
-;
-
-SevEsIdtNotCpuid:
-    ;
-    ; Use VMGEXIT to request termination.
-    ;   1 - #VC was not for CPUID
-    ;
-    mov     eax, 1
-    jmp     SevEsIdtTerminate
-
-SevEsIdtNoCpuidResponse:
-    ;
-    ; Use VMGEXIT to request termination.
-    ;   2 - GHCB_CPUID_RESPONSE not received
-    ;
-    mov     eax, 2
-
-SevEsIdtTerminate:
-    ;
-    ; Use VMGEXIT to request termination. At this point the reason code is
-    ; located in EAX, so shift it left 16 bits to the proper location.
-    ;
-    ; EAX[11:0]  => 0x100 - request termination
-    ; EAX[15:12] => 0x1   - OVMF
-    ; EAX[23:16] => 0xXX  - REASON CODE
-    ;
-    shl     eax, 16
-    or      eax, 0x1100
-    xor     edx, edx
-    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
-
-    ;
-    ; We shouldn't come back from the VMGEXIT, but if we do, just loop.
-    ;
-SevEsIdtHlt:
-    hlt
-    jmp     SevEsIdtHlt
-    iret
-
-    ;
-    ; Total stack usage for the #VC handler is 44 bytes:
-    ;   - 12 bytes for the exception IRET (after popping error code)
-    ;   - 32 bytes for the local variables.
-    ;
-SevEsIdtVmmComm:
-    ;
-    ; If we're here, then we are an SEV-ES guest and this
-    ; was triggered by a CPUID instruction
-    ;
-    ; Set the first byte of the workarea to one to communicate that
-    ; a #VC was taken.
-    mov     byte[SEV_ES_WORK_AREA], 1
-
-    pop     ecx                     ; Error code
-    cmp     ecx, 0x72               ; Be sure it was CPUID
-    jne     SevEsIdtNotCpuid
-
-    ; Set up local variable room on the stack
-    ;   CPUID function         : + 28
-    ;   CPUID request register : + 24
-    ;   GHCB MSR (EAX)         : + 20
-    ;   GHCB MSR (EDX)         : + 16
-    ;   CPUID result (EDX)     : + 12
-    ;   CPUID result (ECX)     : + 8
-    ;   CPUID result (EBX)     : + 4
-    ;   CPUID result (EAX)     : + 0
-    sub     esp, VC_VARIABLE_SIZE
-
-    ; Save the CPUID function being requested
-    mov     [esp + VC_CPUID_FUNCTION], eax
-
-    ; The GHCB CPUID protocol uses the following mapping to request
-    ; a specific register:
-    ;   0 => EAX, 1 => EBX, 2 => ECX, 3 => EDX
-    ;
-    ; Set EAX as the first register to request. This will also be used as a
-    ; loop variable to request all register values (EAX to EDX).
-    xor     eax, eax
-    mov     [esp + VC_CPUID_REQUEST_REGISTER], eax
-
-    ; Save current GHCB MSR value
-    mov     ecx, 0xc0010130
-    rdmsr
-    mov     [esp + VC_GHCB_MSR_EAX], eax
-    mov     [esp + VC_GHCB_MSR_EDX], edx
-
-NextReg:
-    ;
-    ; Setup GHCB MSR
-    ;   GHCB_MSR[63:32] = CPUID function
-    ;   GHCB_MSR[31:30] = CPUID register
-    ;   GHCB_MSR[11:0]  = CPUID request protocol
-    ;
-    mov     eax, [esp + VC_CPUID_REQUEST_REGISTER]
-    cmp     eax, 4
-    jge     VmmDone
-
-    shl     eax, GHCB_CPUID_REGISTER_SHIFT
-    or      eax, GHCB_CPUID_REQUEST
-    mov     edx, [esp + VC_CPUID_FUNCTION]
-    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
-
-    ;
-    ; Read GHCB MSR
-    ;   GHCB_MSR[63:32] = CPUID register value
-    ;   GHCB_MSR[31:30] = CPUID register
-    ;   GHCB_MSR[11:0]  = CPUID response protocol
-    ;
-    mov     ecx, 0xc0010130
-    rdmsr
-    mov     ecx, eax
-    and     ecx, 0xfff
-    cmp     ecx, GHCB_CPUID_RESPONSE
-    jne     SevEsIdtNoCpuidResponse
-
-    ; Save returned value
-    shr     eax, GHCB_CPUID_REGISTER_SHIFT
-    mov     [esp + eax * 4], edx
-
-    ; Next register
-    inc     word [esp + VC_CPUID_REQUEST_REGISTER]
-
-    jmp     NextReg
-
-VmmDone:
-    ;
-    ; At this point we have all CPUID register values. Restore the GHCB MSR,
-    ; set the return register values and return.
-    ;
-    mov     eax, [esp + VC_GHCB_MSR_EAX]
-    mov     edx, [esp + VC_GHCB_MSR_EDX]
-    mov     ecx, 0xc0010130
-    wrmsr
-
-    mov     eax, [esp + VC_CPUID_RESULT_EAX]
-    mov     ebx, [esp + VC_CPUID_RESULT_EBX]
-    mov     ecx, [esp + VC_CPUID_RESULT_ECX]
-    mov     edx, [esp + VC_CPUID_RESULT_EDX]
-
-    add     esp, VC_VARIABLE_SIZE
-
-    ; Update the EIP value to skip over the now handled CPUID instruction
-    ; (the CPUID instruction has a length of 2)
-    add     word [esp], CPUID_INSN_LEN
-    iret
-
-ALIGN   2
-
-Idtr:
-    dw      IDT_END - IDT_BASE - 1  ; Limit
-    dd      ADDR_OF(IDT_BASE)       ; Base
-
-IdtrClear:
-    dw      0                       ; Limit
-    dd      0                       ; Base
-
-ALIGN   16
-
-;
-; The Interrupt Descriptor Table (IDT)
-;   This will be used to determine if SEV-ES is enabled.  Upon execution
-;   of the CPUID instruction, a VMM Communication Exception will occur.
-;   This will tell us if SEV-ES is enabled.  We can use the current value
-;   of the GHCB MSR to determine the SEV attributes.
-;
-IDT_BASE:
-;
-; Vectors 0 - 28 (No handlers)
-;
-%rep 29
-    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)
-;
-    dw      (ADDR_OF(SevEsIdtVmmComm) & 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(SevEsIdtVmmComm) >> 16)     ; Offset high bits 31..16
-;
-; Vectors 30 - 31 (No handlers)
-;
-%rep 2
-    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
-IDT_END:
diff --git a/OvmfPkg/ResetVector/ResetVector.nasmb b/OvmfPkg/ResetVector/ResetVector.nasmb
index 5fbacaed5f9d..8a3269cfc212 100644
--- a/OvmfPkg/ResetVector/ResetVector.nasmb
+++ b/OvmfPkg/ResetVector/ResetVector.nasmb
@@ -77,6 +77,7 @@
   %define SEV_ES_WORK_AREA_ENC_MASK (FixedPcdGet32 (PcdSevEsWorkAreaBase) + 16)
   %define SEV_ES_VC_TOP_OF_STACK (FixedPcdGet32 (PcdOvmfSecPeiTempRamBase) + FixedPcdGet32 (PcdOvmfSecPeiTempRamSize))
 %include "Ia32/Flat32ToFlat64.asm"
+%include "Ia32/AmdSev.asm"
 %include "Ia32/PageTables64.asm"
 %endif
 
-- 
2.17.1


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

* [PATCH v2 2/3] OvmfPkg/ResetVector: add the macro to invoke MSR protocol based VMGEXIT
  2021-07-27 18:10 [PATCH v2 0/3] Move the SEV specific changes in ResetVector in separate file Brijesh Singh
  2021-07-27 18:10 ` [PATCH v2 1/3] OvmfPkg/ResetVector: move SEV specific code in a " Brijesh Singh
@ 2021-07-27 18:10 ` Brijesh Singh
  2021-07-27 18:10 ` [PATCH v2 3/3] OvmfPkg/ResetVector: add the macro to request guest termination Brijesh Singh
  2021-07-29  1:08 ` [PATCH v2 0/3] Move the SEV specific changes in ResetVector in separate file Yao, Jiewen
  3 siblings, 0 replies; 5+ messages in thread
From: Brijesh Singh @ 2021-07-27 18:10 UTC (permalink / raw)
  To: devel
  Cc: Brijesh Singh, James Bottomley, Min Xu, Jiewen Yao, Tom Lendacky,
	Jordan Justen, Ard Biesheuvel, Laszlo Ersek, Erdem Aktas

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

The upcoming SEV-SNP support will need to make a few additional MSR
protocol based VMGEXIT's. Add a macro that wraps the common setup and
response validation logic in one place to keep the code readable.

While at it, define SEV_STATUS_MSR that will be used to get the SEV STATUS
MSR instead of open coding it.

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>
Reviewed-by: Jiewen Yao <jiewen.yao@intel.com>
Acked-by: Ard Biesheuvel <ardb+tianocore@kernel.org>
Suggested-by: Laszlo Ersek <lersek@redhat.com>
Signed-off-by: Brijesh Singh <brijesh.singh@amd.com>
---
 OvmfPkg/ResetVector/Ia32/AmdSev.asm | 71 +++++++++++++++++++----------
 1 file changed, 47 insertions(+), 24 deletions(-)

diff --git a/OvmfPkg/ResetVector/Ia32/AmdSev.asm b/OvmfPkg/ResetVector/Ia32/AmdSev.asm
index 2c9d990af55f..93ba917f36d2 100644
--- a/OvmfPkg/ResetVector/Ia32/AmdSev.asm
+++ b/OvmfPkg/ResetVector/Ia32/AmdSev.asm
@@ -35,6 +35,44 @@ BITS    32
 %define CPUID_INSN_LEN              2
 
 
+%define SEV_GHCB_MSR                0xc0010130
+%define SEV_STATUS_MSR              0xc0010131
+
+; Macro is used to issue the MSR protocol based VMGEXIT. The caller is
+; responsible to populate values in the EDX:EAX registers. After the vmmcall
+; returns, it verifies that the response code matches with the expected
+; code. If it does not match then terminate the guest. The result of request
+; is returned in the EDX:EAX.
+;
+; args 1:Request code, 2: Response code
+%macro VmgExit 2
+    ;
+    ; Add request code:
+    ;   GHCB_MSR[11:0]  = Request code
+    or      eax, %1
+
+    mov     ecx, SEV_GHCB_MSR
+    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
+
+    mov     ecx, SEV_GHCB_MSR
+    rdmsr
+
+    ;
+    ; Verify the reponse code, if it does not match then request to terminate
+    ;   GHCB_MSR[11:0]  = Response code
+    mov     ecx, eax
+    and     ecx, 0xfff
+    cmp     ecx, %2
+    jne     SevEsUnexpectedRespTerminate
+%endmacro
+
 ; Check if Secure Encrypted Virtualization (SEV) features are enabled.
 ;
 ; Register usage is tight in this routine, so multiple calls for the
@@ -84,7 +122,7 @@ CheckSevFeatures:
 
     ; Check if SEV memory encryption is enabled
     ;  MSR_0xC0010131 - Bit 0 (SEV enabled)
-    mov       ecx, 0xc0010131
+    mov       ecx, SEV_STATUS_MSR
     rdmsr
     bt        eax, 0
     jnc       NoSev
@@ -99,7 +137,7 @@ CheckSevFeatures:
 
     ; Check if SEV-ES is enabled
     ;  MSR_0xC0010131 - Bit 1 (SEV-ES enabled)
-    mov       ecx, 0xc0010131
+    mov       ecx, SEV_STATUS_MSR
     rdmsr
     bt        eax, 1
     jnc       GetSevEncBit
@@ -196,10 +234,10 @@ SevEsIdtNotCpuid:
     mov     eax, 1
     jmp     SevEsIdtTerminate
 
-SevEsIdtNoCpuidResponse:
+SevEsUnexpectedRespTerminate:
     ;
     ; Use VMGEXIT to request termination.
-    ;   2 - GHCB_CPUID_RESPONSE not received
+    ;   2 - Unexpected Response is received
     ;
     mov     eax, 2
 
@@ -215,7 +253,7 @@ SevEsIdtTerminate:
     shl     eax, 16
     or      eax, 0x1100
     xor     edx, edx
-    mov     ecx, 0xc0010130
+    mov     ecx, SEV_GHCB_MSR
     wrmsr
     ;
     ; Issue VMGEXIT - NASM doesn't support the vmmcall instruction in 32-bit
@@ -275,7 +313,7 @@ SevEsIdtVmmComm:
     mov     [esp + VC_CPUID_REQUEST_REGISTER], eax
 
     ; Save current GHCB MSR value
-    mov     ecx, 0xc0010130
+    mov     ecx, SEV_GHCB_MSR
     rdmsr
     mov     [esp + VC_GHCB_MSR_EAX], eax
     mov     [esp + VC_GHCB_MSR_EDX], edx
@@ -292,31 +330,16 @@ NextReg:
     jge     VmmDone
 
     shl     eax, GHCB_CPUID_REGISTER_SHIFT
-    or      eax, GHCB_CPUID_REQUEST
     mov     edx, [esp + VC_CPUID_FUNCTION]
-    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
+    VmgExit GHCB_CPUID_REQUEST, GHCB_CPUID_RESPONSE
 
     ;
-    ; Read GHCB MSR
+    ; Response GHCB MSR
     ;   GHCB_MSR[63:32] = CPUID register value
     ;   GHCB_MSR[31:30] = CPUID register
     ;   GHCB_MSR[11:0]  = CPUID response protocol
     ;
-    mov     ecx, 0xc0010130
-    rdmsr
-    mov     ecx, eax
-    and     ecx, 0xfff
-    cmp     ecx, GHCB_CPUID_RESPONSE
-    jne     SevEsIdtNoCpuidResponse
 
     ; Save returned value
     shr     eax, GHCB_CPUID_REGISTER_SHIFT
@@ -334,7 +357,7 @@ VmmDone:
     ;
     mov     eax, [esp + VC_GHCB_MSR_EAX]
     mov     edx, [esp + VC_GHCB_MSR_EDX]
-    mov     ecx, 0xc0010130
+    mov     ecx, SEV_GHCB_MSR
     wrmsr
 
     mov     eax, [esp + VC_CPUID_RESULT_EAX]
-- 
2.17.1


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

* [PATCH v2 3/3] OvmfPkg/ResetVector: add the macro to request guest termination
  2021-07-27 18:10 [PATCH v2 0/3] Move the SEV specific changes in ResetVector in separate file Brijesh Singh
  2021-07-27 18:10 ` [PATCH v2 1/3] OvmfPkg/ResetVector: move SEV specific code in a " Brijesh Singh
  2021-07-27 18:10 ` [PATCH v2 2/3] OvmfPkg/ResetVector: add the macro to invoke MSR protocol based VMGEXIT Brijesh Singh
@ 2021-07-27 18:10 ` Brijesh Singh
  2021-07-29  1:08 ` [PATCH v2 0/3] Move the SEV specific changes in ResetVector in separate file Yao, Jiewen
  3 siblings, 0 replies; 5+ messages in thread
From: Brijesh Singh @ 2021-07-27 18:10 UTC (permalink / raw)
  To: devel
  Cc: Brijesh Singh, James Bottomley, Min Xu, Jiewen Yao, Tom Lendacky,
	Jordan Justen, Ard Biesheuvel, Laszlo Ersek, Erdem Aktas

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

The upcoming SEV-SNP support will need to make a few additional guest
termination requests depending on the failure type. Let's move the logic
to request the guest termination into a macro to keep the code readable.

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>
Reviewed-by: Jiewen Yao <jiewen.yao@intel.com>
Acked-by: Ard Biesheuvel <ardb+tianocore@kernel.org>
Suggested-by: Laszlo Ersek <lersek@redhat.com>
Signed-off-by: Brijesh Singh <brijesh.singh@amd.com>
---
 OvmfPkg/ResetVector/Ia32/AmdSev.asm | 87 +++++++++++++++--------------
 1 file changed, 45 insertions(+), 42 deletions(-)

diff --git a/OvmfPkg/ResetVector/Ia32/AmdSev.asm b/OvmfPkg/ResetVector/Ia32/AmdSev.asm
index 93ba917f36d2..aa95d06eaddb 100644
--- a/OvmfPkg/ResetVector/Ia32/AmdSev.asm
+++ b/OvmfPkg/ResetVector/Ia32/AmdSev.asm
@@ -38,6 +38,13 @@ BITS    32
 %define SEV_GHCB_MSR                0xc0010130
 %define SEV_STATUS_MSR              0xc0010131
 
+; The #VC was not for CPUID
+%define TERM_VC_NOT_CPUID           1
+
+; The unexpected response code
+%define TERM_UNEXPECTED_RESP_CODE   2
+
+
 ; Macro is used to issue the MSR protocol based VMGEXIT. The caller is
 ; responsible to populate values in the EDX:EAX registers. After the vmmcall
 ; returns, it verifies that the response code matches with the expected
@@ -73,6 +80,43 @@ BITS    32
     jne     SevEsUnexpectedRespTerminate
 %endmacro
 
+; Macro to terminate the guest using the VMGEXIT.
+; arg 1: reason code
+%macro TerminateVmgExit 1
+    mov     eax, %1
+    ;
+    ; Use VMGEXIT to request termination. At this point the reason code is
+    ; located in EAX, so shift it left 16 bits to the proper location.
+    ;
+    ; EAX[11:0]  => 0x100 - request termination
+    ; EAX[15:12] => 0x1   - OVMF
+    ; EAX[23:16] => 0xXX  - REASON CODE
+    ;
+    shl     eax, 16
+    or      eax, 0x1100
+    xor     edx, edx
+    mov     ecx, SEV_GHCB_MSR
+    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
+
+    ;
+    ; We shouldn't come back from the VMGEXIT, but if we do, just loop.
+    ;
+%%TerminateHlt:
+    hlt
+    jmp     %%TerminateHlt
+%endmacro
+
+; Terminate the guest due to unexpected response code.
+SevEsUnexpectedRespTerminate:
+    TerminateVmgExit    TERM_UNEXPECTED_RESP_CODE
+
 ; Check if Secure Encrypted Virtualization (SEV) features are enabled.
 ;
 ; Register usage is tight in this routine, so multiple calls for the
@@ -227,48 +271,7 @@ SevEsDisabled:
 ;
 
 SevEsIdtNotCpuid:
-    ;
-    ; Use VMGEXIT to request termination.
-    ;   1 - #VC was not for CPUID
-    ;
-    mov     eax, 1
-    jmp     SevEsIdtTerminate
-
-SevEsUnexpectedRespTerminate:
-    ;
-    ; Use VMGEXIT to request termination.
-    ;   2 - Unexpected Response is received
-    ;
-    mov     eax, 2
-
-SevEsIdtTerminate:
-    ;
-    ; Use VMGEXIT to request termination. At this point the reason code is
-    ; located in EAX, so shift it left 16 bits to the proper location.
-    ;
-    ; EAX[11:0]  => 0x100 - request termination
-    ; EAX[15:12] => 0x1   - OVMF
-    ; EAX[23:16] => 0xXX  - REASON CODE
-    ;
-    shl     eax, 16
-    or      eax, 0x1100
-    xor     edx, edx
-    mov     ecx, SEV_GHCB_MSR
-    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
-
-    ;
-    ; We shouldn't come back from the VMGEXIT, but if we do, just loop.
-    ;
-SevEsIdtHlt:
-    hlt
-    jmp     SevEsIdtHlt
+    TerminateVmgExit TERM_VC_NOT_CPUID
     iret
 
     ;
-- 
2.17.1


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

* Re: [PATCH v2 0/3] Move the SEV specific changes in ResetVector in separate file
  2021-07-27 18:10 [PATCH v2 0/3] Move the SEV specific changes in ResetVector in separate file Brijesh Singh
                   ` (2 preceding siblings ...)
  2021-07-27 18:10 ` [PATCH v2 3/3] OvmfPkg/ResetVector: add the macro to request guest termination Brijesh Singh
@ 2021-07-29  1:08 ` Yao, Jiewen
  3 siblings, 0 replies; 5+ messages in thread
From: Yao, Jiewen @ 2021-07-29  1:08 UTC (permalink / raw)
  To: Brijesh Singh, devel@edk2.groups.io
  Cc: James Bottomley, Xu, Min M, Tom Lendacky, Justen, Jordan L,
	Ard Biesheuvel, Laszlo Ersek, Erdem Aktas

Pushed.

https://github.com/tianocore/edk2/pull/1842

githash: dc485c556d5f5db21debe8de3a45a7564aacbe24..b461d67639f2deced77e9bb967d014b7cfcd75f8


> -----Original Message-----
> From: Brijesh Singh <brijesh.singh@amd.com>
> Sent: Wednesday, July 28, 2021 2:10 AM
> To: devel@edk2.groups.io
> Cc: Brijesh Singh <brijesh.singh@amd.com>; James Bottomley
> <jejb@linux.ibm.com>; Xu, Min M <min.m.xu@intel.com>; Yao, Jiewen
> <jiewen.yao@intel.com>; Tom Lendacky <thomas.lendacky@amd.com>; Justen,
> Jordan L <jordan.l.justen@intel.com>; Ard Biesheuvel
> <ardb+tianocore@kernel.org>; Laszlo Ersek <lersek@redhat.com>; Erdem Aktas
> <erdemaktas@google.com>
> Subject: [PATCH v2 0/3] Move the SEV specific changes in ResetVector in
> separate file
> 
> The PageTable64.asm was created to build the initial page table,
> but over the time it grew to include bunch of the SEV specific code
> which does not directly manipulates the pagetable. Before adding more
> to it, let's move all the SEV-specific routines into a separate file.
> 
> The series is taken from SNP RFCv4. And there is no functionality change
> intended. Its just moving the code from one place to another.
> 
> 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>
> 
> The full branch is available at:
> https://github.com/AMDESE/ovmf/pull/new/refactor-reset-vector
> 
> Changelog:
>  - fix the copyright header in AmdSev.asm
> 
> Brijesh Singh (3):
>   OvmfPkg/ResetVector: move SEV specific code in a separate file
>   OvmfPkg/ResetVector: add the macro to invoke MSR protocol based
>     VMGEXIT
>   OvmfPkg/ResetVector: add the macro to request guest termination
> 
>  .../Ia32/{PageTables64.asm => AmdSev.asm}     | 297 ++++---------
>  OvmfPkg/ResetVector/Ia32/PageTables64.asm     | 391 ------------------
>  OvmfPkg/ResetVector/ResetVector.nasmb         |   1 +
>  3 files changed, 92 insertions(+), 597 deletions(-)
>  copy OvmfPkg/ResetVector/Ia32/{PageTables64.asm => AmdSev.asm} (66%)
> 
> --
> 2.17.1


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

end of thread, other threads:[~2021-07-29  1:09 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2021-07-27 18:10 [PATCH v2 0/3] Move the SEV specific changes in ResetVector in separate file Brijesh Singh
2021-07-27 18:10 ` [PATCH v2 1/3] OvmfPkg/ResetVector: move SEV specific code in a " Brijesh Singh
2021-07-27 18:10 ` [PATCH v2 2/3] OvmfPkg/ResetVector: add the macro to invoke MSR protocol based VMGEXIT Brijesh Singh
2021-07-27 18:10 ` [PATCH v2 3/3] OvmfPkg/ResetVector: add the macro to request guest termination Brijesh Singh
2021-07-29  1:08 ` [PATCH v2 0/3] Move the SEV specific changes in ResetVector in separate file Yao, Jiewen

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