public inbox for devel@edk2.groups.io
 help / color / mirror / Atom feed
* [RFC PATCH v2 06/10] OvmfPkg/DxeBmDmaLib: Fix AllocateBounceBuffer parameter
  2017-03-21 20:59 [RFC PATCH v2 00/10] x86: Secure Encrypted Virtualization (AMD) Brijesh Singh
@ 2017-03-21 20:59 ` Brijesh Singh
  0 siblings, 0 replies; 44+ messages in thread
From: Brijesh Singh @ 2017-03-21 20:59 UTC (permalink / raw)
  To: michael.d.kinney, ersek, edk2-devel, liming.gao, jordan.l.justen
  Cc: leo.duran, brijesh.singh, Thomas.Lendacky

The patch fixes AllocateBounceBuffer parameters.

Signed-off-by: Brijesh Singh <brijesh.singh@amd.com>
---
 OvmfPkg/Library/DxeBmDmaLib/DxeBmDmaLib.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/OvmfPkg/Library/DxeBmDmaLib/DxeBmDmaLib.c b/OvmfPkg/Library/DxeBmDmaLib/DxeBmDmaLib.c
index a342c9e..0d960a8 100644
--- a/OvmfPkg/Library/DxeBmDmaLib/DxeBmDmaLib.c
+++ b/OvmfPkg/Library/DxeBmDmaLib/DxeBmDmaLib.c
@@ -192,8 +192,8 @@ BmDmaMap (
   }
 
   return AllocateBounceBuffer ( 
-           Operation,
            FORCE_BELOW_4GB_TRUE,   
+           Operation,
            PhysicalAddress,
            NumberOfBytes,
            DeviceAddress,



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

* [RESEND] [RFC PATCH v2 00/10] x86: Secure Encrypted Virtualization (AMD)
@ 2017-03-21 21:12 Brijesh Singh
  2017-03-21 21:12 ` [RFC PATCH v2 01/10] OvmfPkg/Include: Define SEV specific CPUID and MSR Brijesh Singh
                   ` (9 more replies)
  0 siblings, 10 replies; 44+ messages in thread
From: Brijesh Singh @ 2017-03-21 21:12 UTC (permalink / raw)
  To: michael.d.kinney, jordan.l.justen, edk2-devel, lersek, liming.gao
  Cc: leo.duran, brijesh.singh, Thomas.Lendacky

(Sorry for churn, correcting Laszlo's email address) 

This RFC series provides support for AMD's new Secure Encrypted 
Virtualization (SEV) feature.

SEV is an extension to the AMD-V architecture which supports running
multiple VMs under the control of a hypervisor. The SEV feature allows
the memory contents of a virtual machine (VM) to be transparently encrypted
with a key unique to the guest VM. The memory controller contains a
high performance encryption engine which can be programmed with multiple
keys for use by a different VMs in the system. The programming and
management of these keys is handled by the AMD Secure Processor firmware
which exposes a commands for these tasks.

SEV guest VMs have the concept of private and shared memory.  Private memory is
encrypted with the guest-specific key, while shared memory may be encrypted
with hypervisor key.  Certain types of memory (namely instruction pages and
guest page tables) are always treated as private memory by the hardware.
For data memory, SEV guest VMs can choose which pages they would like to be
private. The choice is done using the standard CPU page tables using the C-bit,
and is fully controlled by the guest. Due to security reasons all the DMA
operations inside the  guest must be performed on shared pages (C-bit clear).
Note that since C-bit is only controllable by the guest OS when it is operating
in 64-bit or 32-bit PAE mode, in all other modes the SEV hardware forces the
C-bit to a 1.

The following links provide additional details:

AMD Memory Encryption whitepaper:
http://amd-dev.wpengine.netdna-cdn.com/wordpress/media/2013/12/AMD_Memory_Encryption_Whitepaper_v7-Public.pdf

AMD64 Architecture Programmer's Manual:
    http://support.amd.com/TechDocs/24593.pdf
    SME is section 7.10
    SEV is section 15.34

Secure Encrypted Virutualization Key Management:
http://support.amd.com/TechDocs/55766_SEV-KM API_Specification.pdf

KVM Forum Presentation:
http://www.linux-kvm.org/images/7/74/02x08A-Thomas_Lendacky-AMDs_Virtualizatoin_Memory_Encryption_Technology.pdf

[1] http://marc.info/?l=linux-mm&m=148846752931115&w=2

---

Patch series is based on commit 5d5a190 (ArmVirtPkg/HighMemDxe: check new regions against GCD memory space map)
plus I have cherry-picked https://lists.01.org/pipermail/edk2-devel/2017-March/008109.html and
https://lists.01.org/pipermail/edk2-devel/2017-March/008756.html.

source is also available @ https://github.com/codomania/edk2/tree/sev-rfc-2

The patch series is tested with OvmfIa32.dsc, OvmfIa32X64.dsc and OvmfX64.dsc.
Since memory encryption bit is not accessiable when processor is in 32-bit mode
hence any DMA access in this mode would cause assert. I have also tested the
suspend and resume path, it seems to be working fine. I still need to work to
finish adding the SEV Dma support in QemuFwCfgS3Lib package (see TODO).

Changes since v1:
 - bug fixes in OvmfPkg/ResetVector (pointed by Tom Lendacky)
 - add SEV CPUID and MSR register definition in standard include file
 - remove the MemEncryptLib dependency from PlatformPei. Move AmdSevInitialize()
   implementation in local file inside the PlatformPei package
 - rename MemCryptSevLib to MemEncryptSevLib and add functions to set or
   clear memory encryption attribute on memory region
 - integerate SEV support in BmDmaLib
 - split QemuFwCfgDxePei.c into QemuFwCfgDxe.c and QemuFwCfgPei.c to
   allow building seperate QemuFwCfgLib for Dxe and Pei phase
   (recommended by Laszlo Ersek)
 - add SEV support in QemuFwCfgLib
 - clear the memory encryption attribute from framebuffer memory region


TODO:
 - add support for accessing QEMU system flash device when SEV is enabled
 - add support for DMA operation in QemuFwCfgS3Lib when SEV is enabled
 - investigate SMM/SMI support
 - add virtio support

Brijesh Singh (10):
      OvmfPkg/Include: Define SEV specific CPUID and MSR
      OvmfPkg/ResetVector: add memory encryption mask when SEV is enabled
      OvmfPkg/PlatformPei: Add Secure Encrypted Virutualization (SEV) support
      OvmfPkg/BaseMemcryptSevLib: Add SEV helper library
      OvmfPkg/DxeBmDmaLib: Import DxeBmDmaLib package
      OvmfPkg/DxeBmDmaLib: Fix AllocateBounceBuffer parameter
      OvmfPkg/BmDmaLib: Add SEV support
      OvmfPkg/QemuFwCfgLib: Provide Pei and Dxe specific library support
      OvmfPkg/QemuFwCfgLib: Add Secure Encrypted Virtualization (SEV) support
      OvmfPkg/QemuVideoDxe: Clear the C-bit from framebuffer region when SEV is enabled


 OvmfPkg/Include/Library/BmDmaLib.h                 |    0 
 OvmfPkg/Include/Library/MemEncryptSevLib.h         |   69 +++
 OvmfPkg/Include/Register/AmdSevMap.h               |  133 +++++++
 .../BaseMemEncryptSevLib/BaseMemEncryptSevLib.inf  |   46 ++
 .../BaseMemEncryptSevLib/Ia32/MemEncryptSevLib.c   |  124 ++++++
 .../BaseMemEncryptSevLib/X64/MemEncryptSevLib.c    |  120 ++++++
 .../BaseMemEncryptSevLib/X64/VirtualMemory.c       |  304 +++++++++++++++
 .../BaseMemEncryptSevLib/X64/VirtualMemory.h       |  158 ++++++++
 OvmfPkg/Library/DxeBmDmaLib/DxeBmDmaLib.c          |  409 ++++++++++++++++++++
 OvmfPkg/Library/DxeBmDmaLib/DxeBmDmaLib.inf        |   42 ++
 OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgDxe.c        |  189 +++++++++
 OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgDxeLib.inf   |    8 
 OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgLib.c        |  112 +++++
 .../Library/QemuFwCfgLib/QemuFwCfgLibInternal.h    |   38 ++
 OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgPei.c        |  209 ++++++++++
 OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgPeiDxe.c     |  116 ------
 OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgPeiLib.inf   |    8 
 OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgSec.c        |   82 ++++
 OvmfPkg/OvmfPkgIa32.dsc                            |   10 
 OvmfPkg/OvmfPkgIa32X64.dsc                         |   10 
 OvmfPkg/OvmfPkgX64.dsc                             |   10 
 OvmfPkg/PlatformPei/AmdSev.c                       |   97 +++++
 OvmfPkg/PlatformPei/Platform.c                     |    1 
 OvmfPkg/PlatformPei/Platform.h                     |    5 
 OvmfPkg/PlatformPei/PlatformPei.inf                |    2 
 OvmfPkg/QemuVideoDxe/Gop.c                         |   15 +
 OvmfPkg/QemuVideoDxe/QemuVideoDxe.inf              |    1 
 OvmfPkg/ResetVector/Ia32/PageTables64.asm          |   62 +++
 28 files changed, 2252 insertions(+), 128 deletions(-)
 copy MdeModulePkg/Include/Library/BmDmaLib.h => OvmfPkg/Include/Library/BmDmaLib.h (100%)
 create mode 100644 OvmfPkg/Include/Library/MemEncryptSevLib.h
 create mode 100644 OvmfPkg/Include/Register/AmdSevMap.h
 create mode 100644 OvmfPkg/Library/BaseMemEncryptSevLib/BaseMemEncryptSevLib.inf
 create mode 100644 OvmfPkg/Library/BaseMemEncryptSevLib/Ia32/MemEncryptSevLib.c
 create mode 100644 OvmfPkg/Library/BaseMemEncryptSevLib/X64/MemEncryptSevLib.c
 create mode 100644 OvmfPkg/Library/BaseMemEncryptSevLib/X64/VirtualMemory.c
 create mode 100644 OvmfPkg/Library/BaseMemEncryptSevLib/X64/VirtualMemory.h
 create mode 100644 OvmfPkg/Library/DxeBmDmaLib/DxeBmDmaLib.c
 create mode 100644 OvmfPkg/Library/DxeBmDmaLib/DxeBmDmaLib.inf
 create mode 100644 OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgDxe.c
 copy OvmfPkg/Library/QemuFwCfgLib/{QemuFwCfgLib.inf => QemuFwCfgDxeLib.inf} (82%)
 create mode 100644 OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgPei.c
 delete mode 100644 OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgPeiDxe.c
 rename OvmfPkg/Library/QemuFwCfgLib/{QemuFwCfgLib.inf => QemuFwCfgPeiLib.inf} (83%)
 create mode 100644 OvmfPkg/PlatformPei/AmdSev.c

-- 

Brijesh Singh



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

* [RFC PATCH v2 01/10] OvmfPkg/Include: Define SEV specific CPUID and MSR
  2017-03-21 21:12 [RESEND] [RFC PATCH v2 00/10] x86: Secure Encrypted Virtualization (AMD) Brijesh Singh
@ 2017-03-21 21:12 ` Brijesh Singh
  2017-03-22 16:03   ` Laszlo Ersek
  2017-03-21 21:12 ` [RFC PATCH v2 02/10] OvmfPkg/ResetVector: add memory encryption mask when SEV is enabled Brijesh Singh
                   ` (8 subsequent siblings)
  9 siblings, 1 reply; 44+ messages in thread
From: Brijesh Singh @ 2017-03-21 21:12 UTC (permalink / raw)
  To: michael.d.kinney, jordan.l.justen, edk2-devel, lersek, liming.gao
  Cc: leo.duran, brijesh.singh, Thomas.Lendacky

The patch defines AMD's Memory Encryption Information CPUID leaf (0x8000_001F).
The complete description for this CPUID leaf is available in APM volume 2 [1]
Section 15.34 (Secure Encrypted Virtualization).

[1] http://support.amd.com/TechDocs/24593.pdf

Signed-off-by: Brijesh Singh <brijesh.singh@amd.com>
---
 OvmfPkg/Include/Register/AmdSevMap.h |  133 ++++++++++++++++++++++++++++++++++
 1 file changed, 133 insertions(+)
 create mode 100644 OvmfPkg/Include/Register/AmdSevMap.h

diff --git a/OvmfPkg/Include/Register/AmdSevMap.h b/OvmfPkg/Include/Register/AmdSevMap.h
new file mode 100644
index 0000000..de80f39
--- /dev/null
+++ b/OvmfPkg/Include/Register/AmdSevMap.h
@@ -0,0 +1,133 @@
+/** @file
+
+AMD Secure Encrypted Virtualization (SEV) specific CPUID and MSR definitions
+
+The complete description for this CPUID leaf is available in APM volume 2 (Section 15.34)
+http://support.amd.com/TechDocs/24593.pdf
+
+Copyright (c) 2017, Advanced Micro Devices. All rights reserved.<BR>
+
+This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution.  The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#ifndef __AMD_SEV_MAP_H__
+#define __AMD_SEV_MAP_H__
+
+#pragma pack (1)
+
+#define CPUID_MEMORY_ENCRYPTION_INFO             0x8000001F
+
+/**
+  CPUID Memory Encryption support information EAX for CPUID leaf
+  #CPUID_MEMORY_ENCRYPTION_INFO.
+**/
+typedef union {
+  ///
+  /// Individual bit fields
+  ///
+  struct {
+    ///
+    /// [Bit 0] Secure Memory Encryption (Sme) Support
+    ///
+    UINT32  SmeBit:1;
+
+    ///
+    /// [Bit 1] Secure Encrypted Virtualization (Sev) Support
+    ///
+    UINT32  SevBit:1;
+
+    ///
+    /// [Bit 2] Page flush MSR support
+    ///
+    UINT32  PageFlushMsrBit:1;
+
+    ///
+    /// [Bit 3] Encrypted state support
+    ///
+    UINT32  SevEsBit:1;
+
+    ///
+    /// [Bit 4:31] Reserved
+    ///
+    UINT32  ReservedBits:28;
+  } Bits;
+  ///
+  /// All bit fields as a 32-bit value
+  ///
+  UINT32  Uint32;
+} CPUID_MEMORY_ENCRYPTION_INFO_EAX;
+
+/**
+  CPUID Memory Encryption support information EBX for CPUID leaf
+  #CPUID_MEMORY_ENCRYPTION_INFO.
+**/
+typedef union {
+  ///
+  /// Individual bit fields
+  ///
+  struct {
+    ///
+    /// [Bit 0:5] Page table bit number used to enable memory encryption
+    ///
+    UINT32  PtePosBits:6;
+
+    ///
+    /// [Bit 6:11] Reduction of system physical address space bits when memory encryption is enabled
+    ///
+    UINT32  ReducedPhysBits:5;
+
+    ///
+    /// [Bit 12:31] Reserved
+    ///
+    UINT32  ReservedBits:21;
+  } Bits;
+  ///
+  /// All bit fields as a 32-bit value
+  ///
+  UINT32  Uint32;
+} CPUID_MEMORY_ENCRYPTION_INFO_EBX;
+
+/**
+  Secure Encrypted Virtualization (SEV) status register
+
+**/
+#define MSR_SEV_STATUS                     0xc0010131
+
+/**
+  MSR information returned for #MSR_SEV_STATUS
+**/
+typedef union {
+  ///
+  /// Individual bit fields
+  ///
+  struct {
+    ///
+    /// [Bit 0] Secure Encrypted Virtualization (Sev) is enabled
+    ///
+    UINT32  SevBit:1;
+
+    ///
+    /// [Bit 1] Secure Encrypted Virtualization Encrypted State (SevEs) is enabled
+    ///
+    UINT32  SevEsBit:1;
+
+    UINT32  Reserved:30;
+  } Bits;
+  ///
+  /// All bit fields as a 32-bit value
+  ///
+  UINT32  Uint32;
+  ///
+  /// All bit fields as a 64-bit value
+  ///
+  UINT64  Uint64;
+} MSR_SEV_STATUS_REGISTER;
+
+#endif



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

* [RFC PATCH v2 02/10] OvmfPkg/ResetVector: add memory encryption mask when SEV is enabled
  2017-03-21 21:12 [RESEND] [RFC PATCH v2 00/10] x86: Secure Encrypted Virtualization (AMD) Brijesh Singh
  2017-03-21 21:12 ` [RFC PATCH v2 01/10] OvmfPkg/Include: Define SEV specific CPUID and MSR Brijesh Singh
@ 2017-03-21 21:12 ` Brijesh Singh
  2017-03-22 20:20   ` Laszlo Ersek
  2017-03-21 21:13 ` [RFC PATCH v2 03/10] OvmfPkg/PlatformPei: Add Secure Encrypted Virutualization (SEV) support Brijesh Singh
                   ` (7 subsequent siblings)
  9 siblings, 1 reply; 44+ messages in thread
From: Brijesh Singh @ 2017-03-21 21:12 UTC (permalink / raw)
  To: michael.d.kinney, jordan.l.justen, edk2-devel, lersek, liming.gao
  Cc: leo.duran, brijesh.singh, Thomas.Lendacky

SEV guest VMs have the concept of private and shared memory. Private
memory is encrypted with the guest-specific key, while shared memory
may be encrypted with hypervisor key. Certain types of memory (namely
instruction pages and guest page tables) are always treated as private
memory by the hardware. The C-bit in PTE indicate whether the page is
private or shared. The C-bit position for the PTE can be obtained from
CPUID Fn8000_001F[EBX].

When SEV is active, the BIOS is pre-encrypted by the Qemu launch sequence,
we must set the C-bit when building the page table for 64-bit or 32-bit
PAE mode.

Signed-off-by: Brijesh Singh <brijesh.singh@amd.com>
---
 OvmfPkg/ResetVector/Ia32/PageTables64.asm |   62 +++++++++++++++++++++++++++++
 1 file changed, 62 insertions(+)

diff --git a/OvmfPkg/ResetVector/Ia32/PageTables64.asm b/OvmfPkg/ResetVector/Ia32/PageTables64.asm
index 6201cad..7083f6b 100644
--- a/OvmfPkg/ResetVector/Ia32/PageTables64.asm
+++ b/OvmfPkg/ResetVector/Ia32/PageTables64.asm
@@ -37,6 +37,47 @@ BITS    32
                        PAGE_READ_WRITE + \
                        PAGE_PRESENT)
 
+; Check if Secure Encrypted Virtualization (SEV) feature
+;  
+;  If SEV is enabled, then EAX will contain Memory encryption bit position
+;
+CheckSevFeature:
+    xor       eax, eax
+
+    ; Check if we have a valid (0x8000_001F) CPUID leaf
+    mov       eax, 0x80000000
+    cpuid
+    cmp       eax, 0x8000001f
+    jl        NoSev
+
+    ; Check for memory encryption feature:
+    ;  CPUID  Fn8000_001F[EAX] - Bit 1
+    ;
+    mov       eax,  0x8000001f
+    cpuid
+    bt        eax, 1
+    jnc       NoSev
+
+    ; Check if memory encryption is enabled
+    ;  MSR_0xC0010131 - Bit 0 (SEV enabled)
+    ;  MSR_0xC0010131 - Bit 1 (SEV-ES enabled)
+    mov       ecx, 0xc0010131
+    rdmsr
+    bt        eax, 0
+    jnc       NoSev
+
+    ; Get pte bit position to enable memory encryption
+    ; CPUID Fn8000_001F[EBX] - Bits 5:0
+    ;
+    mov       eax, ebx
+    and       eax, 0x3f
+    jmp       SevExit
+
+NoSev:
+    xor       eax, eax
+
+SevExit:
+    OneTimeCallRet CheckSevFeature
 
 ;
 ; Modified:  EAX, ECX
@@ -60,18 +101,38 @@ clearPageTablesMemoryLoop:
     mov     dword[ecx * 4 + PT_ADDR (0) - 4], eax
     loop    clearPageTablesMemoryLoop
 
+    ; Check if its SEV-enabled Guest
+    ;
+    OneTimeCall   CheckSevFeature
+    xor     edx, edx
+    test    eax, eax
+    jz      SevNotActive
+
+    ; If SEV is enabled, Memory encryption bit is always above 31
+    mov     ebx, 32
+    sub     ebx, eax
+    bts     edx, eax
+
+SevNotActive:
+
+    ;
     ;
     ; 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)
@@ -83,6 +144,7 @@ pageTableEntriesLoop:
     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
 
     ;



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

* [RFC PATCH v2 03/10] OvmfPkg/PlatformPei: Add Secure Encrypted Virutualization (SEV) support
  2017-03-21 21:12 [RESEND] [RFC PATCH v2 00/10] x86: Secure Encrypted Virtualization (AMD) Brijesh Singh
  2017-03-21 21:12 ` [RFC PATCH v2 01/10] OvmfPkg/Include: Define SEV specific CPUID and MSR Brijesh Singh
  2017-03-21 21:12 ` [RFC PATCH v2 02/10] OvmfPkg/ResetVector: add memory encryption mask when SEV is enabled Brijesh Singh
@ 2017-03-21 21:13 ` Brijesh Singh
  2017-03-27  8:23   ` Laszlo Ersek
  2017-03-21 21:13 ` [RFC PATCH v2 04/10] OvmfPkg/BaseMemcryptSevLib: Add SEV helper library Brijesh Singh
                   ` (6 subsequent siblings)
  9 siblings, 1 reply; 44+ messages in thread
From: Brijesh Singh @ 2017-03-21 21:13 UTC (permalink / raw)
  To: michael.d.kinney, jordan.l.justen, edk2-devel, lersek, liming.gao
  Cc: leo.duran, brijesh.singh, Thomas.Lendacky

Initialize Secure Encrypted Virtualization support and set the memory encryption mask PCD.

Signed-off-by: Brijesh Singh <brijesh.singh@amd.com>
---
 OvmfPkg/OvmfPkgIa32.dsc             |    3 +
 OvmfPkg/OvmfPkgIa32X64.dsc          |    3 +
 OvmfPkg/OvmfPkgX64.dsc              |    3 +
 OvmfPkg/PlatformPei/AmdSev.c        |   97 +++++++++++++++++++++++++++++++++++
 OvmfPkg/PlatformPei/Platform.c      |    1 
 OvmfPkg/PlatformPei/Platform.h      |    5 ++
 OvmfPkg/PlatformPei/PlatformPei.inf |    2 +
 7 files changed, 114 insertions(+)
 create mode 100644 OvmfPkg/PlatformPei/AmdSev.c

diff --git a/OvmfPkg/OvmfPkgIa32.dsc b/OvmfPkg/OvmfPkgIa32.dsc
index 546cdf7..769251d 100644
--- a/OvmfPkg/OvmfPkgIa32.dsc
+++ b/OvmfPkg/OvmfPkgIa32.dsc
@@ -506,6 +506,9 @@
   gUefiCpuPkgTokenSpaceGuid.PcdCpuMaxLogicalProcessorNumber|64
   gUefiCpuPkgTokenSpaceGuid.PcdCpuApInitTimeOutInMicroSeconds|50000
 
+  # Set memory encryption mask
+  gEfiMdeModulePkgTokenSpaceGuid.PcdPteMemoryEncryptionAddressOrMask|0x0
+
 !if $(SMM_REQUIRE) == TRUE
   gUefiCpuPkgTokenSpaceGuid.PcdCpuSmmSyncMode|0x01
   gUefiCpuPkgTokenSpaceGuid.PcdCpuSmmApSyncTimeout|100000
diff --git a/OvmfPkg/OvmfPkgIa32X64.dsc b/OvmfPkg/OvmfPkgIa32X64.dsc
index 383c8d3..3874c35 100644
--- a/OvmfPkg/OvmfPkgIa32X64.dsc
+++ b/OvmfPkg/OvmfPkgIa32X64.dsc
@@ -514,6 +514,9 @@
   gUefiCpuPkgTokenSpaceGuid.PcdCpuMaxLogicalProcessorNumber|64
   gUefiCpuPkgTokenSpaceGuid.PcdCpuApInitTimeOutInMicroSeconds|50000
 
+  # Set memory encryption mask
+  gEfiMdeModulePkgTokenSpaceGuid.PcdPteMemoryEncryptionAddressOrMask|0x0
+
 !if $(SMM_REQUIRE) == TRUE
   gUefiCpuPkgTokenSpaceGuid.PcdCpuSmmSyncMode|0x01
   gUefiCpuPkgTokenSpaceGuid.PcdCpuSmmApSyncTimeout|100000
diff --git a/OvmfPkg/OvmfPkgX64.dsc b/OvmfPkg/OvmfPkgX64.dsc
index 0b7533c..fe7f086 100644
--- a/OvmfPkg/OvmfPkgX64.dsc
+++ b/OvmfPkg/OvmfPkgX64.dsc
@@ -513,6 +513,9 @@
   gUefiCpuPkgTokenSpaceGuid.PcdCpuMaxLogicalProcessorNumber|64
   gUefiCpuPkgTokenSpaceGuid.PcdCpuApInitTimeOutInMicroSeconds|50000
 
+  # Set memory encryption mask
+  gEfiMdeModulePkgTokenSpaceGuid.PcdPteMemoryEncryptionAddressOrMask|0x0
+
 !if $(SMM_REQUIRE) == TRUE
   gUefiCpuPkgTokenSpaceGuid.PcdCpuSmmSyncMode|0x01
   gUefiCpuPkgTokenSpaceGuid.PcdCpuSmmApSyncTimeout|100000
diff --git a/OvmfPkg/PlatformPei/AmdSev.c b/OvmfPkg/PlatformPei/AmdSev.c
new file mode 100644
index 0000000..7f05a9a
--- /dev/null
+++ b/OvmfPkg/PlatformPei/AmdSev.c
@@ -0,0 +1,97 @@
+/**@file
+  Initialize Secure Encrypted Virtualization (SEV) support
+
+  Copyright (c) 2017, Advanced Micro Devices. All rights reserved.<BR>
+
+  This program and the accompanying materials
+  are licensed and made available under the terms and conditions of the BSD License
+  which accompanies this distribution.  The full text of the license may be found at
+  http://opensource.org/licenses/bsd-license.php
+
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+//
+// The package level header files this module uses
+//
+#include <PiPei.h>
+
+#include <Library/DebugLib.h>
+#include <Library/PcdLib.h>
+#include <Register/Cpuid.h>
+#include <Register/AmdSevMap.h>
+
+/**
+
+  Function returns 'TRUE' when SEV is enabled otherwise FALSE
+
+  **/
+STATIC
+BOOLEAN
+SevIsEnabled (
+  VOID
+  )
+{
+  UINT32 RegEax;
+  MSR_SEV_STATUS_REGISTER Msr;
+  CPUID_MEMORY_ENCRYPTION_INFO_EAX  Eax;
+
+  //
+  // Check if memory encryption leaf exist
+  //
+  AsmCpuid (CPUID_EXTENDED_FUNCTION, &RegEax, NULL, NULL, NULL);
+  if (RegEax >= CPUID_MEMORY_ENCRYPTION_INFO) {
+    //
+    // CPUID Fn8000_001F[EAX] Bit 1 (Sev supported)
+    //
+    AsmCpuid (CPUID_MEMORY_ENCRYPTION_INFO, &Eax.Uint32, NULL, NULL, NULL);
+
+    if (Eax.Bits.SevBit) {
+      //
+      // Check MSR_0xC0010131 Bit 0 (Sev Enabled)
+      //
+      Msr.Uint32 = AsmReadMsr32 (MSR_SEV_STATUS);
+      if (Msr.Bits.SevBit) {
+        return TRUE;
+      }
+    }
+  }
+
+  return FALSE;
+}
+
+/**
+  Function checks if SEV support is available, if present then it updates
+  the dynamic PcdPteMemoryEncryptionAddressOrMask with memory encryption mask.
+
+  **/
+VOID
+EFIAPI
+AmdSevInitialize (
+  VOID
+  )
+{
+  UINT64 MeMask;
+  CPUID_MEMORY_ENCRYPTION_INFO_EBX  Ebx;
+
+  //
+  // Check if SEV is enabled
+  //
+  if (!SevIsEnabled ()) {
+    return;
+  }
+
+  //
+  // CPUID Fn8000_001F[EBX] Bit 0:5 (memory encryption bit position)
+  //
+  AsmCpuid (CPUID_MEMORY_ENCRYPTION_INFO, NULL, &Ebx.Uint32, NULL, NULL);
+  MeMask = LShiftU64 (1, Ebx.Bits.PtePosBits);
+
+  //
+  // Set Memory Encryption Mask PCD
+  //
+  PcdSet64S (PcdPteMemoryEncryptionAddressOrMask, MeMask);
+
+  DEBUG ((EFI_D_INFO, "SEV support is enabled (mask 0x%lx)\n", MeMask));
+}
diff --git a/OvmfPkg/PlatformPei/Platform.c b/OvmfPkg/PlatformPei/Platform.c
index 77a8a16..49e6c66 100644
--- a/OvmfPkg/PlatformPei/Platform.c
+++ b/OvmfPkg/PlatformPei/Platform.c
@@ -667,6 +667,7 @@ InitializePlatform (
     NoexecDxeInitialization ();
   }
 
+  AmdSevInitialize ();
   MiscInitialization ();
   InstallFeatureControlCallback ();
 
diff --git a/OvmfPkg/PlatformPei/Platform.h b/OvmfPkg/PlatformPei/Platform.h
index 18f42c3..a7729b9 100644
--- a/OvmfPkg/PlatformPei/Platform.h
+++ b/OvmfPkg/PlatformPei/Platform.h
@@ -88,6 +88,11 @@ XenDetect (
   VOID
   );
 
+VOID
+AmdSevInitialize (
+  VOID
+  );
+
 extern BOOLEAN mXen;
 
 VOID
diff --git a/OvmfPkg/PlatformPei/PlatformPei.inf b/OvmfPkg/PlatformPei/PlatformPei.inf
index 53c6dd4..2cf4ac876 100644
--- a/OvmfPkg/PlatformPei/PlatformPei.inf
+++ b/OvmfPkg/PlatformPei/PlatformPei.inf
@@ -35,6 +35,7 @@
   MemDetect.c
   Platform.c
   Xen.c
+  AmdSev.c
 
 [Packages]
   IntelFrameworkModulePkg/IntelFrameworkModulePkg.dec
@@ -98,6 +99,7 @@
   gUefiCpuPkgTokenSpaceGuid.PcdCpuMaxLogicalProcessorNumber
   gUefiCpuPkgTokenSpaceGuid.PcdCpuApInitTimeOutInMicroSeconds
   gUefiCpuPkgTokenSpaceGuid.PcdCpuApStackSize
+  gEfiMdeModulePkgTokenSpaceGuid.PcdPteMemoryEncryptionAddressOrMask
 
 [FixedPcd]
   gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseAddress



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

* [RFC PATCH v2 04/10] OvmfPkg/BaseMemcryptSevLib: Add SEV helper library
  2017-03-21 21:12 [RESEND] [RFC PATCH v2 00/10] x86: Secure Encrypted Virtualization (AMD) Brijesh Singh
                   ` (2 preceding siblings ...)
  2017-03-21 21:13 ` [RFC PATCH v2 03/10] OvmfPkg/PlatformPei: Add Secure Encrypted Virutualization (SEV) support Brijesh Singh
@ 2017-03-21 21:13 ` Brijesh Singh
  2017-03-27  9:19   ` Laszlo Ersek
  2017-03-21 21:13 ` [RFC PATCH v2 05/10] OvmfPkg/DxeBmDmaLib: Import DxeBmDmaLib package Brijesh Singh
                   ` (5 subsequent siblings)
  9 siblings, 1 reply; 44+ messages in thread
From: Brijesh Singh @ 2017-03-21 21:13 UTC (permalink / raw)
  To: michael.d.kinney, jordan.l.justen, edk2-devel, lersek, liming.gao
  Cc: leo.duran, brijesh.singh, Thomas.Lendacky

Add Secure Encrypted Virtualization (SEV) helper library. The library provides
the routines to set or clear memory encryption bit for a given memory region
and functions to check whether SEV is enabled.

Signed-off-by: Brijesh Singh <brijesh.singh@amd.com>
---
 OvmfPkg/Include/Library/MemEncryptSevLib.h         |   69 +++++
 .../BaseMemEncryptSevLib/BaseMemEncryptSevLib.inf  |   46 +++
 .../BaseMemEncryptSevLib/Ia32/MemEncryptSevLib.c   |  124 ++++++++
 .../BaseMemEncryptSevLib/X64/MemEncryptSevLib.c    |  120 ++++++++
 .../BaseMemEncryptSevLib/X64/VirtualMemory.c       |  304 ++++++++++++++++++++
 .../BaseMemEncryptSevLib/X64/VirtualMemory.h       |  158 ++++++++++
 OvmfPkg/OvmfPkgIa32.dsc                            |    1 
 OvmfPkg/OvmfPkgIa32X64.dsc                         |    1 
 OvmfPkg/OvmfPkgX64.dsc                             |    1 
 9 files changed, 824 insertions(+)
 create mode 100644 OvmfPkg/Include/Library/MemEncryptSevLib.h
 create mode 100644 OvmfPkg/Library/BaseMemEncryptSevLib/BaseMemEncryptSevLib.inf
 create mode 100644 OvmfPkg/Library/BaseMemEncryptSevLib/Ia32/MemEncryptSevLib.c
 create mode 100644 OvmfPkg/Library/BaseMemEncryptSevLib/X64/MemEncryptSevLib.c
 create mode 100644 OvmfPkg/Library/BaseMemEncryptSevLib/X64/VirtualMemory.c
 create mode 100644 OvmfPkg/Library/BaseMemEncryptSevLib/X64/VirtualMemory.h

diff --git a/OvmfPkg/Include/Library/MemEncryptSevLib.h b/OvmfPkg/Include/Library/MemEncryptSevLib.h
new file mode 100644
index 0000000..a9e9356
--- /dev/null
+++ b/OvmfPkg/Include/Library/MemEncryptSevLib.h
@@ -0,0 +1,69 @@
+/** @file
+
+  Define Secure Encrypted Virtualization (SEV) base library helper function
+
+  Copyright (c) 2017, AMD Incorporated. All rights reserved.<BR>
+
+  This program and the accompanying materials
+  are licensed and made available under the terms and conditions of the BSD License
+  which accompanies this distribution.  The full text of the license may be found at
+  http://opensource.org/licenses/bsd-license.php
+
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#ifndef __MEM_ENCRYPT_SEV_LIB_H_
+#define __MEM_ENCRYPT_SEV_LIB_H_
+
+#include <Base.h>
+
+/**
+  Returns a boolean to indicate whether SEV is enabled
+
+  @retval TRUE           When SEV is active
+  @retval FALSE          When SEV is not enabled
+  **/
+BOOLEAN
+EFIAPI
+MemEncryptSevIsEnabled (
+  VOID
+  );
+
+/**
+  This function clears memory encryption bit for the memory region specified by BaseAddress and
+  Number of pages from the current page table context.
+
+  @param[in]  BaseAddress           The physical address that is the start address of a memory region.
+  @param[in]  NumberOfPages         The number of pages from start memory region.
+
+  @retval RETURN_SUCCESS            The attributes were cleared for the memory region.
+  @retval RETURN_INVALID_PARAMETER  Number of pages is zero.
+  @retval RETURN_UNSUPPORTED        Clearing memory encryption attribute is not supported
+  **/
+RETURN_STATUS
+EFIAPI
+MemEncryptSevClearPageEncMask (
+  IN PHYSICAL_ADDRESS         BaseAddress,
+  IN UINT32                   NumberOfPages
+  );
+
+/**
+  This function sets memory encryption bit for the memory region specified by BaseAddress and
+  Number of pages from the current page table context.
+
+  @param[in]  BaseAddress           The physical address that is the start address of a memory region.
+  @param[in]  NumberOfPages         The number of pages from start memory region.
+
+  @retval RETURN_SUCCESS            The attributes were set for the memory region.
+  @retval RETURN_INVALID_PARAMETER  Number of pages is zero.
+  @retval RETURN_UNSUPPORTED        Clearing memory encryption attribute is not supported
+  **/
+RETURN_STATUS
+EFIAPI
+MemEncryptSevSetPageEncMask (
+  IN PHYSICAL_ADDRESS         BaseAddress,
+  IN UINT32                   NumberOfPages
+  );
+#endif // __MEM_ENCRYPT_SEV_LIB_H_
diff --git a/OvmfPkg/Library/BaseMemEncryptSevLib/BaseMemEncryptSevLib.inf b/OvmfPkg/Library/BaseMemEncryptSevLib/BaseMemEncryptSevLib.inf
new file mode 100644
index 0000000..c23261f
--- /dev/null
+++ b/OvmfPkg/Library/BaseMemEncryptSevLib/BaseMemEncryptSevLib.inf
@@ -0,0 +1,46 @@
+## @file
+#
+# Copyright (c) 2017 Advanced Micro Devices. All rights reserved.<BR>
+#
+#  This program and the accompanying materials
+#  are licensed and made available under the terms and conditions of the BSD License
+#  which accompanies this distribution. The full text of the license may be found at
+#  http://opensource.org/licenses/bsd-license.php
+#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = MemEncryptSevLib
+  FILE_GUID                      = c1594631-3888-4be4-949f-9c630dbc842b
+  MODULE_TYPE                    = BASE
+  VERSION_STRING                 = 1.0
+  LIBRARY_CLASS                  = MemEncryptSevLib|PEIM DXE_DRIVER DXE_RUNTIME_DRIVER DXE_SMM_DRIVER UEFI_DRIVER
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+# VALID_ARCHITECTURES           = IA32 X64
+#
+
+[Packages]
+  MdePkg/MdePkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+  OvmfPkg/OvmfPkg.dec
+  UefiCpuPkg/UefiCpuPkg.dec
+
+[Sources.X64]
+  X64/MemEncryptSevLib.c
+  X64/VirtualMemory.c
+
+[Sources.IA32]
+  Ia32/MemEncryptSevLib.c
+
+[LibraryClasses]
+  BaseLib
+  DebugLib
+  MemoryAllocationLib
+  CacheMaintenanceLib
diff --git a/OvmfPkg/Library/BaseMemEncryptSevLib/Ia32/MemEncryptSevLib.c b/OvmfPkg/Library/BaseMemEncryptSevLib/Ia32/MemEncryptSevLib.c
new file mode 100644
index 0000000..70fdd2e
--- /dev/null
+++ b/OvmfPkg/Library/BaseMemEncryptSevLib/Ia32/MemEncryptSevLib.c
@@ -0,0 +1,124 @@
+/** @file
+
+  Secure Encrypted Virtualization (SEV) library helper function
+
+  Copyright (c) 2017, AMD Incorporated. All rights reserved.<BR>
+
+  This program and the accompanying materials
+  are licensed and made available under the terms and conditions of the BSD License
+  which accompanies this distribution.  The full text of the license may be found at
+  http://opensource.org/licenses/bsd-license.php
+
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include "Uefi.h"
+#include <Library/BaseLib.h>
+#include <Library/DebugLib.h>
+#include <Register/Cpuid.h>
+#include <Register/AmdSevMap.h>
+#include <Library/MemEncryptSevLib.h>
+
+STATIC BOOLEAN SevStatus = FALSE;
+STATIC BOOLEAN SevStatusChecked = FALSE;
+
+/**
+ 
+  Returns a boolean to indicate whether SEV is enabled
+
+  @retval TRUE           When SEV is active
+  @retval FALSE          When SEV is not enabled
+  **/
+BOOLEAN
+EFIAPI
+MemEncryptSevIsEnabled (
+  VOID
+  )
+{
+  UINT32 RegEax;
+  MSR_SEV_STATUS_REGISTER Msr;
+  CPUID_MEMORY_ENCRYPTION_INFO_EAX  Eax;
+
+  //
+  // If Status is already checked then return it
+  //
+  if (SevStatusChecked) {
+    return SevStatus;
+  }
+
+  //
+  // Check if memory encryption leaf exist
+  //
+  AsmCpuid (CPUID_EXTENDED_FUNCTION, &RegEax, NULL, NULL, NULL);
+  if (RegEax >= CPUID_MEMORY_ENCRYPTION_INFO) {
+    //
+    // CPUID Fn8000_001F[EAX] Bit 1 (Sev supported)
+    //
+    AsmCpuid (CPUID_MEMORY_ENCRYPTION_INFO, &Eax.Uint32, NULL, NULL, NULL);
+
+    if (Eax.Bits.SevBit) {
+      //
+      // Check MSR_0xC0010131 Bit 0 (Sev is Enabled)
+      //
+      Msr.Uint32 = AsmReadMsr32 (MSR_SEV_STATUS);
+      if (Msr.Bits.SevBit) {
+        return TRUE;
+      }
+    }
+  }
+
+  SevStatusChecked = TRUE;
+
+  return FALSE;
+}
+
+/**
+  This function clears memory encryption bit for the memory region specified by BaseAddress and
+  Number of pages from the current page table context.
+
+  @param[in]  BaseAddress             The physical address that is the start address of a memory region.
+  @param[in]  NumberOfPages           The number of pages from start memory region.
+
+  @retval RETURN_SUCCESS              The attributes were cleared for the memory region.
+  @retval RETURN_INVALID_PARAMETER    Number of pages is zero.
+  @retval RETURN_UNSUPPORTED          Setting the memory encyrption attribute is not supported
+  **/
+RETURN_STATUS
+EFIAPI
+MemEncryptSevClearPageEncMask (
+  IN PHYSICAL_ADDRESS         BaseAddress,
+  IN UINT32                   NumberOfPages
+  )
+{
+  //
+  // Memory encryption bit is not accessible in 32-bit mode
+  //
+  return RETURN_UNSUPPORTED;
+}
+
+/**
+  This function sets memory encryption bit for the memory region specified by BaseAddress and
+  Number of pages from the current page table context.
+
+  @param[in]  BaseAddress             The physical address that is the start address of a memory region.
+  @param[in]  NumberOfPages           The number of pages from start memory region.
+
+  @retval RETURN_SUCCESS              The attributes were cleared for the memory region.
+  @retval RETURN_INVALID_PARAMETER    Number of pages is zero.
+  @retval RETURN_UNSUPPORTED          Setting the memory encyrption attribute is not supported
+  **/
+RETURN_STATUS
+EFIAPI
+MemEncryptSevSetPageEncMask (
+  IN PHYSICAL_ADDRESS         BaseAddress,
+  IN UINT32                   NumberOfPages
+  )
+{
+  //
+  // Memory encryption bit is not accessible in 32-bit mode
+  //
+  return RETURN_UNSUPPORTED;
+}
+
diff --git a/OvmfPkg/Library/BaseMemEncryptSevLib/X64/MemEncryptSevLib.c b/OvmfPkg/Library/BaseMemEncryptSevLib/X64/MemEncryptSevLib.c
new file mode 100644
index 0000000..098acf2
--- /dev/null
+++ b/OvmfPkg/Library/BaseMemEncryptSevLib/X64/MemEncryptSevLib.c
@@ -0,0 +1,120 @@
+/** @file
+
+  Secure Encrypted Virtualization (SEV) library helper function
+
+  Copyright (c) 2017, AMD Incorporated. All rights reserved.<BR>
+
+  This program and the accompanying materials
+  are licensed and made available under the terms and conditions of the BSD License
+  which accompanies this distribution.  The full text of the license may be found at
+  http://opensource.org/licenses/bsd-license.php
+
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include "Uefi.h"
+#include <Library/BaseLib.h>
+#include <Library/DebugLib.h>
+#include <Register/Cpuid.h>
+#include <Register/AmdSevMap.h>
+#include <Library/MemEncryptSevLib.h>
+
+#include "VirtualMemory.h"
+
+STATIC BOOLEAN SevStatus = FALSE;
+STATIC BOOLEAN SevStatusChecked = FALSE;
+
+/**
+  Returns a boolean to indicate whether SEV is enabled
+
+  @retval TRUE           When SEV is active
+  @retval FALSE          When SEV is not enabled
+  **/
+BOOLEAN
+EFIAPI
+MemEncryptSevIsEnabled (
+  VOID
+  )
+{
+  UINT32 RegEax;
+  MSR_SEV_STATUS_REGISTER Msr;
+  CPUID_MEMORY_ENCRYPTION_INFO_EAX  Eax;
+
+  //
+  // If Status is already checked then return it
+  //
+  if (SevStatusChecked) {
+    return SevStatus;
+  }
+
+  //
+  // Check if memory encryption leaf exist
+  //
+  AsmCpuid (CPUID_EXTENDED_FUNCTION, &RegEax, NULL, NULL, NULL);
+  if (RegEax >= CPUID_MEMORY_ENCRYPTION_INFO) {
+    //
+    // CPUID Fn8000_001F[EAX] Bit 1 (Sev supported)
+    //
+    AsmCpuid (CPUID_MEMORY_ENCRYPTION_INFO, &Eax.Uint32, NULL, NULL, NULL);
+
+    if (Eax.Bits.SevBit) {
+      //
+      // Check MSR_0xC0010131 Bit 0 (Sev Enabled)
+      //
+      Msr.Uint32 = AsmReadMsr32 (MSR_SEV_STATUS);
+      if (Msr.Bits.SevBit) {
+        return TRUE;
+      }
+    }
+  }
+
+  SevStatusChecked = TRUE;
+
+  return FALSE;
+}
+
+/**
+ 
+  This function clears memory encryption bit for the memory region specified by BaseAddress and
+  Number of pages from the current page table context.
+
+  @param[in]  BaseAddress             The physical address that is the start address of a memory region.
+  @param[in]  NumberOfPages           The number of pages from start memory region.
+
+  @retval RETURN_SUCCESS              The attributes were cleared for the memory region.
+  @retval RETURN_INVALID_PARAMETER    Number of pages is zero.
+  @retval RETURN_UNSUPPORTED          Clearing the memory encryption attribute is not supported
+  **/
+RETURN_STATUS
+EFIAPI
+MemEncryptSevClearPageEncMask (
+  IN PHYSICAL_ADDRESS         BaseAddress,
+  IN UINT32                   NumPages
+  )
+{
+  return Set_Memory_Decrypted (BaseAddress, NumPages * EFI_PAGE_SIZE);
+}
+
+/**
+ 
+  This function clears memory encryption bit for the memory region specified by BaseAddress and
+  Number of pages from the current page table context.
+
+  @param[in]  BaseAddress             The physical address that is the start address of a memory region.
+  @param[in]  NumberOfPages           The number of pages from start memory region.
+
+  @retval RETURN_SUCCESS              The attributes were cleared for the memory region.
+  @retval RETURN_INVALID_PARAMETER    Number of pages is zero.
+  @retval RETURN_UNSUPPORTED          Clearing the memory encryption attribute is not supported
+  **/
+RETURN_STATUS
+EFIAPI
+MemEncryptSevSetPageEncMask (
+  IN PHYSICAL_ADDRESS         BaseAddress,
+  IN UINT32                   NumPages
+  )
+{
+  return Set_Memory_Encrypted (BaseAddress, NumPages * EFI_PAGE_SIZE);
+}
diff --git a/OvmfPkg/Library/BaseMemEncryptSevLib/X64/VirtualMemory.c b/OvmfPkg/Library/BaseMemEncryptSevLib/X64/VirtualMemory.c
new file mode 100644
index 0000000..7acebf3
--- /dev/null
+++ b/OvmfPkg/Library/BaseMemEncryptSevLib/X64/VirtualMemory.c
@@ -0,0 +1,304 @@
+/** @file
+ 
+  Virtual Memory Management Services to set or clear the memory encryption bit
+
+  References:
+    1) IA-32 Intel(R) Architecture Software Developer's Manual Volume 1:Basic Architecture, Intel
+    2) IA-32 Intel(R) Architecture Software Developer's Manual Volume 2:Instruction Set Reference, Intel
+    3) IA-32 Intel(R) Architecture Software Developer's Manual Volume 3:System Programmer's Guide, Intel
+
+Copyright (c) 2006 - 2016, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2017, AMD Incorporated. All rights reserved.<BR>
+
+This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution.  The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include "VirtualMemory.h"
+
+#include <Register/AmdSevMap.h>
+
+STATIC UINT64 AddressEncMask;
+
+typedef enum {
+   SetCBit,
+   ClearCBit
+} MAP_RANGE_MODE;
+
+/**
+  Split 2M page to 4K.
+
+  @param[in]      PhysicalAddress       Start physical address the 2M page covered.
+  @param[in, out] PageEntry2M           Pointer to 2M page entry.
+  @param[in]      StackBase             Stack base address.
+  @param[in]      StackSize             Stack size.
+
+**/
+STATIC
+VOID
+Split2MPageTo4K (
+  IN EFI_PHYSICAL_ADDRESS               PhysicalAddress,
+  IN OUT UINT64                         *PageEntry2M,
+  IN EFI_PHYSICAL_ADDRESS               StackBase,
+  IN UINTN                              StackSize
+  )
+{
+  EFI_PHYSICAL_ADDRESS                  PhysicalAddress4K;
+  UINTN                                 IndexOfPageTableEntries;
+  PAGE_TABLE_4K_ENTRY                   *PageTableEntry, *PageTableEntry1;
+
+  PageTableEntry = AllocatePages(1);
+
+  PageTableEntry1 = PageTableEntry;
+
+  ASSERT (PageTableEntry != NULL);
+  ASSERT (*PageEntry2M & AddressEncMask);
+
+  PhysicalAddress4K = PhysicalAddress;
+  for (IndexOfPageTableEntries = 0; IndexOfPageTableEntries < 512; IndexOfPageTableEntries++, PageTableEntry++, PhysicalAddress4K += SIZE_4KB) {
+    //
+    // Fill in the Page Table entries
+    //
+    PageTableEntry->Uint64 = (UINT64) PhysicalAddress4K | AddressEncMask;
+    PageTableEntry->Bits.ReadWrite = 1;
+    PageTableEntry->Bits.Present = 1;
+    if ((PhysicalAddress4K >= StackBase) && (PhysicalAddress4K < StackBase + StackSize)) {
+      //
+      // Set Nx bit for stack.
+      //
+      PageTableEntry->Bits.Nx = 1;
+    }
+  }
+
+  //
+  // Fill in 2M page entry.
+  //
+  *PageEntry2M = (UINT64) (UINTN) PageTableEntry1 | IA32_PG_P | IA32_PG_RW | AddressEncMask;
+}
+
+/**
+  Split 1G page to 2M.
+
+  @param[in]      PhysicalAddress       Start physical address the 1G page covered.
+  @param[in, out] PageEntry1G           Pointer to 1G page entry.
+  @param[in]      StackBase             Stack base address.
+  @param[in]      StackSize             Stack size.
+
+**/
+STATIC
+VOID
+Split1GPageTo2M (
+  IN EFI_PHYSICAL_ADDRESS               PhysicalAddress,
+  IN OUT UINT64                         *PageEntry1G,
+  IN EFI_PHYSICAL_ADDRESS               StackBase,
+  IN UINTN                              StackSize
+  )
+{
+  EFI_PHYSICAL_ADDRESS                  PhysicalAddress2M;
+  UINTN                                 IndexOfPageDirectoryEntries;
+  PAGE_TABLE_ENTRY                      *PageDirectoryEntry;
+
+  PageDirectoryEntry = AllocatePages(1);
+
+  ASSERT (PageDirectoryEntry != NULL);
+  ASSERT (*PageEntry1G & AddressEncMask);
+  //
+  // Fill in 1G page entry.
+  //
+  *PageEntry1G = (UINT64) (UINTN) PageDirectoryEntry | IA32_PG_P | IA32_PG_RW | AddressEncMask;
+
+  PhysicalAddress2M = PhysicalAddress;
+  for (IndexOfPageDirectoryEntries = 0; IndexOfPageDirectoryEntries < 512; IndexOfPageDirectoryEntries++, PageDirectoryEntry++, PhysicalAddress2M += SIZE_2MB) {
+    if ((PhysicalAddress2M < StackBase + StackSize) && ((PhysicalAddress2M + SIZE_2MB) > StackBase)) {
+      //
+      // Need to split this 2M page that covers stack range.
+      //
+      Split2MPageTo4K (PhysicalAddress2M, (UINT64 *) PageDirectoryEntry, StackBase, StackSize);
+    } else {
+      //
+      // Fill in the Page Directory entries
+      //
+      PageDirectoryEntry->Uint64 = (UINT64) PhysicalAddress2M | AddressEncMask;
+      PageDirectoryEntry->Bits.ReadWrite = 1;
+      PageDirectoryEntry->Bits.Present = 1;
+      PageDirectoryEntry->Bits.MustBe1 = 1;
+    }
+  }
+}
+
+
+STATIC VOID
+SetOrClearCBit(
+  IN UINT64*  PageTablePointer,
+  IN MAP_RANGE_MODE Mode
+  )
+{
+  if (Mode == SetCBit) {
+    *PageTablePointer |= AddressEncMask;
+  } else {
+    *PageTablePointer &= ~AddressEncMask;
+  }
+
+}
+
+STATIC
+UINT64
+GetMemEncryptionAddressMask (
+  VOID
+  )
+{
+  UINT64 MeMask;
+  CPUID_MEMORY_ENCRYPTION_INFO_EBX  Ebx;
+
+  //
+  // CPUID Fn8000_001F[EBX] Bit 0:5 (memory encryption bit position)
+  //
+  AsmCpuid (CPUID_MEMORY_ENCRYPTION_INFO, NULL, &Ebx.Uint32, NULL, NULL);
+  MeMask = LShiftU64 (1, Ebx.Bits.PtePosBits);
+
+  return MeMask & PAGING_1G_ADDRESS_MASK_64;
+}
+
+STATIC
+EFI_STATUS
+EFIAPI
+Set_Memory_Enc_Dec (
+  IN EFI_PHYSICAL_ADDRESS     PhysicalAddress,
+  IN UINT64                   Length,
+  IN MAP_RANGE_MODE           Mode
+  )
+{
+  PAGE_MAP_AND_DIRECTORY_POINTER *PageMapLevel4Entry;
+  PAGE_MAP_AND_DIRECTORY_POINTER *PageUpperDirectoryPointerEntry;
+  PAGE_MAP_AND_DIRECTORY_POINTER *PageDirectoryPointerEntry;
+  PAGE_TABLE_1G_ENTRY            *PageDirectory1GEntry;
+  PAGE_TABLE_ENTRY               *PageDirectory2MEntry;
+  PAGE_TABLE_4K_ENTRY            *PageTableEntry;
+  UINT64                         PgTableMask;
+
+  AddressEncMask = GetMemEncryptionAddressMask ();
+
+  if (!AddressEncMask) {
+    return RETURN_ACCESS_DENIED;
+  }
+
+  PgTableMask = AddressEncMask | EFI_PAGE_MASK;
+
+  DEBUG ((EFI_D_VERBOSE, "Set memory range 0x%#Lx+0x%x (%s)\n", PhysicalAddress, Length,
+			  Mode == ClearCBit ? "unencrypted" : "encrypted"));
+
+  if (Length == 0) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  //
+  // We are going to change the memory encryption attribute from C=0 -> C=1 or vice versa
+  // Flush the caches to ensure that data is written into memory with correct C-bit
+  //
+  WriteBackInvalidateDataCacheRange((VOID*) PhysicalAddress, Length);
+
+  while (Length)
+  {
+
+    PageMapLevel4Entry = (VOID*) (AsmReadCr3() & ~PgTableMask);
+    PageMapLevel4Entry += PML4_OFFSET(PhysicalAddress);
+    if (!PageMapLevel4Entry->Bits.Present) {
+      DEBUG((DEBUG_WARN, "ERROR bad PML4 for %lx\n", PhysicalAddress));
+      return EFI_NO_MAPPING;
+    }
+
+    PageDirectory1GEntry = (VOID*) (PageMapLevel4Entry->Bits.PageTableBaseAddress<<12 & ~PgTableMask);
+    PageDirectory1GEntry += PDP_OFFSET(PhysicalAddress);
+    if (!PageDirectory1GEntry->Bits.Present) {
+       DEBUG((DEBUG_WARN, "ERROR bad PDPE for %lx\n", PhysicalAddress));
+       return EFI_NO_MAPPING;
+    }
+
+    // If the MustBe1 bit is not 1, it's not actually a 1GB entry
+    if (PageDirectory1GEntry->Bits.MustBe1) {
+      // Valid 1GB page
+      // If we have at least 1GB to go, we can just update this entry
+      if (!(PhysicalAddress & ((1<<30) - 1)) && Length >= (1<<30)) {
+        SetOrClearCBit(&PageDirectory1GEntry->Uint64, Mode);
+        DEBUG((DEBUG_VERBOSE, "Updated 1GB entry for %lx\n", PhysicalAddress));
+        PhysicalAddress += 1<<30;
+        Length -= 1<<30;
+      } else {
+        // We must split the page
+        DEBUG((DEBUG_VERBOSE, "Spliting 1GB page\n"));
+        Split1GPageTo2M(((UINT64)PageDirectory1GEntry->Bits.PageTableBaseAddress)<<30, (UINT64*) PageDirectory1GEntry, 0, 0);
+        continue;
+      }
+    } else {
+      // Actually a PDP
+      PageUpperDirectoryPointerEntry = (PAGE_MAP_AND_DIRECTORY_POINTER*) PageDirectory1GEntry;
+      PageDirectory2MEntry = (VOID*) (PageUpperDirectoryPointerEntry->Bits.PageTableBaseAddress<<12 & ~PgTableMask);
+      PageDirectory2MEntry += PDE_OFFSET(PhysicalAddress);
+      if (!PageDirectory2MEntry->Bits.Present) {
+        DEBUG((DEBUG_WARN, "ERROR bad PDE for %lx\n", PhysicalAddress));
+        return EFI_NO_MAPPING;
+      }
+      // If the MustBe1 bit is not a 1, it's not a 2MB entry
+      if (PageDirectory2MEntry->Bits.MustBe1) {
+        // Valid 2MB page
+        // If we have at least 2MB left to go, we can just update this entry
+        if (!(PhysicalAddress & ((1<<21)-1)) && Length >= (1<<21)) {
+          SetOrClearCBit(&PageDirectory2MEntry->Uint64, Mode);
+          DEBUG((DEBUG_VERBOSE, "Updated 2MB entry for %lx\n", PhysicalAddress));
+          PhysicalAddress += 1<<21;
+          Length -= 1<<21;
+        } else {
+          // We must split up this page into 4K pages
+          DEBUG((DEBUG_VERBOSE, "Spliting 2MB page at %lx\n", PhysicalAddress));
+          Split2MPageTo4K(((UINT64)PageDirectory2MEntry->Bits.PageTableBaseAddress) << 21, (UINT64*) PageDirectory2MEntry, 0, 0);
+          continue;
+        }
+      } else {
+        PageDirectoryPointerEntry = (PAGE_MAP_AND_DIRECTORY_POINTER*) PageDirectory2MEntry;
+        PageTableEntry = (VOID*) (PageDirectoryPointerEntry->Bits.PageTableBaseAddress<<12 & ~PgTableMask);
+        PageTableEntry += PTE_OFFSET(PhysicalAddress);
+        if (!PageTableEntry->Bits.Present) {
+          DEBUG((DEBUG_WARN, "ERROR bad PTE for %lx\n", PhysicalAddress));
+          return EFI_NO_MAPPING;
+        }
+        SetOrClearCBit(&PageTableEntry->Uint64, Mode);
+        DEBUG((DEBUG_VERBOSE, "Updated 4KB entry for %lx\n", PhysicalAddress));
+        PhysicalAddress += EFI_PAGE_SIZE;
+        Length -= EFI_PAGE_SIZE;
+      }
+    }
+  }
+
+  //
+  // Flush TLB
+  //
+  AsmWriteCr3(AsmReadCr3());
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+EFIAPI
+Set_Memory_Decrypted (
+  IN  EFI_PHYSICAL_ADDRESS     PhysicalAddress,
+  IN  UINT64                   Length
+  )
+{
+  return Set_Memory_Enc_Dec (PhysicalAddress, Length, ClearCBit);
+}
+
+EFI_STATUS
+EFIAPI
+Set_Memory_Encrypted (
+  IN  EFI_PHYSICAL_ADDRESS     PhysicalAddress,
+  IN  UINT64                   Length
+  )
+{
+  return Set_Memory_Enc_Dec (PhysicalAddress, Length, SetCBit);
+}
+
diff --git a/OvmfPkg/Library/BaseMemEncryptSevLib/X64/VirtualMemory.h b/OvmfPkg/Library/BaseMemEncryptSevLib/X64/VirtualMemory.h
new file mode 100644
index 0000000..a556211
--- /dev/null
+++ b/OvmfPkg/Library/BaseMemEncryptSevLib/X64/VirtualMemory.h
@@ -0,0 +1,158 @@
+/** @file
+ 
+  Virtual Memory Management Services to set or clear the memory encryption bit
+
+  References:
+    1) IA-32 Intel(R) Architecture Software Developer's Manual Volume 1:Basic Architecture, Intel
+    2) IA-32 Intel(R) Architecture Software Developer's Manual Volume 2:Instruction Set Reference, Intel
+    3) IA-32 Intel(R) Architecture Software Developer's Manual Volume 3:System Programmer's Guide, Intel
+
+Copyright (c) 2006 - 2016, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2017, AMD Incorporated. All rights reserved.<BR>
+
+This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution.  The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#ifndef __VIRTUAL_MEMORY__
+#define __VIRTUAL_MEMORY__
+
+#include <Uefi.h>
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/MemoryAllocationLib.h>
+//#include <Library/UefiBootServicesTableLib.h>
+//#include <Library/UefiRuntimeServicesTableLib.h>
+
+#include <Library/CacheMaintenanceLib.h>
+#define SYS_CODE64_SEL 0x38
+
+#pragma pack(1)
+
+//
+// Page-Map Level-4 Offset (PML4) and
+// Page-Directory-Pointer Offset (PDPE) entries 4K & 2MB
+//
+
+typedef union {
+  struct {
+    UINT64  Present:1;                // 0 = Not present in memory, 1 = Present in memory
+    UINT64  ReadWrite:1;              // 0 = Read-Only, 1= Read/Write
+    UINT64  UserSupervisor:1;         // 0 = Supervisor, 1=User
+    UINT64  WriteThrough:1;           // 0 = Write-Back caching, 1=Write-Through caching
+    UINT64  CacheDisabled:1;          // 0 = Cached, 1=Non-Cached
+    UINT64  Accessed:1;               // 0 = Not accessed, 1 = Accessed (set by CPU)
+    UINT64  Reserved:1;               // Reserved
+    UINT64  MustBeZero:2;             // Must Be Zero
+    UINT64  Available:3;              // Available for use by system software
+    UINT64  PageTableBaseAddress:40;  // Page Table Base Address
+    UINT64  AvabilableHigh:11;        // Available for use by system software
+    UINT64  Nx:1;                     // No Execute bit
+  } Bits;
+  UINT64    Uint64;
+} PAGE_MAP_AND_DIRECTORY_POINTER;
+
+//
+// Page Table Entry 4KB
+//
+typedef union {
+  struct {
+    UINT64  Present:1;                // 0 = Not present in memory, 1 = Present in memory
+    UINT64  ReadWrite:1;              // 0 = Read-Only, 1= Read/Write
+    UINT64  UserSupervisor:1;         // 0 = Supervisor, 1=User
+    UINT64  WriteThrough:1;           // 0 = Write-Back caching, 1=Write-Through caching
+    UINT64  CacheDisabled:1;          // 0 = Cached, 1=Non-Cached
+    UINT64  Accessed:1;               // 0 = Not accessed, 1 = Accessed (set by CPU)
+    UINT64  Dirty:1;                  // 0 = Not Dirty, 1 = written by processor on access to page
+    UINT64  PAT:1;                    //
+    UINT64  Global:1;                 // 0 = Not global page, 1 = global page TLB not cleared on CR3 write
+    UINT64  Available:3;              // Available for use by system software
+    UINT64  PageTableBaseAddress:40;  // Page Table Base Address
+    UINT64  AvabilableHigh:11;        // Available for use by system software
+    UINT64  Nx:1;                     // 0 = Execute Code, 1 = No Code Execution
+  } Bits;
+  UINT64    Uint64;
+} PAGE_TABLE_4K_ENTRY;
+
+//
+// Page Table Entry 2MB
+//
+typedef union {
+  struct {
+    UINT64  Present:1;                // 0 = Not present in memory, 1 = Present in memory
+    UINT64  ReadWrite:1;              // 0 = Read-Only, 1= Read/Write
+    UINT64  UserSupervisor:1;         // 0 = Supervisor, 1=User
+    UINT64  WriteThrough:1;           // 0 = Write-Back caching, 1=Write-Through caching
+    UINT64  CacheDisabled:1;          // 0 = Cached, 1=Non-Cached
+    UINT64  Accessed:1;               // 0 = Not accessed, 1 = Accessed (set by CPU)
+    UINT64  Dirty:1;                  // 0 = Not Dirty, 1 = written by processor on access to page
+    UINT64  MustBe1:1;                // Must be 1 
+    UINT64  Global:1;                 // 0 = Not global page, 1 = global page TLB not cleared on CR3 write
+    UINT64  Available:3;              // Available for use by system software
+    UINT64  PAT:1;                    //
+    UINT64  MustBeZero:8;             // Must be zero;
+    UINT64  PageTableBaseAddress:31;  // Page Table Base Address
+    UINT64  AvabilableHigh:11;        // Available for use by system software
+    UINT64  Nx:1;                     // 0 = Execute Code, 1 = No Code Execution
+  } Bits;
+  UINT64    Uint64;
+} PAGE_TABLE_ENTRY;
+
+//
+// Page Table Entry 1GB
+//
+typedef union {
+  struct {
+    UINT64  Present:1;                // 0 = Not present in memory, 1 = Present in memory
+    UINT64  ReadWrite:1;              // 0 = Read-Only, 1= Read/Write
+    UINT64  UserSupervisor:1;         // 0 = Supervisor, 1=User
+    UINT64  WriteThrough:1;           // 0 = Write-Back caching, 1=Write-Through caching
+    UINT64  CacheDisabled:1;          // 0 = Cached, 1=Non-Cached
+    UINT64  Accessed:1;               // 0 = Not accessed, 1 = Accessed (set by CPU)
+    UINT64  Dirty:1;                  // 0 = Not Dirty, 1 = written by processor on access to page
+    UINT64  MustBe1:1;                // Must be 1 
+    UINT64  Global:1;                 // 0 = Not global page, 1 = global page TLB not cleared on CR3 write
+    UINT64  Available:3;              // Available for use by system software
+    UINT64  PAT:1;                    //
+    UINT64  MustBeZero:17;            // Must be zero;
+    UINT64  PageTableBaseAddress:22;  // Page Table Base Address
+    UINT64  AvabilableHigh:11;        // Available for use by system software
+    UINT64  Nx:1;                     // 0 = Execute Code, 1 = No Code Execution
+  } Bits;
+  UINT64    Uint64;
+} PAGE_TABLE_1G_ENTRY;
+
+#pragma pack()
+
+#define IA32_PG_P                   BIT0
+#define IA32_PG_RW                  BIT1
+
+#define PAGETABLE_ENTRY_MASK        ((1UL << 9) - 1) 
+#define PML4_OFFSET(x)              ( (x >> 39) & PAGETABLE_ENTRY_MASK) 
+#define PDP_OFFSET(x)               ( (x >> 30) & PAGETABLE_ENTRY_MASK) 
+#define PDE_OFFSET(x)               ( (x >> 21) & PAGETABLE_ENTRY_MASK) 
+#define PTE_OFFSET(x)               ( (x >> 12) & PAGETABLE_ENTRY_MASK) 
+#define PAGING_1G_ADDRESS_MASK_64   0x000FFFFFC0000000ull
+
+EFI_STATUS
+EFIAPI
+Set_Memory_Decrypted (
+  IN  EFI_PHYSICAL_ADDRESS     PhysicalAddress,
+  IN  UINT64                   Length
+  );
+
+EFI_STATUS
+EFIAPI
+Set_Memory_Encrypted (
+  IN  EFI_PHYSICAL_ADDRESS     PhysicalAddress,
+  IN  UINT64                   Length
+  );
+
+#endif
diff --git a/OvmfPkg/OvmfPkgIa32.dsc b/OvmfPkg/OvmfPkgIa32.dsc
index 769251d..c2821b7 100644
--- a/OvmfPkg/OvmfPkgIa32.dsc
+++ b/OvmfPkg/OvmfPkgIa32.dsc
@@ -126,6 +126,7 @@
   QemuFwCfgLib|OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgLib.inf
   VirtioLib|OvmfPkg/Library/VirtioLib/VirtioLib.inf
   LoadLinuxLib|OvmfPkg/Library/LoadLinuxLib/LoadLinuxLib.inf
+  MemEncryptSevLib|OvmfPkg/Library/BaseMemEncryptSevLib/BaseMemEncryptSevLib.inf
 !if $(SMM_REQUIRE) == FALSE
   LockBoxLib|OvmfPkg/Library/LockBoxLib/LockBoxBaseLib.inf
 !endif
diff --git a/OvmfPkg/OvmfPkgIa32X64.dsc b/OvmfPkg/OvmfPkgIa32X64.dsc
index 3874c35..1dd8064 100644
--- a/OvmfPkg/OvmfPkgIa32X64.dsc
+++ b/OvmfPkg/OvmfPkgIa32X64.dsc
@@ -131,6 +131,7 @@
   QemuFwCfgLib|OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgLib.inf
   VirtioLib|OvmfPkg/Library/VirtioLib/VirtioLib.inf
   LoadLinuxLib|OvmfPkg/Library/LoadLinuxLib/LoadLinuxLib.inf
+  MemEncryptSevLib|OvmfPkg/Library/BaseMemEncryptSevLib/BaseMemEncryptSevLib.inf
 !if $(SMM_REQUIRE) == FALSE
   LockBoxLib|OvmfPkg/Library/LockBoxLib/LockBoxBaseLib.inf
 !endif
diff --git a/OvmfPkg/OvmfPkgX64.dsc b/OvmfPkg/OvmfPkgX64.dsc
index fe7f086..06bee32 100644
--- a/OvmfPkg/OvmfPkgX64.dsc
+++ b/OvmfPkg/OvmfPkgX64.dsc
@@ -131,6 +131,7 @@
   QemuFwCfgLib|OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgLib.inf
   VirtioLib|OvmfPkg/Library/VirtioLib/VirtioLib.inf
   LoadLinuxLib|OvmfPkg/Library/LoadLinuxLib/LoadLinuxLib.inf
+  MemEncryptSevLib|OvmfPkg/Library/BaseMemEncryptSevLib/BaseMemEncryptSevLib.inf
 !if $(SMM_REQUIRE) == FALSE
   LockBoxLib|OvmfPkg/Library/LockBoxLib/LockBoxBaseLib.inf
 !endif



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

* [RFC PATCH v2 05/10] OvmfPkg/DxeBmDmaLib: Import DxeBmDmaLib package
  2017-03-21 21:12 [RESEND] [RFC PATCH v2 00/10] x86: Secure Encrypted Virtualization (AMD) Brijesh Singh
                   ` (3 preceding siblings ...)
  2017-03-21 21:13 ` [RFC PATCH v2 04/10] OvmfPkg/BaseMemcryptSevLib: Add SEV helper library Brijesh Singh
@ 2017-03-21 21:13 ` Brijesh Singh
  2017-03-27  9:22   ` Laszlo Ersek
  2017-03-21 21:13 ` [RFC PATCH v2 06/10] OvmfPkg/DxeBmDmaLib: Fix AllocateBounceBuffer parameter Brijesh Singh
                   ` (4 subsequent siblings)
  9 siblings, 1 reply; 44+ messages in thread
From: Brijesh Singh @ 2017-03-21 21:13 UTC (permalink / raw)
  To: michael.d.kinney, jordan.l.justen, edk2-devel, lersek, liming.gao
  Cc: leo.duran, brijesh.singh, Thomas.Lendacky

Import DxeBmDmaLib package in OvmfPkg, we need to modify the package to
include SEV support.

The BmDmaLib is proposed by Leo Duran
https://lists.01.org/pipermail/edk2-devel/2017-March/008109.html

Signed-off-by: Brijesh Singh <brijesh.singh@amd.com>
---
 OvmfPkg/Include/Library/BmDmaLib.h               |    0 
 OvmfPkg/Library/DxeBmDmaLib/DxeBmDmaLib.c        |    0 
 OvmfPkg/Library/DxeBmDmaLib/DxeBmDmaLib.inf      |    0 
 OvmfPkg/OvmfPkgIa32.dsc                          |    2 +-
 OvmfPkg/OvmfPkgIa32X64.dsc                       |    2 +-
 OvmfPkg/OvmfPkgX64.dsc                           |    2 +-
 6 files changed, 3 insertions(+), 3 deletions(-)
 copy MdeModulePkg/Include/Library/BmDmaLib.h => OvmfPkg/Include/Library/BmDmaLib.h (100%)
 copy MdeModulePkg/Library/DxeBmDmaLib/DxeBmDmaLib.c => OvmfPkg/Library/DxeBmDmaLib/DxeBmDmaLib.c (100%)
 copy MdeModulePkg/Library/DxeBmDmaLib/DxeBmDmaLib.inf => OvmfPkg/Library/DxeBmDmaLib/DxeBmDmaLib.inf (100%)

diff --git a/MdeModulePkg/Include/Library/BmDmaLib.h b/OvmfPkg/Include/Library/BmDmaLib.h
similarity index 100%
copy from MdeModulePkg/Include/Library/BmDmaLib.h
copy to OvmfPkg/Include/Library/BmDmaLib.h
diff --git a/MdeModulePkg/Library/DxeBmDmaLib/DxeBmDmaLib.c b/OvmfPkg/Library/DxeBmDmaLib/DxeBmDmaLib.c
similarity index 100%
copy from MdeModulePkg/Library/DxeBmDmaLib/DxeBmDmaLib.c
copy to OvmfPkg/Library/DxeBmDmaLib/DxeBmDmaLib.c
diff --git a/MdeModulePkg/Library/DxeBmDmaLib/DxeBmDmaLib.inf b/OvmfPkg/Library/DxeBmDmaLib/DxeBmDmaLib.inf
similarity index 100%
copy from MdeModulePkg/Library/DxeBmDmaLib/DxeBmDmaLib.inf
copy to OvmfPkg/Library/DxeBmDmaLib/DxeBmDmaLib.inf
diff --git a/OvmfPkg/OvmfPkgIa32.dsc b/OvmfPkg/OvmfPkgIa32.dsc
index c2821b7..58d6c3d 100644
--- a/OvmfPkg/OvmfPkgIa32.dsc
+++ b/OvmfPkg/OvmfPkgIa32.dsc
@@ -91,7 +91,7 @@
   UefiHiiServicesLib|MdeModulePkg/Library/UefiHiiServicesLib/UefiHiiServicesLib.inf
   HiiLib|MdeModulePkg/Library/UefiHiiLib/UefiHiiLib.inf
   SortLib|MdeModulePkg/Library/UefiSortLib/UefiSortLib.inf
-  BmDmaLib|MdeModulePkg/Library/DxeBmDmaLib/DxeBmDmaLib.inf
+  BmDmaLib|OvmfPkg/Library/DxeBmDmaLib/DxeBmDmaLib.inf
   UefiBootManagerLib|MdeModulePkg/Library/UefiBootManagerLib/UefiBootManagerLib.inf
   BootLogoLib|MdeModulePkg/Library/BootLogoLib/BootLogoLib.inf
   FileExplorerLib|MdeModulePkg/Library/FileExplorerLib/FileExplorerLib.inf
diff --git a/OvmfPkg/OvmfPkgIa32X64.dsc b/OvmfPkg/OvmfPkgIa32X64.dsc
index 1dd8064..ac2ef24 100644
--- a/OvmfPkg/OvmfPkgIa32X64.dsc
+++ b/OvmfPkg/OvmfPkgIa32X64.dsc
@@ -96,7 +96,7 @@
   UefiHiiServicesLib|MdeModulePkg/Library/UefiHiiServicesLib/UefiHiiServicesLib.inf
   HiiLib|MdeModulePkg/Library/UefiHiiLib/UefiHiiLib.inf
   SortLib|MdeModulePkg/Library/UefiSortLib/UefiSortLib.inf
-  BmDmaLib|MdeModulePkg/Library/DxeBmDmaLib/DxeBmDmaLib.inf
+  BmDmaLib|OvmfPkg/Library/DxeBmDmaLib/DxeBmDmaLib.inf
   UefiBootManagerLib|MdeModulePkg/Library/UefiBootManagerLib/UefiBootManagerLib.inf
   BootLogoLib|MdeModulePkg/Library/BootLogoLib/BootLogoLib.inf
   FileExplorerLib|MdeModulePkg/Library/FileExplorerLib/FileExplorerLib.inf
diff --git a/OvmfPkg/OvmfPkgX64.dsc b/OvmfPkg/OvmfPkgX64.dsc
index 06bee32..799f9e1 100644
--- a/OvmfPkg/OvmfPkgX64.dsc
+++ b/OvmfPkg/OvmfPkgX64.dsc
@@ -96,7 +96,7 @@
   UefiHiiServicesLib|MdeModulePkg/Library/UefiHiiServicesLib/UefiHiiServicesLib.inf
   HiiLib|MdeModulePkg/Library/UefiHiiLib/UefiHiiLib.inf
   SortLib|MdeModulePkg/Library/UefiSortLib/UefiSortLib.inf
-  BmDmaLib|MdeModulePkg/Library/DxeBmDmaLib/DxeBmDmaLib.inf
+  BmDmaLib|OvmfPkg/Library/DxeBmDmaLib/DxeBmDmaLib.inf
   UefiBootManagerLib|MdeModulePkg/Library/UefiBootManagerLib/UefiBootManagerLib.inf
   BootLogoLib|MdeModulePkg/Library/BootLogoLib/BootLogoLib.inf
   FileExplorerLib|MdeModulePkg/Library/FileExplorerLib/FileExplorerLib.inf



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

* [RFC PATCH v2 06/10] OvmfPkg/DxeBmDmaLib: Fix AllocateBounceBuffer parameter
  2017-03-21 21:12 [RESEND] [RFC PATCH v2 00/10] x86: Secure Encrypted Virtualization (AMD) Brijesh Singh
                   ` (4 preceding siblings ...)
  2017-03-21 21:13 ` [RFC PATCH v2 05/10] OvmfPkg/DxeBmDmaLib: Import DxeBmDmaLib package Brijesh Singh
@ 2017-03-21 21:13 ` Brijesh Singh
  2017-03-27  9:21   ` Laszlo Ersek
  2017-03-21 21:13 ` [RFC PATCH v2 07/10] OvmfPkg/BmDmaLib: Add SEV support Brijesh Singh
                   ` (3 subsequent siblings)
  9 siblings, 1 reply; 44+ messages in thread
From: Brijesh Singh @ 2017-03-21 21:13 UTC (permalink / raw)
  To: michael.d.kinney, jordan.l.justen, edk2-devel, lersek, liming.gao
  Cc: leo.duran, brijesh.singh, Thomas.Lendacky

The patch fixes AllocateBounceBuffer parameters.

Signed-off-by: Brijesh Singh <brijesh.singh@amd.com>
---
 OvmfPkg/Library/DxeBmDmaLib/DxeBmDmaLib.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/OvmfPkg/Library/DxeBmDmaLib/DxeBmDmaLib.c b/OvmfPkg/Library/DxeBmDmaLib/DxeBmDmaLib.c
index a342c9e..0d960a8 100644
--- a/OvmfPkg/Library/DxeBmDmaLib/DxeBmDmaLib.c
+++ b/OvmfPkg/Library/DxeBmDmaLib/DxeBmDmaLib.c
@@ -192,8 +192,8 @@ BmDmaMap (
   }
 
   return AllocateBounceBuffer ( 
-           Operation,
            FORCE_BELOW_4GB_TRUE,   
+           Operation,
            PhysicalAddress,
            NumberOfBytes,
            DeviceAddress,



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

* [RFC PATCH v2 07/10] OvmfPkg/BmDmaLib: Add SEV support
  2017-03-21 21:12 [RESEND] [RFC PATCH v2 00/10] x86: Secure Encrypted Virtualization (AMD) Brijesh Singh
                   ` (5 preceding siblings ...)
  2017-03-21 21:13 ` [RFC PATCH v2 06/10] OvmfPkg/DxeBmDmaLib: Fix AllocateBounceBuffer parameter Brijesh Singh
@ 2017-03-21 21:13 ` Brijesh Singh
  2017-03-27  9:28   ` Laszlo Ersek
  2017-03-21 21:13 ` [RFC PATCH v2 08/10] OvmfPkg/QemuFwCfgLib: Provide Pei and Dxe specific library support Brijesh Singh
                   ` (2 subsequent siblings)
  9 siblings, 1 reply; 44+ messages in thread
From: Brijesh Singh @ 2017-03-21 21:13 UTC (permalink / raw)
  To: michael.d.kinney, jordan.l.justen, edk2-devel, lersek, liming.gao
  Cc: leo.duran, brijesh.singh, Thomas.Lendacky

When SEV is enabled, the DMA operations must be performed on a shared
(i.e unencrypted) pages. The patch adds SEV specific hooks to use the
bounce buffer when caller map/unmap host address to a DMA address and
similarly clears/set memory encryption attribute when caller allocates or
free the DMA pages.

Signed-off-by: Brijesh Singh <brijesh.singh@amd.com>
---
 OvmfPkg/Library/DxeBmDmaLib/DxeBmDmaLib.c   |   60 +++++++++++++++++++++++++++
 OvmfPkg/Library/DxeBmDmaLib/DxeBmDmaLib.inf |    3 +
 2 files changed, 61 insertions(+), 2 deletions(-)

diff --git a/OvmfPkg/Library/DxeBmDmaLib/DxeBmDmaLib.c b/OvmfPkg/Library/DxeBmDmaLib/DxeBmDmaLib.c
index 0d960a8..39814cc 100644
--- a/OvmfPkg/Library/DxeBmDmaLib/DxeBmDmaLib.c
+++ b/OvmfPkg/Library/DxeBmDmaLib/DxeBmDmaLib.c
@@ -25,6 +25,7 @@
 #include <Library/MemoryAllocationLib.h>
 #include <Library/UefiBootServicesTableLib.h>
 #include <Library/BmDmaLib.h>
+#include <Library/MemEncryptSevLib.h>
 
 
 #define FORCE_BELOW_4GB_TRUE   TRUE
@@ -100,6 +101,15 @@ AllocateBounceBuffer (
   }
 
   //
+  // Clear C-bit on DMA pages
+  //
+  if (MemEncryptSevIsEnabled ()) {
+    Status = MemEncryptSevClearPageEncMask (MapInfo->MappedHostAddress, MapInfo->NumberOfPages);
+    if (Status != EFI_SUCCESS) {
+      return Status;
+    }
+  }
+  //
   // If this is a read operation from the Bus Master's point of view,
   // then copy the contents of the real buffer into the mapped buffer
   // so the Bus Master can read the contents of the real buffer.
@@ -170,6 +180,23 @@ BmDmaMap (
 
   PhysicalAddress = (EFI_PHYSICAL_ADDRESS) (UINTN) HostAddress;
   if (DmaAbove4GB || (PhysicalAddress + *NumberOfBytes) <= SIZE_4GB) {
+
+    //
+    // When SEV is enabled the DMA operation must be performed on shared pages. We force to use the
+    // bounce buffer path which will take care of allocating shared Dma buffers mapping
+    //
+    if (MemEncryptSevIsEnabled () &&
+        (Operation == DmaOperationBusMasterRead || Operation == DmaOperationBusMasterWrite)) {
+      return AllocateBounceBuffer (
+                                   FORCE_BELOW_4GB_FALSE,
+                                   Operation,
+                                   PhysicalAddress,
+                                   NumberOfBytes,
+                                   DeviceAddress,
+                                   Mapping
+                                   );
+    }
+
     //
     // If we CAN handle DMA above 4GB or the transfer is below 4GB,
     // the DeviceAddress is simply the HostAddress
@@ -218,7 +245,8 @@ BmDmaUnmap (
   IN  VOID                 *Mapping
   )
 {
-  MAP_INFO  *MapInfo;
+  MAP_INFO           *MapInfo;
+  EFI_STATUS         Status;
 
   //
   // Check for invalid inputs
@@ -251,6 +279,17 @@ BmDmaUnmap (
   }
 
   //
+  // When SEV is enabled then Dma buffer allocate by bounce buffer have C-bit cleared,
+  // restore the C-bit before we release the resources
+  //
+  if (MemEncryptSevIsEnabled ()) {
+    Status = MemEncryptSevSetPageEncMask (MapInfo->MappedHostAddress, MapInfo->NumberOfPages);
+    if (Status != EFI_SUCCESS) {
+      return Status;
+    }
+  }
+
+  //
   // Free the mapped buffer and the MAP_INFO structure.
   //
   gBS->FreePages (MapInfo->MappedHostAddress, MapInfo->NumberOfPages);
@@ -322,8 +361,15 @@ BmDmaAllocateBuffer (
                   );
   if (!EFI_ERROR (Status)) {
     *HostAddress = (VOID *) (UINTN) PhysicalAddress;
+    //
+    // Clear C-bit on Dma pages
+    //
+    if (MemEncryptSevIsEnabled ()) {
+      Status = MemEncryptSevClearPageEncMask (PhysicalAddress, Pages);
+    }
   }
 
+
   return Status;
 }
 
@@ -346,6 +392,18 @@ BmDmaFreeBuffer (
   IN  UINTN                Pages
   )
 {
+  EFI_STATUS           Status;
+
+  //
+  // Restore the C-bit on DMA pages
+  //
+  if (MemEncryptSevIsEnabled ()) {
+    Status = MemEncryptSevSetPageEncMask ((UINTN) HostAddress, Pages);
+    if (Status != EFI_SUCCESS) {
+      return Status;
+    }
+  }
+
   return gBS->FreePages ((EFI_PHYSICAL_ADDRESS) (UINTN) HostAddress, Pages);
 }
 
diff --git a/OvmfPkg/Library/DxeBmDmaLib/DxeBmDmaLib.inf b/OvmfPkg/Library/DxeBmDmaLib/DxeBmDmaLib.inf
index 4ddb27d..fb97caa 100644
--- a/OvmfPkg/Library/DxeBmDmaLib/DxeBmDmaLib.inf
+++ b/OvmfPkg/Library/DxeBmDmaLib/DxeBmDmaLib.inf
@@ -29,6 +29,7 @@
 [Packages]
   MdePkg/MdePkg.dec
   MdeModulePkg/MdeModulePkg.dec
+  OvmfPkg/OvmfPkg.dec
 
 [LibraryClasses]
   BaseLib
@@ -37,5 +38,5 @@
   DxeServicesTableLib
   MemoryAllocationLib
   UefiBootServicesTableLib
-
+  MemEncryptSevLib
 



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

* [RFC PATCH v2 08/10] OvmfPkg/QemuFwCfgLib: Provide Pei and Dxe specific library support
  2017-03-21 21:12 [RESEND] [RFC PATCH v2 00/10] x86: Secure Encrypted Virtualization (AMD) Brijesh Singh
                   ` (6 preceding siblings ...)
  2017-03-21 21:13 ` [RFC PATCH v2 07/10] OvmfPkg/BmDmaLib: Add SEV support Brijesh Singh
@ 2017-03-21 21:13 ` Brijesh Singh
  2017-03-27  9:41   ` Laszlo Ersek
  2017-03-21 21:13 ` [RFC PATCH v2 09/10] OvmfPkg/QemuFwCfgLib: Add Secure Encrypted Virtualization (SEV) support Brijesh Singh
  2017-03-21 21:13 ` [RFC PATCH v2 10/10] OvmfPkg/QemuVideoDxe: Clear the C-bit from framebuffer region when SEV is enabled Brijesh Singh
  9 siblings, 1 reply; 44+ messages in thread
From: Brijesh Singh @ 2017-03-21 21:13 UTC (permalink / raw)
  To: michael.d.kinney, jordan.l.justen, edk2-devel, lersek, liming.gao
  Cc: leo.duran, brijesh.singh, Thomas.Lendacky

Current QemuFwCfgLib.inf is used in both Pei and Dxe phases. The patch adds
Pei and Dxe inf file to provide a seperate QemuFwCfg library for Pei and Dxe
phases. There is no code change in this patch other than rearranging the files
and updating inf files.

The patch is precursor to add SEV support in QemuFwCfgLib, When SEV guest is
enabled then in Pei phase we support IO operation but in Dxe phase we can
support both IO and DMA operations.

Signed-off-by: Brijesh Singh <brijesh.singh@amd.com>
---
 OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgDxe.c      |    0 
 OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgDxeLib.inf |    6 +++---
 OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgPei.c      |    0 
 OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgPeiLib.inf |    6 +++---
 OvmfPkg/OvmfPkgIa32.dsc                          |    4 +++-
 OvmfPkg/OvmfPkgIa32X64.dsc                       |    4 +++-
 OvmfPkg/OvmfPkgX64.dsc                           |    4 +++-
 7 files changed, 15 insertions(+), 9 deletions(-)
 copy OvmfPkg/Library/QemuFwCfgLib/{QemuFwCfgPeiDxe.c => QemuFwCfgDxe.c} (100%)
 copy OvmfPkg/Library/QemuFwCfgLib/{QemuFwCfgLib.inf => QemuFwCfgDxeLib.inf} (83%)
 rename OvmfPkg/Library/QemuFwCfgLib/{QemuFwCfgPeiDxe.c => QemuFwCfgPei.c} (100%)
 rename OvmfPkg/Library/QemuFwCfgLib/{QemuFwCfgLib.inf => QemuFwCfgPeiLib.inf} (83%)

diff --git a/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgPeiDxe.c b/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgDxe.c
similarity index 100%
copy from OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgPeiDxe.c
copy to OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgDxe.c
diff --git a/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgLib.inf b/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgDxeLib.inf
similarity index 83%
copy from OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgLib.inf
copy to OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgDxeLib.inf
index 6894760..346bb88 100644
--- a/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgLib.inf
+++ b/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgDxeLib.inf
@@ -19,10 +19,10 @@
 [Defines]
   INF_VERSION                    = 0x00010005
   BASE_NAME                      = QemuFwCfgLib
-  FILE_GUID                      = fdd53716-31e1-4acc-9007-8bd5d877c96f
+  FILE_GUID                      = 80474090-55e7-4c28-b25c-9f236ba41f28
   MODULE_TYPE                    = BASE
   VERSION_STRING                 = 1.0
-  LIBRARY_CLASS                  = QemuFwCfgLib|PEIM DXE_DRIVER DXE_RUNTIME_DRIVER DXE_SMM_DRIVER
+  LIBRARY_CLASS                  = QemuFwCfgLib|DXE_DRIVER DXE_RUNTIME_DRIVER DXE_SMM_DRIVER
 
   CONSTRUCTOR                    = QemuFwCfgInitialize
 
@@ -35,7 +35,7 @@
 [Sources]
   QemuFwCfgLibInternal.h
   QemuFwCfgLib.c
-  QemuFwCfgPeiDxe.c
+  QemuFwCfgDxe.c
 
 [Packages]
   MdePkg/MdePkg.dec
diff --git a/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgPeiDxe.c b/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgPei.c
similarity index 100%
rename from OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgPeiDxe.c
rename to OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgPei.c
diff --git a/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgLib.inf b/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgPeiLib.inf
similarity index 83%
rename from OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgLib.inf
rename to OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgPeiLib.inf
index 6894760..4f966a8 100644
--- a/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgLib.inf
+++ b/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgPeiLib.inf
@@ -19,10 +19,10 @@
 [Defines]
   INF_VERSION                    = 0x00010005
   BASE_NAME                      = QemuFwCfgLib
-  FILE_GUID                      = fdd53716-31e1-4acc-9007-8bd5d877c96f
+  FILE_GUID                      = ddd4f5f0-5304-42a8-9efa-d14bf11a3533
   MODULE_TYPE                    = BASE
   VERSION_STRING                 = 1.0
-  LIBRARY_CLASS                  = QemuFwCfgLib|PEIM DXE_DRIVER DXE_RUNTIME_DRIVER DXE_SMM_DRIVER
+  LIBRARY_CLASS                  = QemuFwCfgLib|PEIM
 
   CONSTRUCTOR                    = QemuFwCfgInitialize
 
@@ -35,7 +35,7 @@
 [Sources]
   QemuFwCfgLibInternal.h
   QemuFwCfgLib.c
-  QemuFwCfgPeiDxe.c
+  QemuFwCfgPei.c
 
 [Packages]
   MdePkg/MdePkg.dec
diff --git a/OvmfPkg/OvmfPkgIa32.dsc b/OvmfPkg/OvmfPkgIa32.dsc
index 58d6c3d..3e94295 100644
--- a/OvmfPkg/OvmfPkgIa32.dsc
+++ b/OvmfPkg/OvmfPkgIa32.dsc
@@ -123,7 +123,7 @@
   DpcLib|MdeModulePkg/Library/DxeDpcLib/DxeDpcLib.inf
   UefiUsbLib|MdePkg/Library/UefiUsbLib/UefiUsbLib.inf
   SerializeVariablesLib|OvmfPkg/Library/SerializeVariablesLib/SerializeVariablesLib.inf
-  QemuFwCfgLib|OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgLib.inf
+  QemuFwCfgLib|OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgDxeLib.inf
   VirtioLib|OvmfPkg/Library/VirtioLib/VirtioLib.inf
   LoadLinuxLib|OvmfPkg/Library/LoadLinuxLib/LoadLinuxLib.inf
   MemEncryptSevLib|OvmfPkg/Library/BaseMemEncryptSevLib/BaseMemEncryptSevLib.inf
@@ -216,6 +216,7 @@
   DebugLib|OvmfPkg/Library/PlatformDebugLibIoPort/PlatformDebugLibIoPort.inf
 !endif
   PeCoffLib|MdePkg/Library/BasePeCoffLib/BasePeCoffLib.inf
+  QemuFwCfgLib|OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgPeiLib.inf
 
 [LibraryClasses.common.PEIM]
   HobLib|MdePkg/Library/PeiHobLib/PeiHobLib.inf
@@ -240,6 +241,7 @@
   CpuExceptionHandlerLib|UefiCpuPkg/Library/CpuExceptionHandlerLib/PeiCpuExceptionHandlerLib.inf
   MpInitLib|UefiCpuPkg/Library/MpInitLib/PeiMpInitLib.inf
   QemuFwCfgS3Lib|OvmfPkg/Library/QemuFwCfgS3Lib/PeiQemuFwCfgS3LibFwCfg.inf
+  QemuFwCfgLib|OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgPeiLib.inf
 
 [LibraryClasses.common.DXE_CORE]
   HobLib|MdePkg/Library/DxeCoreHobLib/DxeCoreHobLib.inf
diff --git a/OvmfPkg/OvmfPkgIa32X64.dsc b/OvmfPkg/OvmfPkgIa32X64.dsc
index ac2ef24..0b22229 100644
--- a/OvmfPkg/OvmfPkgIa32X64.dsc
+++ b/OvmfPkg/OvmfPkgIa32X64.dsc
@@ -128,7 +128,7 @@
   DpcLib|MdeModulePkg/Library/DxeDpcLib/DxeDpcLib.inf
   UefiUsbLib|MdePkg/Library/UefiUsbLib/UefiUsbLib.inf
   SerializeVariablesLib|OvmfPkg/Library/SerializeVariablesLib/SerializeVariablesLib.inf
-  QemuFwCfgLib|OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgLib.inf
+  QemuFwCfgLib|OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgDxeLib.inf
   VirtioLib|OvmfPkg/Library/VirtioLib/VirtioLib.inf
   LoadLinuxLib|OvmfPkg/Library/LoadLinuxLib/LoadLinuxLib.inf
   MemEncryptSevLib|OvmfPkg/Library/BaseMemEncryptSevLib/BaseMemEncryptSevLib.inf
@@ -221,6 +221,7 @@
   DebugLib|OvmfPkg/Library/PlatformDebugLibIoPort/PlatformDebugLibIoPort.inf
 !endif
   PeCoffLib|MdePkg/Library/BasePeCoffLib/BasePeCoffLib.inf
+  QemuFwCfgLib|OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgPeiLib.inf
 
 [LibraryClasses.common.PEIM]
   HobLib|MdePkg/Library/PeiHobLib/PeiHobLib.inf
@@ -245,6 +246,7 @@
   CpuExceptionHandlerLib|UefiCpuPkg/Library/CpuExceptionHandlerLib/PeiCpuExceptionHandlerLib.inf
   MpInitLib|UefiCpuPkg/Library/MpInitLib/PeiMpInitLib.inf
   QemuFwCfgS3Lib|OvmfPkg/Library/QemuFwCfgS3Lib/PeiQemuFwCfgS3LibFwCfg.inf
+  QemuFwCfgLib|OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgPeiLib.inf
 
 [LibraryClasses.common.DXE_CORE]
   HobLib|MdePkg/Library/DxeCoreHobLib/DxeCoreHobLib.inf
diff --git a/OvmfPkg/OvmfPkgX64.dsc b/OvmfPkg/OvmfPkgX64.dsc
index 799f9e1..01f3803 100644
--- a/OvmfPkg/OvmfPkgX64.dsc
+++ b/OvmfPkg/OvmfPkgX64.dsc
@@ -128,7 +128,7 @@
   DpcLib|MdeModulePkg/Library/DxeDpcLib/DxeDpcLib.inf
   UefiUsbLib|MdePkg/Library/UefiUsbLib/UefiUsbLib.inf
   SerializeVariablesLib|OvmfPkg/Library/SerializeVariablesLib/SerializeVariablesLib.inf
-  QemuFwCfgLib|OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgLib.inf
+  QemuFwCfgLib|OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgDxeLib.inf
   VirtioLib|OvmfPkg/Library/VirtioLib/VirtioLib.inf
   LoadLinuxLib|OvmfPkg/Library/LoadLinuxLib/LoadLinuxLib.inf
   MemEncryptSevLib|OvmfPkg/Library/BaseMemEncryptSevLib/BaseMemEncryptSevLib.inf
@@ -221,6 +221,7 @@
   DebugLib|OvmfPkg/Library/PlatformDebugLibIoPort/PlatformDebugLibIoPort.inf
 !endif
   PeCoffLib|MdePkg/Library/BasePeCoffLib/BasePeCoffLib.inf
+  QemuFwCfgLib|OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgPeiLib.inf
 
 [LibraryClasses.common.PEIM]
   HobLib|MdePkg/Library/PeiHobLib/PeiHobLib.inf
@@ -245,6 +246,7 @@
   CpuExceptionHandlerLib|UefiCpuPkg/Library/CpuExceptionHandlerLib/PeiCpuExceptionHandlerLib.inf
   MpInitLib|UefiCpuPkg/Library/MpInitLib/PeiMpInitLib.inf
   QemuFwCfgS3Lib|OvmfPkg/Library/QemuFwCfgS3Lib/PeiQemuFwCfgS3LibFwCfg.inf
+  QemuFwCfgLib|OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgPeiLib.inf
 
 [LibraryClasses.common.DXE_CORE]
   HobLib|MdePkg/Library/DxeCoreHobLib/DxeCoreHobLib.inf



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

* [RFC PATCH v2 09/10] OvmfPkg/QemuFwCfgLib: Add Secure Encrypted Virtualization (SEV) support
  2017-03-21 21:12 [RESEND] [RFC PATCH v2 00/10] x86: Secure Encrypted Virtualization (AMD) Brijesh Singh
                   ` (7 preceding siblings ...)
  2017-03-21 21:13 ` [RFC PATCH v2 08/10] OvmfPkg/QemuFwCfgLib: Provide Pei and Dxe specific library support Brijesh Singh
@ 2017-03-21 21:13 ` Brijesh Singh
  2017-03-27 10:19   ` Laszlo Ersek
  2017-03-21 21:13 ` [RFC PATCH v2 10/10] OvmfPkg/QemuVideoDxe: Clear the C-bit from framebuffer region when SEV is enabled Brijesh Singh
  9 siblings, 1 reply; 44+ messages in thread
From: Brijesh Singh @ 2017-03-21 21:13 UTC (permalink / raw)
  To: michael.d.kinney, jordan.l.justen, edk2-devel, lersek, liming.gao
  Cc: leo.duran, brijesh.singh, Thomas.Lendacky

The patch adds SEV support in QemuFwCfgLib. When SEV is enabled:

 * Pei phase support IO-style operations. This is mainly because we need to
   use a bounce buffer inorder to support DMA operation. Allocate a memory
   for bounce buffer can get painful in Pei phase hence if we detect FWCfg DMA
   support then silently fallback to IO.

* Dxe phase supports both IO and DMA style operations.
---
 OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgDxe.c        |   73 +++++++++++++
 OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgDxeLib.inf   |    2 
 OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgLib.c        |  112 ++++++++++++++++++++
 .../Library/QemuFwCfgLib/QemuFwCfgLibInternal.h    |   38 +++++++
 OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgPei.c        |   93 +++++++++++++++++
 OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgPeiLib.inf   |    2 
 OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgSec.c        |   82 +++++++++++++++
 7 files changed, 402 insertions(+)

diff --git a/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgDxe.c b/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgDxe.c
index ac05f4c..be8e945 100644
--- a/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgDxe.c
+++ b/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgDxe.c
@@ -4,6 +4,7 @@
 
   Copyright (C) 2013, Red Hat, Inc.
   Copyright (c) 2011 - 2013, Intel Corporation. All rights reserved.<BR>
+  Copyright (c) 2017, Advanced Micro Devices. All rights reserved.<BR>
 
   This program and the accompanying materials are licensed and made available
   under the terms and conditions of the BSD License which accompanies this
@@ -14,14 +15,34 @@
   WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 **/
 
+#include "Uefi.h"
+
+#include <Library/BaseLib.h>
 #include <Library/DebugLib.h>
 #include <Library/QemuFwCfgLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/MemEncryptSevLib.h>
+#include <Library/BmDmaLib.h>
 
 #include "QemuFwCfgLibInternal.h"
 
 STATIC BOOLEAN mQemuFwCfgSupported = FALSE;
 STATIC BOOLEAN mQemuFwCfgDmaSupported;
+STATIC BOOLEAN mQemuFwCfgSevIsEnabled = FALSE;
+
+/**
+ Returns a boolean indicating whether the SEV is enabled
 
+ @retval    TRUE    SEV is enabled
+ @retval    FALSE   SEV is not enabled
+**/
+BOOLEAN
+InternalQemuFwCfgSevIsEnabled (
+  VOID
+  )
+{
+  return mQemuFwCfgSevIsEnabled;
+}
 
 /**
   Returns a boolean indicating if the firmware configuration interface
@@ -79,6 +100,9 @@ QemuFwCfgInitialize (
     mQemuFwCfgDmaSupported = TRUE;
     DEBUG ((DEBUG_INFO, "QemuFwCfg interface (DMA) is supported.\n"));
   }
+
+  mQemuFwCfgSevIsEnabled = MemEncryptSevIsEnabled ();
+
   return RETURN_SUCCESS;
 }
 
@@ -114,3 +138,52 @@ InternalQemuFwCfgDmaIsAvailable (
 {
   return mQemuFwCfgDmaSupported;
 }
+
+/**
+ Allocate a bounce buffer for SEV DMA.
+
+  @param[in]     NumPage  Number of pages.
+  @param[out]    Buffer   Allocated DMA Buffer pointer
+
+**/
+VOID
+InternalQemuFwCfgSevDmaAllocateBuffer (
+  IN     UINT32   NumPages,
+  OUT    VOID     **Buffer
+  )
+{
+  EFI_STATUS  Status;
+
+  //
+  // Allocate DMA bounce buffer
+  //
+  Status = BmDmaAllocateBuffer (TRUE, EfiBootServicesData, NumPages, Buffer);
+  if (EFI_ERROR(Status)) {
+    DEBUG ((EFI_D_ERROR, "SEV: Failed to allocate bounce buffer %d pages\n", NumPages));
+    ASSERT_EFI_ERROR (Status);
+    CpuDeadLoop ();
+  }
+
+  DEBUG ((EFI_D_VERBOSE, "QemuFwCfgSevDma allocate buffer 0x%Lx Pages %d\n", (UINTN)Buffer, NumPages));
+}
+
+/**
+ Free the DMA buffer allocated using InternalQemuFwCfgSevDmaAllocateBuffer
+
+  @param[in]     NumPage  Number of pages.
+  @param[in]     Buffer   DMA Buffer pointer
+
+**/
+VOID
+InternalQemuFwCfgSevDmaFreeBuffer (
+  IN     VOID     *Buffer,
+  IN     UINT32   NumPages
+  )
+{
+  //
+  // Free the bounce buffer
+  //
+  DEBUG ((EFI_D_VERBOSE, "QemuFwCfgSevDma free buffer 0x%Lx Pages %d\n", (UINTN)Buffer, NumPages));
+  BmDmaFreeBuffer (Buffer, NumPages);
+}
+
diff --git a/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgDxeLib.inf b/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgDxeLib.inf
index 346bb88..536887f 100644
--- a/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgDxeLib.inf
+++ b/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgDxeLib.inf
@@ -47,4 +47,6 @@
   DebugLib
   IoLib
   MemoryAllocationLib
+  MemEncryptSevLib
+  BmDmaLib
 
diff --git a/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgLib.c b/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgLib.c
index 1bf725d..d2560a3 100644
--- a/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgLib.c
+++ b/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgLib.c
@@ -47,6 +47,111 @@ QemuFwCfgSelectItem (
 
 
 /**
+  Transfer an array of bytes, or skip a number of bytes, using the SEV DMA bounce
+  interface. The function is same as InternalQemuFwCfgDmaBytes with excpetion that
+  it uses bounce buffer
+
+  @param[in]     Size     Size in bytes to transfer or skip.
+
+  @param[in,out] HostBuffer Buffer to read data into or write data from. Ignored,
+                            and may be NULL, if Size is zero, or Control is
+                            FW_CFG_DMA_CTL_SKIP.
+
+  @param[in]     Control  One of the following:
+                          FW_CFG_DMA_CTL_WRITE - write to fw_cfg from Buffer.
+                          FW_CFG_DMA_CTL_READ  - read from fw_cfg into Buffer.
+                          FW_CFG_DMA_CTL_SKIP  - skip bytes in fw_cfg.
+**/
+VOID
+InternalQemuFwCfgSevDmaBytes (
+  IN     UINT32   Size,
+  IN OUT VOID     *HostBuffer OPTIONAL,
+  IN     UINT32   Control
+  )
+{
+  volatile FW_CFG_DMA_ACCESS *Access;
+  UINT32                     AccessHigh, AccessLow;
+  UINT32                     Status;
+  UINT32                     NumPages;
+  VOID                       *DmaBuffer, *Buffer;
+
+  //
+  // Calculate number of pages we need to allocate for this operation
+  //
+  if (Control == FW_CFG_DMA_CTL_SKIP) {
+    //
+    // Control data does not need the actual buffer
+    //
+    NumPages = EFI_SIZE_TO_PAGES (sizeof (*Access));
+  } else {
+    NumPages = EFI_SIZE_TO_PAGES (sizeof (*Access) + Size);
+  }
+
+  //
+  // Allocate DMA bounce buffer
+  //
+  InternalQemuFwCfgSevDmaAllocateBuffer (NumPages, &DmaBuffer);
+
+  Access = (FW_CFG_DMA_ACCESS *)DmaBuffer;
+  Buffer = DmaBuffer + sizeof(*Access);
+
+  Access->Control = SwapBytes32 (Control);
+  Access->Length  = SwapBytes32 (Size);
+  Access->Address = SwapBytes64 ((UINTN)Buffer);
+
+  //
+  // Copy data from Host buffer into DMA buffer
+  //
+  if (HostBuffer && (Control == FW_CFG_DMA_CTL_WRITE)) {
+    CopyMem (Buffer, HostBuffer, Size);
+  }
+
+  //
+  // Delimit the transfer from (a) modifications to Access, (b) in case of a
+  // write, from writes to Buffer by the caller.
+  //
+  MemoryFence ();
+
+  //
+  // Start the transfer.
+  //
+  AccessHigh = (UINT32)RShiftU64 ((UINTN)Access, 32);
+  AccessLow  = (UINT32)(UINTN)Access;
+  IoWrite32 (FW_CFG_IO_DMA_ADDRESS,     SwapBytes32 (AccessHigh));
+  IoWrite32 (FW_CFG_IO_DMA_ADDRESS + 4, SwapBytes32 (AccessLow));
+
+  //
+  // Don't look at Access->Control before starting the transfer.
+  //
+  MemoryFence ();
+
+  //
+  // Wait for the transfer to complete.
+  //
+  do {
+    Status = SwapBytes32 (Access->Control);
+    ASSERT ((Status & FW_CFG_DMA_CTL_ERROR) == 0);
+  } while (Status != 0);
+
+  //
+  // After a read, the caller will want to use Buffer.
+  //
+  MemoryFence ();
+
+  //
+  // Copy data from DMA buffer into Host Buffer
+  //
+  if (HostBuffer && (Control == FW_CFG_DMA_CTL_READ)) {
+    CopyMem (HostBuffer, Buffer, Size);
+  }
+
+  //
+  // Free the DMA bounce buffer
+  //
+  InternalQemuFwCfgSevDmaFreeBuffer (DmaBuffer, NumPages);
+}
+
+/**
   Transfer an array of bytes, or skip a number of bytes, using the DMA
   interface.
 
@@ -79,6 +184,13 @@ InternalQemuFwCfgDmaBytes (
     return;
   }
 
+  //
+  // When SEV is enabled then use SEV version of DmaReadWrite
+  //
+  if (InternalQemuFwCfgSevIsEnabled ()) {
+    return InternalQemuFwCfgSevDmaBytes (Size, Buffer, Control);
+  }
+
   Access.Control = SwapBytes32 (Control);
   Access.Length  = SwapBytes32 (Size);
   Access.Address = SwapBytes64 ((UINTN)Buffer);
diff --git a/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgLibInternal.h b/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgLibInternal.h
index 6e87c62..8e2ff45 100644
--- a/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgLibInternal.h
+++ b/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgLibInternal.h
@@ -2,6 +2,7 @@
   Internal interfaces specific to the QemuFwCfgLib instances in OvmfPkg.
 
   Copyright (C) 2016, Red Hat, Inc.
+  Copyright (C) 2017, Advanced Micro Devices.
 
   This program and the accompanying materials are licensed and made available
   under the terms and conditions of the BSD License which accompanies this
@@ -43,4 +44,41 @@ InternalQemuFwCfgDmaIsAvailable (
   VOID
   );
 
+/**
+ Returns a boolean indicating whether the SEV is enabled
+
+ @retval    TRUE    SEV is enabled
+ @retval    FALSE   SEV is not enabled
+**/
+BOOLEAN
+InternalQemuFwCfgSevIsEnabled (
+  VOID
+  );
+
+/**
+ Allocate a bounce buffer for SEV DMA.
+
+  @param[in]     NumPage  Number of pages.
+  @param[out]    Buffer   Allocated DMA Buffer pointer
+
+**/
+VOID
+InternalQemuFwCfgSevDmaAllocateBuffer (
+  IN     UINT32   NumPages,
+  OUT    VOID     **Buffer
+  );
+
+/**
+ Free the DMA buffer allocated using InternalQemuFwCfgSevDmaAllocateBuffer
+
+  @param[in]     NumPage  Number of pages.
+  @param[in]     Buffer   DMA Buffer pointer
+
+**/
+VOID
+InternalQemuFwCfgSevDmaFreeBuffer (
+  IN     VOID     *Buffer,
+  IN     UINT32   NumPages
+  );
+
 #endif
diff --git a/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgPei.c b/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgPei.c
index ac05f4c..3dc9270 100644
--- a/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgPei.c
+++ b/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgPei.c
@@ -4,6 +4,7 @@
 
   Copyright (C) 2013, Red Hat, Inc.
   Copyright (c) 2011 - 2013, Intel Corporation. All rights reserved.<BR>
+  Copyright (c) 2017, Advanced Micro Devices. All rights reserved.<BR>
 
   This program and the accompanying materials are licensed and made available
   under the terms and conditions of the BSD License which accompanies this
@@ -14,14 +15,55 @@
   WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 **/
 
+#include <Library/BaseLib.h>
 #include <Library/DebugLib.h>
 #include <Library/QemuFwCfgLib.h>
+#include <Register/Cpuid.h>
+#include <Register/AmdSevMap.h>
 
 #include "QemuFwCfgLibInternal.h"
 
 STATIC BOOLEAN mQemuFwCfgSupported = FALSE;
 STATIC BOOLEAN mQemuFwCfgDmaSupported;
 
+/**
+ Returns a boolean indicating whether the SEV is enabled
+
+ @retval    TRUE    SEV is enabled
+ @retval    FALSE   SEV is not enabled
+**/
+BOOLEAN
+InternalQemuFwCfgSevIsEnabled (
+  VOID
+  )
+{
+  UINT32 RegEax;
+  MSR_SEV_STATUS_REGISTER Msr;
+  CPUID_MEMORY_ENCRYPTION_INFO_EAX  Eax;
+
+  //
+  // Check if memory encryption leaf exist
+  //
+  AsmCpuid (CPUID_EXTENDED_FUNCTION, &RegEax, NULL, NULL, NULL);
+  if (RegEax >= CPUID_MEMORY_ENCRYPTION_INFO) {
+    //
+    // CPUID Fn8000_001F[EAX] Bit 1 (Sev supported)
+    //
+    AsmCpuid (CPUID_MEMORY_ENCRYPTION_INFO, &Eax.Uint32, NULL, NULL, NULL);
+
+    if (Eax.Bits.SevBit) {
+      //
+      // Check MSR_0xC0010131 Bit 0 (Sev Enabled)
+      //
+      Msr.Uint32 = AsmReadMsr32 (MSR_SEV_STATUS);
+      if (Msr.Bits.SevBit) {
+        return TRUE;
+      }
+    }
+  }
+
+  return FALSE;
+}
 
 /**
   Returns a boolean indicating if the firmware configuration interface
@@ -79,6 +121,17 @@ QemuFwCfgInitialize (
     mQemuFwCfgDmaSupported = TRUE;
     DEBUG ((DEBUG_INFO, "QemuFwCfg interface (DMA) is supported.\n"));
   }
+
+  //
+  // When SEV is enabled then we do not support DMA interface.
+  // This is because we need to use bounce buffer to support DMA operation in SEV guest.
+  // Allocating memory for bounce buffer can get painful in Pei phase
+  //
+  if (mQemuFwCfgDmaSupported && InternalQemuFwCfgSevIsEnabled ()) {
+    mQemuFwCfgDmaSupported = FALSE;
+    DEBUG ((DEBUG_INFO, "QemuFwCfg disabling DMA interface and defaulting to IO Port.\n"));
+  }
+
   return RETURN_SUCCESS;
 }
 
@@ -114,3 +167,43 @@ InternalQemuFwCfgDmaIsAvailable (
 {
   return mQemuFwCfgDmaSupported;
 }
+
+/**
+ Allocate a bounce buffer for SEV DMA.
+
+  @param[in]     NumPage  Number of pages.
+  @param[out]    Buffer   Allocated DMA Buffer pointer
+
+**/
+VOID
+InternalQemuFwCfgSevDmaAllocateBuffer (
+  IN     UINT32   NumPages,
+  OUT    VOID     **Buffer
+  )
+{
+  //
+  // We should never reach here
+  //
+  ASSERT (FALSE);
+  CpuDeadLoop ();
+}
+
+/**
+ Free the DMA buffer allocated using InternalQemuFwCfgSevDmaAllocateBuffer
+
+  @param[in]     NumPage  Number of pages.
+  @param[in]     Buffer   DMA Buffer pointer
+
+**/
+VOID
+InternalQemuFwCfgSevDmaFreeBuffer (
+  IN     VOID     *Buffer,
+  IN     UINT32   NumPages
+  )
+{
+  //
+  // We should never reach here
+  //
+  ASSERT (FALSE);
+  CpuDeadLoop ();
+}
diff --git a/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgPeiLib.inf b/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgPeiLib.inf
index 4f966a8..83cc0de 100644
--- a/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgPeiLib.inf
+++ b/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgPeiLib.inf
@@ -39,7 +39,9 @@
 
 [Packages]
   MdePkg/MdePkg.dec
+  MdeModulePkg/MdeModulePkg.dec
   OvmfPkg/OvmfPkg.dec
+  UefiCpuPkg/UefiCpuPkg.dec
 
 [LibraryClasses]
   BaseLib
diff --git a/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgSec.c b/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgSec.c
index 465ccbe..70b0a47 100644
--- a/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgSec.c
+++ b/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgSec.c
@@ -16,8 +16,11 @@
   WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 **/
 
+#include <Library/BaseLib.h>
 #include <Library/DebugLib.h>
 #include <Library/QemuFwCfgLib.h>
+#include <Register/Cpuid.h>
+#include <Register/AmdSevMap.h>
 
 #include "QemuFwCfgLibInternal.h"
 
@@ -94,3 +97,82 @@ InternalQemuFwCfgDmaIsAvailable (
 {
   return FALSE;
 }
+
+/**
+ Returns a boolean indicating whether the SEV is enabled
+
+ @retval    TRUE    SEV is enabled
+ @retval    FALSE   SEV is not enabled
+**/
+BOOLEAN
+InternalQemuFwCfgSevIsEnabled (
+  VOID
+  )
+{
+  UINT32 RegEax;
+  MSR_SEV_STATUS_REGISTER Msr;
+  CPUID_MEMORY_ENCRYPTION_INFO_EAX  Eax;
+
+  //
+  // Check if memory encryption leaf exist
+  //
+  AsmCpuid (CPUID_EXTENDED_FUNCTION, &RegEax, NULL, NULL, NULL);
+  if (RegEax >= CPUID_MEMORY_ENCRYPTION_INFO) {
+    //
+    // CPUID Fn8000_001F[EAX] Bit 1 (Sev supported)
+    //
+    AsmCpuid (CPUID_MEMORY_ENCRYPTION_INFO, &Eax.Uint32, NULL, NULL, NULL);
+
+    if (Eax.Bits.SevBit) {
+      //
+      // Check MSR_0xC0010131 Bit 0 (Sev Enabled)
+      //
+      Msr.Uint32 = AsmReadMsr32 (MSR_SEV_STATUS);
+      if (Msr.Bits.SevBit) {
+        return TRUE;
+      }
+    }
+  }
+
+  return FALSE;
+}
+
+/**
+ Allocate a bounce buffer for SEV DMA.
+
+  @param[in]     NumPage  Number of pages.
+  @param[out]    Buffer   Allocated DMA Buffer pointer
+
+**/
+VOID
+InternalQemuFwCfgSevDmaAllocateBuffer (
+  IN     UINT32   NumPages,
+  OUT    VOID     **Buffer
+  )
+{
+  //
+  // We should never reach here
+  //
+  ASSERT (FALSE);
+  CpuDeadLoop ();
+}
+
+/**
+ Free the DMA buffer allocated using InternalQemuFwCfgSevDmaAllocateBuffer
+
+  @param[in]     NumPage  Number of pages.
+  @param[in]     Buffer   DMA Buffer pointer
+
+**/
+VOID
+InternalQemuFwCfgSevDmaFreeBuffer (
+  IN     VOID     *Buffer,
+  IN     UINT32   NumPages
+  )
+{
+  //
+  // We should never reach here
+  //
+  ASSERT (FALSE);
+  CpuDeadLoop ();
+}



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

* [RFC PATCH v2 10/10] OvmfPkg/QemuVideoDxe: Clear the C-bit from framebuffer region when SEV is enabled
  2017-03-21 21:12 [RESEND] [RFC PATCH v2 00/10] x86: Secure Encrypted Virtualization (AMD) Brijesh Singh
                   ` (8 preceding siblings ...)
  2017-03-21 21:13 ` [RFC PATCH v2 09/10] OvmfPkg/QemuFwCfgLib: Add Secure Encrypted Virtualization (SEV) support Brijesh Singh
@ 2017-03-21 21:13 ` Brijesh Singh
  2017-03-27 10:29   ` Laszlo Ersek
  9 siblings, 1 reply; 44+ messages in thread
From: Brijesh Singh @ 2017-03-21 21:13 UTC (permalink / raw)
  To: michael.d.kinney, jordan.l.justen, edk2-devel, lersek, liming.gao
  Cc: leo.duran, brijesh.singh, Thomas.Lendacky

Since the framebuffer memory region is shared between the guest and hypervisor
hence we must clear the memory encryption bit from this memory region when SEV
is enabled.

Signed-off-by: Brijesh Singh <brijesh.singh@amd.com>
---
 OvmfPkg/QemuVideoDxe/Gop.c            |   15 +++++++++++++++
 OvmfPkg/QemuVideoDxe/QemuVideoDxe.inf |    1 +
 2 files changed, 16 insertions(+)

diff --git a/OvmfPkg/QemuVideoDxe/Gop.c b/OvmfPkg/QemuVideoDxe/Gop.c
index 359e921..96661d1 100644
--- a/OvmfPkg/QemuVideoDxe/Gop.c
+++ b/OvmfPkg/QemuVideoDxe/Gop.c
@@ -13,6 +13,8 @@
 
 **/
 
+#include <Library/MemEncryptSevLib.h>
+
 #include "Qemu.h"
 
 STATIC
@@ -65,6 +67,19 @@ QemuVideoCompleteModeData (
                         (VOID**) &FrameBufDesc
                         );
 
+  //
+  // Framebuffer memory region is shared between hypervisor and guest,
+  // Clear the memory encryption mask when SEV is active.
+  //
+  if (MemEncryptSevIsEnabled ()) {
+    EFI_STATUS Status;
+
+    Status = MemEncryptSevClearPageEncMask (FrameBufDesc->AddrRangeMin, EFI_SIZE_TO_PAGES (FrameBufDesc->AddrLen));
+    if (EFI_ERROR(Status)) {
+      DEBUG ((EFI_D_WARN, "Failed to clear memory encryption mask 0x%#Lx+0x%x\n", FrameBufDesc->AddrRangeMin, FrameBufDesc->AddrLen));
+    }
+  }
+
   Mode->FrameBufferBase = FrameBufDesc->AddrRangeMin;
   Mode->FrameBufferSize = Info->HorizontalResolution * Info->VerticalResolution;
   Mode->FrameBufferSize = Mode->FrameBufferSize * ((ModeData->ColorDepth + 7) / 8);
diff --git a/OvmfPkg/QemuVideoDxe/QemuVideoDxe.inf b/OvmfPkg/QemuVideoDxe/QemuVideoDxe.inf
index affb6ff..83ea86c 100644
--- a/OvmfPkg/QemuVideoDxe/QemuVideoDxe.inf
+++ b/OvmfPkg/QemuVideoDxe/QemuVideoDxe.inf
@@ -60,6 +60,7 @@
   UefiBootServicesTableLib
   UefiDriverEntryPoint
   UefiLib
+  MemEncryptSevLib
 
 [Protocols]
   gEfiDriverSupportedEfiVersionProtocolGuid     # PROTOCOL ALWAYS_PRODUCED



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

* Re: [RFC PATCH v2 01/10] OvmfPkg/Include: Define SEV specific CPUID and MSR
  2017-03-21 21:12 ` [RFC PATCH v2 01/10] OvmfPkg/Include: Define SEV specific CPUID and MSR Brijesh Singh
@ 2017-03-22 16:03   ` Laszlo Ersek
  2017-03-23  7:42     ` Fan, Jeff
  0 siblings, 1 reply; 44+ messages in thread
From: Laszlo Ersek @ 2017-03-22 16:03 UTC (permalink / raw)
  To: Brijesh Singh, michael.d.kinney, jordan.l.justen, edk2-devel,
	liming.gao, Jeff Fan
  Cc: brijesh.singh, leo.duran, Thomas.Lendacky

Adding Jeff

On 03/21/17 22:12, Brijesh Singh wrote:
> The patch defines AMD's Memory Encryption Information CPUID leaf (0x8000_001F).
> The complete description for this CPUID leaf is available in APM volume 2 [1]
> Section 15.34 (Secure Encrypted Virtualization).
> 
> [1] http://support.amd.com/TechDocs/24593.pdf
> 
> Signed-off-by: Brijesh Singh <brijesh.singh@amd.com>
> ---
>  OvmfPkg/Include/Register/AmdSevMap.h |  133 ++++++++++++++++++++++++++++++++++
>  1 file changed, 133 insertions(+)
>  create mode 100644 OvmfPkg/Include/Register/AmdSevMap.h
> 
> diff --git a/OvmfPkg/Include/Register/AmdSevMap.h b/OvmfPkg/Include/Register/AmdSevMap.h
> new file mode 100644
> index 0000000..de80f39
> --- /dev/null
> +++ b/OvmfPkg/Include/Register/AmdSevMap.h
> @@ -0,0 +1,133 @@
> +/** @file
> +
> +AMD Secure Encrypted Virtualization (SEV) specific CPUID and MSR definitions
> +
> +The complete description for this CPUID leaf is available in APM volume 2 (Section 15.34)
> +http://support.amd.com/TechDocs/24593.pdf
> +
> +Copyright (c) 2017, Advanced Micro Devices. All rights reserved.<BR>
> +
> +This program and the accompanying materials
> +are licensed and made available under the terms and conditions of the BSD License
> +which accompanies this distribution.  The full text of the license may be found at
> +http://opensource.org/licenses/bsd-license.php
> +
> +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
> +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
> +
> +**/
> +
> +#ifndef __AMD_SEV_MAP_H__
> +#define __AMD_SEV_MAP_H__
> +
> +#pragma pack (1)
> +
> +#define CPUID_MEMORY_ENCRYPTION_INFO             0x8000001F
> +
> +/**
> +  CPUID Memory Encryption support information EAX for CPUID leaf
> +  #CPUID_MEMORY_ENCRYPTION_INFO.
> +**/
> +typedef union {
> +  ///
> +  /// Individual bit fields
> +  ///
> +  struct {
> +    ///
> +    /// [Bit 0] Secure Memory Encryption (Sme) Support
> +    ///
> +    UINT32  SmeBit:1;
> +
> +    ///
> +    /// [Bit 1] Secure Encrypted Virtualization (Sev) Support
> +    ///
> +    UINT32  SevBit:1;
> +
> +    ///
> +    /// [Bit 2] Page flush MSR support
> +    ///
> +    UINT32  PageFlushMsrBit:1;
> +
> +    ///
> +    /// [Bit 3] Encrypted state support
> +    ///
> +    UINT32  SevEsBit:1;
> +
> +    ///
> +    /// [Bit 4:31] Reserved
> +    ///
> +    UINT32  ReservedBits:28;
> +  } Bits;
> +  ///
> +  /// All bit fields as a 32-bit value
> +  ///
> +  UINT32  Uint32;
> +} CPUID_MEMORY_ENCRYPTION_INFO_EAX;
> +
> +/**
> +  CPUID Memory Encryption support information EBX for CPUID leaf
> +  #CPUID_MEMORY_ENCRYPTION_INFO.
> +**/
> +typedef union {
> +  ///
> +  /// Individual bit fields
> +  ///
> +  struct {
> +    ///
> +    /// [Bit 0:5] Page table bit number used to enable memory encryption
> +    ///
> +    UINT32  PtePosBits:6;
> +
> +    ///
> +    /// [Bit 6:11] Reduction of system physical address space bits when memory encryption is enabled
> +    ///
> +    UINT32  ReducedPhysBits:5;
> +
> +    ///
> +    /// [Bit 12:31] Reserved
> +    ///
> +    UINT32  ReservedBits:21;
> +  } Bits;
> +  ///
> +  /// All bit fields as a 32-bit value
> +  ///
> +  UINT32  Uint32;
> +} CPUID_MEMORY_ENCRYPTION_INFO_EBX;
> +
> +/**
> +  Secure Encrypted Virtualization (SEV) status register
> +
> +**/
> +#define MSR_SEV_STATUS                     0xc0010131
> +
> +/**
> +  MSR information returned for #MSR_SEV_STATUS
> +**/
> +typedef union {
> +  ///
> +  /// Individual bit fields
> +  ///
> +  struct {
> +    ///
> +    /// [Bit 0] Secure Encrypted Virtualization (Sev) is enabled
> +    ///
> +    UINT32  SevBit:1;
> +
> +    ///
> +    /// [Bit 1] Secure Encrypted Virtualization Encrypted State (SevEs) is enabled
> +    ///
> +    UINT32  SevEsBit:1;
> +
> +    UINT32  Reserved:30;
> +  } Bits;
> +  ///
> +  /// All bit fields as a 32-bit value
> +  ///
> +  UINT32  Uint32;
> +  ///
> +  /// All bit fields as a 64-bit value
> +  ///
> +  UINT64  Uint64;
> +} MSR_SEV_STATUS_REGISTER;
> +
> +#endif
> 
> _______________________________________________
> edk2-devel mailing list
> edk2-devel@lists.01.org
> https://lists.01.org/mailman/listinfo/edk2-devel
> 

I feel that these definitions should be added to
"UefiCpuPkg/Include/Register/Cpuid.h", or else to another (new) header
file in that directory.

Jeff, what do you think?

Thanks!
Laszlo


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

* Re: [RFC PATCH v2 02/10] OvmfPkg/ResetVector: add memory encryption mask when SEV is enabled
  2017-03-21 21:12 ` [RFC PATCH v2 02/10] OvmfPkg/ResetVector: add memory encryption mask when SEV is enabled Brijesh Singh
@ 2017-03-22 20:20   ` Laszlo Ersek
  2017-03-23 15:05     ` Brijesh Singh
  0 siblings, 1 reply; 44+ messages in thread
From: Laszlo Ersek @ 2017-03-22 20:20 UTC (permalink / raw)
  To: Brijesh Singh, michael.d.kinney, jordan.l.justen, edk2-devel,
	liming.gao
  Cc: brijesh.singh, leo.duran, Thomas.Lendacky

On 03/21/17 22:12, Brijesh Singh wrote:
> SEV guest VMs have the concept of private and shared memory. Private
> memory is encrypted with the guest-specific key, while shared memory
> may be encrypted with hypervisor key. Certain types of memory (namely
> instruction pages and guest page tables) are always treated as private
> memory by the hardware. The C-bit in PTE indicate whether the page is
> private or shared. The C-bit position for the PTE can be obtained from
> CPUID Fn8000_001F[EBX].
> 
> When SEV is active, the BIOS is pre-encrypted by the Qemu launch sequence,
> we must set the C-bit when building the page table for 64-bit or 32-bit
> PAE mode.
> 
> Signed-off-by: Brijesh Singh <brijesh.singh@amd.com>
> ---
>  OvmfPkg/ResetVector/Ia32/PageTables64.asm |   62 +++++++++++++++++++++++++++++
>  1 file changed, 62 insertions(+)
> 
> diff --git a/OvmfPkg/ResetVector/Ia32/PageTables64.asm b/OvmfPkg/ResetVector/Ia32/PageTables64.asm
> index 6201cad..7083f6b 100644
> --- a/OvmfPkg/ResetVector/Ia32/PageTables64.asm
> +++ b/OvmfPkg/ResetVector/Ia32/PageTables64.asm
> @@ -37,6 +37,47 @@ BITS    32
>                         PAGE_READ_WRITE + \
>                         PAGE_PRESENT)
>  
> +; Check if Secure Encrypted Virtualization (SEV) feature
> +;  
> +;  If SEV is enabled, then EAX will contain Memory encryption bit position

I suggest to say, in the comment here, that a valid eax will be at least
32, and 0 on "SEV unavailable or disabled".

> +;
> +CheckSevFeature:
> +    xor       eax, eax

I think this xor may not be necessary (there's no path out of this
function that wouldn't set eax intentionally), but it doesn't hurt.

(Sorry if I should have noticed this in v1 -- there's no need to
resubmit just because of this.)

In the below logic, which branch exactly (to NoSev) will be taken on
Intel processors?

> +
> +    ; Check if we have a valid (0x8000_001F) CPUID leaf
> +    mov       eax, 0x80000000
> +    cpuid
> +    cmp       eax, 0x8000001f
> +    jl        NoSev
> +
> +    ; Check for memory encryption feature:
> +    ;  CPUID  Fn8000_001F[EAX] - Bit 1
> +    ;
> +    mov       eax,  0x8000001f
> +    cpuid
> +    bt        eax, 1
> +    jnc       NoSev
> +
> +    ; Check if memory encryption is enabled
> +    ;  MSR_0xC0010131 - Bit 0 (SEV enabled)
> +    ;  MSR_0xC0010131 - Bit 1 (SEV-ES enabled)
> +    mov       ecx, 0xc0010131
> +    rdmsr
> +    bt        eax, 0
> +    jnc       NoSev

Do we need to check SEV-ES specifically? bit1 is not tested.

> +
> +    ; Get pte bit position to enable memory encryption
> +    ; CPUID Fn8000_001F[EBX] - Bits 5:0
> +    ;
> +    mov       eax, ebx
> +    and       eax, 0x3f
> +    jmp       SevExit
> +
> +NoSev:
> +    xor       eax, eax
> +
> +SevExit:
> +    OneTimeCallRet CheckSevFeature
>  
>  ;
>  ; Modified:  EAX, ECX

Can you please update (or delete) this comment? I think EBX and EDX may
be modified too.

> @@ -60,18 +101,38 @@ clearPageTablesMemoryLoop:
>      mov     dword[ecx * 4 + PT_ADDR (0) - 4], eax
>      loop    clearPageTablesMemoryLoop
>  
> +    ; Check if its SEV-enabled Guest
> +    ;
> +    OneTimeCall   CheckSevFeature
> +    xor     edx, edx
> +    test    eax, eax
> +    jz      SevNotActive
> +
> +    ; If SEV is enabled, Memory encryption bit is always above 31
> +    mov     ebx, 32
> +    sub     ebx, eax

I apologize if I'm mistaken, but I think we want to decrease eax with 32
(i.e., with ebx), so that we get the C bit's position within the high
address (= more significant) DWORD of the PTE.

But, isn't the argument order for SUB reversed? To me the above seems to
imply EBX := EBX - EAX, which appears wrong.

... I think we could even say

  sub eax, 32

The rest looks good to me.

Thanks
Laszlo

> +    bts     edx, eax
> +
> +SevNotActive:
> +
> +    ;
>      ;
>      ; 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)
> @@ -83,6 +144,7 @@ pageTableEntriesLoop:
>      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
>  
>      ;
> 
> _______________________________________________
> edk2-devel mailing list
> edk2-devel@lists.01.org
> https://lists.01.org/mailman/listinfo/edk2-devel
> 



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

* Re: [RFC PATCH v2 01/10] OvmfPkg/Include: Define SEV specific CPUID and MSR
  2017-03-22 16:03   ` Laszlo Ersek
@ 2017-03-23  7:42     ` Fan, Jeff
  2017-03-23  9:19       ` Laszlo Ersek
  0 siblings, 1 reply; 44+ messages in thread
From: Fan, Jeff @ 2017-03-23  7:42 UTC (permalink / raw)
  To: Laszlo Ersek, Brijesh Singh, Kinney, Michael D, Justen, Jordan L,
	edk2-devel@ml01.01.org, Gao, Liming
  Cc: leo.duran@amd.com, brijesh.singh@amd.com, Thomas.Lendacky@amd.com

Laszlo,

UefiCpuPkg/Include/Register/Cpuid.h defined the CPUID only described in IA32 SDM.
UefiCpuPkg/Include/Register/ArchitecturalMsr.h defined the IA32 Architectural MSRs in IA32 SDM
UefiCpuPkg/Include/Register/Msr/xxxxMsr.h defined the IA32 Model-specific MSRs in IA32 SDM.

I am not sure if Brijesh/Leo has some idea to place SEV specific CPUID/MSRs definitions.
I think one new file or new folder is better.

Thanks!
Jeff

-----Original Message-----
From: edk2-devel [mailto:edk2-devel-bounces@lists.01.org] On Behalf Of Laszlo Ersek
Sent: Thursday, March 23, 2017 12:04 AM
To: Brijesh Singh; Kinney, Michael D; Justen, Jordan L; edk2-devel@ml01.01.org; Gao, Liming; Fan, Jeff
Cc: leo.duran@amd.com; brijesh.singh@amd.com; Thomas.Lendacky@amd.com
Subject: Re: [edk2] [RFC PATCH v2 01/10] OvmfPkg/Include: Define SEV specific CPUID and MSR

Adding Jeff

On 03/21/17 22:12, Brijesh Singh wrote:
> The patch defines AMD's Memory Encryption Information CPUID leaf (0x8000_001F).
> The complete description for this CPUID leaf is available in APM 
> volume 2 [1] Section 15.34 (Secure Encrypted Virtualization).
> 
> [1] http://support.amd.com/TechDocs/24593.pdf
> 
> Signed-off-by: Brijesh Singh <brijesh.singh@amd.com>
> ---
>  OvmfPkg/Include/Register/AmdSevMap.h |  133 
> ++++++++++++++++++++++++++++++++++
>  1 file changed, 133 insertions(+)
>  create mode 100644 OvmfPkg/Include/Register/AmdSevMap.h
> 
> diff --git a/OvmfPkg/Include/Register/AmdSevMap.h 
> b/OvmfPkg/Include/Register/AmdSevMap.h
> new file mode 100644
> index 0000000..de80f39
> --- /dev/null
> +++ b/OvmfPkg/Include/Register/AmdSevMap.h
> @@ -0,0 +1,133 @@
> +/** @file
> +
> +AMD Secure Encrypted Virtualization (SEV) specific CPUID and MSR 
> +definitions
> +
> +The complete description for this CPUID leaf is available in APM 
> +volume 2 (Section 15.34) http://support.amd.com/TechDocs/24593.pdf
> +
> +Copyright (c) 2017, Advanced Micro Devices. All rights reserved.<BR>
> +
> +This program and the accompanying materials are licensed and made 
> +available under the terms and conditions of the BSD License which 
> +accompanies this distribution.  The full text of the license may be 
> +found at http://opensource.org/licenses/bsd-license.php
> +
> +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, 
> +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
> +
> +**/
> +
> +#ifndef __AMD_SEV_MAP_H__
> +#define __AMD_SEV_MAP_H__
> +
> +#pragma pack (1)
> +
> +#define CPUID_MEMORY_ENCRYPTION_INFO             0x8000001F
> +
> +/**
> +  CPUID Memory Encryption support information EAX for CPUID leaf
> +  #CPUID_MEMORY_ENCRYPTION_INFO.
> +**/
> +typedef union {
> +  ///
> +  /// Individual bit fields
> +  ///
> +  struct {
> +    ///
> +    /// [Bit 0] Secure Memory Encryption (Sme) Support
> +    ///
> +    UINT32  SmeBit:1;
> +
> +    ///
> +    /// [Bit 1] Secure Encrypted Virtualization (Sev) Support
> +    ///
> +    UINT32  SevBit:1;
> +
> +    ///
> +    /// [Bit 2] Page flush MSR support
> +    ///
> +    UINT32  PageFlushMsrBit:1;
> +
> +    ///
> +    /// [Bit 3] Encrypted state support
> +    ///
> +    UINT32  SevEsBit:1;
> +
> +    ///
> +    /// [Bit 4:31] Reserved
> +    ///
> +    UINT32  ReservedBits:28;
> +  } Bits;
> +  ///
> +  /// All bit fields as a 32-bit value
> +  ///
> +  UINT32  Uint32;
> +} CPUID_MEMORY_ENCRYPTION_INFO_EAX;
> +
> +/**
> +  CPUID Memory Encryption support information EBX for CPUID leaf
> +  #CPUID_MEMORY_ENCRYPTION_INFO.
> +**/
> +typedef union {
> +  ///
> +  /// Individual bit fields
> +  ///
> +  struct {
> +    ///
> +    /// [Bit 0:5] Page table bit number used to enable memory encryption
> +    ///
> +    UINT32  PtePosBits:6;
> +
> +    ///
> +    /// [Bit 6:11] Reduction of system physical address space bits when memory encryption is enabled
> +    ///
> +    UINT32  ReducedPhysBits:5;
> +
> +    ///
> +    /// [Bit 12:31] Reserved
> +    ///
> +    UINT32  ReservedBits:21;
> +  } Bits;
> +  ///
> +  /// All bit fields as a 32-bit value
> +  ///
> +  UINT32  Uint32;
> +} CPUID_MEMORY_ENCRYPTION_INFO_EBX;
> +
> +/**
> +  Secure Encrypted Virtualization (SEV) status register
> +
> +**/
> +#define MSR_SEV_STATUS                     0xc0010131
> +
> +/**
> +  MSR information returned for #MSR_SEV_STATUS **/ typedef union {
> +  ///
> +  /// Individual bit fields
> +  ///
> +  struct {
> +    ///
> +    /// [Bit 0] Secure Encrypted Virtualization (Sev) is enabled
> +    ///
> +    UINT32  SevBit:1;
> +
> +    ///
> +    /// [Bit 1] Secure Encrypted Virtualization Encrypted State (SevEs) is enabled
> +    ///
> +    UINT32  SevEsBit:1;
> +
> +    UINT32  Reserved:30;
> +  } Bits;
> +  ///
> +  /// All bit fields as a 32-bit value
> +  ///
> +  UINT32  Uint32;
> +  ///
> +  /// All bit fields as a 64-bit value
> +  ///
> +  UINT64  Uint64;
> +} MSR_SEV_STATUS_REGISTER;
> +
> +#endif
> 
> _______________________________________________
> edk2-devel mailing list
> edk2-devel@lists.01.org
> https://lists.01.org/mailman/listinfo/edk2-devel
> 

I feel that these definitions should be added to "UefiCpuPkg/Include/Register/Cpuid.h", or else to another (new) header file in that directory.

Jeff, what do you think?

Thanks!
Laszlo
_______________________________________________
edk2-devel mailing list
edk2-devel@lists.01.org
https://lists.01.org/mailman/listinfo/edk2-devel


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

* Re: [RFC PATCH v2 01/10] OvmfPkg/Include: Define SEV specific CPUID and MSR
  2017-03-23  7:42     ` Fan, Jeff
@ 2017-03-23  9:19       ` Laszlo Ersek
  2017-03-27  7:57         ` Fan, Jeff
  0 siblings, 1 reply; 44+ messages in thread
From: Laszlo Ersek @ 2017-03-23  9:19 UTC (permalink / raw)
  To: Fan, Jeff, Brijesh Singh, Kinney, Michael D, Justen, Jordan L,
	edk2-devel@ml01.01.org, Gao, Liming
  Cc: leo.duran@amd.com, brijesh.singh@amd.com, Thomas.Lendacky@amd.com

On 03/23/17 08:42, Fan, Jeff wrote:
> Laszlo,
> 
> UefiCpuPkg/Include/Register/Cpuid.h defined the CPUID only described in IA32 SDM.
> UefiCpuPkg/Include/Register/ArchitecturalMsr.h defined the IA32 Architectural MSRs in IA32 SDM
> UefiCpuPkg/Include/Register/Msr/xxxxMsr.h defined the IA32 Model-specific MSRs in IA32 SDM.
> 
> I am not sure if Brijesh/Leo has some idea to place SEV specific CPUID/MSRs definitions.
> I think one new file or new folder is better.

I agree, both would work for me. My main point is that this feature
depends on physical processor attributes, not on emulated (virtual)
hardware or on various hypervisors, plus it is defined in a public
industry spec, so it seems to belong under UefiCpuPkg, not OvmfPkg.

How about

  UefiCpuPkg/Include/AmdRegister/Cpuid.h
  UefiCpuPkg/Include/AmdRegister/ArchitecturalMsr.h
  UefiCpuPkg/Include/AmdRegister/Msr/xxxxMsr.h

or else:

  UefiCpuPkg/Include/Register/Amd/Cpuid.h
  UefiCpuPkg/Include/Register/Amd/ArchitecturalMsr.h
  UefiCpuPkg/Include/Register/Amd/Msr/xxxxMsr.h

(as appropriate -- I'm not saying that this patch should create all of
these files / subdirectories at once).

Thanks
Laszlo
> 
> -----Original Message-----
> From: edk2-devel [mailto:edk2-devel-bounces@lists.01.org] On Behalf Of Laszlo Ersek
> Sent: Thursday, March 23, 2017 12:04 AM
> To: Brijesh Singh; Kinney, Michael D; Justen, Jordan L; edk2-devel@ml01.01.org; Gao, Liming; Fan, Jeff
> Cc: leo.duran@amd.com; brijesh.singh@amd.com; Thomas.Lendacky@amd.com
> Subject: Re: [edk2] [RFC PATCH v2 01/10] OvmfPkg/Include: Define SEV specific CPUID and MSR
> 
> Adding Jeff
> 
> On 03/21/17 22:12, Brijesh Singh wrote:
>> The patch defines AMD's Memory Encryption Information CPUID leaf (0x8000_001F).
>> The complete description for this CPUID leaf is available in APM 
>> volume 2 [1] Section 15.34 (Secure Encrypted Virtualization).
>>
>> [1] http://support.amd.com/TechDocs/24593.pdf
>>
>> Signed-off-by: Brijesh Singh <brijesh.singh@amd.com>
>> ---
>>  OvmfPkg/Include/Register/AmdSevMap.h |  133 
>> ++++++++++++++++++++++++++++++++++
>>  1 file changed, 133 insertions(+)
>>  create mode 100644 OvmfPkg/Include/Register/AmdSevMap.h
>>
>> diff --git a/OvmfPkg/Include/Register/AmdSevMap.h 
>> b/OvmfPkg/Include/Register/AmdSevMap.h
>> new file mode 100644
>> index 0000000..de80f39
>> --- /dev/null
>> +++ b/OvmfPkg/Include/Register/AmdSevMap.h
>> @@ -0,0 +1,133 @@
>> +/** @file
>> +
>> +AMD Secure Encrypted Virtualization (SEV) specific CPUID and MSR 
>> +definitions
>> +
>> +The complete description for this CPUID leaf is available in APM 
>> +volume 2 (Section 15.34) http://support.amd.com/TechDocs/24593.pdf
>> +
>> +Copyright (c) 2017, Advanced Micro Devices. All rights reserved.<BR>
>> +
>> +This program and the accompanying materials are licensed and made 
>> +available under the terms and conditions of the BSD License which 
>> +accompanies this distribution.  The full text of the license may be 
>> +found at http://opensource.org/licenses/bsd-license.php
>> +
>> +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, 
>> +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
>> +
>> +**/
>> +
>> +#ifndef __AMD_SEV_MAP_H__
>> +#define __AMD_SEV_MAP_H__
>> +
>> +#pragma pack (1)
>> +
>> +#define CPUID_MEMORY_ENCRYPTION_INFO             0x8000001F
>> +
>> +/**
>> +  CPUID Memory Encryption support information EAX for CPUID leaf
>> +  #CPUID_MEMORY_ENCRYPTION_INFO.
>> +**/
>> +typedef union {
>> +  ///
>> +  /// Individual bit fields
>> +  ///
>> +  struct {
>> +    ///
>> +    /// [Bit 0] Secure Memory Encryption (Sme) Support
>> +    ///
>> +    UINT32  SmeBit:1;
>> +
>> +    ///
>> +    /// [Bit 1] Secure Encrypted Virtualization (Sev) Support
>> +    ///
>> +    UINT32  SevBit:1;
>> +
>> +    ///
>> +    /// [Bit 2] Page flush MSR support
>> +    ///
>> +    UINT32  PageFlushMsrBit:1;
>> +
>> +    ///
>> +    /// [Bit 3] Encrypted state support
>> +    ///
>> +    UINT32  SevEsBit:1;
>> +
>> +    ///
>> +    /// [Bit 4:31] Reserved
>> +    ///
>> +    UINT32  ReservedBits:28;
>> +  } Bits;
>> +  ///
>> +  /// All bit fields as a 32-bit value
>> +  ///
>> +  UINT32  Uint32;
>> +} CPUID_MEMORY_ENCRYPTION_INFO_EAX;
>> +
>> +/**
>> +  CPUID Memory Encryption support information EBX for CPUID leaf
>> +  #CPUID_MEMORY_ENCRYPTION_INFO.
>> +**/
>> +typedef union {
>> +  ///
>> +  /// Individual bit fields
>> +  ///
>> +  struct {
>> +    ///
>> +    /// [Bit 0:5] Page table bit number used to enable memory encryption
>> +    ///
>> +    UINT32  PtePosBits:6;
>> +
>> +    ///
>> +    /// [Bit 6:11] Reduction of system physical address space bits when memory encryption is enabled
>> +    ///
>> +    UINT32  ReducedPhysBits:5;
>> +
>> +    ///
>> +    /// [Bit 12:31] Reserved
>> +    ///
>> +    UINT32  ReservedBits:21;
>> +  } Bits;
>> +  ///
>> +  /// All bit fields as a 32-bit value
>> +  ///
>> +  UINT32  Uint32;
>> +} CPUID_MEMORY_ENCRYPTION_INFO_EBX;
>> +
>> +/**
>> +  Secure Encrypted Virtualization (SEV) status register
>> +
>> +**/
>> +#define MSR_SEV_STATUS                     0xc0010131
>> +
>> +/**
>> +  MSR information returned for #MSR_SEV_STATUS **/ typedef union {
>> +  ///
>> +  /// Individual bit fields
>> +  ///
>> +  struct {
>> +    ///
>> +    /// [Bit 0] Secure Encrypted Virtualization (Sev) is enabled
>> +    ///
>> +    UINT32  SevBit:1;
>> +
>> +    ///
>> +    /// [Bit 1] Secure Encrypted Virtualization Encrypted State (SevEs) is enabled
>> +    ///
>> +    UINT32  SevEsBit:1;
>> +
>> +    UINT32  Reserved:30;
>> +  } Bits;
>> +  ///
>> +  /// All bit fields as a 32-bit value
>> +  ///
>> +  UINT32  Uint32;
>> +  ///
>> +  /// All bit fields as a 64-bit value
>> +  ///
>> +  UINT64  Uint64;
>> +} MSR_SEV_STATUS_REGISTER;
>> +
>> +#endif
>>
>> _______________________________________________
>> edk2-devel mailing list
>> edk2-devel@lists.01.org
>> https://lists.01.org/mailman/listinfo/edk2-devel
>>
> 
> I feel that these definitions should be added to "UefiCpuPkg/Include/Register/Cpuid.h", or else to another (new) header file in that directory.
> 
> Jeff, what do you think?
> 
> Thanks!
> Laszlo
> _______________________________________________
> edk2-devel mailing list
> edk2-devel@lists.01.org
> https://lists.01.org/mailman/listinfo/edk2-devel
> 



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

* Re: [RFC PATCH v2 02/10] OvmfPkg/ResetVector: add memory encryption mask when SEV is enabled
  2017-03-22 20:20   ` Laszlo Ersek
@ 2017-03-23 15:05     ` Brijesh Singh
  2017-03-23 16:16       ` Laszlo Ersek
  0 siblings, 1 reply; 44+ messages in thread
From: Brijesh Singh @ 2017-03-23 15:05 UTC (permalink / raw)
  To: Laszlo Ersek
  Cc: Kinney, Michael D, Justen, Jordan L, edk2-devel, Gao, Liming,
	brijesh.singh, Leo Duran, Tom Lendacky

On Wed, Mar 22, 2017 at 3:20 PM, Laszlo Ersek <lersek@redhat.com> wrote:

> On 03/21/17 22:12, Brijesh Singh wrote:
> > SEV guest VMs have the concept of private and shared memory. Private
> > memory is encrypted with the guest-specific key, while shared memory
> > may be encrypted with hypervisor key. Certain types of memory (namely
> > instruction pages and guest page tables) are always treated as private
> > memory by the hardware. The C-bit in PTE indicate whether the page is
> > private or shared. The C-bit position for the PTE can be obtained from
> > CPUID Fn8000_001F[EBX].
> >
> > When SEV is active, the BIOS is pre-encrypted by the Qemu launch
> sequence,
> > we must set the C-bit when building the page table for 64-bit or 32-bit
> > PAE mode.
> >
> > Signed-off-by: Brijesh Singh <brijesh.singh@amd.com>
> > ---
> >  OvmfPkg/ResetVector/Ia32/PageTables64.asm |   62
> +++++++++++++++++++++++++++++
> >  1 file changed, 62 insertions(+)
> >
> > diff --git a/OvmfPkg/ResetVector/Ia32/PageTables64.asm
> b/OvmfPkg/ResetVector/Ia32/PageTables64.asm
> > index 6201cad..7083f6b 100644
> > --- a/OvmfPkg/ResetVector/Ia32/PageTables64.asm
> > +++ b/OvmfPkg/ResetVector/Ia32/PageTables64.asm
> > @@ -37,6 +37,47 @@ BITS    32
> >                         PAGE_READ_WRITE + \
> >                         PAGE_PRESENT)
> >
> > +; Check if Secure Encrypted Virtualization (SEV) feature
> > +;
> > +;  If SEV is enabled, then EAX will contain Memory encryption bit
> position
>
> I suggest to say, in the comment here, that a valid eax will be at least
> 32, and 0 on "SEV unavailable or disabled".
>
>
WIll do.



> > +;
> > +CheckSevFeature:
> > +    xor       eax, eax
>
> I think this xor may not be necessary (there's no path out of this
> function that wouldn't set eax intentionally), but it doesn't hurt.
>
> (Sorry if I should have noticed this in v1 -- there's no need to
> resubmit just because of this.)
>
> In the below logic, which branch exactly (to NoSev) will be taken on
> Intel processors?
>
>
The below check should branch to NoSev  on Intel processor
(please note that 0x8000_001F is new leaf and may not exist on older AMD
processor hence we will also branch to NoSev on AMD processor which does
not support this leaf)

*; Check if we have a valid (0x8000_001F) CPUID leaf
**mov       eax, 0x80000000
**cpuid
**cmp       eax, 0x8000001f
**jl        NoSev*


 > +

> +    ; Check if we have a valid (0x8000_001F) CPUID leaf
> > +    mov       eax, 0x80000000
> > +    cpuid
> > +    cmp       eax, 0x8000001f
> > +    jl        NoSev
> > +
> > +    ; Check for memory encryption feature:
> > +    ;  CPUID  Fn8000_001F[EAX] - Bit 1
> > +    ;
> > +    mov       eax,  0x8000001f
> > +    cpuid
> > +    bt        eax, 1
> > +    jnc       NoSev
> > +
> > +    ; Check if memory encryption is enabled
> > +    ;  MSR_0xC0010131 - Bit 0 (SEV enabled)
> > +    ;  MSR_0xC0010131 - Bit 1 (SEV-ES enabled)
> > +    mov       ecx, 0xc001013.
> > +    rdmsr
> > +    bt        eax, 0
> > +    jnc       NoSev
>
> Do we need to check SEV-ES specifically? bit1 is not tested.
>
>
We don't need to check SEV-ES bit, I just added it here for documentation
purposes. In current patch series I am not adding any of the ES funtionality
and will be revisit later.


> +
> > +    ; Get pte bit position to enable memory encryption
> > +    ; CPUID Fn8000_001F[EBX] - Bits 5:0
> > +    ;
> > +    mov       eax, ebx
> > +    and       eax, 0x3f
> > +    jmp       SevExit
> > +
> > +NoSev:
> > +    xor       eax, eax
> > +
> > +SevExit:
> > +    OneTimeCallRet CheckSevFeature
> >
> >  ;
> >  ; Modified:  EAX, ECX
>
> Can you please update (or delete) this comment? I think EBX and EDX may
> be modified too.
>
>
Will do. Since cpuid clobbers these registers I can push/pop these inside
the CheckSevFeature.



> > @@ -60,18 +101,38 @@ clearPageTablesMemoryLoop:
> >      mov     dword[ecx * 4 + PT_ADDR (0) - 4], eax
> >      loop    clearPageTablesMemoryLoop
> >
> > +    ; Check if its SEV-enabled Guest
> > +    ;
> > +    OneTimeCall   CheckSevFeature
> > +    xor     edx, edx
> > +    test    eax, eax
> > +    jz      SevNotActive
> > +
> > +    ; If SEV is enabled, Memory encryption bit is always above 31
> > +    mov     ebx, 32
> > +    sub     ebx, eax
>
> I apologize if I'm mistaken, but I think we want to decrease eax with 32
> (i.e., with ebx), so that we get the C bit's position within the high
> address (= more significant) DWORD of the PTE.
>
> But, isn't the argument order for SUB reversed? To me the above seems to
> imply EBX := EBX - EAX, which appears wrong.
>
> ... I think we could even say
>
>   sub eax, 32
>
>

Ah  good catch.  You are right that I should be using "sub eax, ebx" or
"sub eax, 32". I am scratching my head to figure out why SEV guest was
booting
with this bug. If the mask calculation is wrong then we should be failing
to boot the SEV guest.  But looking at "bts instruction" [1] indicates that
 some
assembler support bit offset larger than 31. Since eax still contains the
original
bit position hence the mask creation logic was still working.

I will fix it.

[1] http://x86.renejeschke.de/html/file_module_x86_id_25.html

Thank you.

-Brijesh


> The rest looks good to me.
>
> Thanks
> Laszlo
>
> > +    bts     edx, eax
> > +
> > +SevNotActive:
> > +
> > +    ;
> >      ;
> >      ; 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)
> > @@ -83,6 +144,7 @@ pageTableEntriesLoop:
> >      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
> >
> >      ;
> >
> > _______________________________________________
> > edk2-devel mailing list
> > edk2-devel@lists.01.org
> > https://lists.01.org/mailman/listinfo/edk2-devel
> >
>
>


-- 
Confusion is always the most honest response.


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

* Re: [RFC PATCH v2 02/10] OvmfPkg/ResetVector: add memory encryption mask when SEV is enabled
  2017-03-23 15:05     ` Brijesh Singh
@ 2017-03-23 16:16       ` Laszlo Ersek
  2017-03-23 16:48         ` Brijesh Singh
  0 siblings, 1 reply; 44+ messages in thread
From: Laszlo Ersek @ 2017-03-23 16:16 UTC (permalink / raw)
  To: Brijesh Singh
  Cc: Kinney, Michael D, Justen, Jordan L, edk2-devel, Gao, Liming,
	brijesh.singh, Leo Duran, Tom Lendacky

On 03/23/17 16:05, Brijesh Singh wrote:
> On Wed, Mar 22, 2017 at 3:20 PM, Laszlo Ersek <lersek@redhat.com> wrote:

>> In the below logic, which branch exactly (to NoSev) will be taken on
>> Intel processors?
>>
>>
> The below check should branch to NoSev  on Intel processor
> (please note that 0x8000_001F is new leaf and may not exist on older AMD
> processor hence we will also branch to NoSev on AMD processor which does
> not support this leaf)
> 
> *; Check if we have a valid (0x8000_001F) CPUID leaf
> **mov       eax, 0x80000000
> **cpuid
> **cmp       eax, 0x8000001f
> **jl        NoSev*

Yes, I figured that maybe this "highest supported cpuid leaf" check
would catch Intel processors.

But, what prevents a future Intel processor from exposing such a high
CPUID leaf, for a completely different purpose? Should we not perform
some kind of vendor-id check? (I'm quite unfamiliar with CPUID, as you
can tell, I just seem to recall a comment (from Liming perhaps?) for one
of your MdeModulePkg patches, where he said that directly using a
software-defined CPUID leaf (?) would not be portable across all CPU
vendors, or some such.)

Thanks!
Laszlo


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

* Re: [RFC PATCH v2 02/10] OvmfPkg/ResetVector: add memory encryption mask when SEV is enabled
  2017-03-23 16:16       ` Laszlo Ersek
@ 2017-03-23 16:48         ` Brijesh Singh
  2017-03-23 16:54           ` Laszlo Ersek
  0 siblings, 1 reply; 44+ messages in thread
From: Brijesh Singh @ 2017-03-23 16:48 UTC (permalink / raw)
  To: Laszlo Ersek
  Cc: Kinney, Michael D, Justen, Jordan L, edk2-devel, Gao, Liming,
	brijesh.singh, Leo Duran, Tom Lendacky

On Thu, Mar 23, 2017 at 11:16 AM, Laszlo Ersek <lersek@redhat.com> wrote:

> On 03/23/17 16:05, Brijesh Singh wrote:
> > On Wed, Mar 22, 2017 at 3:20 PM, Laszlo Ersek <lersek@redhat.com> wrote:
>
> >> In the below logic, which branch exactly (to NoSev) will be taken on
> >> Intel processors?
> >>
> >>
> > The below check should branch to NoSev  on Intel processor
> > (please note that 0x8000_001F is new leaf and may not exist on older AMD
> > processor hence we will also branch to NoSev on AMD processor which does
> > not support this leaf)
> >
> > *; Check if we have a valid (0x8000_001F) CPUID leaf
> > **mov       eax, 0x80000000
> > **cpuid
> > **cmp       eax, 0x8000001f
> > **jl        NoSev*
>
> Yes, I figured that maybe this "highest supported cpuid leaf" check
> would catch Intel processors.
>
> But, what prevents a future Intel processor from exposing such a high
> CPUID leaf, for a completely different purpose? Should we not perform
> some kind of vendor-id check? (I'm quite unfamiliar with CPUID, as you
> can tell, I just seem to recall a comment (from Liming perhaps?) for one
> of your MdeModulePkg patches, where he said that directly using a
> software-defined CPUID leaf (?) would not be portable across all CPU
> vendors, or some such.)
>
>

I had similar question in my mind.  Before creating the patch I checked
with
AMD architecture team. The response was, CPUID 0x8000_001F definition
is fixed for x86 architecture. So, if Intel ever decides to report this
CPUID leaf
then it will comply to exact same definition.

I think vendor check is weak, e.g user could change the vendor string
through the qemu property which will break this loop. Because of this, I
wanted
to avoid any kind of vendor string or hypervisor defined CPUID checks
inside the code.

BTW, in my previous patches I was using KVM software defined CPUID leaf and
I
got rid of it because hypervisor's are flexiable to define that CPUID in
whatever
way they want.

-Brijesh


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

* Re: [RFC PATCH v2 02/10] OvmfPkg/ResetVector: add memory encryption mask when SEV is enabled
  2017-03-23 16:48         ` Brijesh Singh
@ 2017-03-23 16:54           ` Laszlo Ersek
  2017-03-23 17:44             ` Brijesh Singh
  0 siblings, 1 reply; 44+ messages in thread
From: Laszlo Ersek @ 2017-03-23 16:54 UTC (permalink / raw)
  To: Brijesh Singh
  Cc: Kinney, Michael D, Justen, Jordan L, edk2-devel, Gao, Liming,
	brijesh.singh, Leo Duran, Tom Lendacky

On 03/23/17 17:48, Brijesh Singh wrote:
> On Thu, Mar 23, 2017 at 11:16 AM, Laszlo Ersek <lersek@redhat.com> wrote:
> 
>> On 03/23/17 16:05, Brijesh Singh wrote:
>>> On Wed, Mar 22, 2017 at 3:20 PM, Laszlo Ersek <lersek@redhat.com> wrote:
>>
>>>> In the below logic, which branch exactly (to NoSev) will be taken on
>>>> Intel processors?
>>>>
>>>>
>>> The below check should branch to NoSev  on Intel processor
>>> (please note that 0x8000_001F is new leaf and may not exist on older AMD
>>> processor hence we will also branch to NoSev on AMD processor which does
>>> not support this leaf)
>>>
>>> *; Check if we have a valid (0x8000_001F) CPUID leaf
>>> **mov       eax, 0x80000000
>>> **cpuid
>>> **cmp       eax, 0x8000001f
>>> **jl        NoSev*
>>
>> Yes, I figured that maybe this "highest supported cpuid leaf" check
>> would catch Intel processors.
>>
>> But, what prevents a future Intel processor from exposing such a high
>> CPUID leaf, for a completely different purpose? Should we not perform
>> some kind of vendor-id check? (I'm quite unfamiliar with CPUID, as you
>> can tell, I just seem to recall a comment (from Liming perhaps?) for one
>> of your MdeModulePkg patches, where he said that directly using a
>> software-defined CPUID leaf (?) would not be portable across all CPU
>> vendors, or some such.)
>>
>>
> 
> I had similar question in my mind.  Before creating the patch I checked
> with
> AMD architecture team. The response was, CPUID 0x8000_001F definition
> is fixed for x86 architecture. So, if Intel ever decides to report this
> CPUID leaf
> then it will comply to exact same definition.

OK, this looks safe then. Can you please add it as a comment to the code?

Thanks!
Laszlo

> 
> I think vendor check is weak, e.g user could change the vendor string
> through the qemu property which will break this loop. Because of this, I
> wanted
> to avoid any kind of vendor string or hypervisor defined CPUID checks
> inside the code.
> 
> BTW, in my previous patches I was using KVM software defined CPUID leaf and
> I
> got rid of it because hypervisor's are flexiable to define that CPUID in
> whatever
> way they want.
> 
> -Brijesh
> 



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

* Re: [RFC PATCH v2 02/10] OvmfPkg/ResetVector: add memory encryption mask when SEV is enabled
  2017-03-23 16:54           ` Laszlo Ersek
@ 2017-03-23 17:44             ` Brijesh Singh
  0 siblings, 0 replies; 44+ messages in thread
From: Brijesh Singh @ 2017-03-23 17:44 UTC (permalink / raw)
  To: Laszlo Ersek
  Cc: Kinney, Michael D, Justen, Jordan L, edk2-devel, Gao, Liming,
	brijesh.singh, Leo Duran, Tom Lendacky

On Thu, Mar 23, 2017 at 11:54 AM, Laszlo Ersek <lersek@redhat.com> >
>
> > I had similar question in my mind.  Before creating the patch I checked
> > with
> > AMD architecture team. The response was, CPUID 0x8000_001F definition
> > is fixed for x86 architecture. So, if Intel ever decides to report this
> > CPUID leaf
> > then it will comply to exact same definition.
>
> OK, this looks safe then. Can you please add it as a comment to the code?
>
>

Sure will do.

-Brijesh


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

* Re: [RFC PATCH v2 01/10] OvmfPkg/Include: Define SEV specific CPUID and MSR
  2017-03-23  9:19       ` Laszlo Ersek
@ 2017-03-27  7:57         ` Fan, Jeff
  2017-03-27 11:58           ` Brijesh Singh
  2017-03-27 15:59           ` Duran, Leo
  0 siblings, 2 replies; 44+ messages in thread
From: Fan, Jeff @ 2017-03-27  7:57 UTC (permalink / raw)
  To: Laszlo Ersek, Brijesh Singh, Kinney, Michael D, Justen, Jordan L,
	edk2-devel@ml01.01.org, Gao, Liming
  Cc: leo.duran@amd.com, brijesh.singh@amd.com, Thomas.Lendacky@amd.com

Laszlo,

One Amd directory under UefiCpuPkg/Include/Register is better.

Does Brijesh/Leo have any comments, or have other suggestions?

Thanks!
Jeff

-----Original Message-----
From: Laszlo Ersek [mailto:lersek@redhat.com] 
Sent: Thursday, March 23, 2017 5:20 PM
To: Fan, Jeff; Brijesh Singh; Kinney, Michael D; Justen, Jordan L; edk2-devel@ml01.01.org; Gao, Liming
Cc: leo.duran@amd.com; brijesh.singh@amd.com; Thomas.Lendacky@amd.com
Subject: Re: [edk2] [RFC PATCH v2 01/10] OvmfPkg/Include: Define SEV specific CPUID and MSR

On 03/23/17 08:42, Fan, Jeff wrote:
> Laszlo,
> 
> UefiCpuPkg/Include/Register/Cpuid.h defined the CPUID only described in IA32 SDM.
> UefiCpuPkg/Include/Register/ArchitecturalMsr.h defined the IA32 
> Architectural MSRs in IA32 SDM UefiCpuPkg/Include/Register/Msr/xxxxMsr.h defined the IA32 Model-specific MSRs in IA32 SDM.
> 
> I am not sure if Brijesh/Leo has some idea to place SEV specific CPUID/MSRs definitions.
> I think one new file or new folder is better.

I agree, both would work for me. My main point is that this feature depends on physical processor attributes, not on emulated (virtual) hardware or on various hypervisors, plus it is defined in a public industry spec, so it seems to belong under UefiCpuPkg, not OvmfPkg.

How about

  UefiCpuPkg/Include/AmdRegister/Cpuid.h
  UefiCpuPkg/Include/AmdRegister/ArchitecturalMsr.h
  UefiCpuPkg/Include/AmdRegister/Msr/xxxxMsr.h

or else:

  UefiCpuPkg/Include/Register/Amd/Cpuid.h
  UefiCpuPkg/Include/Register/Amd/ArchitecturalMsr.h
  UefiCpuPkg/Include/Register/Amd/Msr/xxxxMsr.h

(as appropriate -- I'm not saying that this patch should create all of these files / subdirectories at once).

Thanks
Laszlo
> 
> -----Original Message-----
> From: edk2-devel [mailto:edk2-devel-bounces@lists.01.org] On Behalf Of 
> Laszlo Ersek
> Sent: Thursday, March 23, 2017 12:04 AM
> To: Brijesh Singh; Kinney, Michael D; Justen, Jordan L; 
> edk2-devel@ml01.01.org; Gao, Liming; Fan, Jeff
> Cc: leo.duran@amd.com; brijesh.singh@amd.com; Thomas.Lendacky@amd.com
> Subject: Re: [edk2] [RFC PATCH v2 01/10] OvmfPkg/Include: Define SEV 
> specific CPUID and MSR
> 
> Adding Jeff
> 
> On 03/21/17 22:12, Brijesh Singh wrote:
>> The patch defines AMD's Memory Encryption Information CPUID leaf (0x8000_001F).
>> The complete description for this CPUID leaf is available in APM 
>> volume 2 [1] Section 15.34 (Secure Encrypted Virtualization).
>>
>> [1] http://support.amd.com/TechDocs/24593.pdf
>>
>> Signed-off-by: Brijesh Singh <brijesh.singh@amd.com>
>> ---
>>  OvmfPkg/Include/Register/AmdSevMap.h |  133
>> ++++++++++++++++++++++++++++++++++
>>  1 file changed, 133 insertions(+)
>>  create mode 100644 OvmfPkg/Include/Register/AmdSevMap.h
>>
>> diff --git a/OvmfPkg/Include/Register/AmdSevMap.h
>> b/OvmfPkg/Include/Register/AmdSevMap.h
>> new file mode 100644
>> index 0000000..de80f39
>> --- /dev/null
>> +++ b/OvmfPkg/Include/Register/AmdSevMap.h
>> @@ -0,0 +1,133 @@
>> +/** @file
>> +
>> +AMD Secure Encrypted Virtualization (SEV) specific CPUID and MSR 
>> +definitions
>> +
>> +The complete description for this CPUID leaf is available in APM 
>> +volume 2 (Section 15.34) http://support.amd.com/TechDocs/24593.pdf
>> +
>> +Copyright (c) 2017, Advanced Micro Devices. All rights reserved.<BR>
>> +
>> +This program and the accompanying materials are licensed and made 
>> +available under the terms and conditions of the BSD License which 
>> +accompanies this distribution.  The full text of the license may be 
>> +found at http://opensource.org/licenses/bsd-license.php
>> +
>> +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" 
>> +BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
>> +
>> +**/
>> +
>> +#ifndef __AMD_SEV_MAP_H__
>> +#define __AMD_SEV_MAP_H__
>> +
>> +#pragma pack (1)
>> +
>> +#define CPUID_MEMORY_ENCRYPTION_INFO             0x8000001F
>> +
>> +/**
>> +  CPUID Memory Encryption support information EAX for CPUID leaf
>> +  #CPUID_MEMORY_ENCRYPTION_INFO.
>> +**/
>> +typedef union {
>> +  ///
>> +  /// Individual bit fields
>> +  ///
>> +  struct {
>> +    ///
>> +    /// [Bit 0] Secure Memory Encryption (Sme) Support
>> +    ///
>> +    UINT32  SmeBit:1;
>> +
>> +    ///
>> +    /// [Bit 1] Secure Encrypted Virtualization (Sev) Support
>> +    ///
>> +    UINT32  SevBit:1;
>> +
>> +    ///
>> +    /// [Bit 2] Page flush MSR support
>> +    ///
>> +    UINT32  PageFlushMsrBit:1;
>> +
>> +    ///
>> +    /// [Bit 3] Encrypted state support
>> +    ///
>> +    UINT32  SevEsBit:1;
>> +
>> +    ///
>> +    /// [Bit 4:31] Reserved
>> +    ///
>> +    UINT32  ReservedBits:28;
>> +  } Bits;
>> +  ///
>> +  /// All bit fields as a 32-bit value
>> +  ///
>> +  UINT32  Uint32;
>> +} CPUID_MEMORY_ENCRYPTION_INFO_EAX;
>> +
>> +/**
>> +  CPUID Memory Encryption support information EBX for CPUID leaf
>> +  #CPUID_MEMORY_ENCRYPTION_INFO.
>> +**/
>> +typedef union {
>> +  ///
>> +  /// Individual bit fields
>> +  ///
>> +  struct {
>> +    ///
>> +    /// [Bit 0:5] Page table bit number used to enable memory encryption
>> +    ///
>> +    UINT32  PtePosBits:6;
>> +
>> +    ///
>> +    /// [Bit 6:11] Reduction of system physical address space bits when memory encryption is enabled
>> +    ///
>> +    UINT32  ReducedPhysBits:5;
>> +
>> +    ///
>> +    /// [Bit 12:31] Reserved
>> +    ///
>> +    UINT32  ReservedBits:21;
>> +  } Bits;
>> +  ///
>> +  /// All bit fields as a 32-bit value
>> +  ///
>> +  UINT32  Uint32;
>> +} CPUID_MEMORY_ENCRYPTION_INFO_EBX;
>> +
>> +/**
>> +  Secure Encrypted Virtualization (SEV) status register
>> +
>> +**/
>> +#define MSR_SEV_STATUS                     0xc0010131
>> +
>> +/**
>> +  MSR information returned for #MSR_SEV_STATUS **/ typedef union {
>> +  ///
>> +  /// Individual bit fields
>> +  ///
>> +  struct {
>> +    ///
>> +    /// [Bit 0] Secure Encrypted Virtualization (Sev) is enabled
>> +    ///
>> +    UINT32  SevBit:1;
>> +
>> +    ///
>> +    /// [Bit 1] Secure Encrypted Virtualization Encrypted State (SevEs) is enabled
>> +    ///
>> +    UINT32  SevEsBit:1;
>> +
>> +    UINT32  Reserved:30;
>> +  } Bits;
>> +  ///
>> +  /// All bit fields as a 32-bit value
>> +  ///
>> +  UINT32  Uint32;
>> +  ///
>> +  /// All bit fields as a 64-bit value
>> +  ///
>> +  UINT64  Uint64;
>> +} MSR_SEV_STATUS_REGISTER;
>> +
>> +#endif
>>
>> _______________________________________________
>> edk2-devel mailing list
>> edk2-devel@lists.01.org
>> https://lists.01.org/mailman/listinfo/edk2-devel
>>
> 
> I feel that these definitions should be added to "UefiCpuPkg/Include/Register/Cpuid.h", or else to another (new) header file in that directory.
> 
> Jeff, what do you think?
> 
> Thanks!
> Laszlo
> _______________________________________________
> edk2-devel mailing list
> edk2-devel@lists.01.org
> https://lists.01.org/mailman/listinfo/edk2-devel
> 



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

* Re: [RFC PATCH v2 03/10] OvmfPkg/PlatformPei: Add Secure Encrypted Virutualization (SEV) support
  2017-03-21 21:13 ` [RFC PATCH v2 03/10] OvmfPkg/PlatformPei: Add Secure Encrypted Virutualization (SEV) support Brijesh Singh
@ 2017-03-27  8:23   ` Laszlo Ersek
  2017-03-27 12:22     ` Brijesh Singh
  0 siblings, 1 reply; 44+ messages in thread
From: Laszlo Ersek @ 2017-03-27  8:23 UTC (permalink / raw)
  To: Brijesh Singh, michael.d.kinney, jordan.l.justen, edk2-devel,
	liming.gao
  Cc: brijesh.singh, leo.duran, Thomas.Lendacky

Please fix the typo ("Virutualization") in the subject.

On 03/21/17 22:13, Brijesh Singh wrote:
> Initialize Secure Encrypted Virtualization support and set the memory encryption mask PCD.

Please wrap commit messages at 74 characters.

> 
> Signed-off-by: Brijesh Singh <brijesh.singh@amd.com>
> ---
>  OvmfPkg/OvmfPkgIa32.dsc             |    3 +
>  OvmfPkg/OvmfPkgIa32X64.dsc          |    3 +
>  OvmfPkg/OvmfPkgX64.dsc              |    3 +
>  OvmfPkg/PlatformPei/AmdSev.c        |   97 +++++++++++++++++++++++++++++++++++
>  OvmfPkg/PlatformPei/Platform.c      |    1 
>  OvmfPkg/PlatformPei/Platform.h      |    5 ++
>  OvmfPkg/PlatformPei/PlatformPei.inf |    2 +
>  7 files changed, 114 insertions(+)
>  create mode 100644 OvmfPkg/PlatformPei/AmdSev.c
> 
> diff --git a/OvmfPkg/OvmfPkgIa32.dsc b/OvmfPkg/OvmfPkgIa32.dsc
> index 546cdf7..769251d 100644
> --- a/OvmfPkg/OvmfPkgIa32.dsc
> +++ b/OvmfPkg/OvmfPkgIa32.dsc
> @@ -506,6 +506,9 @@
>    gUefiCpuPkgTokenSpaceGuid.PcdCpuMaxLogicalProcessorNumber|64
>    gUefiCpuPkgTokenSpaceGuid.PcdCpuApInitTimeOutInMicroSeconds|50000
>  
> +  # Set memory encryption mask
> +  gEfiMdeModulePkgTokenSpaceGuid.PcdPteMemoryEncryptionAddressOrMask|0x0
> +

Please update your git config as described here:

https://github.com/tianocore/tianocore.github.io/wiki/Laszlo's-unkempt-git-guide-for-edk2-contributors-and-maintainers#contrib-05

(the "xfuncname" setting in particular,) and here:

https://github.com/tianocore/tianocore.github.io/wiki/Laszlo's-unkempt-git-guide-for-edk2-contributors-and-maintainers#contrib-09

The point of these settings is that the diff hunk header marked with @@
above will display the DSC section that the hunk modifies (and I'll know
immediately that you are adding a dynamic PCD default).

>  !if $(SMM_REQUIRE) == TRUE
>    gUefiCpuPkgTokenSpaceGuid.PcdCpuSmmSyncMode|0x01
>    gUefiCpuPkgTokenSpaceGuid.PcdCpuSmmApSyncTimeout|100000
> diff --git a/OvmfPkg/OvmfPkgIa32X64.dsc b/OvmfPkg/OvmfPkgIa32X64.dsc
> index 383c8d3..3874c35 100644
> --- a/OvmfPkg/OvmfPkgIa32X64.dsc
> +++ b/OvmfPkg/OvmfPkgIa32X64.dsc
> @@ -514,6 +514,9 @@
>    gUefiCpuPkgTokenSpaceGuid.PcdCpuMaxLogicalProcessorNumber|64
>    gUefiCpuPkgTokenSpaceGuid.PcdCpuApInitTimeOutInMicroSeconds|50000
>  
> +  # Set memory encryption mask
> +  gEfiMdeModulePkgTokenSpaceGuid.PcdPteMemoryEncryptionAddressOrMask|0x0
> +
>  !if $(SMM_REQUIRE) == TRUE
>    gUefiCpuPkgTokenSpaceGuid.PcdCpuSmmSyncMode|0x01
>    gUefiCpuPkgTokenSpaceGuid.PcdCpuSmmApSyncTimeout|100000
> diff --git a/OvmfPkg/OvmfPkgX64.dsc b/OvmfPkg/OvmfPkgX64.dsc
> index 0b7533c..fe7f086 100644
> --- a/OvmfPkg/OvmfPkgX64.dsc
> +++ b/OvmfPkg/OvmfPkgX64.dsc
> @@ -513,6 +513,9 @@
>    gUefiCpuPkgTokenSpaceGuid.PcdCpuMaxLogicalProcessorNumber|64
>    gUefiCpuPkgTokenSpaceGuid.PcdCpuApInitTimeOutInMicroSeconds|50000
>  
> +  # Set memory encryption mask
> +  gEfiMdeModulePkgTokenSpaceGuid.PcdPteMemoryEncryptionAddressOrMask|0x0
> +
>  !if $(SMM_REQUIRE) == TRUE
>    gUefiCpuPkgTokenSpaceGuid.PcdCpuSmmSyncMode|0x01
>    gUefiCpuPkgTokenSpaceGuid.PcdCpuSmmApSyncTimeout|100000
> diff --git a/OvmfPkg/PlatformPei/AmdSev.c b/OvmfPkg/PlatformPei/AmdSev.c
> new file mode 100644
> index 0000000..7f05a9a
> --- /dev/null
> +++ b/OvmfPkg/PlatformPei/AmdSev.c

New file -- can you please double check it is CRLF terminated? Hm,
looking at your "sev-rfc-2" branch, the file does use CRLF. Good.

> @@ -0,0 +1,97 @@
> +/**@file
> +  Initialize Secure Encrypted Virtualization (SEV) support
> +
> +  Copyright (c) 2017, Advanced Micro Devices. All rights reserved.<BR>
> +
> +  This program and the accompanying materials
> +  are licensed and made available under the terms and conditions of the BSD License
> +  which accompanies this distribution.  The full text of the license may be found at

This line is too wide. Please make sure no line is wider than 79 chars.

Please check your patches with

  python BaseTools/Scripts/PatchCheck.py

before submission.

> +  http://opensource.org/licenses/bsd-license.php
> +
> +  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
> +  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
> +
> +**/
> +//
> +// The package level header files this module uses
> +//
> +#include <PiPei.h>
> +
> +#include <Library/DebugLib.h>
> +#include <Library/PcdLib.h>
> +#include <Register/Cpuid.h>
> +#include <Register/AmdSevMap.h>
> +
> +/**
> +
> +  Function returns 'TRUE' when SEV is enabled otherwise FALSE
> +
> +  **/

One idiomatic way to write this comment is:

/**
  Query whether SEV is enabled.

  @retval TRUE   SEV is enabled.
  @retval FALSE  Otherwise.
**/

> +STATIC
> +BOOLEAN
> +SevIsEnabled (
> +  VOID
> +  )
> +{
> +  UINT32 RegEax;
> +  MSR_SEV_STATUS_REGISTER Msr;
> +  CPUID_MEMORY_ENCRYPTION_INFO_EAX  Eax;

Please align the definitions like this:

  UINT32                           RegEax;
  MSR_SEV_STATUS_REGISTER          Msr;
  CPUID_MEMORY_ENCRYPTION_INFO_EAX Eax;


> +
> +  //
> +  // Check if memory encryption leaf exist
> +  //
> +  AsmCpuid (CPUID_EXTENDED_FUNCTION, &RegEax, NULL, NULL, NULL);
> +  if (RegEax >= CPUID_MEMORY_ENCRYPTION_INFO) {
> +    //
> +    // CPUID Fn8000_001F[EAX] Bit 1 (Sev supported)
> +    //
> +    AsmCpuid (CPUID_MEMORY_ENCRYPTION_INFO, &Eax.Uint32, NULL, NULL, NULL);
> +
> +    if (Eax.Bits.SevBit) {
> +      //
> +      // Check MSR_0xC0010131 Bit 0 (Sev Enabled)
> +      //
> +      Msr.Uint32 = AsmReadMsr32 (MSR_SEV_STATUS);
> +      if (Msr.Bits.SevBit) {
> +        return TRUE;
> +      }
> +    }
> +  }
> +
> +  return FALSE;
> +}
> +
> +/**
> +  Function checks if SEV support is available, if present then it updates
> +  the dynamic PcdPteMemoryEncryptionAddressOrMask with memory encryption mask.
> +
> +  **/
> +VOID
> +EFIAPI
> +AmdSevInitialize (
> +  VOID
> +  )
> +{
> +  UINT64 MeMask;
> +  CPUID_MEMORY_ENCRYPTION_INFO_EBX  Ebx;

Same alignment / layout comment.

Also, I suggest renaming "MeMask" to "EncryptionMask".

> +
> +  //
> +  // Check if SEV is enabled
> +  //
> +  if (!SevIsEnabled ()) {
> +    return;
> +  }
> +
> +  //
> +  // CPUID Fn8000_001F[EBX] Bit 0:5 (memory encryption bit position)
> +  //
> +  AsmCpuid (CPUID_MEMORY_ENCRYPTION_INFO, NULL, &Ebx.Uint32, NULL, NULL);
> +  MeMask = LShiftU64 (1, Ebx.Bits.PtePosBits);
> +
> +  //
> +  // Set Memory Encryption Mask PCD
> +  //
> +  PcdSet64S (PcdPteMemoryEncryptionAddressOrMask, MeMask);

Please save the status of the PcdSet64S() function call, and assert that
it works:

  RETURN_ERROR PcdStatus;

  PcdStatus = PcdSet64S (...);
  ASSERT_RETURN_ERROR (PcdStatus);

> +
> +  DEBUG ((EFI_D_INFO, "SEV support is enabled (mask 0x%lx)\n", MeMask));

We no longer use EFI_D_* macros in new code, please use DEBUG_* instead.

> +}
> diff --git a/OvmfPkg/PlatformPei/Platform.c b/OvmfPkg/PlatformPei/Platform.c
> index 77a8a16..49e6c66 100644
> --- a/OvmfPkg/PlatformPei/Platform.c
> +++ b/OvmfPkg/PlatformPei/Platform.c
> @@ -667,6 +667,7 @@ InitializePlatform (
>      NoexecDxeInitialization ();
>    }
>  
> +  AmdSevInitialize ();
>    MiscInitialization ();
>    InstallFeatureControlCallback ();
>  

OK, so this is something we do on S3 resume as well... Yes, S3Resume2Pei
consumes this PCD.

> diff --git a/OvmfPkg/PlatformPei/Platform.h b/OvmfPkg/PlatformPei/Platform.h
> index 18f42c3..a7729b9 100644
> --- a/OvmfPkg/PlatformPei/Platform.h
> +++ b/OvmfPkg/PlatformPei/Platform.h
> @@ -88,6 +88,11 @@ XenDetect (
>    VOID
>    );
>  
> +VOID
> +AmdSevInitialize (
> +  VOID
> +  );
> +
>  extern BOOLEAN mXen;
>  
>  VOID

Again, I request that you please configure your edk2 working tree as
described in the above wiki article. In particular,

https://github.com/tianocore/tianocore.github.io/wiki/Laszlo's-unkempt-git-guide-for-edk2-contributors-and-maintainers#contrib-10

and

https://github.com/tianocore/tianocore.github.io/wiki/Laszlo's-unkempt-git-guide-for-edk2-contributors-and-maintainers#contrib-23

will ensure that .h files are formatted before .c files into the
patches, which helps quite a bit with review.

(With newer git, you can set -O permanently for git-format-patch,
through "diff.orderFile".)

> diff --git a/OvmfPkg/PlatformPei/PlatformPei.inf b/OvmfPkg/PlatformPei/PlatformPei.inf
> index 53c6dd4..2cf4ac876 100644
> --- a/OvmfPkg/PlatformPei/PlatformPei.inf
> +++ b/OvmfPkg/PlatformPei/PlatformPei.inf
> @@ -35,6 +35,7 @@
>    MemDetect.c
>    Platform.c
>    Xen.c
> +  AmdSev.c
>  
>  [Packages]

If possible please try to keep the list of files alphabetically sorted.

>    IntelFrameworkModulePkg/IntelFrameworkModulePkg.dec
> @@ -98,6 +99,7 @@
>    gUefiCpuPkgTokenSpaceGuid.PcdCpuMaxLogicalProcessorNumber
>    gUefiCpuPkgTokenSpaceGuid.PcdCpuApInitTimeOutInMicroSeconds
>    gUefiCpuPkgTokenSpaceGuid.PcdCpuApStackSize
> +  gEfiMdeModulePkgTokenSpaceGuid.PcdPteMemoryEncryptionAddressOrMask

Ditto for the list of PCDs.

Functionally the patch looks okay to me.

Thanks,
Laszlo

>  
>  [FixedPcd]
>    gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseAddress
> 
> _______________________________________________
> edk2-devel mailing list
> edk2-devel@lists.01.org
> https://lists.01.org/mailman/listinfo/edk2-devel
> 



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

* Re: [RFC PATCH v2 04/10] OvmfPkg/BaseMemcryptSevLib: Add SEV helper library
  2017-03-21 21:13 ` [RFC PATCH v2 04/10] OvmfPkg/BaseMemcryptSevLib: Add SEV helper library Brijesh Singh
@ 2017-03-27  9:19   ` Laszlo Ersek
  2017-03-27 10:07     ` Laszlo Ersek
  0 siblings, 1 reply; 44+ messages in thread
From: Laszlo Ersek @ 2017-03-27  9:19 UTC (permalink / raw)
  To: Brijesh Singh, michael.d.kinney, jordan.l.justen, edk2-devel,
	liming.gao
  Cc: brijesh.singh, leo.duran, Thomas.Lendacky

On 03/21/17 22:13, Brijesh Singh wrote:
> Add Secure Encrypted Virtualization (SEV) helper library. The library provides
> the routines to set or clear memory encryption bit for a given memory region
> and functions to check whether SEV is enabled.

Please rewrap this commit message to 74 characters.

> 
> Signed-off-by: Brijesh Singh <brijesh.singh@amd.com>
> ---
>  OvmfPkg/Include/Library/MemEncryptSevLib.h         |   69 +++++
>  .../BaseMemEncryptSevLib/BaseMemEncryptSevLib.inf  |   46 +++
>  .../BaseMemEncryptSevLib/Ia32/MemEncryptSevLib.c   |  124 ++++++++
>  .../BaseMemEncryptSevLib/X64/MemEncryptSevLib.c    |  120 ++++++++
>  .../BaseMemEncryptSevLib/X64/VirtualMemory.c       |  304 ++++++++++++++++++++
>  .../BaseMemEncryptSevLib/X64/VirtualMemory.h       |  158 ++++++++++
>  OvmfPkg/OvmfPkgIa32.dsc                            |    1 
>  OvmfPkg/OvmfPkgIa32X64.dsc                         |    1 
>  OvmfPkg/OvmfPkgX64.dsc                             |    1 

Please format patches as described under

https://github.com/tianocore/tianocore.github.io/wiki/Laszlo's-unkempt-git-guide-for-edk2-contributors-and-maintainers#contrib-23

In particular, the options

  --stat=1000                                  \
  --stat-graph-width=20                        \

will ensure that git does not use the "..." abbreviation in the
diffstat, while also keeping the plus/minus stats reasonably narrow.

>  9 files changed, 824 insertions(+)
>  create mode 100644 OvmfPkg/Include/Library/MemEncryptSevLib.h
>  create mode 100644 OvmfPkg/Library/BaseMemEncryptSevLib/BaseMemEncryptSevLib.inf
>  create mode 100644 OvmfPkg/Library/BaseMemEncryptSevLib/Ia32/MemEncryptSevLib.c
>  create mode 100644 OvmfPkg/Library/BaseMemEncryptSevLib/X64/MemEncryptSevLib.c
>  create mode 100644 OvmfPkg/Library/BaseMemEncryptSevLib/X64/VirtualMemory.c
>  create mode 100644 OvmfPkg/Library/BaseMemEncryptSevLib/X64/VirtualMemory.h
> 
> diff --git a/OvmfPkg/Include/Library/MemEncryptSevLib.h b/OvmfPkg/Include/Library/MemEncryptSevLib.h
> new file mode 100644
> index 0000000..a9e9356
> --- /dev/null
> +++ b/OvmfPkg/Include/Library/MemEncryptSevLib.h
> @@ -0,0 +1,69 @@
> +/** @file
> +
> +  Define Secure Encrypted Virtualization (SEV) base library helper function
> +
> +  Copyright (c) 2017, AMD Incorporated. All rights reserved.<BR>
> +
> +  This program and the accompanying materials
> +  are licensed and made available under the terms and conditions of the BSD License
> +  which accompanies this distribution.  The full text of the license may be found at

Overlong line. No line should be wider than 79 chars.

> +  http://opensource.org/licenses/bsd-license.php
> +
> +  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
> +  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
> +
> +**/
> +
> +#ifndef __MEM_ENCRYPT_SEV_LIB_H_
> +#define __MEM_ENCRYPT_SEV_LIB_H_

If you start the guard macro name with two underscores, then please also
end it with two underscores.

> +
> +#include <Base.h>
> +
> +/**
> +  Returns a boolean to indicate whether SEV is enabled
> +
> +  @retval TRUE           When SEV is active
> +  @retval FALSE          When SEV is not enabled
> +  **/
> +BOOLEAN
> +EFIAPI
> +MemEncryptSevIsEnabled (
> +  VOID
> +  );

Would it make sense to call this library function in PlatformPei, rather
than add a separate SevIsEnabled() function to it (in patch #3)? The
implementations look nearly identical.

The client module type restrictions under LIBRARY_CLASS (below) look
fine for that; all of the permitted module types support writeable
global variables in OVMF.

> +
> +/**
> +  This function clears memory encryption bit for the memory region specified by BaseAddress and
> +  Number of pages from the current page table context.
> +
> +  @param[in]  BaseAddress           The physical address that is the start address of a memory region.
> +  @param[in]  NumberOfPages         The number of pages from start memory region.
> +
> +  @retval RETURN_SUCCESS            The attributes were cleared for the memory region.
> +  @retval RETURN_INVALID_PARAMETER  Number of pages is zero.
> +  @retval RETURN_UNSUPPORTED        Clearing memory encryption attribute is not supported
> +  **/

These lines as well are too wide.

> +RETURN_STATUS
> +EFIAPI
> +MemEncryptSevClearPageEncMask (
> +  IN PHYSICAL_ADDRESS         BaseAddress,
> +  IN UINT32                   NumberOfPages
> +  );
> +
> +/**
> +  This function sets memory encryption bit for the memory region specified by BaseAddress and
> +  Number of pages from the current page table context.
> +
> +  @param[in]  BaseAddress           The physical address that is the start address of a memory region.
> +  @param[in]  NumberOfPages         The number of pages from start memory region.
> +
> +  @retval RETURN_SUCCESS            The attributes were set for the memory region.
> +  @retval RETURN_INVALID_PARAMETER  Number of pages is zero.
> +  @retval RETURN_UNSUPPORTED        Clearing memory encryption attribute is not supported
> +  **/
> +RETURN_STATUS
> +EFIAPI
> +MemEncryptSevSetPageEncMask (
> +  IN PHYSICAL_ADDRESS         BaseAddress,
> +  IN UINT32                   NumberOfPages
> +  );
> +#endif // __MEM_ENCRYPT_SEV_LIB_H_
> diff --git a/OvmfPkg/Library/BaseMemEncryptSevLib/BaseMemEncryptSevLib.inf b/OvmfPkg/Library/BaseMemEncryptSevLib/BaseMemEncryptSevLib.inf
> new file mode 100644
> index 0000000..c23261f
> --- /dev/null
> +++ b/OvmfPkg/Library/BaseMemEncryptSevLib/BaseMemEncryptSevLib.inf
> @@ -0,0 +1,46 @@
> +## @file

Please add one or two sentences under @file about the purpose of this
library instance.

> +#
> +# Copyright (c) 2017 Advanced Micro Devices. All rights reserved.<BR>
> +#
> +#  This program and the accompanying materials
> +#  are licensed and made available under the terms and conditions of the BSD License
> +#  which accompanies this distribution. The full text of the license may be found at
> +#  http://opensource.org/licenses/bsd-license.php
> +#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
> +#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
> +#
> +#
> +##

Please rewrap to 79 chars.

(I think I won't ask for that explicitly in any other locations; please
just ensure all new files conform to that.)

> +
> +[Defines]
> +  INF_VERSION                    = 0x00010005

Please use "1.25" here, that's the most recent release of the INF spec
(to my knowledge).

> +  BASE_NAME                      = MemEncryptSevLib
> +  FILE_GUID                      = c1594631-3888-4be4-949f-9c630dbc842b
> +  MODULE_TYPE                    = BASE
> +  VERSION_STRING                 = 1.0
> +  LIBRARY_CLASS                  = MemEncryptSevLib|PEIM DXE_DRIVER DXE_RUNTIME_DRIVER DXE_SMM_DRIVER UEFI_DRIVER
> +
> +#
> +# The following information is for reference only and not required by the build tools.
> +#
> +# VALID_ARCHITECTURES           = IA32 X64
> +#
> +
> +[Packages]
> +  MdePkg/MdePkg.dec
> +  MdeModulePkg/MdeModulePkg.dec
> +  OvmfPkg/OvmfPkg.dec
> +  UefiCpuPkg/UefiCpuPkg.dec
> +
> +[Sources.X64]
> +  X64/MemEncryptSevLib.c
> +  X64/VirtualMemory.c
> +
> +[Sources.IA32]
> +  Ia32/MemEncryptSevLib.c
> +
> +[LibraryClasses]
> +  BaseLib
> +  DebugLib
> +  MemoryAllocationLib
> +  CacheMaintenanceLib

Please sort the entries in each section alphabetically.

> diff --git a/OvmfPkg/Library/BaseMemEncryptSevLib/Ia32/MemEncryptSevLib.c b/OvmfPkg/Library/BaseMemEncryptSevLib/Ia32/MemEncryptSevLib.c
> new file mode 100644
> index 0000000..70fdd2e
> --- /dev/null
> +++ b/OvmfPkg/Library/BaseMemEncryptSevLib/Ia32/MemEncryptSevLib.c
> @@ -0,0 +1,124 @@
> +/** @file
> +
> +  Secure Encrypted Virtualization (SEV) library helper function
> +
> +  Copyright (c) 2017, AMD Incorporated. All rights reserved.<BR>
> +
> +  This program and the accompanying materials
> +  are licensed and made available under the terms and conditions of the BSD License
> +  which accompanies this distribution.  The full text of the license may be found at
> +  http://opensource.org/licenses/bsd-license.php
> +
> +  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
> +  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
> +
> +**/
> +
> +#include "Uefi.h"
> +#include <Library/BaseLib.h>
> +#include <Library/DebugLib.h>
> +#include <Register/Cpuid.h>
> +#include <Register/AmdSevMap.h>
> +#include <Library/MemEncryptSevLib.h>
> +
> +STATIC BOOLEAN SevStatus = FALSE;
> +STATIC BOOLEAN SevStatusChecked = FALSE;

These variables should be called mSevStatus and mSevStatusChecked.

> +
> +/**
> + 
> +  Returns a boolean to indicate whether SEV is enabled
> +
> +  @retval TRUE           When SEV is active
> +  @retval FALSE          When SEV is not enabled
> +  **/
> +BOOLEAN
> +EFIAPI
> +MemEncryptSevIsEnabled (
> +  VOID
> +  )
> +{
> +  UINT32 RegEax;
> +  MSR_SEV_STATUS_REGISTER Msr;
> +  CPUID_MEMORY_ENCRYPTION_INFO_EAX  Eax;

Please align the variable names.

> +
> +  //
> +  // If Status is already checked then return it
> +  //
> +  if (SevStatusChecked) {
> +    return SevStatus;
> +  }
> +
> +  //
> +  // Check if memory encryption leaf exist
> +  //
> +  AsmCpuid (CPUID_EXTENDED_FUNCTION, &RegEax, NULL, NULL, NULL);
> +  if (RegEax >= CPUID_MEMORY_ENCRYPTION_INFO) {
> +    //
> +    // CPUID Fn8000_001F[EAX] Bit 1 (Sev supported)
> +    //
> +    AsmCpuid (CPUID_MEMORY_ENCRYPTION_INFO, &Eax.Uint32, NULL, NULL, NULL);
> +
> +    if (Eax.Bits.SevBit) {
> +      //
> +      // Check MSR_0xC0010131 Bit 0 (Sev is Enabled)
> +      //
> +      Msr.Uint32 = AsmReadMsr32 (MSR_SEV_STATUS);
> +      if (Msr.Bits.SevBit) {

You forgot to set mSevStatusChecked to TRUE here.

> +        return TRUE;
> +      }
> +    }
> +  }
> +
> +  SevStatusChecked = TRUE;
> +
> +  return FALSE;
> +}
> +
> +/**
> +  This function clears memory encryption bit for the memory region specified by BaseAddress and
> +  Number of pages from the current page table context.
> +
> +  @param[in]  BaseAddress             The physical address that is the start address of a memory region.
> +  @param[in]  NumberOfPages           The number of pages from start memory region.
> +
> +  @retval RETURN_SUCCESS              The attributes were cleared for the memory region.
> +  @retval RETURN_INVALID_PARAMETER    Number of pages is zero.
> +  @retval RETURN_UNSUPPORTED          Setting the memory encyrption attribute is not supported
> +  **/
> +RETURN_STATUS
> +EFIAPI
> +MemEncryptSevClearPageEncMask (
> +  IN PHYSICAL_ADDRESS         BaseAddress,
> +  IN UINT32                   NumberOfPages
> +  )
> +{
> +  //
> +  // Memory encryption bit is not accessible in 32-bit mode
> +  //
> +  return RETURN_UNSUPPORTED;
> +}
> +
> +/**
> +  This function sets memory encryption bit for the memory region specified by BaseAddress and
> +  Number of pages from the current page table context.
> +
> +  @param[in]  BaseAddress             The physical address that is the start address of a memory region.
> +  @param[in]  NumberOfPages           The number of pages from start memory region.
> +
> +  @retval RETURN_SUCCESS              The attributes were cleared for the memory region.
> +  @retval RETURN_INVALID_PARAMETER    Number of pages is zero.
> +  @retval RETURN_UNSUPPORTED          Setting the memory encyrption attribute is not supported
> +  **/
> +RETURN_STATUS
> +EFIAPI
> +MemEncryptSevSetPageEncMask (
> +  IN PHYSICAL_ADDRESS         BaseAddress,
> +  IN UINT32                   NumberOfPages
> +  )
> +{
> +  //
> +  // Memory encryption bit is not accessible in 32-bit mode
> +  //
> +  return RETURN_UNSUPPORTED;
> +}
> +
> diff --git a/OvmfPkg/Library/BaseMemEncryptSevLib/X64/MemEncryptSevLib.c b/OvmfPkg/Library/BaseMemEncryptSevLib/X64/MemEncryptSevLib.c
> new file mode 100644
> index 0000000..098acf2
> --- /dev/null
> +++ b/OvmfPkg/Library/BaseMemEncryptSevLib/X64/MemEncryptSevLib.c
> @@ -0,0 +1,120 @@
> +/** @file
> +
> +  Secure Encrypted Virtualization (SEV) library helper function
> +
> +  Copyright (c) 2017, AMD Incorporated. All rights reserved.<BR>
> +
> +  This program and the accompanying materials
> +  are licensed and made available under the terms and conditions of the BSD License
> +  which accompanies this distribution.  The full text of the license may be found at
> +  http://opensource.org/licenses/bsd-license.php
> +
> +  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
> +  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
> +
> +**/
> +
> +#include "Uefi.h"
> +#include <Library/BaseLib.h>
> +#include <Library/DebugLib.h>
> +#include <Register/Cpuid.h>
> +#include <Register/AmdSevMap.h>
> +#include <Library/MemEncryptSevLib.h>
> +
> +#include "VirtualMemory.h"
> +
> +STATIC BOOLEAN SevStatus = FALSE;
> +STATIC BOOLEAN SevStatusChecked = FALSE;
> +
> +/**
> +  Returns a boolean to indicate whether SEV is enabled
> +
> +  @retval TRUE           When SEV is active
> +  @retval FALSE          When SEV is not enabled
> +  **/
> +BOOLEAN
> +EFIAPI
> +MemEncryptSevIsEnabled (
> +  VOID
> +  )
> +{
> +  UINT32 RegEax;
> +  MSR_SEV_STATUS_REGISTER Msr;
> +  CPUID_MEMORY_ENCRYPTION_INFO_EAX  Eax;
> +
> +  //
> +  // If Status is already checked then return it
> +  //
> +  if (SevStatusChecked) {
> +    return SevStatus;
> +  }
> +
> +  //
> +  // Check if memory encryption leaf exist
> +  //
> +  AsmCpuid (CPUID_EXTENDED_FUNCTION, &RegEax, NULL, NULL, NULL);
> +  if (RegEax >= CPUID_MEMORY_ENCRYPTION_INFO) {
> +    //
> +    // CPUID Fn8000_001F[EAX] Bit 1 (Sev supported)
> +    //
> +    AsmCpuid (CPUID_MEMORY_ENCRYPTION_INFO, &Eax.Uint32, NULL, NULL, NULL);
> +
> +    if (Eax.Bits.SevBit) {
> +      //
> +      // Check MSR_0xC0010131 Bit 0 (Sev Enabled)
> +      //
> +      Msr.Uint32 = AsmReadMsr32 (MSR_SEV_STATUS);
> +      if (Msr.Bits.SevBit) {
> +        return TRUE;
> +      }
> +    }
> +  }
> +
> +  SevStatusChecked = TRUE;
> +
> +  return FALSE;
> +}

In fact, I suggest that:

(a) you introduce two new files, called

MemEncryptSevLibInternal.h
MemEncryptSevLibInternal.c

(b) add the .c file to both [Sources.X64] and [Sources.IA32],

(c) rename MemEncryptSevIsEnabled() to InternalMemEncryptSevIsEnabled,
and declare it in the new header file,

(d) move MemEncryptSevIsEnabled, SevStatus and SevStatusChecked to the
new .c file.


> +
> +/**
> + 
> +  This function clears memory encryption bit for the memory region specified by BaseAddress and
> +  Number of pages from the current page table context.
> +
> +  @param[in]  BaseAddress             The physical address that is the start address of a memory region.
> +  @param[in]  NumberOfPages           The number of pages from start memory region.
> +
> +  @retval RETURN_SUCCESS              The attributes were cleared for the memory region.
> +  @retval RETURN_INVALID_PARAMETER    Number of pages is zero.
> +  @retval RETURN_UNSUPPORTED          Clearing the memory encryption attribute is not supported
> +  **/
> +RETURN_STATUS
> +EFIAPI
> +MemEncryptSevClearPageEncMask (
> +  IN PHYSICAL_ADDRESS         BaseAddress,
> +  IN UINT32                   NumPages
> +  )
> +{
> +  return Set_Memory_Decrypted (BaseAddress, NumPages * EFI_PAGE_SIZE);
> +}

"Set_Memory_Decrypted" is not idiomatic edk2, please call it
SetMemoryDecrypted,

Also, the second argument should be written as

  EFI_PAGES_TO_SIZE (NumPages)

... However, for that, you should please switch the type of "NumPages"
to UINTN. Is that functionally okay?


> +
> +/**
> + 
> +  This function clears memory encryption bit for the memory region specified by BaseAddress and
> +  Number of pages from the current page table context.
> +
> +  @param[in]  BaseAddress             The physical address that is the start address of a memory region.
> +  @param[in]  NumberOfPages           The number of pages from start memory region.
> +
> +  @retval RETURN_SUCCESS              The attributes were cleared for the memory region.
> +  @retval RETURN_INVALID_PARAMETER    Number of pages is zero.
> +  @retval RETURN_UNSUPPORTED          Clearing the memory encryption attribute is not supported
> +  **/
> +RETURN_STATUS
> +EFIAPI
> +MemEncryptSevSetPageEncMask (
> +  IN PHYSICAL_ADDRESS         BaseAddress,
> +  IN UINT32                   NumPages
> +  )
> +{
> +  return Set_Memory_Encrypted (BaseAddress, NumPages * EFI_PAGE_SIZE);
> +}

Same comments here.

> diff --git a/OvmfPkg/Library/BaseMemEncryptSevLib/X64/VirtualMemory.c b/OvmfPkg/Library/BaseMemEncryptSevLib/X64/VirtualMemory.c
> new file mode 100644
> index 0000000..7acebf3
> --- /dev/null
> +++ b/OvmfPkg/Library/BaseMemEncryptSevLib/X64/VirtualMemory.c
> @@ -0,0 +1,304 @@
> +/** @file
> + 
> +  Virtual Memory Management Services to set or clear the memory encryption bit
> +
> +  References:
> +    1) IA-32 Intel(R) Architecture Software Developer's Manual Volume 1:Basic Architecture, Intel
> +    2) IA-32 Intel(R) Architecture Software Developer's Manual Volume 2:Instruction Set Reference, Intel
> +    3) IA-32 Intel(R) Architecture Software Developer's Manual Volume 3:System Programmer's Guide, Intel
> +
> +Copyright (c) 2006 - 2016, Intel Corporation. All rights reserved.<BR>
> +Copyright (c) 2017, AMD Incorporated. All rights reserved.<BR>
> +
> +This program and the accompanying materials
> +are licensed and made available under the terms and conditions of the BSD License
> +which accompanies this distribution.  The full text of the license may be found at
> +http://opensource.org/licenses/bsd-license.php
> +
> +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
> +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
> +
> +**/
> +
> +#include "VirtualMemory.h"
> +
> +#include <Register/AmdSevMap.h>

Please put the <> includes first, and the "" includes second.

> +
> +STATIC UINT64 AddressEncMask;

Should be called "mAddressEncMask".

> +
> +typedef enum {
> +   SetCBit,
> +   ClearCBit
> +} MAP_RANGE_MODE;
> +
> +/**
> +  Split 2M page to 4K.
> +
> +  @param[in]      PhysicalAddress       Start physical address the 2M page covered.
> +  @param[in, out] PageEntry2M           Pointer to 2M page entry.
> +  @param[in]      StackBase             Stack base address.
> +  @param[in]      StackSize             Stack size.
> +
> +**/
> +STATIC
> +VOID
> +Split2MPageTo4K (
> +  IN EFI_PHYSICAL_ADDRESS               PhysicalAddress,

Your use of PHYSICAL_ADDRESS <-> EFI_PHYSICAL_ADDRESS is inconsistent.
Since this is a BASE type library, I suggest to stick with
PHYSICAL_ADDRESS. Can you please check all occurrences of
EFI_PHYSICAL_ADDRESS?

> +  IN OUT UINT64                         *PageEntry2M,

IN and OUT columns should be visually separated across all parameters.

> +  IN EFI_PHYSICAL_ADDRESS               StackBase,
> +  IN UINTN                              StackSize
> +  )
> +{
> +  EFI_PHYSICAL_ADDRESS                  PhysicalAddress4K;
> +  UINTN                                 IndexOfPageTableEntries;
> +  PAGE_TABLE_4K_ENTRY                   *PageTableEntry, *PageTableEntry1;
> +
> +  PageTableEntry = AllocatePages(1);
> +
> +  PageTableEntry1 = PageTableEntry;
> +
> +  ASSERT (PageTableEntry != NULL);
> +  ASSERT (*PageEntry2M & AddressEncMask);
> +
> +  PhysicalAddress4K = PhysicalAddress;
> +  for (IndexOfPageTableEntries = 0; IndexOfPageTableEntries < 512; IndexOfPageTableEntries++, PageTableEntry++, PhysicalAddress4K += SIZE_4KB) {
> +    //
> +    // Fill in the Page Table entries
> +    //
> +    PageTableEntry->Uint64 = (UINT64) PhysicalAddress4K | AddressEncMask;
> +    PageTableEntry->Bits.ReadWrite = 1;
> +    PageTableEntry->Bits.Present = 1;
> +    if ((PhysicalAddress4K >= StackBase) && (PhysicalAddress4K < StackBase + StackSize)) {
> +      //
> +      // Set Nx bit for stack.
> +      //
> +      PageTableEntry->Bits.Nx = 1;
> +    }
> +  }
> +
> +  //
> +  // Fill in 2M page entry.
> +  //
> +  *PageEntry2M = (UINT64) (UINTN) PageTableEntry1 | IA32_PG_P | IA32_PG_RW | AddressEncMask;
> +}

Side question: is this function copied from some other place in edk2? If
so, I suggest to add a comment (in the code or in the commit message)
where it comes from.

Also, shouldn't you call CpuFlushTlb() somewhere, when messing with page
tables? (Hm, maybe not; a given virtual address will continue to map to
the same physical address.)

> +
> +/**
> +  Split 1G page to 2M.
> +
> +  @param[in]      PhysicalAddress       Start physical address the 1G page covered.
> +  @param[in, out] PageEntry1G           Pointer to 1G page entry.
> +  @param[in]      StackBase             Stack base address.
> +  @param[in]      StackSize             Stack size.
> +
> +**/
> +STATIC
> +VOID
> +Split1GPageTo2M (
> +  IN EFI_PHYSICAL_ADDRESS               PhysicalAddress,
> +  IN OUT UINT64                         *PageEntry1G,
> +  IN EFI_PHYSICAL_ADDRESS               StackBase,
> +  IN UINTN                              StackSize
> +  )
> +{
> +  EFI_PHYSICAL_ADDRESS                  PhysicalAddress2M;
> +  UINTN                                 IndexOfPageDirectoryEntries;
> +  PAGE_TABLE_ENTRY                      *PageDirectoryEntry;
> +
> +  PageDirectoryEntry = AllocatePages(1);
> +
> +  ASSERT (PageDirectoryEntry != NULL);
> +  ASSERT (*PageEntry1G & AddressEncMask);
> +  //
> +  // Fill in 1G page entry.
> +  //
> +  *PageEntry1G = (UINT64) (UINTN) PageDirectoryEntry | IA32_PG_P | IA32_PG_RW | AddressEncMask;
> +
> +  PhysicalAddress2M = PhysicalAddress;
> +  for (IndexOfPageDirectoryEntries = 0; IndexOfPageDirectoryEntries < 512; IndexOfPageDirectoryEntries++, PageDirectoryEntry++, PhysicalAddress2M += SIZE_2MB) {
> +    if ((PhysicalAddress2M < StackBase + StackSize) && ((PhysicalAddress2M + SIZE_2MB) > StackBase)) {
> +      //
> +      // Need to split this 2M page that covers stack range.
> +      //
> +      Split2MPageTo4K (PhysicalAddress2M, (UINT64 *) PageDirectoryEntry, StackBase, StackSize);
> +    } else {
> +      //
> +      // Fill in the Page Directory entries
> +      //
> +      PageDirectoryEntry->Uint64 = (UINT64) PhysicalAddress2M | AddressEncMask;
> +      PageDirectoryEntry->Bits.ReadWrite = 1;
> +      PageDirectoryEntry->Bits.Present = 1;
> +      PageDirectoryEntry->Bits.MustBe1 = 1;
> +    }
> +  }
> +}
> +
> +
> +STATIC VOID
> +SetOrClearCBit(
> +  IN UINT64*  PageTablePointer,
> +  IN MAP_RANGE_MODE Mode

Non-idiomatic formatting, plus "IN" is actually incorrect for
PageTablePointer, as it is both read and written. This is what you need:

  IN OUT UINT64         *PageTablePointer,
  IN     MAP_RANGE_MODE Mode

> +  )
> +{
> +  if (Mode == SetCBit) {
> +    *PageTablePointer |= AddressEncMask;
> +  } else {
> +    *PageTablePointer &= ~AddressEncMask;
> +  }
> +
> +}
> +
> +STATIC
> +UINT64
> +GetMemEncryptionAddressMask (
> +  VOID
> +  )
> +{
> +  UINT64 MeMask;
> +  CPUID_MEMORY_ENCRYPTION_INFO_EBX  Ebx;

variable name alignment

> +
> +  //
> +  // CPUID Fn8000_001F[EBX] Bit 0:5 (memory encryption bit position)
> +  //
> +  AsmCpuid (CPUID_MEMORY_ENCRYPTION_INFO, NULL, &Ebx.Uint32, NULL, NULL);
> +  MeMask = LShiftU64 (1, Ebx.Bits.PtePosBits);
> +
> +  return MeMask & PAGING_1G_ADDRESS_MASK_64;
> +}

Can you perhaps export this function and call it from PlatformPei as
well? Just asking.

> +
> +STATIC
> +EFI_STATUS
> +EFIAPI
> +Set_Memory_Enc_Dec (

Please use camel case without underscores.

Also, this function looks like the "workhorse" of the library. Can you
add a leading comment block to it?

> +  IN EFI_PHYSICAL_ADDRESS     PhysicalAddress,
> +  IN UINT64                   Length,
> +  IN MAP_RANGE_MODE           Mode
> +  )
> +{
> +  PAGE_MAP_AND_DIRECTORY_POINTER *PageMapLevel4Entry;
> +  PAGE_MAP_AND_DIRECTORY_POINTER *PageUpperDirectoryPointerEntry;
> +  PAGE_MAP_AND_DIRECTORY_POINTER *PageDirectoryPointerEntry;
> +  PAGE_TABLE_1G_ENTRY            *PageDirectory1GEntry;
> +  PAGE_TABLE_ENTRY               *PageDirectory2MEntry;
> +  PAGE_TABLE_4K_ENTRY            *PageTableEntry;
> +  UINT64                         PgTableMask;
> +
> +  AddressEncMask = GetMemEncryptionAddressMask ();

You unconditionally rewrite the static variable here, and then you rely
on it in the other helper functions.

What do you think about adding some internal caching to
GetMemEncryptionAddressMask(), and then calling
GetMemEncryptionAddressMask() explicitly everywhere the mask is needed?

> +
> +  if (!AddressEncMask) {
> +    return RETURN_ACCESS_DENIED;
> +  }
> +
> +  PgTableMask = AddressEncMask | EFI_PAGE_MASK;
> +
> +  DEBUG ((EFI_D_VERBOSE, "Set memory range 0x%#Lx+0x%x (%s)\n", PhysicalAddress, Length,
> +			  Mode == ClearCBit ? "unencrypted" : "encrypted"));

Please use DEBUG_VERBOSE.

Also, %x is not right for printing Length (UINT64).

> +
> +  if (Length == 0) {
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  //
> +  // We are going to change the memory encryption attribute from C=0 -> C=1 or vice versa
> +  // Flush the caches to ensure that data is written into memory with correct C-bit
> +  //
> +  WriteBackInvalidateDataCacheRange((VOID*) PhysicalAddress, Length);

Please convert pointers to (UINTN) first.

> +
> +  while (Length)
> +  {
> +
> +    PageMapLevel4Entry = (VOID*) (AsmReadCr3() & ~PgTableMask);
> +    PageMapLevel4Entry += PML4_OFFSET(PhysicalAddress);
> +    if (!PageMapLevel4Entry->Bits.Present) {
> +      DEBUG((DEBUG_WARN, "ERROR bad PML4 for %lx\n", PhysicalAddress));

missing space after DEBUG

> +      return EFI_NO_MAPPING;
> +    }
> +
> +    PageDirectory1GEntry = (VOID*) (PageMapLevel4Entry->Bits.PageTableBaseAddress<<12 & ~PgTableMask);

missing spaces around <<

also, to clarify the binding precedence of << over &, please use
parentheses.

> +    PageDirectory1GEntry += PDP_OFFSET(PhysicalAddress);
> +    if (!PageDirectory1GEntry->Bits.Present) {
> +       DEBUG((DEBUG_WARN, "ERROR bad PDPE for %lx\n", PhysicalAddress));

missing space after DEBUG... please check the rest of the occurrences

> +       return EFI_NO_MAPPING;
> +    }
> +
> +    // If the MustBe1 bit is not 1, it's not actually a 1GB entry

Comment style is

//
// comment
//

please check the rest

> +    if (PageDirectory1GEntry->Bits.MustBe1) {
> +      // Valid 1GB page
> +      // If we have at least 1GB to go, we can just update this entry
> +      if (!(PhysicalAddress & ((1<<30) - 1)) && Length >= (1<<30)) {

For constants like the above, please consider using the macro BIT30

> +        SetOrClearCBit(&PageDirectory1GEntry->Uint64, Mode);

missing space after SetOrClearCBit

> +        DEBUG((DEBUG_VERBOSE, "Updated 1GB entry for %lx\n", PhysicalAddress));
> +        PhysicalAddress += 1<<30;
> +        Length -= 1<<30;
> +      } else {
> +        // We must split the page
> +        DEBUG((DEBUG_VERBOSE, "Spliting 1GB page\n"));
> +        Split1GPageTo2M(((UINT64)PageDirectory1GEntry->Bits.PageTableBaseAddress)<<30, (UINT64*) PageDirectory1GEntry, 0, 0);
> +        continue;
> +      }
> +    } else {
> +      // Actually a PDP
> +      PageUpperDirectoryPointerEntry = (PAGE_MAP_AND_DIRECTORY_POINTER*) PageDirectory1GEntry;
> +      PageDirectory2MEntry = (VOID*) (PageUpperDirectoryPointerEntry->Bits.PageTableBaseAddress<<12 & ~PgTableMask);
> +      PageDirectory2MEntry += PDE_OFFSET(PhysicalAddress);
> +      if (!PageDirectory2MEntry->Bits.Present) {
> +        DEBUG((DEBUG_WARN, "ERROR bad PDE for %lx\n", PhysicalAddress));
> +        return EFI_NO_MAPPING;
> +      }
> +      // If the MustBe1 bit is not a 1, it's not a 2MB entry
> +      if (PageDirectory2MEntry->Bits.MustBe1) {
> +        // Valid 2MB page
> +        // If we have at least 2MB left to go, we can just update this entry
> +        if (!(PhysicalAddress & ((1<<21)-1)) && Length >= (1<<21)) {
> +          SetOrClearCBit(&PageDirectory2MEntry->Uint64, Mode);
> +          DEBUG((DEBUG_VERBOSE, "Updated 2MB entry for %lx\n", PhysicalAddress));
> +          PhysicalAddress += 1<<21;
> +          Length -= 1<<21;
> +        } else {
> +          // We must split up this page into 4K pages
> +          DEBUG((DEBUG_VERBOSE, "Spliting 2MB page at %lx\n", PhysicalAddress));
> +          Split2MPageTo4K(((UINT64)PageDirectory2MEntry->Bits.PageTableBaseAddress) << 21, (UINT64*) PageDirectory2MEntry, 0, 0);
> +          continue;
> +        }
> +      } else {
> +        PageDirectoryPointerEntry = (PAGE_MAP_AND_DIRECTORY_POINTER*) PageDirectory2MEntry;
> +        PageTableEntry = (VOID*) (PageDirectoryPointerEntry->Bits.PageTableBaseAddress<<12 & ~PgTableMask);
> +        PageTableEntry += PTE_OFFSET(PhysicalAddress);
> +        if (!PageTableEntry->Bits.Present) {
> +          DEBUG((DEBUG_WARN, "ERROR bad PTE for %lx\n", PhysicalAddress));
> +          return EFI_NO_MAPPING;
> +        }
> +        SetOrClearCBit(&PageTableEntry->Uint64, Mode);
> +        DEBUG((DEBUG_VERBOSE, "Updated 4KB entry for %lx\n", PhysicalAddress));
> +        PhysicalAddress += EFI_PAGE_SIZE;
> +        Length -= EFI_PAGE_SIZE;
> +      }
> +    }
> +  }

So, I didn't do any functional validation for the above, just coding style.

> +
> +  //
> +  // Flush TLB
> +  //
> +  AsmWriteCr3(AsmReadCr3());

Please just call CpuFlushTlb().

> +  return EFI_SUCCESS;
> +}
> +
> +EFI_STATUS
> +EFIAPI
> +Set_Memory_Decrypted (
> +  IN  EFI_PHYSICAL_ADDRESS     PhysicalAddress,
> +  IN  UINT64                   Length
> +  )
> +{
> +  return Set_Memory_Enc_Dec (PhysicalAddress, Length, ClearCBit);
> +}
> +
> +EFI_STATUS
> +EFIAPI
> +Set_Memory_Encrypted (
> +  IN  EFI_PHYSICAL_ADDRESS     PhysicalAddress,
> +  IN  UINT64                   Length
> +  )
> +{
> +  return Set_Memory_Enc_Dec (PhysicalAddress, Length, SetCBit);
> +}
> +
> diff --git a/OvmfPkg/Library/BaseMemEncryptSevLib/X64/VirtualMemory.h b/OvmfPkg/Library/BaseMemEncryptSevLib/X64/VirtualMemory.h

Can we upstream the contents of this file to MdePkg somehow? My first
idea would be Include/IndustryStandard.

However, the following types are already in
"MdePkg/Include/Library/BaseLib.h":

///
/// IA32 and x64 Specific Functions.
/// Byte packed structure for 16-bit Real Mode EFLAGS.
///

IA32_FLAGS16, IA32_EFLAGS32, IA32_CR0, IA32_CR4,
IA32_SEGMENT_DESCRIPTOR, IA32_DESCRIPTOR, IA32_IDT_GATE_DESCRIPTOR, ...
and a bunch of others.

I'm asking because now we have:

BaseTools/Source/C/GenPage/VirtualMemory.h
DuetPkg/DxeIpl/Ia32/VirtualMemory.h
DuetPkg/DxeIpl/X64/VirtualMemory.h
MdeModulePkg/Core/DxeIplPeim/X64/VirtualMemory.h
OvmfPkg/Library/BaseMemEncryptSevLib/X64/VirtualMemory.h

> new file mode 100644
> index 0000000..a556211
> --- /dev/null
> +++ b/OvmfPkg/Library/BaseMemEncryptSevLib/X64/VirtualMemory.h
> @@ -0,0 +1,158 @@
> +/** @file
> + 
> +  Virtual Memory Management Services to set or clear the memory encryption bit
> +
> +  References:
> +    1) IA-32 Intel(R) Architecture Software Developer's Manual Volume 1:Basic Architecture, Intel
> +    2) IA-32 Intel(R) Architecture Software Developer's Manual Volume 2:Instruction Set Reference, Intel
> +    3) IA-32 Intel(R) Architecture Software Developer's Manual Volume 3:System Programmer's Guide, Intel
> +
> +Copyright (c) 2006 - 2016, Intel Corporation. All rights reserved.<BR>
> +Copyright (c) 2017, AMD Incorporated. All rights reserved.<BR>
> +
> +This program and the accompanying materials
> +are licensed and made available under the terms and conditions of the BSD License
> +which accompanies this distribution.  The full text of the license may be found at
> +http://opensource.org/licenses/bsd-license.php
> +
> +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
> +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
> +
> +**/
> +
> +#ifndef __VIRTUAL_MEMORY__
> +#define __VIRTUAL_MEMORY__
> +
> +#include <Uefi.h>
> +#include <Library/BaseLib.h>
> +#include <Library/BaseMemoryLib.h>
> +#include <Library/DebugLib.h>
> +#include <Library/MemoryAllocationLib.h>
> +//#include <Library/UefiBootServicesTableLib.h>
> +//#include <Library/UefiRuntimeServicesTableLib.h>
> +
> +#include <Library/CacheMaintenanceLib.h>
> +#define SYS_CODE64_SEL 0x38
> +
> +#pragma pack(1)
> +
> +//
> +// Page-Map Level-4 Offset (PML4) and
> +// Page-Directory-Pointer Offset (PDPE) entries 4K & 2MB
> +//
> +
> +typedef union {
> +  struct {
> +    UINT64  Present:1;                // 0 = Not present in memory, 1 = Present in memory
> +    UINT64  ReadWrite:1;              // 0 = Read-Only, 1= Read/Write
> +    UINT64  UserSupervisor:1;         // 0 = Supervisor, 1=User
> +    UINT64  WriteThrough:1;           // 0 = Write-Back caching, 1=Write-Through caching
> +    UINT64  CacheDisabled:1;          // 0 = Cached, 1=Non-Cached
> +    UINT64  Accessed:1;               // 0 = Not accessed, 1 = Accessed (set by CPU)
> +    UINT64  Reserved:1;               // Reserved
> +    UINT64  MustBeZero:2;             // Must Be Zero
> +    UINT64  Available:3;              // Available for use by system software
> +    UINT64  PageTableBaseAddress:40;  // Page Table Base Address
> +    UINT64  AvabilableHigh:11;        // Available for use by system software
> +    UINT64  Nx:1;                     // No Execute bit
> +  } Bits;
> +  UINT64    Uint64;
> +} PAGE_MAP_AND_DIRECTORY_POINTER;
> +
> +//
> +// Page Table Entry 4KB
> +//
> +typedef union {
> +  struct {
> +    UINT64  Present:1;                // 0 = Not present in memory, 1 = Present in memory
> +    UINT64  ReadWrite:1;              // 0 = Read-Only, 1= Read/Write
> +    UINT64  UserSupervisor:1;         // 0 = Supervisor, 1=User
> +    UINT64  WriteThrough:1;           // 0 = Write-Back caching, 1=Write-Through caching
> +    UINT64  CacheDisabled:1;          // 0 = Cached, 1=Non-Cached
> +    UINT64  Accessed:1;               // 0 = Not accessed, 1 = Accessed (set by CPU)
> +    UINT64  Dirty:1;                  // 0 = Not Dirty, 1 = written by processor on access to page
> +    UINT64  PAT:1;                    //
> +    UINT64  Global:1;                 // 0 = Not global page, 1 = global page TLB not cleared on CR3 write
> +    UINT64  Available:3;              // Available for use by system software
> +    UINT64  PageTableBaseAddress:40;  // Page Table Base Address
> +    UINT64  AvabilableHigh:11;        // Available for use by system software
> +    UINT64  Nx:1;                     // 0 = Execute Code, 1 = No Code Execution
> +  } Bits;
> +  UINT64    Uint64;
> +} PAGE_TABLE_4K_ENTRY;
> +
> +//
> +// Page Table Entry 2MB
> +//
> +typedef union {
> +  struct {
> +    UINT64  Present:1;                // 0 = Not present in memory, 1 = Present in memory
> +    UINT64  ReadWrite:1;              // 0 = Read-Only, 1= Read/Write
> +    UINT64  UserSupervisor:1;         // 0 = Supervisor, 1=User
> +    UINT64  WriteThrough:1;           // 0 = Write-Back caching, 1=Write-Through caching
> +    UINT64  CacheDisabled:1;          // 0 = Cached, 1=Non-Cached
> +    UINT64  Accessed:1;               // 0 = Not accessed, 1 = Accessed (set by CPU)
> +    UINT64  Dirty:1;                  // 0 = Not Dirty, 1 = written by processor on access to page
> +    UINT64  MustBe1:1;                // Must be 1 
> +    UINT64  Global:1;                 // 0 = Not global page, 1 = global page TLB not cleared on CR3 write
> +    UINT64  Available:3;              // Available for use by system software
> +    UINT64  PAT:1;                    //
> +    UINT64  MustBeZero:8;             // Must be zero;
> +    UINT64  PageTableBaseAddress:31;  // Page Table Base Address
> +    UINT64  AvabilableHigh:11;        // Available for use by system software
> +    UINT64  Nx:1;                     // 0 = Execute Code, 1 = No Code Execution
> +  } Bits;
> +  UINT64    Uint64;
> +} PAGE_TABLE_ENTRY;
> +
> +//
> +// Page Table Entry 1GB
> +//
> +typedef union {
> +  struct {
> +    UINT64  Present:1;                // 0 = Not present in memory, 1 = Present in memory
> +    UINT64  ReadWrite:1;              // 0 = Read-Only, 1= Read/Write
> +    UINT64  UserSupervisor:1;         // 0 = Supervisor, 1=User
> +    UINT64  WriteThrough:1;           // 0 = Write-Back caching, 1=Write-Through caching
> +    UINT64  CacheDisabled:1;          // 0 = Cached, 1=Non-Cached
> +    UINT64  Accessed:1;               // 0 = Not accessed, 1 = Accessed (set by CPU)
> +    UINT64  Dirty:1;                  // 0 = Not Dirty, 1 = written by processor on access to page
> +    UINT64  MustBe1:1;                // Must be 1 
> +    UINT64  Global:1;                 // 0 = Not global page, 1 = global page TLB not cleared on CR3 write
> +    UINT64  Available:3;              // Available for use by system software
> +    UINT64  PAT:1;                    //
> +    UINT64  MustBeZero:17;            // Must be zero;
> +    UINT64  PageTableBaseAddress:22;  // Page Table Base Address
> +    UINT64  AvabilableHigh:11;        // Available for use by system software
> +    UINT64  Nx:1;                     // 0 = Execute Code, 1 = No Code Execution
> +  } Bits;
> +  UINT64    Uint64;
> +} PAGE_TABLE_1G_ENTRY;
> +
> +#pragma pack()
> +
> +#define IA32_PG_P                   BIT0
> +#define IA32_PG_RW                  BIT1
> +
> +#define PAGETABLE_ENTRY_MASK        ((1UL << 9) - 1) 
> +#define PML4_OFFSET(x)              ( (x >> 39) & PAGETABLE_ENTRY_MASK) 
> +#define PDP_OFFSET(x)               ( (x >> 30) & PAGETABLE_ENTRY_MASK) 
> +#define PDE_OFFSET(x)               ( (x >> 21) & PAGETABLE_ENTRY_MASK) 
> +#define PTE_OFFSET(x)               ( (x >> 12) & PAGETABLE_ENTRY_MASK) 
> +#define PAGING_1G_ADDRESS_MASK_64   0x000FFFFFC0000000ull
> +
> +EFI_STATUS
> +EFIAPI
> +Set_Memory_Decrypted (
> +  IN  EFI_PHYSICAL_ADDRESS     PhysicalAddress,
> +  IN  UINT64                   Length
> +  );
> +
> +EFI_STATUS
> +EFIAPI
> +Set_Memory_Encrypted (
> +  IN  EFI_PHYSICAL_ADDRESS     PhysicalAddress,
> +  IN  UINT64                   Length
> +  );
> +
> +#endif
> diff --git a/OvmfPkg/OvmfPkgIa32.dsc b/OvmfPkg/OvmfPkgIa32.dsc
> index 769251d..c2821b7 100644
> --- a/OvmfPkg/OvmfPkgIa32.dsc
> +++ b/OvmfPkg/OvmfPkgIa32.dsc
> @@ -126,6 +126,7 @@
>    QemuFwCfgLib|OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgLib.inf
>    VirtioLib|OvmfPkg/Library/VirtioLib/VirtioLib.inf
>    LoadLinuxLib|OvmfPkg/Library/LoadLinuxLib/LoadLinuxLib.inf
> +  MemEncryptSevLib|OvmfPkg/Library/BaseMemEncryptSevLib/BaseMemEncryptSevLib.inf
>  !if $(SMM_REQUIRE) == FALSE
>    LockBoxLib|OvmfPkg/Library/LockBoxLib/LockBoxBaseLib.inf
>  !endif
> diff --git a/OvmfPkg/OvmfPkgIa32X64.dsc b/OvmfPkg/OvmfPkgIa32X64.dsc
> index 3874c35..1dd8064 100644
> --- a/OvmfPkg/OvmfPkgIa32X64.dsc
> +++ b/OvmfPkg/OvmfPkgIa32X64.dsc
> @@ -131,6 +131,7 @@
>    QemuFwCfgLib|OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgLib.inf
>    VirtioLib|OvmfPkg/Library/VirtioLib/VirtioLib.inf
>    LoadLinuxLib|OvmfPkg/Library/LoadLinuxLib/LoadLinuxLib.inf
> +  MemEncryptSevLib|OvmfPkg/Library/BaseMemEncryptSevLib/BaseMemEncryptSevLib.inf
>  !if $(SMM_REQUIRE) == FALSE
>    LockBoxLib|OvmfPkg/Library/LockBoxLib/LockBoxBaseLib.inf
>  !endif
> diff --git a/OvmfPkg/OvmfPkgX64.dsc b/OvmfPkg/OvmfPkgX64.dsc
> index fe7f086..06bee32 100644
> --- a/OvmfPkg/OvmfPkgX64.dsc
> +++ b/OvmfPkg/OvmfPkgX64.dsc
> @@ -131,6 +131,7 @@
>    QemuFwCfgLib|OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgLib.inf
>    VirtioLib|OvmfPkg/Library/VirtioLib/VirtioLib.inf
>    LoadLinuxLib|OvmfPkg/Library/LoadLinuxLib/LoadLinuxLib.inf
> +  MemEncryptSevLib|OvmfPkg/Library/BaseMemEncryptSevLib/BaseMemEncryptSevLib.inf
>  !if $(SMM_REQUIRE) == FALSE
>    LockBoxLib|OvmfPkg/Library/LockBoxLib/LockBoxBaseLib.inf
>  !endif
> 

Thanks
Laszlo



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

* Re: [RFC PATCH v2 06/10] OvmfPkg/DxeBmDmaLib: Fix AllocateBounceBuffer parameter
  2017-03-21 21:13 ` [RFC PATCH v2 06/10] OvmfPkg/DxeBmDmaLib: Fix AllocateBounceBuffer parameter Brijesh Singh
@ 2017-03-27  9:21   ` Laszlo Ersek
  2017-03-27 18:40     ` Brijesh Singh
  0 siblings, 1 reply; 44+ messages in thread
From: Laszlo Ersek @ 2017-03-27  9:21 UTC (permalink / raw)
  To: Brijesh Singh, michael.d.kinney, jordan.l.justen, edk2-devel,
	liming.gao
  Cc: brijesh.singh, leo.duran, Thomas.Lendacky

On 03/21/17 22:13, Brijesh Singh wrote:
> The patch fixes AllocateBounceBuffer parameters.
> 
> Signed-off-by: Brijesh Singh <brijesh.singh@amd.com>
> ---
>  OvmfPkg/Library/DxeBmDmaLib/DxeBmDmaLib.c |    2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/OvmfPkg/Library/DxeBmDmaLib/DxeBmDmaLib.c b/OvmfPkg/Library/DxeBmDmaLib/DxeBmDmaLib.c
> index a342c9e..0d960a8 100644
> --- a/OvmfPkg/Library/DxeBmDmaLib/DxeBmDmaLib.c
> +++ b/OvmfPkg/Library/DxeBmDmaLib/DxeBmDmaLib.c
> @@ -192,8 +192,8 @@ BmDmaMap (
>    }
>  
>    return AllocateBounceBuffer ( 
> -           Operation,
>             FORCE_BELOW_4GB_TRUE,   
> +           Operation,
>             PhysicalAddress,
>             NumberOfBytes,
>             DeviceAddress,
> 
> _______________________________________________
> edk2-devel mailing list
> edk2-devel@lists.01.org
> https://lists.01.org/mailman/listinfo/edk2-devel
> 

I'm not yet convinced that we should copy DxeBmDmaLib to OvmfPkg at all,
but even if we do, the argument order should be fixed in the original
first (under MdeModulePkg), and then copied to OvmfPkg.

Thanks
Laszlo


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

* Re: [RFC PATCH v2 05/10] OvmfPkg/DxeBmDmaLib: Import DxeBmDmaLib package
  2017-03-21 21:13 ` [RFC PATCH v2 05/10] OvmfPkg/DxeBmDmaLib: Import DxeBmDmaLib package Brijesh Singh
@ 2017-03-27  9:22   ` Laszlo Ersek
  0 siblings, 0 replies; 44+ messages in thread
From: Laszlo Ersek @ 2017-03-27  9:22 UTC (permalink / raw)
  To: Brijesh Singh, michael.d.kinney, jordan.l.justen, edk2-devel,
	liming.gao
  Cc: brijesh.singh, leo.duran, Thomas.Lendacky

On 03/21/17 22:13, Brijesh Singh wrote:
> Import DxeBmDmaLib package in OvmfPkg, we need to modify the package to
> include SEV support.
> 
> The BmDmaLib is proposed by Leo Duran
> https://lists.01.org/pipermail/edk2-devel/2017-March/008109.html
> 
> Signed-off-by: Brijesh Singh <brijesh.singh@amd.com>
> ---
>  OvmfPkg/Include/Library/BmDmaLib.h               |    0 
>  OvmfPkg/Library/DxeBmDmaLib/DxeBmDmaLib.c        |    0 
>  OvmfPkg/Library/DxeBmDmaLib/DxeBmDmaLib.inf      |    0 
>  OvmfPkg/OvmfPkgIa32.dsc                          |    2 +-
>  OvmfPkg/OvmfPkgIa32X64.dsc                       |    2 +-
>  OvmfPkg/OvmfPkgX64.dsc                           |    2 +-
>  6 files changed, 3 insertions(+), 3 deletions(-)
>  copy MdeModulePkg/Include/Library/BmDmaLib.h => OvmfPkg/Include/Library/BmDmaLib.h (100%)
>  copy MdeModulePkg/Library/DxeBmDmaLib/DxeBmDmaLib.c => OvmfPkg/Library/DxeBmDmaLib/DxeBmDmaLib.c (100%)
>  copy MdeModulePkg/Library/DxeBmDmaLib/DxeBmDmaLib.inf => OvmfPkg/Library/DxeBmDmaLib/DxeBmDmaLib.inf (100%)

I'm not yet convinced that we need a separate instance of this library
class, but even if that's the case, the library class header should
never be copied.

Thanks
Laszlo

> 
> diff --git a/MdeModulePkg/Include/Library/BmDmaLib.h b/OvmfPkg/Include/Library/BmDmaLib.h
> similarity index 100%
> copy from MdeModulePkg/Include/Library/BmDmaLib.h
> copy to OvmfPkg/Include/Library/BmDmaLib.h
> diff --git a/MdeModulePkg/Library/DxeBmDmaLib/DxeBmDmaLib.c b/OvmfPkg/Library/DxeBmDmaLib/DxeBmDmaLib.c
> similarity index 100%
> copy from MdeModulePkg/Library/DxeBmDmaLib/DxeBmDmaLib.c
> copy to OvmfPkg/Library/DxeBmDmaLib/DxeBmDmaLib.c
> diff --git a/MdeModulePkg/Library/DxeBmDmaLib/DxeBmDmaLib.inf b/OvmfPkg/Library/DxeBmDmaLib/DxeBmDmaLib.inf
> similarity index 100%
> copy from MdeModulePkg/Library/DxeBmDmaLib/DxeBmDmaLib.inf
> copy to OvmfPkg/Library/DxeBmDmaLib/DxeBmDmaLib.inf
> diff --git a/OvmfPkg/OvmfPkgIa32.dsc b/OvmfPkg/OvmfPkgIa32.dsc
> index c2821b7..58d6c3d 100644
> --- a/OvmfPkg/OvmfPkgIa32.dsc
> +++ b/OvmfPkg/OvmfPkgIa32.dsc
> @@ -91,7 +91,7 @@
>    UefiHiiServicesLib|MdeModulePkg/Library/UefiHiiServicesLib/UefiHiiServicesLib.inf
>    HiiLib|MdeModulePkg/Library/UefiHiiLib/UefiHiiLib.inf
>    SortLib|MdeModulePkg/Library/UefiSortLib/UefiSortLib.inf
> -  BmDmaLib|MdeModulePkg/Library/DxeBmDmaLib/DxeBmDmaLib.inf
> +  BmDmaLib|OvmfPkg/Library/DxeBmDmaLib/DxeBmDmaLib.inf
>    UefiBootManagerLib|MdeModulePkg/Library/UefiBootManagerLib/UefiBootManagerLib.inf
>    BootLogoLib|MdeModulePkg/Library/BootLogoLib/BootLogoLib.inf
>    FileExplorerLib|MdeModulePkg/Library/FileExplorerLib/FileExplorerLib.inf
> diff --git a/OvmfPkg/OvmfPkgIa32X64.dsc b/OvmfPkg/OvmfPkgIa32X64.dsc
> index 1dd8064..ac2ef24 100644
> --- a/OvmfPkg/OvmfPkgIa32X64.dsc
> +++ b/OvmfPkg/OvmfPkgIa32X64.dsc
> @@ -96,7 +96,7 @@
>    UefiHiiServicesLib|MdeModulePkg/Library/UefiHiiServicesLib/UefiHiiServicesLib.inf
>    HiiLib|MdeModulePkg/Library/UefiHiiLib/UefiHiiLib.inf
>    SortLib|MdeModulePkg/Library/UefiSortLib/UefiSortLib.inf
> -  BmDmaLib|MdeModulePkg/Library/DxeBmDmaLib/DxeBmDmaLib.inf
> +  BmDmaLib|OvmfPkg/Library/DxeBmDmaLib/DxeBmDmaLib.inf
>    UefiBootManagerLib|MdeModulePkg/Library/UefiBootManagerLib/UefiBootManagerLib.inf
>    BootLogoLib|MdeModulePkg/Library/BootLogoLib/BootLogoLib.inf
>    FileExplorerLib|MdeModulePkg/Library/FileExplorerLib/FileExplorerLib.inf
> diff --git a/OvmfPkg/OvmfPkgX64.dsc b/OvmfPkg/OvmfPkgX64.dsc
> index 06bee32..799f9e1 100644
> --- a/OvmfPkg/OvmfPkgX64.dsc
> +++ b/OvmfPkg/OvmfPkgX64.dsc
> @@ -96,7 +96,7 @@
>    UefiHiiServicesLib|MdeModulePkg/Library/UefiHiiServicesLib/UefiHiiServicesLib.inf
>    HiiLib|MdeModulePkg/Library/UefiHiiLib/UefiHiiLib.inf
>    SortLib|MdeModulePkg/Library/UefiSortLib/UefiSortLib.inf
> -  BmDmaLib|MdeModulePkg/Library/DxeBmDmaLib/DxeBmDmaLib.inf
> +  BmDmaLib|OvmfPkg/Library/DxeBmDmaLib/DxeBmDmaLib.inf
>    UefiBootManagerLib|MdeModulePkg/Library/UefiBootManagerLib/UefiBootManagerLib.inf
>    BootLogoLib|MdeModulePkg/Library/BootLogoLib/BootLogoLib.inf
>    FileExplorerLib|MdeModulePkg/Library/FileExplorerLib/FileExplorerLib.inf
> 
> _______________________________________________
> edk2-devel mailing list
> edk2-devel@lists.01.org
> https://lists.01.org/mailman/listinfo/edk2-devel
> 



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

* Re: [RFC PATCH v2 07/10] OvmfPkg/BmDmaLib: Add SEV support
  2017-03-21 21:13 ` [RFC PATCH v2 07/10] OvmfPkg/BmDmaLib: Add SEV support Brijesh Singh
@ 2017-03-27  9:28   ` Laszlo Ersek
  0 siblings, 0 replies; 44+ messages in thread
From: Laszlo Ersek @ 2017-03-27  9:28 UTC (permalink / raw)
  To: Brijesh Singh, michael.d.kinney, jordan.l.justen, edk2-devel,
	liming.gao
  Cc: brijesh.singh, leo.duran, Thomas.Lendacky

On 03/21/17 22:13, Brijesh Singh wrote:
> When SEV is enabled, the DMA operations must be performed on a shared
> (i.e unencrypted) pages. The patch adds SEV specific hooks to use the
> bounce buffer when caller map/unmap host address to a DMA address and
> similarly clears/set memory encryption attribute when caller allocates or
> free the DMA pages.
> 
> Signed-off-by: Brijesh Singh <brijesh.singh@amd.com>
> ---
>  OvmfPkg/Library/DxeBmDmaLib/DxeBmDmaLib.c   |   60 +++++++++++++++++++++++++++
>  OvmfPkg/Library/DxeBmDmaLib/DxeBmDmaLib.inf |    3 +
>  2 files changed, 61 insertions(+), 2 deletions(-)

It looks like Leo's DxeBmDmaLib isn't final yet (based on the v4
feedback I can see on the list).

Can we perhaps modify the BmDmaLib library class (= public interface)
such that a client module (an executable or even another library) can
reuse the base instance of BmDmaLib, and only provide the hooks?

If not, I guess it's not a big deal, MdeModulePkg/Library/DxeBmDmaLib
contains about 10-12 KB of source. I figured I'd ask though.

Thanks,
Laszlo

> 
> diff --git a/OvmfPkg/Library/DxeBmDmaLib/DxeBmDmaLib.c b/OvmfPkg/Library/DxeBmDmaLib/DxeBmDmaLib.c
> index 0d960a8..39814cc 100644
> --- a/OvmfPkg/Library/DxeBmDmaLib/DxeBmDmaLib.c
> +++ b/OvmfPkg/Library/DxeBmDmaLib/DxeBmDmaLib.c
> @@ -25,6 +25,7 @@
>  #include <Library/MemoryAllocationLib.h>
>  #include <Library/UefiBootServicesTableLib.h>
>  #include <Library/BmDmaLib.h>
> +#include <Library/MemEncryptSevLib.h>
>  
>  
>  #define FORCE_BELOW_4GB_TRUE   TRUE
> @@ -100,6 +101,15 @@ AllocateBounceBuffer (
>    }
>  
>    //
> +  // Clear C-bit on DMA pages
> +  //
> +  if (MemEncryptSevIsEnabled ()) {
> +    Status = MemEncryptSevClearPageEncMask (MapInfo->MappedHostAddress, MapInfo->NumberOfPages);
> +    if (Status != EFI_SUCCESS) {
> +      return Status;
> +    }
> +  }
> +  //
>    // If this is a read operation from the Bus Master's point of view,
>    // then copy the contents of the real buffer into the mapped buffer
>    // so the Bus Master can read the contents of the real buffer.
> @@ -170,6 +180,23 @@ BmDmaMap (
>  
>    PhysicalAddress = (EFI_PHYSICAL_ADDRESS) (UINTN) HostAddress;
>    if (DmaAbove4GB || (PhysicalAddress + *NumberOfBytes) <= SIZE_4GB) {
> +
> +    //
> +    // When SEV is enabled the DMA operation must be performed on shared pages. We force to use the
> +    // bounce buffer path which will take care of allocating shared Dma buffers mapping
> +    //
> +    if (MemEncryptSevIsEnabled () &&
> +        (Operation == DmaOperationBusMasterRead || Operation == DmaOperationBusMasterWrite)) {
> +      return AllocateBounceBuffer (
> +                                   FORCE_BELOW_4GB_FALSE,
> +                                   Operation,
> +                                   PhysicalAddress,
> +                                   NumberOfBytes,
> +                                   DeviceAddress,
> +                                   Mapping
> +                                   );
> +    }
> +
>      //
>      // If we CAN handle DMA above 4GB or the transfer is below 4GB,
>      // the DeviceAddress is simply the HostAddress
> @@ -218,7 +245,8 @@ BmDmaUnmap (
>    IN  VOID                 *Mapping
>    )
>  {
> -  MAP_INFO  *MapInfo;
> +  MAP_INFO           *MapInfo;
> +  EFI_STATUS         Status;
>  
>    //
>    // Check for invalid inputs
> @@ -251,6 +279,17 @@ BmDmaUnmap (
>    }
>  
>    //
> +  // When SEV is enabled then Dma buffer allocate by bounce buffer have C-bit cleared,
> +  // restore the C-bit before we release the resources
> +  //
> +  if (MemEncryptSevIsEnabled ()) {
> +    Status = MemEncryptSevSetPageEncMask (MapInfo->MappedHostAddress, MapInfo->NumberOfPages);
> +    if (Status != EFI_SUCCESS) {
> +      return Status;
> +    }
> +  }
> +
> +  //
>    // Free the mapped buffer and the MAP_INFO structure.
>    //
>    gBS->FreePages (MapInfo->MappedHostAddress, MapInfo->NumberOfPages);
> @@ -322,8 +361,15 @@ BmDmaAllocateBuffer (
>                    );
>    if (!EFI_ERROR (Status)) {
>      *HostAddress = (VOID *) (UINTN) PhysicalAddress;
> +    //
> +    // Clear C-bit on Dma pages
> +    //
> +    if (MemEncryptSevIsEnabled ()) {
> +      Status = MemEncryptSevClearPageEncMask (PhysicalAddress, Pages);
> +    }
>    }
>  
> +
>    return Status;
>  }
>  
> @@ -346,6 +392,18 @@ BmDmaFreeBuffer (
>    IN  UINTN                Pages
>    )
>  {
> +  EFI_STATUS           Status;
> +
> +  //
> +  // Restore the C-bit on DMA pages
> +  //
> +  if (MemEncryptSevIsEnabled ()) {
> +    Status = MemEncryptSevSetPageEncMask ((UINTN) HostAddress, Pages);
> +    if (Status != EFI_SUCCESS) {
> +      return Status;
> +    }
> +  }
> +
>    return gBS->FreePages ((EFI_PHYSICAL_ADDRESS) (UINTN) HostAddress, Pages);
>  }
>  
> diff --git a/OvmfPkg/Library/DxeBmDmaLib/DxeBmDmaLib.inf b/OvmfPkg/Library/DxeBmDmaLib/DxeBmDmaLib.inf
> index 4ddb27d..fb97caa 100644
> --- a/OvmfPkg/Library/DxeBmDmaLib/DxeBmDmaLib.inf
> +++ b/OvmfPkg/Library/DxeBmDmaLib/DxeBmDmaLib.inf
> @@ -29,6 +29,7 @@
>  [Packages]
>    MdePkg/MdePkg.dec
>    MdeModulePkg/MdeModulePkg.dec
> +  OvmfPkg/OvmfPkg.dec
>  
>  [LibraryClasses]
>    BaseLib
> @@ -37,5 +38,5 @@
>    DxeServicesTableLib
>    MemoryAllocationLib
>    UefiBootServicesTableLib
> -
> +  MemEncryptSevLib
>  
> 
> _______________________________________________
> edk2-devel mailing list
> edk2-devel@lists.01.org
> https://lists.01.org/mailman/listinfo/edk2-devel
> 



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

* Re: [RFC PATCH v2 08/10] OvmfPkg/QemuFwCfgLib: Provide Pei and Dxe specific library support
  2017-03-21 21:13 ` [RFC PATCH v2 08/10] OvmfPkg/QemuFwCfgLib: Provide Pei and Dxe specific library support Brijesh Singh
@ 2017-03-27  9:41   ` Laszlo Ersek
  0 siblings, 0 replies; 44+ messages in thread
From: Laszlo Ersek @ 2017-03-27  9:41 UTC (permalink / raw)
  To: Brijesh Singh, michael.d.kinney, jordan.l.justen, edk2-devel,
	liming.gao
  Cc: brijesh.singh, leo.duran, Thomas.Lendacky

On 03/21/17 22:13, Brijesh Singh wrote:
> Current QemuFwCfgLib.inf is used in both Pei and Dxe phases. The patch adds
> Pei and Dxe inf file to provide a seperate QemuFwCfg library for Pei and Dxe
> phases. There is no code change in this patch other than rearranging the files
> and updating inf files.
> 
> The patch is precursor to add SEV support in QemuFwCfgLib, When SEV guest is
> enabled then in Pei phase we support IO operation but in Dxe phase we can
> support both IO and DMA operations.
> 
> Signed-off-by: Brijesh Singh <brijesh.singh@amd.com>
> ---
>  OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgDxe.c      |    0 
>  OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgDxeLib.inf |    6 +++---
>  OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgPei.c      |    0 
>  OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgPeiLib.inf |    6 +++---
>  OvmfPkg/OvmfPkgIa32.dsc                          |    4 +++-
>  OvmfPkg/OvmfPkgIa32X64.dsc                       |    4 +++-
>  OvmfPkg/OvmfPkgX64.dsc                           |    4 +++-
>  7 files changed, 15 insertions(+), 9 deletions(-)
>  copy OvmfPkg/Library/QemuFwCfgLib/{QemuFwCfgPeiDxe.c => QemuFwCfgDxe.c} (100%)
>  copy OvmfPkg/Library/QemuFwCfgLib/{QemuFwCfgLib.inf => QemuFwCfgDxeLib.inf} (83%)
>  rename OvmfPkg/Library/QemuFwCfgLib/{QemuFwCfgPeiDxe.c => QemuFwCfgPei.c} (100%)
>  rename OvmfPkg/Library/QemuFwCfgLib/{QemuFwCfgLib.inf => QemuFwCfgPeiLib.inf} (83%)
> 
> diff --git a/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgPeiDxe.c b/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgDxe.c
> similarity index 100%
> copy from OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgPeiDxe.c
> copy to OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgDxe.c
> diff --git a/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgLib.inf b/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgDxeLib.inf
> similarity index 83%
> copy from OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgLib.inf
> copy to OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgDxeLib.inf
> index 6894760..346bb88 100644
> --- a/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgLib.inf
> +++ b/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgDxeLib.inf
> @@ -19,10 +19,10 @@
>  [Defines]
>    INF_VERSION                    = 0x00010005
>    BASE_NAME                      = QemuFwCfgLib
> -  FILE_GUID                      = fdd53716-31e1-4acc-9007-8bd5d877c96f
> +  FILE_GUID                      = 80474090-55e7-4c28-b25c-9f236ba41f28
>    MODULE_TYPE                    = BASE
>    VERSION_STRING                 = 1.0
> -  LIBRARY_CLASS                  = QemuFwCfgLib|PEIM DXE_DRIVER DXE_RUNTIME_DRIVER DXE_SMM_DRIVER
> +  LIBRARY_CLASS                  = QemuFwCfgLib|DXE_DRIVER DXE_RUNTIME_DRIVER DXE_SMM_DRIVER
>  
>    CONSTRUCTOR                    = QemuFwCfgInitialize
>  
> @@ -35,7 +35,7 @@
>  [Sources]
>    QemuFwCfgLibInternal.h
>    QemuFwCfgLib.c
> -  QemuFwCfgPeiDxe.c
> +  QemuFwCfgDxe.c
>  
>  [Packages]
>    MdePkg/MdePkg.dec
> diff --git a/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgPeiDxe.c b/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgPei.c
> similarity index 100%
> rename from OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgPeiDxe.c
> rename to OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgPei.c
> diff --git a/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgLib.inf b/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgPeiLib.inf
> similarity index 83%
> rename from OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgLib.inf
> rename to OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgPeiLib.inf
> index 6894760..4f966a8 100644
> --- a/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgLib.inf
> +++ b/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgPeiLib.inf
> @@ -19,10 +19,10 @@
>  [Defines]
>    INF_VERSION                    = 0x00010005
>    BASE_NAME                      = QemuFwCfgLib
> -  FILE_GUID                      = fdd53716-31e1-4acc-9007-8bd5d877c96f
> +  FILE_GUID                      = ddd4f5f0-5304-42a8-9efa-d14bf11a3533
>    MODULE_TYPE                    = BASE
>    VERSION_STRING                 = 1.0
> -  LIBRARY_CLASS                  = QemuFwCfgLib|PEIM DXE_DRIVER DXE_RUNTIME_DRIVER DXE_SMM_DRIVER
> +  LIBRARY_CLASS                  = QemuFwCfgLib|PEIM
>  
>    CONSTRUCTOR                    = QemuFwCfgInitialize
>  
> @@ -35,7 +35,7 @@
>  [Sources]
>    QemuFwCfgLibInternal.h
>    QemuFwCfgLib.c
> -  QemuFwCfgPeiDxe.c
> +  QemuFwCfgPei.c
>  
>  [Packages]
>    MdePkg/MdePkg.dec
> diff --git a/OvmfPkg/OvmfPkgIa32.dsc b/OvmfPkg/OvmfPkgIa32.dsc
> index 58d6c3d..3e94295 100644
> --- a/OvmfPkg/OvmfPkgIa32.dsc
> +++ b/OvmfPkg/OvmfPkgIa32.dsc
> @@ -123,7 +123,7 @@
>    DpcLib|MdeModulePkg/Library/DxeDpcLib/DxeDpcLib.inf
>    UefiUsbLib|MdePkg/Library/UefiUsbLib/UefiUsbLib.inf
>    SerializeVariablesLib|OvmfPkg/Library/SerializeVariablesLib/SerializeVariablesLib.inf
> -  QemuFwCfgLib|OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgLib.inf
> +  QemuFwCfgLib|OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgDxeLib.inf
>    VirtioLib|OvmfPkg/Library/VirtioLib/VirtioLib.inf
>    LoadLinuxLib|OvmfPkg/Library/LoadLinuxLib/LoadLinuxLib.inf
>    MemEncryptSevLib|OvmfPkg/Library/BaseMemEncryptSevLib/BaseMemEncryptSevLib.inf
> @@ -216,6 +216,7 @@
>    DebugLib|OvmfPkg/Library/PlatformDebugLibIoPort/PlatformDebugLibIoPort.inf
>  !endif
>    PeCoffLib|MdePkg/Library/BasePeCoffLib/BasePeCoffLib.inf
> +  QemuFwCfgLib|OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgPeiLib.inf

The PEI_CORE module type is not listed in any of the library instance
INF files, so this resolution is useless.

The rest looks OK to me.

Thanks
Laszlo

>  
>  [LibraryClasses.common.PEIM]
>    HobLib|MdePkg/Library/PeiHobLib/PeiHobLib.inf
> @@ -240,6 +241,7 @@
>    CpuExceptionHandlerLib|UefiCpuPkg/Library/CpuExceptionHandlerLib/PeiCpuExceptionHandlerLib.inf
>    MpInitLib|UefiCpuPkg/Library/MpInitLib/PeiMpInitLib.inf
>    QemuFwCfgS3Lib|OvmfPkg/Library/QemuFwCfgS3Lib/PeiQemuFwCfgS3LibFwCfg.inf
> +  QemuFwCfgLib|OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgPeiLib.inf
>  
>  [LibraryClasses.common.DXE_CORE]
>    HobLib|MdePkg/Library/DxeCoreHobLib/DxeCoreHobLib.inf
> diff --git a/OvmfPkg/OvmfPkgIa32X64.dsc b/OvmfPkg/OvmfPkgIa32X64.dsc
> index ac2ef24..0b22229 100644
> --- a/OvmfPkg/OvmfPkgIa32X64.dsc
> +++ b/OvmfPkg/OvmfPkgIa32X64.dsc
> @@ -128,7 +128,7 @@
>    DpcLib|MdeModulePkg/Library/DxeDpcLib/DxeDpcLib.inf
>    UefiUsbLib|MdePkg/Library/UefiUsbLib/UefiUsbLib.inf
>    SerializeVariablesLib|OvmfPkg/Library/SerializeVariablesLib/SerializeVariablesLib.inf
> -  QemuFwCfgLib|OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgLib.inf
> +  QemuFwCfgLib|OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgDxeLib.inf
>    VirtioLib|OvmfPkg/Library/VirtioLib/VirtioLib.inf
>    LoadLinuxLib|OvmfPkg/Library/LoadLinuxLib/LoadLinuxLib.inf
>    MemEncryptSevLib|OvmfPkg/Library/BaseMemEncryptSevLib/BaseMemEncryptSevLib.inf
> @@ -221,6 +221,7 @@
>    DebugLib|OvmfPkg/Library/PlatformDebugLibIoPort/PlatformDebugLibIoPort.inf
>  !endif
>    PeCoffLib|MdePkg/Library/BasePeCoffLib/BasePeCoffLib.inf
> +  QemuFwCfgLib|OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgPeiLib.inf
>  
>  [LibraryClasses.common.PEIM]
>    HobLib|MdePkg/Library/PeiHobLib/PeiHobLib.inf
> @@ -245,6 +246,7 @@
>    CpuExceptionHandlerLib|UefiCpuPkg/Library/CpuExceptionHandlerLib/PeiCpuExceptionHandlerLib.inf
>    MpInitLib|UefiCpuPkg/Library/MpInitLib/PeiMpInitLib.inf
>    QemuFwCfgS3Lib|OvmfPkg/Library/QemuFwCfgS3Lib/PeiQemuFwCfgS3LibFwCfg.inf
> +  QemuFwCfgLib|OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgPeiLib.inf
>  
>  [LibraryClasses.common.DXE_CORE]
>    HobLib|MdePkg/Library/DxeCoreHobLib/DxeCoreHobLib.inf
> diff --git a/OvmfPkg/OvmfPkgX64.dsc b/OvmfPkg/OvmfPkgX64.dsc
> index 799f9e1..01f3803 100644
> --- a/OvmfPkg/OvmfPkgX64.dsc
> +++ b/OvmfPkg/OvmfPkgX64.dsc
> @@ -128,7 +128,7 @@
>    DpcLib|MdeModulePkg/Library/DxeDpcLib/DxeDpcLib.inf
>    UefiUsbLib|MdePkg/Library/UefiUsbLib/UefiUsbLib.inf
>    SerializeVariablesLib|OvmfPkg/Library/SerializeVariablesLib/SerializeVariablesLib.inf
> -  QemuFwCfgLib|OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgLib.inf
> +  QemuFwCfgLib|OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgDxeLib.inf
>    VirtioLib|OvmfPkg/Library/VirtioLib/VirtioLib.inf
>    LoadLinuxLib|OvmfPkg/Library/LoadLinuxLib/LoadLinuxLib.inf
>    MemEncryptSevLib|OvmfPkg/Library/BaseMemEncryptSevLib/BaseMemEncryptSevLib.inf
> @@ -221,6 +221,7 @@
>    DebugLib|OvmfPkg/Library/PlatformDebugLibIoPort/PlatformDebugLibIoPort.inf
>  !endif
>    PeCoffLib|MdePkg/Library/BasePeCoffLib/BasePeCoffLib.inf
> +  QemuFwCfgLib|OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgPeiLib.inf
>  
>  [LibraryClasses.common.PEIM]
>    HobLib|MdePkg/Library/PeiHobLib/PeiHobLib.inf
> @@ -245,6 +246,7 @@
>    CpuExceptionHandlerLib|UefiCpuPkg/Library/CpuExceptionHandlerLib/PeiCpuExceptionHandlerLib.inf
>    MpInitLib|UefiCpuPkg/Library/MpInitLib/PeiMpInitLib.inf
>    QemuFwCfgS3Lib|OvmfPkg/Library/QemuFwCfgS3Lib/PeiQemuFwCfgS3LibFwCfg.inf
> +  QemuFwCfgLib|OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgPeiLib.inf
>  
>  [LibraryClasses.common.DXE_CORE]
>    HobLib|MdePkg/Library/DxeCoreHobLib/DxeCoreHobLib.inf
> 
> _______________________________________________
> edk2-devel mailing list
> edk2-devel@lists.01.org
> https://lists.01.org/mailman/listinfo/edk2-devel
> 



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

* Re: [RFC PATCH v2 04/10] OvmfPkg/BaseMemcryptSevLib: Add SEV helper library
  2017-03-27  9:19   ` Laszlo Ersek
@ 2017-03-27 10:07     ` Laszlo Ersek
  2017-03-27 18:44       ` Brijesh Singh
  0 siblings, 1 reply; 44+ messages in thread
From: Laszlo Ersek @ 2017-03-27 10:07 UTC (permalink / raw)
  To: Brijesh Singh, michael.d.kinney, jordan.l.justen, edk2-devel,
	liming.gao
  Cc: brijesh.singh, leo.duran, Thomas.Lendacky

On 03/27/17 11:19, Laszlo Ersek wrote:
> On 03/21/17 22:13, Brijesh Singh wrote:

>> +  Returns a boolean to indicate whether SEV is enabled
>> +
>> +  @retval TRUE           When SEV is active
>> +  @retval FALSE          When SEV is not enabled
>> +  **/
>> +BOOLEAN
>> +EFIAPI
>> +MemEncryptSevIsEnabled (
>> +  VOID
>> +  );
> 
> Would it make sense to call this library function in PlatformPei, rather
> than add a separate SevIsEnabled() function to it (in patch #3)? The
> implementations look nearly identical.

I realize that earlier I seemingly suggested the opposite:

http://mid.mail-archive.com/dd9436dc-415c-9fab-081c-39dd2cd71fd5@redhat.com

http://mid.mail-archive.com/9193d837-6a78-b1c4-42c0-427fbc1f2364@redhat.com

However, at that time, my understanding was that this library would only
be used in PlatformPei (hence the single user wouldn't justify the new
library instance). Now it seems that there are going to be several
client modules that check on SEV enablement. Is that right?

Thanks
Laszlo


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

* Re: [RFC PATCH v2 09/10] OvmfPkg/QemuFwCfgLib: Add Secure Encrypted Virtualization (SEV) support
  2017-03-21 21:13 ` [RFC PATCH v2 09/10] OvmfPkg/QemuFwCfgLib: Add Secure Encrypted Virtualization (SEV) support Brijesh Singh
@ 2017-03-27 10:19   ` Laszlo Ersek
  2017-03-27 19:24     ` Brijesh Singh
  0 siblings, 1 reply; 44+ messages in thread
From: Laszlo Ersek @ 2017-03-27 10:19 UTC (permalink / raw)
  To: Brijesh Singh, michael.d.kinney, jordan.l.justen, edk2-devel,
	liming.gao
  Cc: brijesh.singh, leo.duran, Thomas.Lendacky

On 03/21/17 22:13, Brijesh Singh wrote:
> The patch adds SEV support in QemuFwCfgLib. When SEV is enabled:
> 
>  * Pei phase support IO-style operations. This is mainly because we need to
>    use a bounce buffer inorder to support DMA operation. Allocate a memory
>    for bounce buffer can get painful in Pei phase hence if we detect FWCfg DMA
>    support then silently fallback to IO.
> 
> * Dxe phase supports both IO and DMA style operations.
> ---
>  OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgDxe.c        |   73 +++++++++++++
>  OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgDxeLib.inf   |    2 
>  OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgLib.c        |  112 ++++++++++++++++++++
>  .../Library/QemuFwCfgLib/QemuFwCfgLibInternal.h    |   38 +++++++
>  OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgPei.c        |   93 +++++++++++++++++
>  OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgPeiLib.inf   |    2 
>  OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgSec.c        |   82 +++++++++++++++
>  7 files changed, 402 insertions(+)

Can you please split this patch into 5 patches?
- new interfaces in QemuFwCfgLibInternal.h
- implementation of new APIs for SEC instance
- implementation of new APIs for PEI instance
- implementation of new APIs for DXE instance
- call new APIs from common code

If that is possible. Otherwise, it's quite hard to review & compare the
instances for the different firmware phases.

Anyway, some things I've noticed:

- InternalQemuFwCfgSevIsEnabled() should use global variables in the PEI
instance as well. Possibly the appropriate interface from
BaseMemcryptSevLib could be called from both the PEI and DXE instances
here. (I think the DXE instance already does that.)

- regarding InternalQemuFwCfgDmaBytes(): would it be possible to hook
the SEV-related tricks into the existent function, rather than
copy+modify the entire function as InternalQemuFwCfgSevDmaBytes()? It
seems to me that a conditional "prologue" and "epilogue" in
InternalQemuFwCfgDmaBytes() could do the trick.

... From skimming this patch, I think those are the only
functionality-related comments I have at this point, beyond the remarks
I made elsewhere in this series (like: line length, DEBUG_* macros, and
so on). Please recheck all patches for those comments.

Thanks!
Laszlo

> 
> diff --git a/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgDxe.c b/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgDxe.c
> index ac05f4c..be8e945 100644
> --- a/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgDxe.c
> +++ b/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgDxe.c
> @@ -4,6 +4,7 @@
>  
>    Copyright (C) 2013, Red Hat, Inc.
>    Copyright (c) 2011 - 2013, Intel Corporation. All rights reserved.<BR>
> +  Copyright (c) 2017, Advanced Micro Devices. All rights reserved.<BR>
>  
>    This program and the accompanying materials are licensed and made available
>    under the terms and conditions of the BSD License which accompanies this
> @@ -14,14 +15,34 @@
>    WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
>  **/
>  
> +#include "Uefi.h"
> +
> +#include <Library/BaseLib.h>
>  #include <Library/DebugLib.h>
>  #include <Library/QemuFwCfgLib.h>
> +#include <Library/UefiBootServicesTableLib.h>
> +#include <Library/MemEncryptSevLib.h>
> +#include <Library/BmDmaLib.h>
>  
>  #include "QemuFwCfgLibInternal.h"
>  
>  STATIC BOOLEAN mQemuFwCfgSupported = FALSE;
>  STATIC BOOLEAN mQemuFwCfgDmaSupported;
> +STATIC BOOLEAN mQemuFwCfgSevIsEnabled = FALSE;
> +
> +/**
> + Returns a boolean indicating whether the SEV is enabled
>  
> + @retval    TRUE    SEV is enabled
> + @retval    FALSE   SEV is not enabled
> +**/
> +BOOLEAN
> +InternalQemuFwCfgSevIsEnabled (
> +  VOID
> +  )
> +{
> +  return mQemuFwCfgSevIsEnabled;
> +}
>  
>  /**
>    Returns a boolean indicating if the firmware configuration interface
> @@ -79,6 +100,9 @@ QemuFwCfgInitialize (
>      mQemuFwCfgDmaSupported = TRUE;
>      DEBUG ((DEBUG_INFO, "QemuFwCfg interface (DMA) is supported.\n"));
>    }
> +
> +  mQemuFwCfgSevIsEnabled = MemEncryptSevIsEnabled ();
> +
>    return RETURN_SUCCESS;
>  }
>  
> @@ -114,3 +138,52 @@ InternalQemuFwCfgDmaIsAvailable (
>  {
>    return mQemuFwCfgDmaSupported;
>  }
> +
> +/**
> + Allocate a bounce buffer for SEV DMA.
> +

Please document that this function either succeeds or doesn't return.

> +  @param[in]     NumPage  Number of pages.
> +  @param[out]    Buffer   Allocated DMA Buffer pointer
> +
> +**/
> +VOID
> +InternalQemuFwCfgSevDmaAllocateBuffer (
> +  IN     UINT32   NumPages,
> +  OUT    VOID     **Buffer
> +  )
> +{
> +  EFI_STATUS  Status;
> +
> +  //
> +  // Allocate DMA bounce buffer
> +  //
> +  Status = BmDmaAllocateBuffer (TRUE, EfiBootServicesData, NumPages, Buffer);
> +  if (EFI_ERROR(Status)) {
> +    DEBUG ((EFI_D_ERROR, "SEV: Failed to allocate bounce buffer %d pages\n", NumPages));
> +    ASSERT_EFI_ERROR (Status);
> +    CpuDeadLoop ();
> +  }
> +
> +  DEBUG ((EFI_D_VERBOSE, "QemuFwCfgSevDma allocate buffer 0x%Lx Pages %d\n", (UINTN)Buffer, NumPages));
> +}
> +
> +/**
> + Free the DMA buffer allocated using InternalQemuFwCfgSevDmaAllocateBuffer
> +
> +  @param[in]     NumPage  Number of pages.
> +  @param[in]     Buffer   DMA Buffer pointer
> +
> +**/
> +VOID
> +InternalQemuFwCfgSevDmaFreeBuffer (
> +  IN     VOID     *Buffer,
> +  IN     UINT32   NumPages
> +  )
> +{
> +  //
> +  // Free the bounce buffer
> +  //
> +  DEBUG ((EFI_D_VERBOSE, "QemuFwCfgSevDma free buffer 0x%Lx Pages %d\n", (UINTN)Buffer, NumPages));
> +  BmDmaFreeBuffer (Buffer, NumPages);
> +}
> +
> diff --git a/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgDxeLib.inf b/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgDxeLib.inf
> index 346bb88..536887f 100644
> --- a/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgDxeLib.inf
> +++ b/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgDxeLib.inf
> @@ -47,4 +47,6 @@
>    DebugLib
>    IoLib
>    MemoryAllocationLib
> +  MemEncryptSevLib
> +  BmDmaLib
>  
> diff --git a/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgLib.c b/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgLib.c
> index 1bf725d..d2560a3 100644
> --- a/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgLib.c
> +++ b/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgLib.c
> @@ -47,6 +47,111 @@ QemuFwCfgSelectItem (
>  
>  
>  /**
> +  Transfer an array of bytes, or skip a number of bytes, using the SEV DMA bounce
> +  interface. The function is same as InternalQemuFwCfgDmaBytes with excpetion that
> +  it uses bounce buffer
> +
> +  @param[in]     Size     Size in bytes to transfer or skip.
> +
> +  @param[in,out] HostBuffer Buffer to read data into or write data from. Ignored,
> +                            and may be NULL, if Size is zero, or Control is
> +                            FW_CFG_DMA_CTL_SKIP.
> +
> +  @param[in]     Control  One of the following:
> +                          FW_CFG_DMA_CTL_WRITE - write to fw_cfg from Buffer.
> +                          FW_CFG_DMA_CTL_READ  - read from fw_cfg into Buffer.
> +                          FW_CFG_DMA_CTL_SKIP  - skip bytes in fw_cfg.
> +**/
> +VOID
> +InternalQemuFwCfgSevDmaBytes (
> +  IN     UINT32   Size,
> +  IN OUT VOID     *HostBuffer OPTIONAL,
> +  IN     UINT32   Control
> +  )
> +{
> +  volatile FW_CFG_DMA_ACCESS *Access;
> +  UINT32                     AccessHigh, AccessLow;
> +  UINT32                     Status;
> +  UINT32                     NumPages;
> +  VOID                       *DmaBuffer, *Buffer;
> +
> +  //
> +  // Calculate number of pages we need to allocate for this operation
> +  //
> +  if (Control == FW_CFG_DMA_CTL_SKIP) {
> +    //
> +    // Control data does not need the actual buffer
> +    //
> +    NumPages = EFI_SIZE_TO_PAGES (sizeof (*Access));
> +  } else {
> +    NumPages = EFI_SIZE_TO_PAGES (sizeof (*Access) + Size);
> +  }
> +
> +  //
> +  // Allocate DMA bounce buffer
> +  //
> +  InternalQemuFwCfgSevDmaAllocateBuffer (NumPages, &DmaBuffer);
> +
> +  Access = (FW_CFG_DMA_ACCESS *)DmaBuffer;
> +  Buffer = DmaBuffer + sizeof(*Access);
> +
> +  Access->Control = SwapBytes32 (Control);
> +  Access->Length  = SwapBytes32 (Size);
> +  Access->Address = SwapBytes64 ((UINTN)Buffer);
> +
> +  //
> +  // Copy data from Host buffer into DMA buffer
> +  //
> +  if (HostBuffer && (Control == FW_CFG_DMA_CTL_WRITE)) {
> +    CopyMem (Buffer, HostBuffer, Size);
> +  }
> +
> +  //
> +  // Delimit the transfer from (a) modifications to Access, (b) in case of a
> +  // write, from writes to Buffer by the caller.
> +  //
> +  MemoryFence ();
> +
> +  //
> +  // Start the transfer.
> +  //
> +  AccessHigh = (UINT32)RShiftU64 ((UINTN)Access, 32);
> +  AccessLow  = (UINT32)(UINTN)Access;
> +  IoWrite32 (FW_CFG_IO_DMA_ADDRESS,     SwapBytes32 (AccessHigh));
> +  IoWrite32 (FW_CFG_IO_DMA_ADDRESS + 4, SwapBytes32 (AccessLow));
> +
> +  //
> +  // Don't look at Access->Control before starting the transfer.
> +  //
> +  MemoryFence ();
> +
> +  //
> +  // Wait for the transfer to complete.
> +  //
> +  do {
> +    Status = SwapBytes32 (Access->Control);
> +    ASSERT ((Status & FW_CFG_DMA_CTL_ERROR) == 0);
> +  } while (Status != 0);
> +
> +  //
> +  // After a read, the caller will want to use Buffer.
> +  //
> +  MemoryFence ();
> +
> +  //
> +  // Copy data from DMA buffer into Host Buffer
> +  //
> +  if (HostBuffer && (Control == FW_CFG_DMA_CTL_READ)) {
> +    CopyMem (HostBuffer, Buffer, Size);
> +  }
> +
> +  //
> +  // Free the DMA bounce buffer
> +  //
> +  InternalQemuFwCfgSevDmaFreeBuffer (DmaBuffer, NumPages);
> +}
> +
> +/**
>    Transfer an array of bytes, or skip a number of bytes, using the DMA
>    interface.
>  
> @@ -79,6 +184,13 @@ InternalQemuFwCfgDmaBytes (
>      return;
>    }
>  
> +  //
> +  // When SEV is enabled then use SEV version of DmaReadWrite
> +  //
> +  if (InternalQemuFwCfgSevIsEnabled ()) {
> +    return InternalQemuFwCfgSevDmaBytes (Size, Buffer, Control);
> +  }
> +
>    Access.Control = SwapBytes32 (Control);
>    Access.Length  = SwapBytes32 (Size);
>    Access.Address = SwapBytes64 ((UINTN)Buffer);
> diff --git a/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgLibInternal.h b/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgLibInternal.h
> index 6e87c62..8e2ff45 100644
> --- a/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgLibInternal.h
> +++ b/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgLibInternal.h
> @@ -2,6 +2,7 @@
>    Internal interfaces specific to the QemuFwCfgLib instances in OvmfPkg.
>  
>    Copyright (C) 2016, Red Hat, Inc.
> +  Copyright (C) 2017, Advanced Micro Devices.
>  
>    This program and the accompanying materials are licensed and made available
>    under the terms and conditions of the BSD License which accompanies this
> @@ -43,4 +44,41 @@ InternalQemuFwCfgDmaIsAvailable (
>    VOID
>    );
>  
> +/**
> + Returns a boolean indicating whether the SEV is enabled
> +
> + @retval    TRUE    SEV is enabled
> + @retval    FALSE   SEV is not enabled
> +**/
> +BOOLEAN
> +InternalQemuFwCfgSevIsEnabled (
> +  VOID
> +  );
> +
> +/**
> + Allocate a bounce buffer for SEV DMA.
> +
> +  @param[in]     NumPage  Number of pages.
> +  @param[out]    Buffer   Allocated DMA Buffer pointer
> +
> +**/
> +VOID
> +InternalQemuFwCfgSevDmaAllocateBuffer (
> +  IN     UINT32   NumPages,
> +  OUT    VOID     **Buffer
> +  );
> +
> +/**
> + Free the DMA buffer allocated using InternalQemuFwCfgSevDmaAllocateBuffer
> +
> +  @param[in]     NumPage  Number of pages.
> +  @param[in]     Buffer   DMA Buffer pointer
> +
> +**/
> +VOID
> +InternalQemuFwCfgSevDmaFreeBuffer (
> +  IN     VOID     *Buffer,
> +  IN     UINT32   NumPages
> +  );
> +
>  #endif
> diff --git a/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgPei.c b/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgPei.c
> index ac05f4c..3dc9270 100644
> --- a/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgPei.c
> +++ b/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgPei.c
> @@ -4,6 +4,7 @@
>  
>    Copyright (C) 2013, Red Hat, Inc.
>    Copyright (c) 2011 - 2013, Intel Corporation. All rights reserved.<BR>
> +  Copyright (c) 2017, Advanced Micro Devices. All rights reserved.<BR>
>  
>    This program and the accompanying materials are licensed and made available
>    under the terms and conditions of the BSD License which accompanies this
> @@ -14,14 +15,55 @@
>    WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
>  **/
>  
> +#include <Library/BaseLib.h>
>  #include <Library/DebugLib.h>
>  #include <Library/QemuFwCfgLib.h>
> +#include <Register/Cpuid.h>
> +#include <Register/AmdSevMap.h>
>  
>  #include "QemuFwCfgLibInternal.h"
>  
>  STATIC BOOLEAN mQemuFwCfgSupported = FALSE;
>  STATIC BOOLEAN mQemuFwCfgDmaSupported;
>  
> +/**
> + Returns a boolean indicating whether the SEV is enabled
> +
> + @retval    TRUE    SEV is enabled
> + @retval    FALSE   SEV is not enabled
> +**/
> +BOOLEAN
> +InternalQemuFwCfgSevIsEnabled (
> +  VOID
> +  )
> +{
> +  UINT32 RegEax;
> +  MSR_SEV_STATUS_REGISTER Msr;
> +  CPUID_MEMORY_ENCRYPTION_INFO_EAX  Eax;
> +
> +  //
> +  // Check if memory encryption leaf exist
> +  //
> +  AsmCpuid (CPUID_EXTENDED_FUNCTION, &RegEax, NULL, NULL, NULL);
> +  if (RegEax >= CPUID_MEMORY_ENCRYPTION_INFO) {
> +    //
> +    // CPUID Fn8000_001F[EAX] Bit 1 (Sev supported)
> +    //
> +    AsmCpuid (CPUID_MEMORY_ENCRYPTION_INFO, &Eax.Uint32, NULL, NULL, NULL);
> +
> +    if (Eax.Bits.SevBit) {
> +      //
> +      // Check MSR_0xC0010131 Bit 0 (Sev Enabled)
> +      //
> +      Msr.Uint32 = AsmReadMsr32 (MSR_SEV_STATUS);
> +      if (Msr.Bits.SevBit) {
> +        return TRUE;
> +      }
> +    }
> +  }
> +
> +  return FALSE;
> +}
>  
>  /**
>    Returns a boolean indicating if the firmware configuration interface
> @@ -79,6 +121,17 @@ QemuFwCfgInitialize (
>      mQemuFwCfgDmaSupported = TRUE;
>      DEBUG ((DEBUG_INFO, "QemuFwCfg interface (DMA) is supported.\n"));
>    }
> +
> +  //
> +  // When SEV is enabled then we do not support DMA interface.
> +  // This is because we need to use bounce buffer to support DMA operation in SEV guest.
> +  // Allocating memory for bounce buffer can get painful in Pei phase
> +  //
> +  if (mQemuFwCfgDmaSupported && InternalQemuFwCfgSevIsEnabled ()) {
> +    mQemuFwCfgDmaSupported = FALSE;
> +    DEBUG ((DEBUG_INFO, "QemuFwCfg disabling DMA interface and defaulting to IO Port.\n"));
> +  }
> +
>    return RETURN_SUCCESS;
>  }
>  
> @@ -114,3 +167,43 @@ InternalQemuFwCfgDmaIsAvailable (
>  {
>    return mQemuFwCfgDmaSupported;
>  }
> +
> +/**
> + Allocate a bounce buffer for SEV DMA.
> +
> +  @param[in]     NumPage  Number of pages.
> +  @param[out]    Buffer   Allocated DMA Buffer pointer
> +
> +**/
> +VOID
> +InternalQemuFwCfgSevDmaAllocateBuffer (
> +  IN     UINT32   NumPages,
> +  OUT    VOID     **Buffer
> +  )
> +{
> +  //
> +  // We should never reach here
> +  //
> +  ASSERT (FALSE);
> +  CpuDeadLoop ();
> +}
> +
> +/**
> + Free the DMA buffer allocated using InternalQemuFwCfgSevDmaAllocateBuffer
> +
> +  @param[in]     NumPage  Number of pages.
> +  @param[in]     Buffer   DMA Buffer pointer
> +
> +**/
> +VOID
> +InternalQemuFwCfgSevDmaFreeBuffer (
> +  IN     VOID     *Buffer,
> +  IN     UINT32   NumPages
> +  )
> +{
> +  //
> +  // We should never reach here
> +  //
> +  ASSERT (FALSE);
> +  CpuDeadLoop ();
> +}
> diff --git a/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgPeiLib.inf b/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgPeiLib.inf
> index 4f966a8..83cc0de 100644
> --- a/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgPeiLib.inf
> +++ b/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgPeiLib.inf
> @@ -39,7 +39,9 @@
>  
>  [Packages]
>    MdePkg/MdePkg.dec
> +  MdeModulePkg/MdeModulePkg.dec
>    OvmfPkg/OvmfPkg.dec
> +  UefiCpuPkg/UefiCpuPkg.dec
>  
>  [LibraryClasses]
>    BaseLib
> diff --git a/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgSec.c b/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgSec.c
> index 465ccbe..70b0a47 100644
> --- a/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgSec.c
> +++ b/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgSec.c
> @@ -16,8 +16,11 @@
>    WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
>  **/
>  
> +#include <Library/BaseLib.h>
>  #include <Library/DebugLib.h>
>  #include <Library/QemuFwCfgLib.h>
> +#include <Register/Cpuid.h>
> +#include <Register/AmdSevMap.h>
>  
>  #include "QemuFwCfgLibInternal.h"
>  
> @@ -94,3 +97,82 @@ InternalQemuFwCfgDmaIsAvailable (
>  {
>    return FALSE;
>  }
> +
> +/**
> + Returns a boolean indicating whether the SEV is enabled
> +
> + @retval    TRUE    SEV is enabled
> + @retval    FALSE   SEV is not enabled
> +**/
> +BOOLEAN
> +InternalQemuFwCfgSevIsEnabled (
> +  VOID
> +  )
> +{
> +  UINT32 RegEax;
> +  MSR_SEV_STATUS_REGISTER Msr;
> +  CPUID_MEMORY_ENCRYPTION_INFO_EAX  Eax;
> +
> +  //
> +  // Check if memory encryption leaf exist
> +  //
> +  AsmCpuid (CPUID_EXTENDED_FUNCTION, &RegEax, NULL, NULL, NULL);
> +  if (RegEax >= CPUID_MEMORY_ENCRYPTION_INFO) {
> +    //
> +    // CPUID Fn8000_001F[EAX] Bit 1 (Sev supported)
> +    //
> +    AsmCpuid (CPUID_MEMORY_ENCRYPTION_INFO, &Eax.Uint32, NULL, NULL, NULL);
> +
> +    if (Eax.Bits.SevBit) {
> +      //
> +      // Check MSR_0xC0010131 Bit 0 (Sev Enabled)
> +      //
> +      Msr.Uint32 = AsmReadMsr32 (MSR_SEV_STATUS);
> +      if (Msr.Bits.SevBit) {
> +        return TRUE;
> +      }
> +    }
> +  }
> +
> +  return FALSE;
> +}
> +
> +/**
> + Allocate a bounce buffer for SEV DMA.
> +
> +  @param[in]     NumPage  Number of pages.
> +  @param[out]    Buffer   Allocated DMA Buffer pointer
> +
> +**/
> +VOID
> +InternalQemuFwCfgSevDmaAllocateBuffer (
> +  IN     UINT32   NumPages,
> +  OUT    VOID     **Buffer
> +  )
> +{
> +  //
> +  // We should never reach here
> +  //
> +  ASSERT (FALSE);
> +  CpuDeadLoop ();
> +}
> +
> +/**
> + Free the DMA buffer allocated using InternalQemuFwCfgSevDmaAllocateBuffer
> +
> +  @param[in]     NumPage  Number of pages.
> +  @param[in]     Buffer   DMA Buffer pointer
> +
> +**/
> +VOID
> +InternalQemuFwCfgSevDmaFreeBuffer (
> +  IN     VOID     *Buffer,
> +  IN     UINT32   NumPages
> +  )
> +{
> +  //
> +  // We should never reach here
> +  //
> +  ASSERT (FALSE);
> +  CpuDeadLoop ();
> +}
> 
> _______________________________________________
> edk2-devel mailing list
> edk2-devel@lists.01.org
> https://lists.01.org/mailman/listinfo/edk2-devel
> 



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

* Re: [RFC PATCH v2 10/10] OvmfPkg/QemuVideoDxe: Clear the C-bit from framebuffer region when SEV is enabled
  2017-03-21 21:13 ` [RFC PATCH v2 10/10] OvmfPkg/QemuVideoDxe: Clear the C-bit from framebuffer region when SEV is enabled Brijesh Singh
@ 2017-03-27 10:29   ` Laszlo Ersek
  0 siblings, 0 replies; 44+ messages in thread
From: Laszlo Ersek @ 2017-03-27 10:29 UTC (permalink / raw)
  To: Brijesh Singh, michael.d.kinney, jordan.l.justen, edk2-devel,
	liming.gao
  Cc: brijesh.singh, leo.duran, Thomas.Lendacky

On 03/21/17 22:13, Brijesh Singh wrote:
> Since the framebuffer memory region is shared between the guest and hypervisor
> hence we must clear the memory encryption bit from this memory region when SEV
> is enabled.
> 
> Signed-off-by: Brijesh Singh <brijesh.singh@amd.com>
> ---
>  OvmfPkg/QemuVideoDxe/Gop.c            |   15 +++++++++++++++
>  OvmfPkg/QemuVideoDxe/QemuVideoDxe.inf |    1 +
>  2 files changed, 16 insertions(+)
> 
> diff --git a/OvmfPkg/QemuVideoDxe/Gop.c b/OvmfPkg/QemuVideoDxe/Gop.c
> index 359e921..96661d1 100644
> --- a/OvmfPkg/QemuVideoDxe/Gop.c
> +++ b/OvmfPkg/QemuVideoDxe/Gop.c
> @@ -13,6 +13,8 @@
>  
>  **/
>  
> +#include <Library/MemEncryptSevLib.h>
> +
>  #include "Qemu.h"
>  
>  STATIC
> @@ -65,6 +67,19 @@ QemuVideoCompleteModeData (
>                          (VOID**) &FrameBufDesc
>                          );
>  
> +  //
> +  // Framebuffer memory region is shared between hypervisor and guest,
> +  // Clear the memory encryption mask when SEV is active.
> +  //
> +  if (MemEncryptSevIsEnabled ()) {
> +    EFI_STATUS Status;
> +
> +    Status = MemEncryptSevClearPageEncMask (FrameBufDesc->AddrRangeMin, EFI_SIZE_TO_PAGES (FrameBufDesc->AddrLen));
> +    if (EFI_ERROR(Status)) {
> +      DEBUG ((EFI_D_WARN, "Failed to clear memory encryption mask 0x%#Lx+0x%x\n", FrameBufDesc->AddrRangeMin, FrameBufDesc->AddrLen));
> +    }
> +  }
> +
>    Mode->FrameBufferBase = FrameBufDesc->AddrRangeMin;
>    Mode->FrameBufferSize = Info->HorizontalResolution * Info->VerticalResolution;
>    Mode->FrameBufferSize = Mode->FrameBufferSize * ((ModeData->ColorDepth + 7) / 8);

This way the above logic is executed on every GOP->SetMode() call.

Instead, I think it should occur in QemuVideoControllerDriverStart().

And, likely, undone / rolled back in QemuVideoControllerDriverStop().

Thanks
Laszlo

> diff --git a/OvmfPkg/QemuVideoDxe/QemuVideoDxe.inf b/OvmfPkg/QemuVideoDxe/QemuVideoDxe.inf
> index affb6ff..83ea86c 100644
> --- a/OvmfPkg/QemuVideoDxe/QemuVideoDxe.inf
> +++ b/OvmfPkg/QemuVideoDxe/QemuVideoDxe.inf
> @@ -60,6 +60,7 @@
>    UefiBootServicesTableLib
>    UefiDriverEntryPoint
>    UefiLib
> +  MemEncryptSevLib
>  
>  [Protocols]
>    gEfiDriverSupportedEfiVersionProtocolGuid     # PROTOCOL ALWAYS_PRODUCED
> 
> _______________________________________________
> edk2-devel mailing list
> edk2-devel@lists.01.org
> https://lists.01.org/mailman/listinfo/edk2-devel
> 



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

* Re: [RFC PATCH v2 01/10] OvmfPkg/Include: Define SEV specific CPUID and MSR
  2017-03-27  7:57         ` Fan, Jeff
@ 2017-03-27 11:58           ` Brijesh Singh
  2017-03-27 17:33             ` Laszlo Ersek
  2017-03-28  0:45             ` Fan, Jeff
  2017-03-27 15:59           ` Duran, Leo
  1 sibling, 2 replies; 44+ messages in thread
From: Brijesh Singh @ 2017-03-27 11:58 UTC (permalink / raw)
  To: Fan, Jeff
  Cc: Laszlo Ersek, Kinney, Michael D, Justen, Jordan L,
	edk2-devel@ml01.01.org, Gao, Liming, leo.duran@amd.com,
	brijesh.singh@amd.com, Thomas.Lendacky@amd.com

On Mon, Mar 27, 2017 at 2:57 AM, Fan, Jeff <jeff.fan@intel.com> wrote:

> Laszlo,
>
> One Amd directory under UefiCpuPkg/Include/Register is better.
>
> Does Brijesh/Leo have any comments, or have other suggestions?
>
>

I am not sure if creating a new UefiCpuPkg/Include/Register/Amd/Cpuid is a
good idea, CPUID Fn8000_001F
leaf can go in UefiCpuPkg/Include/Register/Cpuid.h. Looking at
UefiCpuPkg/Include/Register/Cpuid.h indicates
that this file defines the standard x86 CPUID's. The definition of CPUID's
listed in this file are same on both Intel
and AMD platforms. I was told by our architecture team that if Intel ever
decides to support the new leaf then it will
comply to the exact same bit definition.

I am a bit unsure about where the MSR_SEV_STATUS should go, one part of me
thinks that this MSR should be
defined in OvmfPkg and other part thinks that it can go into
UefiCpuPkg/Include/Amd/Msr.h. It is a read-only MSR
and has meaning in a virtualization context hence I was more inclined
towards defining into OvmfPkg instead of UefiCpuPkg.

Leo,  any comments/suggestions ?

-Brijesh


> -----Original Message-----
> From: Laszlo Ersek [mailto:lersek@redhat.com]
> Sent: Thursday, March 23, 2017 5:20 PM
> To: Fan, Jeff; Brijesh Singh; Kinney, Michael D; Justen, Jordan L;
> edk2-devel@ml01.01.org; Gao, Liming
> Cc: leo.duran@amd.com; brijesh.singh@amd.com; Thomas.Lendacky@amd.com
> Subject: Re: [edk2] [RFC PATCH v2 01/10] OvmfPkg/Include: Define SEV
> specific CPUID and MSR
>
> On 03/23/17 08:42, Fan, Jeff wrote:
> > Laszlo,
> >
> > UefiCpuPkg/Include/Register/Cpuid.h defined the CPUID only described in
> IA32 SDM.
> > UefiCpuPkg/Include/Register/ArchitecturalMsr.h defined the IA32
> > Architectural MSRs in IA32 SDM UefiCpuPkg/Include/Register/Msr/xxxxMsr.h
> defined the IA32 Model-specific MSRs in IA32 SDM.
> >
> > I am not sure if Brijesh/Leo has some idea to place SEV specific
> CPUID/MSRs definitions.
> > I think one new file or new folder is better.
>
> I agree, both would work for me. My main point is that this feature
> depends on physical processor attributes, not on emulated (virtual)
> hardware or on various hypervisors, plus it is defined in a public industry
> spec, so it seems to belong under UefiCpuPkg, not OvmfPkg.
>
> How about
>
>   UefiCpuPkg/Include/AmdRegister/Cpuid.h
>   UefiCpuPkg/Include/AmdRegister/ArchitecturalMsr.h
>   UefiCpuPkg/Include/AmdRegister/Msr/xxxxMsr.h
>
> or else:
>
>   UefiCpuPkg/Include/Register/Amd/Cpuid.h
>   UefiCpuPkg/Include/Register/Amd/ArchitecturalMsr.h
>   UefiCpuPkg/Include/Register/Amd/Msr/xxxxMsr.h
>
> (as appropriate -- I'm not saying that this patch should create all of
> these files / subdirectories at once).
>
> Thanks
> Laszlo
> >
> > -----Original Message-----
> > From: edk2-devel [mailto:edk2-devel-bounces@lists.01.org] On Behalf Of
> > Laszlo Ersek
> > Sent: Thursday, March 23, 2017 12:04 AM
> > To: Brijesh Singh; Kinney, Michael D; Justen, Jordan L;
> > edk2-devel@ml01.01.org; Gao, Liming; Fan, Jeff
> > Cc: leo.duran@amd.com; brijesh.singh@amd.com; Thomas.Lendacky@amd.com
> > Subject: Re: [edk2] [RFC PATCH v2 01/10] OvmfPkg/Include: Define SEV
> > specific CPUID and MSR
> >
> > Adding Jeff
> >
> > On 03/21/17 22:12, Brijesh Singh wrote:
> >> The patch defines AMD's Memory Encryption Information CPUID leaf
> (0x8000_001F).
> >> The complete description for this CPUID leaf is available in APM
> >> volume 2 [1] Section 15.34 (Secure Encrypted Virtualization).
> >>
> >> [1] http://support.amd.com/TechDocs/24593.pdf
> >>
> >> Signed-off-by: Brijesh Singh <brijesh.singh@amd.com>
> >> ---
> >>  OvmfPkg/Include/Register/AmdSevMap.h |  133
> >> ++++++++++++++++++++++++++++++++++
> >>  1 file changed, 133 insertions(+)
> >>  create mode 100644 OvmfPkg/Include/Register/AmdSevMap.h
> >>
> >> diff --git a/OvmfPkg/Include/Register/AmdSevMap.h
> >> b/OvmfPkg/Include/Register/AmdSevMap.h
> >> new file mode 100644
> >> index 0000000..de80f39
> >> --- /dev/null
> >> +++ b/OvmfPkg/Include/Register/AmdSevMap.h
> >> @@ -0,0 +1,133 @@
> >> +/** @file
> >> +
> >> +AMD Secure Encrypted Virtualization (SEV) specific CPUID and MSR
> >> +definitions
> >> +
> >> +The complete description for this CPUID leaf is available in APM
> >> +volume 2 (Section 15.34) http://support.amd.com/TechDocs/24593.pdf
> >> +
> >> +Copyright (c) 2017, Advanced Micro Devices. All rights reserved.<BR>
> >> +
> >> +This program and the accompanying materials are licensed and made
> >> +available under the terms and conditions of the BSD License which
> >> +accompanies this distribution.  The full text of the license may be
> >> +found at http://opensource.org/licenses/bsd-license.php
> >> +
> >> +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS"
> >> +BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER
> EXPRESS OR IMPLIED.
> >> +
> >> +**/
> >> +
> >> +#ifndef __AMD_SEV_MAP_H__
> >> +#define __AMD_SEV_MAP_H__
> >> +
> >> +#pragma pack (1)
> >> +
> >> +#define CPUID_MEMORY_ENCRYPTION_INFO             0x8000001F
> >> +
> >> +/**
> >> +  CPUID Memory Encryption support information EAX for CPUID leaf
> >> +  #CPUID_MEMORY_ENCRYPTION_INFO.
> >> +**/
> >> +typedef union {
> >> +  ///
> >> +  /// Individual bit fields
> >> +  ///
> >> +  struct {
> >> +    ///
> >> +    /// [Bit 0] Secure Memory Encryption (Sme) Support
> >> +    ///
> >> +    UINT32  SmeBit:1;
> >> +
> >> +    ///
> >> +    /// [Bit 1] Secure Encrypted Virtualization (Sev) Support
> >> +    ///
> >> +    UINT32  SevBit:1;
> >> +
> >> +    ///
> >> +    /// [Bit 2] Page flush MSR support
> >> +    ///
> >> +    UINT32  PageFlushMsrBit:1;
> >> +
> >> +    ///
> >> +    /// [Bit 3] Encrypted state support
> >> +    ///
> >> +    UINT32  SevEsBit:1;
> >> +
> >> +    ///
> >> +    /// [Bit 4:31] Reserved
> >> +    ///
> >> +    UINT32  ReservedBits:28;
> >> +  } Bits;
> >> +  ///
> >> +  /// All bit fields as a 32-bit value
> >> +  ///
> >> +  UINT32  Uint32;
> >> +} CPUID_MEMORY_ENCRYPTION_INFO_EAX;
> >> +
> >> +/**
> >> +  CPUID Memory Encryption support information EBX for CPUID leaf
> >> +  #CPUID_MEMORY_ENCRYPTION_INFO.
> >> +**/
> >> +typedef union {
> >> +  ///
> >> +  /// Individual bit fields
> >> +  ///
> >> +  struct {
> >> +    ///
> >> +    /// [Bit 0:5] Page table bit number used to enable memory
> encryption
> >> +    ///
> >> +    UINT32  PtePosBits:6;
> >> +
> >> +    ///
> >> +    /// [Bit 6:11] Reduction of system physical address space bits
> when memory encryption is enabled
> >> +    ///
> >> +    UINT32  ReducedPhysBits:5;
> >> +
> >> +    ///
> >> +    /// [Bit 12:31] Reserved
> >> +    ///
> >> +    UINT32  ReservedBits:21;
> >> +  } Bits;
> >> +  ///
> >> +  /// All bit fields as a 32-bit value
> >> +  ///
> >> +  UINT32  Uint32;
> >> +} CPUID_MEMORY_ENCRYPTION_INFO_EBX;
> >> +
> >> +/**
> >> +  Secure Encrypted Virtualization (SEV) status register
> >> +
> >> +**/
> >> +#define MSR_SEV_STATUS                     0xc0010131
> >> +
> >> +/**
> >> +  MSR information returned for #MSR_SEV_STATUS **/ typedef union {
> >> +  ///
> >> +  /// Individual bit fields
> >> +  ///
> >> +  struct {
> >> +    ///
> >> +    /// [Bit 0] Secure Encrypted Virtualization (Sev) is enabled
> >> +    ///
> >> +    UINT32  SevBit:1;
> >> +
> >> +    ///
> >> +    /// [Bit 1] Secure Encrypted Virtualization Encrypted State
> (SevEs) is enabled
> >> +    ///
> >> +    UINT32  SevEsBit:1;
> >> +
> >> +    UINT32  Reserved:30;
> >> +  } Bits;
> >> +  ///
> >> +  /// All bit fields as a 32-bit value
> >> +  ///
> >> +  UINT32  Uint32;
> >> +  ///
> >> +  /// All bit fields as a 64-bit value
> >> +  ///
> >> +  UINT64  Uint64;
> >> +} MSR_SEV_STATUS_REGISTER;
> >> +
> >> +#endif
> >>
> >> _______________________________________________
> >> edk2-devel mailing list
> >> edk2-devel@lists.01.org
> >> https://lists.01.org/mailman/listinfo/edk2-devel
> >>
> >
> > I feel that these definitions should be added to
> "UefiCpuPkg/Include/Register/Cpuid.h", or else to another (new) header
> file in that directory.
> >
> > Jeff, what do you think?
> >
> > Thanks!
> > Laszlo
> > _______________________________________________
> > edk2-devel mailing list
> > edk2-devel@lists.01.org
> > https://lists.01.org/mailman/listinfo/edk2-devel
> >
>
>


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

* Re: [RFC PATCH v2 03/10] OvmfPkg/PlatformPei: Add Secure Encrypted Virutualization (SEV) support
  2017-03-27  8:23   ` Laszlo Ersek
@ 2017-03-27 12:22     ` Brijesh Singh
  0 siblings, 0 replies; 44+ messages in thread
From: Brijesh Singh @ 2017-03-27 12:22 UTC (permalink / raw)
  To: Laszlo Ersek
  Cc: Kinney, Michael D, Justen, Jordan L, edk2-devel, Gao, Liming,
	brijesh.singh, Leo Duran, Tom Lendacky

On Mon, Mar 27, 2017 at 3:23 AM, Laszlo Ersek <lersek@redhat.com> wrote:

> Please fix the typo ("Virutualization") in the subject.
>
> On 03/21/17 22:13, Brijesh Singh wrote:
> > Initialize Secure Encrypted Virtualization support and set the memory
> encryption mask PCD.
>
> Please wrap commit messages at 74 characters.
>
>
Will do.



> >
> > Signed-off-by: Brijesh Singh <brijesh.singh@amd.com>
> > ---
> >  OvmfPkg/OvmfPkgIa32.dsc             |    3 +
> >  OvmfPkg/OvmfPkgIa32X64.dsc          |    3 +
> >  OvmfPkg/OvmfPkgX64.dsc              |    3 +
> >  OvmfPkg/PlatformPei/AmdSev.c        |   97
> +++++++++++++++++++++++++++++++++++
> >  OvmfPkg/PlatformPei/Platform.c      |    1
> >  OvmfPkg/PlatformPei/Platform.h      |    5 ++
> >  OvmfPkg/PlatformPei/PlatformPei.inf |    2 +
> >  7 files changed, 114 insertions(+)
> >  create mode 100644 OvmfPkg/PlatformPei/AmdSev.c
> >
> > diff --git a/OvmfPkg/OvmfPkgIa32.dsc b/OvmfPkg/OvmfPkgIa32.dsc
> > index 546cdf7..769251d 100644
> > --- a/OvmfPkg/OvmfPkgIa32.dsc
> > +++ b/OvmfPkg/OvmfPkgIa32.dsc
> > @@ -506,6 +506,9 @@
> >    gUefiCpuPkgTokenSpaceGuid.PcdCpuMaxLogicalProcessorNumber|64
> >    gUefiCpuPkgTokenSpaceGuid.PcdCpuApInitTimeOutInMicroSeconds|50000
> >
> > +  # Set memory encryption mask
> > +  gEfiMdeModulePkgTokenSpaceGuid.PcdPteMemoryEncryptionAddressO
> rMask|0x0
> > +
>
> Please update your git config as described here:
>
> https://github.com/tianocore/tianocore.github.io/wiki/
> Laszlo's-unkempt-git-guide-for-edk2-contributors-and-
> maintainers#contrib-05
>
> (the "xfuncname" setting in particular,) and here:
>
> https://github.com/tianocore/tianocore.github.io/wiki/
> Laszlo's-unkempt-git-guide-for-edk2-contributors-and-
> maintainers#contrib-09
>
> The point of these settings is that the diff hunk header marked with @@
> above will display the DSC section that the hunk modifies (and I'll know
> immediately that you are adding a dynamic PCD default).
>
>
Thanks for the pointer, I will configure our project based on the settings
described in the wiki.



> >  !if $(SMM_REQUIRE) == TRUE
> >    gUefiCpuPkgTokenSpaceGuid.PcdCpuSmmSyncMode|0x01
> >    gUefiCpuPkgTokenSpaceGuid.PcdCpuSmmApSyncTimeout|100000
> > diff --git a/OvmfPkg/OvmfPkgIa32X64.dsc b/OvmfPkg/OvmfPkgIa32X64.dsc
> > index 383c8d3..3874c35 100644
> > --- a/OvmfPkg/OvmfPkgIa32X64.dsc
> > +++ b/OvmfPkg/OvmfPkgIa32X64.dsc
> > @@ -514,6 +514,9 @@
> >    gUefiCpuPkgTokenSpaceGuid.PcdCpuMaxLogicalProcessorNumber|64
> >    gUefiCpuPkgTokenSpaceGuid.PcdCpuApInitTimeOutInMicroSeconds|50000
> >
> > +  # Set memory encryption mask
> > +  gEfiMdeModulePkgTokenSpaceGuid.PcdPteMemoryEncryptionAddressO
> rMask|0x0
> > +
> >  !if $(SMM_REQUIRE) == TRUE
> >    gUefiCpuPkgTokenSpaceGuid.PcdCpuSmmSyncMode|0x01
> >    gUefiCpuPkgTokenSpaceGuid.PcdCpuSmmApSyncTimeout|100000
> > diff --git a/OvmfPkg/OvmfPkgX64.dsc b/OvmfPkg/OvmfPkgX64.dsc
> > index 0b7533c..fe7f086 100644
> > --- a/OvmfPkg/OvmfPkgX64.dsc
> > +++ b/OvmfPkg/OvmfPkgX64.dsc
> > @@ -513,6 +513,9 @@
> >    gUefiCpuPkgTokenSpaceGuid.PcdCpuMaxLogicalProcessorNumber|64
> >    gUefiCpuPkgTokenSpaceGuid.PcdCpuApInitTimeOutInMicroSeconds|50000
> >
> > +  # Set memory encryption mask
> > +  gEfiMdeModulePkgTokenSpaceGuid.PcdPteMemoryEncryptionAddressO
> rMask|0x0
> > +
> >  !if $(SMM_REQUIRE) == TRUE
> >    gUefiCpuPkgTokenSpaceGuid.PcdCpuSmmSyncMode|0x01
> >    gUefiCpuPkgTokenSpaceGuid.PcdCpuSmmApSyncTimeout|100000
> > diff --git a/OvmfPkg/PlatformPei/AmdSev.c b/OvmfPkg/PlatformPei/AmdSev.c
> > new file mode 100644
> > index 0000000..7f05a9a
> > --- /dev/null
> > +++ b/OvmfPkg/PlatformPei/AmdSev.c
>
> New file -- can you please double check it is CRLF terminated? Hm,
> looking at your "sev-rfc-2" branch, the file does use CRLF. Good.
>
> > @@ -0,0 +1,97 @@
> > +/**@file
> > +  Initialize Secure Encrypted Virtualization (SEV) support
> > +
> > +  Copyright (c) 2017, Advanced Micro Devices. All rights reserved.<BR>
> > +
> > +  This program and the accompanying materials
> > +  are licensed and made available under the terms and conditions of the
> BSD License
> > +  which accompanies this distribution.  The full text of the license
> may be found at
>
> This line is too wide. Please make sure no line is wider than 79 chars.
>
> Please check your patches with
>
>   python BaseTools/Scripts/PatchCheck.py
>
> before submission.
>
> > +  http://opensource.org/licenses/bsd-license.php
> > +
> > +  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
> > +  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR
> IMPLIED.
> > +
> > +**/
> > +//
> > +// The package level header files this module uses
> > +//
> > +#include <PiPei.h>
> > +
> > +#include <Library/DebugLib.h>
> > +#include <Library/PcdLib.h>
> > +#include <Register/Cpuid.h>
> > +#include <Register/AmdSevMap.h>
> > +
> > +/**
> > +
> > +  Function returns 'TRUE' when SEV is enabled otherwise FALSE
> > +
> > +  **/
>
> One idiomatic way to write this comment is:
>
> /**
>   Query whether SEV is enabled.
>
>   @retval TRUE   SEV is enabled.
>   @retval FALSE  Otherwise.
> **/
>
>

I will update comment.



> > +STATIC
> > +BOOLEAN
> > +SevIsEnabled (
> > +  VOID
> > +  )
> > +{
> > +  UINT32 RegEax;
> > +  MSR_SEV_STATUS_REGISTER Msr;
> > +  CPUID_MEMORY_ENCRYPTION_INFO_EAX  Eax;
>
> Please align the definitions like this:
>
>   UINT32                           RegEax;
>   MSR_SEV_STATUS_REGISTER          Msr;
>   CPUID_MEMORY_ENCRYPTION_INFO_EAX Eax;
>
>
>
Will do



> > +
> > +  //
> > +  // Check if memory encryption leaf exist
> > +  //
> > +  AsmCpuid (CPUID_EXTENDED_FUNCTION, &RegEax, NULL, NULL, NULL);
> > +  if (RegEax >= CPUID_MEMORY_ENCRYPTION_INFO) {
> > +    //
> > +    // CPUID Fn8000_001F[EAX] Bit 1 (Sev supported)
> > +    //
> > +    AsmCpuid (CPUID_MEMORY_ENCRYPTION_INFO, &Eax.Uint32, NULL, NULL,
> NULL);
> > +
> > +    if (Eax.Bits.SevBit) {
> > +      //
> > +      // Check MSR_0xC0010131 Bit 0 (Sev Enabled)
> > +      //
> > +      Msr.Uint32 = AsmReadMsr32 (MSR_SEV_STATUS);
> > +      if (Msr.Bits.SevBit) {
> > +        return TRUE;
> > +      }
> > +    }
> > +  }
> > +
> > +  return FALSE;
> > +}
> > +
> > +/**
> > +  Function checks if SEV support is available, if present then it
> updates
> > +  the dynamic PcdPteMemoryEncryptionAddressOrMask with memory
> encryption mask.
> > +
> > +  **/
> > +VOID
> > +EFIAPI
> > +AmdSevInitialize (
> > +  VOID
> > +  )
> > +{
> > +  UINT64 MeMask;
> > +  CPUID_MEMORY_ENCRYPTION_INFO_EBX  Ebx;
>
> Same alignment / layout comment.
>
> Also, I suggest renaming "MeMask" to "EncryptionMask".
>
>

Will fix both alignment/layout and rename the variable.



> > +
> > +  //
> > +  // Check if SEV is enabled
> > +  //
> > +  if (!SevIsEnabled ()) {
> > +    return;
> > +  }
> > +
> > +  //
> > +  // CPUID Fn8000_001F[EBX] Bit 0:5 (memory encryption bit position)
> > +  //
> > +  AsmCpuid (CPUID_MEMORY_ENCRYPTION_INFO, NULL, &Ebx.Uint32, NULL,
> NULL);
> > +  MeMask = LShiftU64 (1, Ebx.Bits.PtePosBits);
> > +
> > +  //
> > +  // Set Memory Encryption Mask PCD
> > +  //
> > +  PcdSet64S (PcdPteMemoryEncryptionAddressOrMask, MeMask);
>
> Please save the status of the PcdSet64S() function call, and assert that
> it works:
>
>   RETURN_ERROR PcdStatus;
>
>   PcdStatus = PcdSet64S (...);
>   ASSERT_RETURN_ERROR (PcdStatus);
>
>

Okay, will update the code.



> > +
> > +  DEBUG ((EFI_D_INFO, "SEV support is enabled (mask 0x%lx)\n", MeMask));
>
> We no longer use EFI_D_* macros in new code, please use DEBUG_* instead.
>
>
Ah, I was not aware of this. I may have used this macro in other patches. I
will go and fix them.



> > +}
> > diff --git a/OvmfPkg/PlatformPei/Platform.c b/OvmfPkg/PlatformPei/
> Platform.c
> > index 77a8a16..49e6c66 100644
> > --- a/OvmfPkg/PlatformPei/Platform.c
> > +++ b/OvmfPkg/PlatformPei/Platform.c
> > @@ -667,6 +667,7 @@ InitializePlatform (
> >      NoexecDxeInitialization ();
> >    }
> >
> > +  AmdSevInitialize ();
> >    MiscInitialization ();
> >    InstallFeatureControlCallback ();
> >
>
> OK, so this is something we do on S3 resume as well... Yes, S3Resume2Pei
> consumes this PCD.
>
>
I did run a S3 resume and could see the code was kicking in and we were
able to resume fine.



> > diff --git a/OvmfPkg/PlatformPei/Platform.h b/OvmfPkg/PlatformPei/
> Platform.h
> > index 18f42c3..a7729b9 100644
> > --- a/OvmfPkg/PlatformPei/Platform.h
> > +++ b/OvmfPkg/PlatformPei/Platform.h
> > @@ -88,6 +88,11 @@ XenDetect (
> >    VOID
> >    );
> >
> > +VOID
> > +AmdSevInitialize (
> > +  VOID
> > +  );
> > +
> >  extern BOOLEAN mXen;
> >
> >  VOID
>
> Again, I request that you please configure your edk2 working tree as
> described in the above wiki article. In particular,
>
> https://github.com/tianocore/tianocore.github.io/wiki/
> Laszlo's-unkempt-git-guide-for-edk2-contributors-and-
> maintainers#contrib-10
>
> and
>
> https://github.com/tianocore/tianocore.github.io/wiki/
> Laszlo's-unkempt-git-guide-for-edk2-contributors-and-
> maintainers#contrib-23
>
> will ensure that .h files are formatted before .c files into the
> patches, which helps quite a bit with review.
>
> (With newer git, you can set -O permanently for git-format-patch,
> through "diff.orderFile".)
>


Sure I will update gitconfig file with those settings.


> diff --git a/OvmfPkg/PlatformPei/PlatformPei.inf b/OvmfPkg/PlatformPei/
> PlatformPei.inf
> > index 53c6dd4..2cf4ac876 100644
> > --- a/OvmfPkg/PlatformPei/PlatformPei.inf
> > +++ b/OvmfPkg/PlatformPei/PlatformPei.inf
> > @@ -35,6 +35,7 @@
> >    MemDetect.c
> >    Platform.c
> >    Xen.c
> > +  AmdSev.c
> >
> >  [Packages]
>
> If possible please try to keep the list of files alphabetically sorted.
>
>
Will do.


> >    IntelFrameworkModulePkg/IntelFrameworkModulePkg.dec
> > @@ -98,6 +99,7 @@
> >    gUefiCpuPkgTokenSpaceGuid.PcdCpuMaxLogicalProcessorNumber
> >    gUefiCpuPkgTokenSpaceGuid.PcdCpuApInitTimeOutInMicroSeconds
> >    gUefiCpuPkgTokenSpaceGuid.PcdCpuApStackSize
> > +  gEfiMdeModulePkgTokenSpaceGuid.PcdPteMemoryEncryptionAddressOrMask
>
> Ditto for the list of PCDs.
>
> Functionally the patch looks okay to me.
>
>
Thanks




> Thanks,
> Laszlo
>
> >
> >  [FixedPcd]
> >    gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseAddress
> >
> > _______________________________________________
> > edk2-devel mailing list
> > edk2-devel@lists.01.org
> > https://lists.01.org/mailman/listinfo/edk2-devel
> >
>
>


-- 
Confusion is always the most honest response.


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

* Re: [RFC PATCH v2 01/10] OvmfPkg/Include: Define SEV specific CPUID and MSR
  2017-03-27  7:57         ` Fan, Jeff
  2017-03-27 11:58           ` Brijesh Singh
@ 2017-03-27 15:59           ` Duran, Leo
  2017-03-27 16:07             ` Brijesh Singh
  1 sibling, 1 reply; 44+ messages in thread
From: Duran, Leo @ 2017-03-27 15:59 UTC (permalink / raw)
  To: 'Fan, Jeff', Laszlo Ersek, Brijesh Singh,
	Kinney, Michael D, Justen, Jordan L, edk2-devel@ml01.01.org,
	Gao, Liming
  Cc: Singh, Brijesh, Lendacky, Thomas

Jeff, et al,

Given that:
1) UefiCpuPkg/Include/Register/Cpuid.h... Does reference an Intel SDM
2) UefiCpuPkg/Include/Register/Msr... Includes intel SoC's

I vote for:
1) UefiCpuPkg/Include/Register/Amd/Cpuid.h
2) UefiCpuPkg/Include/Register/Amd/Msr.h + UefiCpuPkg/Include/Register/Amd/Msr/XxxMsr.h

Leo.

> -----Original Message-----
> From: Fan, Jeff [mailto:jeff.fan@intel.com]
> Sent: Monday, March 27, 2017 2:58 AM
> To: Laszlo Ersek <lersek@redhat.com>; Brijesh Singh
> <brijesh.ksingh@gmail.com>; Kinney, Michael D
> <michael.d.kinney@intel.com>; Justen, Jordan L
> <jordan.l.justen@intel.com>; edk2-devel@ml01.01.org; Gao, Liming
> <liming.gao@intel.com>
> Cc: Duran, Leo <leo.duran@amd.com>; Singh, Brijesh
> <brijesh.singh@amd.com>; Lendacky, Thomas
> <Thomas.Lendacky@amd.com>
> Subject: RE: [edk2] [RFC PATCH v2 01/10] OvmfPkg/Include: Define SEV
> specific CPUID and MSR
> 
> Laszlo,
> 
> One Amd directory under UefiCpuPkg/Include/Register is better.
> 
> Does Brijesh/Leo have any comments, or have other suggestions?
> 
> Thanks!
> Jeff
> 
> -----Original Message-----
> From: Laszlo Ersek [mailto:lersek@redhat.com]
> Sent: Thursday, March 23, 2017 5:20 PM
> To: Fan, Jeff; Brijesh Singh; Kinney, Michael D; Justen, Jordan L; edk2-
> devel@ml01.01.org; Gao, Liming
> Cc: leo.duran@amd.com; brijesh.singh@amd.com;
> Thomas.Lendacky@amd.com
> Subject: Re: [edk2] [RFC PATCH v2 01/10] OvmfPkg/Include: Define SEV
> specific CPUID and MSR
> 
> On 03/23/17 08:42, Fan, Jeff wrote:
> > Laszlo,
> >
> > UefiCpuPkg/Include/Register/Cpuid.h defined the CPUID only described in
> IA32 SDM.
> > UefiCpuPkg/Include/Register/ArchitecturalMsr.h defined the IA32
> > Architectural MSRs in IA32 SDM
> UefiCpuPkg/Include/Register/Msr/xxxxMsr.h defined the IA32 Model-
> specific MSRs in IA32 SDM.
> >
> > I am not sure if Brijesh/Leo has some idea to place SEV specific
> CPUID/MSRs definitions.
> > I think one new file or new folder is better.
> 
> I agree, both would work for me. My main point is that this feature depends
> on physical processor attributes, not on emulated (virtual) hardware or on
> various hypervisors, plus it is defined in a public industry spec, so it seems to
> belong under UefiCpuPkg, not OvmfPkg.
> 
> How about
> 
>   UefiCpuPkg/Include/AmdRegister/Cpuid.h
>   UefiCpuPkg/Include/AmdRegister/ArchitecturalMsr.h
>   UefiCpuPkg/Include/AmdRegister/Msr/xxxxMsr.h
> 
> or else:
> 
>   UefiCpuPkg/Include/Register/Amd/Cpuid.h
>   UefiCpuPkg/Include/Register/Amd/ArchitecturalMsr.h
>   UefiCpuPkg/Include/Register/Amd/Msr/xxxxMsr.h
> 
> (as appropriate -- I'm not saying that this patch should create all of these files
> / subdirectories at once).
> 
> Thanks
> Laszlo
> >
> > -----Original Message-----
> > From: edk2-devel [mailto:edk2-devel-bounces@lists.01.org] On Behalf Of
> > Laszlo Ersek
> > Sent: Thursday, March 23, 2017 12:04 AM
> > To: Brijesh Singh; Kinney, Michael D; Justen, Jordan L;
> > edk2-devel@ml01.01.org; Gao, Liming; Fan, Jeff
> > Cc: leo.duran@amd.com; brijesh.singh@amd.com;
> Thomas.Lendacky@amd.com
> > Subject: Re: [edk2] [RFC PATCH v2 01/10] OvmfPkg/Include: Define SEV
> > specific CPUID and MSR
> >
> > Adding Jeff
> >
> > On 03/21/17 22:12, Brijesh Singh wrote:
> >> The patch defines AMD's Memory Encryption Information CPUID leaf
> (0x8000_001F).
> >> The complete description for this CPUID leaf is available in APM
> >> volume 2 [1] Section 15.34 (Secure Encrypted Virtualization).
> >>
> >> [1] http://support.amd.com/TechDocs/24593.pdf
> >>
> >> Signed-off-by: Brijesh Singh <brijesh.singh@amd.com>
> >> ---
> >>  OvmfPkg/Include/Register/AmdSevMap.h |  133
> >> ++++++++++++++++++++++++++++++++++
> >>  1 file changed, 133 insertions(+)
> >>  create mode 100644 OvmfPkg/Include/Register/AmdSevMap.h
> >>
> >> diff --git a/OvmfPkg/Include/Register/AmdSevMap.h
> >> b/OvmfPkg/Include/Register/AmdSevMap.h
> >> new file mode 100644
> >> index 0000000..de80f39
> >> --- /dev/null
> >> +++ b/OvmfPkg/Include/Register/AmdSevMap.h
> >> @@ -0,0 +1,133 @@
> >> +/** @file
> >> +
> >> +AMD Secure Encrypted Virtualization (SEV) specific CPUID and MSR
> >> +definitions
> >> +
> >> +The complete description for this CPUID leaf is available in APM
> >> +volume 2 (Section 15.34) http://support.amd.com/TechDocs/24593.pdf
> >> +
> >> +Copyright (c) 2017, Advanced Micro Devices. All rights reserved.<BR>
> >> +
> >> +This program and the accompanying materials are licensed and made
> >> +available under the terms and conditions of the BSD License which
> >> +accompanies this distribution.  The full text of the license may be
> >> +found at http://opensource.org/licenses/bsd-license.php
> >> +
> >> +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS"
> >> +BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND,
> EITHER EXPRESS OR IMPLIED.
> >> +
> >> +**/
> >> +
> >> +#ifndef __AMD_SEV_MAP_H__
> >> +#define __AMD_SEV_MAP_H__
> >> +
> >> +#pragma pack (1)
> >> +
> >> +#define CPUID_MEMORY_ENCRYPTION_INFO             0x8000001F
> >> +
> >> +/**
> >> +  CPUID Memory Encryption support information EAX for CPUID leaf
> >> +  #CPUID_MEMORY_ENCRYPTION_INFO.
> >> +**/
> >> +typedef union {
> >> +  ///
> >> +  /// Individual bit fields
> >> +  ///
> >> +  struct {
> >> +    ///
> >> +    /// [Bit 0] Secure Memory Encryption (Sme) Support
> >> +    ///
> >> +    UINT32  SmeBit:1;
> >> +
> >> +    ///
> >> +    /// [Bit 1] Secure Encrypted Virtualization (Sev) Support
> >> +    ///
> >> +    UINT32  SevBit:1;
> >> +
> >> +    ///
> >> +    /// [Bit 2] Page flush MSR support
> >> +    ///
> >> +    UINT32  PageFlushMsrBit:1;
> >> +
> >> +    ///
> >> +    /// [Bit 3] Encrypted state support
> >> +    ///
> >> +    UINT32  SevEsBit:1;
> >> +
> >> +    ///
> >> +    /// [Bit 4:31] Reserved
> >> +    ///
> >> +    UINT32  ReservedBits:28;
> >> +  } Bits;
> >> +  ///
> >> +  /// All bit fields as a 32-bit value
> >> +  ///
> >> +  UINT32  Uint32;
> >> +} CPUID_MEMORY_ENCRYPTION_INFO_EAX;
> >> +
> >> +/**
> >> +  CPUID Memory Encryption support information EBX for CPUID leaf
> >> +  #CPUID_MEMORY_ENCRYPTION_INFO.
> >> +**/
> >> +typedef union {
> >> +  ///
> >> +  /// Individual bit fields
> >> +  ///
> >> +  struct {
> >> +    ///
> >> +    /// [Bit 0:5] Page table bit number used to enable memory encryption
> >> +    ///
> >> +    UINT32  PtePosBits:6;
> >> +
> >> +    ///
> >> +    /// [Bit 6:11] Reduction of system physical address space bits when
> memory encryption is enabled
> >> +    ///
> >> +    UINT32  ReducedPhysBits:5;
> >> +
> >> +    ///
> >> +    /// [Bit 12:31] Reserved
> >> +    ///
> >> +    UINT32  ReservedBits:21;
> >> +  } Bits;
> >> +  ///
> >> +  /// All bit fields as a 32-bit value
> >> +  ///
> >> +  UINT32  Uint32;
> >> +} CPUID_MEMORY_ENCRYPTION_INFO_EBX;
> >> +
> >> +/**
> >> +  Secure Encrypted Virtualization (SEV) status register
> >> +
> >> +**/
> >> +#define MSR_SEV_STATUS                     0xc0010131
> >> +
> >> +/**
> >> +  MSR information returned for #MSR_SEV_STATUS **/ typedef union {
> >> +  ///
> >> +  /// Individual bit fields
> >> +  ///
> >> +  struct {
> >> +    ///
> >> +    /// [Bit 0] Secure Encrypted Virtualization (Sev) is enabled
> >> +    ///
> >> +    UINT32  SevBit:1;
> >> +
> >> +    ///
> >> +    /// [Bit 1] Secure Encrypted Virtualization Encrypted State (SevEs) is
> enabled
> >> +    ///
> >> +    UINT32  SevEsBit:1;
> >> +
> >> +    UINT32  Reserved:30;
> >> +  } Bits;
> >> +  ///
> >> +  /// All bit fields as a 32-bit value
> >> +  ///
> >> +  UINT32  Uint32;
> >> +  ///
> >> +  /// All bit fields as a 64-bit value
> >> +  ///
> >> +  UINT64  Uint64;
> >> +} MSR_SEV_STATUS_REGISTER;
> >> +
> >> +#endif
> >>
> >> _______________________________________________
> >> edk2-devel mailing list
> >> edk2-devel@lists.01.org
> >> https://lists.01.org/mailman/listinfo/edk2-devel
> >>
> >
> > I feel that these definitions should be added to
> "UefiCpuPkg/Include/Register/Cpuid.h", or else to another (new) header file
> in that directory.
> >
> > Jeff, what do you think?
> >
> > Thanks!
> > Laszlo
> > _______________________________________________
> > edk2-devel mailing list
> > edk2-devel@lists.01.org
> > https://lists.01.org/mailman/listinfo/edk2-devel
> >



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

* Re: [RFC PATCH v2 01/10] OvmfPkg/Include: Define SEV specific CPUID and MSR
  2017-03-27 15:59           ` Duran, Leo
@ 2017-03-27 16:07             ` Brijesh Singh
  0 siblings, 0 replies; 44+ messages in thread
From: Brijesh Singh @ 2017-03-27 16:07 UTC (permalink / raw)
  To: Duran, Leo
  Cc: Fan, Jeff, Laszlo Ersek, Kinney, Michael D, Justen, Jordan L,
	edk2-devel@ml01.01.org, Gao, Liming, Singh, Brijesh,
	Lendacky, Thomas

On Mon, Mar 27, 2017 at 10:59 AM, Duran, Leo <leo.duran@amd.com> wrote:

> Jeff, et al,
>
> Given that:
> 1) UefiCpuPkg/Include/Register/Cpuid.h... Does reference an Intel SDM
> 2) UefiCpuPkg/Include/Register/Msr... Includes intel SoC's
>
> I vote for:
> 1) UefiCpuPkg/Include/Register/Amd/Cpuid.h
> 2) UefiCpuPkg/Include/Register/Amd/Msr.h + UefiCpuPkg/Include/Register/
> Amd/Msr/XxxMsr.h
>
>

OK, I will take care of this in next rev.



> Leo.
>
> > -----Original Message-----
> > From: Fan, Jeff [mailto:jeff.fan@intel.com]
> > Sent: Monday, March 27, 2017 2:58 AM
> > To: Laszlo Ersek <lersek@redhat.com>; Brijesh Singh
> > <brijesh.ksingh@gmail.com>; Kinney, Michael D
> > <michael.d.kinney@intel.com>; Justen, Jordan L
> > <jordan.l.justen@intel.com>; edk2-devel@ml01.01.org; Gao, Liming
> > <liming.gao@intel.com>
> > Cc: Duran, Leo <leo.duran@amd.com>; Singh, Brijesh
> > <brijesh.singh@amd.com>; Lendacky, Thomas
> > <Thomas.Lendacky@amd.com>
> > Subject: RE: [edk2] [RFC PATCH v2 01/10] OvmfPkg/Include: Define SEV
> > specific CPUID and MSR
> >
> > Laszlo,
> >
> > One Amd directory under UefiCpuPkg/Include/Register is better.
> >
> > Does Brijesh/Leo have any comments, or have other suggestions?
> >
> > Thanks!
> > Jeff
> >
> > -----Original Message-----
> > From: Laszlo Ersek [mailto:lersek@redhat.com]
> > Sent: Thursday, March 23, 2017 5:20 PM
> > To: Fan, Jeff; Brijesh Singh; Kinney, Michael D; Justen, Jordan L; edk2-
> > devel@ml01.01.org; Gao, Liming
> > Cc: leo.duran@amd.com; brijesh.singh@amd.com;
> > Thomas.Lendacky@amd.com
> > Subject: Re: [edk2] [RFC PATCH v2 01/10] OvmfPkg/Include: Define SEV
> > specific CPUID and MSR
> >
> > On 03/23/17 08:42, Fan, Jeff wrote:
> > > Laszlo,
> > >
> > > UefiCpuPkg/Include/Register/Cpuid.h defined the CPUID only described
> in
> > IA32 SDM.
> > > UefiCpuPkg/Include/Register/ArchitecturalMsr.h defined the IA32
> > > Architectural MSRs in IA32 SDM
> > UefiCpuPkg/Include/Register/Msr/xxxxMsr.h defined the IA32 Model-
> > specific MSRs in IA32 SDM.
> > >
> > > I am not sure if Brijesh/Leo has some idea to place SEV specific
> > CPUID/MSRs definitions.
> > > I think one new file or new folder is better.
> >
> > I agree, both would work for me. My main point is that this feature
> depends
> > on physical processor attributes, not on emulated (virtual) hardware or
> on
> > various hypervisors, plus it is defined in a public industry spec, so it
> seems to
> > belong under UefiCpuPkg, not OvmfPkg.
> >
> > How about
> >
> >   UefiCpuPkg/Include/AmdRegister/Cpuid.h
> >   UefiCpuPkg/Include/AmdRegister/ArchitecturalMsr.h
> >   UefiCpuPkg/Include/AmdRegister/Msr/xxxxMsr.h
> >
> > or else:
> >
> >   UefiCpuPkg/Include/Register/Amd/Cpuid.h
> >   UefiCpuPkg/Include/Register/Amd/ArchitecturalMsr.h
> >   UefiCpuPkg/Include/Register/Amd/Msr/xxxxMsr.h
> >
> > (as appropriate -- I'm not saying that this patch should create all of
> these files
> > / subdirectories at once).
> >
> > Thanks
> > Laszlo
> > >
> > > -----Original Message-----
> > > From: edk2-devel [mailto:edk2-devel-bounces@lists.01.org] On Behalf Of
> > > Laszlo Ersek
> > > Sent: Thursday, March 23, 2017 12:04 AM
> > > To: Brijesh Singh; Kinney, Michael D; Justen, Jordan L;
> > > edk2-devel@ml01.01.org; Gao, Liming; Fan, Jeff
> > > Cc: leo.duran@amd.com; brijesh.singh@amd.com;
> > Thomas.Lendacky@amd.com
> > > Subject: Re: [edk2] [RFC PATCH v2 01/10] OvmfPkg/Include: Define SEV
> > > specific CPUID and MSR
> > >
> > > Adding Jeff
> > >
> > > On 03/21/17 22:12, Brijesh Singh wrote:
> > >> The patch defines AMD's Memory Encryption Information CPUID leaf
> > (0x8000_001F).
> > >> The complete description for this CPUID leaf is available in APM
> > >> volume 2 [1] Section 15.34 (Secure Encrypted Virtualization).
> > >>
> > >> [1] http://support.amd.com/TechDocs/24593.pdf
> > >>
> > >> Signed-off-by: Brijesh Singh <brijesh.singh@amd.com>
> > >> ---
> > >>  OvmfPkg/Include/Register/AmdSevMap.h |  133
> > >> ++++++++++++++++++++++++++++++++++
> > >>  1 file changed, 133 insertions(+)
> > >>  create mode 100644 OvmfPkg/Include/Register/AmdSevMap.h
> > >>
> > >> diff --git a/OvmfPkg/Include/Register/AmdSevMap.h
> > >> b/OvmfPkg/Include/Register/AmdSevMap.h
> > >> new file mode 100644
> > >> index 0000000..de80f39
> > >> --- /dev/null
> > >> +++ b/OvmfPkg/Include/Register/AmdSevMap.h
> > >> @@ -0,0 +1,133 @@
> > >> +/** @file
> > >> +
> > >> +AMD Secure Encrypted Virtualization (SEV) specific CPUID and MSR
> > >> +definitions
> > >> +
> > >> +The complete description for this CPUID leaf is available in APM
> > >> +volume 2 (Section 15.34) http://support.amd.com/TechDocs/24593.pdf
> > >> +
> > >> +Copyright (c) 2017, Advanced Micro Devices. All rights reserved.<BR>
> > >> +
> > >> +This program and the accompanying materials are licensed and made
> > >> +available under the terms and conditions of the BSD License which
> > >> +accompanies this distribution.  The full text of the license may be
> > >> +found at http://opensource.org/licenses/bsd-license.php
> > >> +
> > >> +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS"
> > >> +BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND,
> > EITHER EXPRESS OR IMPLIED.
> > >> +
> > >> +**/
> > >> +
> > >> +#ifndef __AMD_SEV_MAP_H__
> > >> +#define __AMD_SEV_MAP_H__
> > >> +
> > >> +#pragma pack (1)
> > >> +
> > >> +#define CPUID_MEMORY_ENCRYPTION_INFO             0x8000001F
> > >> +
> > >> +/**
> > >> +  CPUID Memory Encryption support information EAX for CPUID leaf
> > >> +  #CPUID_MEMORY_ENCRYPTION_INFO.
> > >> +**/
> > >> +typedef union {
> > >> +  ///
> > >> +  /// Individual bit fields
> > >> +  ///
> > >> +  struct {
> > >> +    ///
> > >> +    /// [Bit 0] Secure Memory Encryption (Sme) Support
> > >> +    ///
> > >> +    UINT32  SmeBit:1;
> > >> +
> > >> +    ///
> > >> +    /// [Bit 1] Secure Encrypted Virtualization (Sev) Support
> > >> +    ///
> > >> +    UINT32  SevBit:1;
> > >> +
> > >> +    ///
> > >> +    /// [Bit 2] Page flush MSR support
> > >> +    ///
> > >> +    UINT32  PageFlushMsrBit:1;
> > >> +
> > >> +    ///
> > >> +    /// [Bit 3] Encrypted state support
> > >> +    ///
> > >> +    UINT32  SevEsBit:1;
> > >> +
> > >> +    ///
> > >> +    /// [Bit 4:31] Reserved
> > >> +    ///
> > >> +    UINT32  ReservedBits:28;
> > >> +  } Bits;
> > >> +  ///
> > >> +  /// All bit fields as a 32-bit value
> > >> +  ///
> > >> +  UINT32  Uint32;
> > >> +} CPUID_MEMORY_ENCRYPTION_INFO_EAX;
> > >> +
> > >> +/**
> > >> +  CPUID Memory Encryption support information EBX for CPUID leaf
> > >> +  #CPUID_MEMORY_ENCRYPTION_INFO.
> > >> +**/
> > >> +typedef union {
> > >> +  ///
> > >> +  /// Individual bit fields
> > >> +  ///
> > >> +  struct {
> > >> +    ///
> > >> +    /// [Bit 0:5] Page table bit number used to enable memory
> encryption
> > >> +    ///
> > >> +    UINT32  PtePosBits:6;
> > >> +
> > >> +    ///
> > >> +    /// [Bit 6:11] Reduction of system physical address space bits
> when
> > memory encryption is enabled
> > >> +    ///
> > >> +    UINT32  ReducedPhysBits:5;
> > >> +
> > >> +    ///
> > >> +    /// [Bit 12:31] Reserved
> > >> +    ///
> > >> +    UINT32  ReservedBits:21;
> > >> +  } Bits;
> > >> +  ///
> > >> +  /// All bit fields as a 32-bit value
> > >> +  ///
> > >> +  UINT32  Uint32;
> > >> +} CPUID_MEMORY_ENCRYPTION_INFO_EBX;
> > >> +
> > >> +/**
> > >> +  Secure Encrypted Virtualization (SEV) status register
> > >> +
> > >> +**/
> > >> +#define MSR_SEV_STATUS                     0xc0010131
> > >> +
> > >> +/**
> > >> +  MSR information returned for #MSR_SEV_STATUS **/ typedef union {
> > >> +  ///
> > >> +  /// Individual bit fields
> > >> +  ///
> > >> +  struct {
> > >> +    ///
> > >> +    /// [Bit 0] Secure Encrypted Virtualization (Sev) is enabled
> > >> +    ///
> > >> +    UINT32  SevBit:1;
> > >> +
> > >> +    ///
> > >> +    /// [Bit 1] Secure Encrypted Virtualization Encrypted State
> (SevEs) is
> > enabled
> > >> +    ///
> > >> +    UINT32  SevEsBit:1;
> > >> +
> > >> +    UINT32  Reserved:30;
> > >> +  } Bits;
> > >> +  ///
> > >> +  /// All bit fields as a 32-bit value
> > >> +  ///
> > >> +  UINT32  Uint32;
> > >> +  ///
> > >> +  /// All bit fields as a 64-bit value
> > >> +  ///
> > >> +  UINT64  Uint64;
> > >> +} MSR_SEV_STATUS_REGISTER;
> > >> +
> > >> +#endif
> > >>
> > >> _______________________________________________
> > >> edk2-devel mailing list
> > >> edk2-devel@lists.01.org
> > >> https://lists.01.org/mailman/listinfo/edk2-devel
> > >>
> > >
> > > I feel that these definitions should be added to
> > "UefiCpuPkg/Include/Register/Cpuid.h", or else to another (new) header
> file
> > in that directory.
> > >
> > > Jeff, what do you think?
> > >
> > > Thanks!
> > > Laszlo
> > > _______________________________________________
> > > edk2-devel mailing list
> > > edk2-devel@lists.01.org
> > > https://lists.01.org/mailman/listinfo/edk2-devel
> > >
>
>


-- 
Confusion is always the most honest response.


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

* Re: [RFC PATCH v2 01/10] OvmfPkg/Include: Define SEV specific CPUID and MSR
  2017-03-27 11:58           ` Brijesh Singh
@ 2017-03-27 17:33             ` Laszlo Ersek
  2017-03-28  0:45             ` Fan, Jeff
  1 sibling, 0 replies; 44+ messages in thread
From: Laszlo Ersek @ 2017-03-27 17:33 UTC (permalink / raw)
  To: Brijesh Singh, Fan, Jeff
  Cc: Kinney, Michael D, Justen, Jordan L, edk2-devel@ml01.01.org,
	Gao, Liming, leo.duran@amd.com, brijesh.singh@amd.com,
	Thomas.Lendacky@amd.com

On 03/27/17 13:58, Brijesh Singh wrote:
> On Mon, Mar 27, 2017 at 2:57 AM, Fan, Jeff <jeff.fan@intel.com> wrote:
> 
>> Laszlo,
>>
>> One Amd directory under UefiCpuPkg/Include/Register is better.
>>
>> Does Brijesh/Leo have any comments, or have other suggestions?
>>
>>
> 
> I am not sure if creating a new UefiCpuPkg/Include/Register/Amd/Cpuid is a
> good idea, CPUID Fn8000_001F
> leaf can go in UefiCpuPkg/Include/Register/Cpuid.h. Looking at
> UefiCpuPkg/Include/Register/Cpuid.h indicates
> that this file defines the standard x86 CPUID's. The definition of CPUID's
> listed in this file are same on both Intel
> and AMD platforms. I was told by our architecture team that if Intel ever
> decides to support the new leaf then it will
> comply to the exact same bit definition.
> 
> I am a bit unsure about where the MSR_SEV_STATUS should go, one part of me
> thinks that this MSR should be
> defined in OvmfPkg and other part thinks that it can go into
> UefiCpuPkg/Include/Amd/Msr.h. It is a read-only MSR
> and has meaning in a virtualization context hence I was more inclined
> towards defining into OvmfPkg instead of UefiCpuPkg.

OK, if we can't reach an agreement for UefiCpuPkg, I'm fine with OvmfPkg.

Thanks
Laszlo

> 
> Leo,  any comments/suggestions ?
> 
> -Brijesh
> 
> 
>> -----Original Message-----
>> From: Laszlo Ersek [mailto:lersek@redhat.com]
>> Sent: Thursday, March 23, 2017 5:20 PM
>> To: Fan, Jeff; Brijesh Singh; Kinney, Michael D; Justen, Jordan L;
>> edk2-devel@ml01.01.org; Gao, Liming
>> Cc: leo.duran@amd.com; brijesh.singh@amd.com; Thomas.Lendacky@amd.com
>> Subject: Re: [edk2] [RFC PATCH v2 01/10] OvmfPkg/Include: Define SEV
>> specific CPUID and MSR
>>
>> On 03/23/17 08:42, Fan, Jeff wrote:
>>> Laszlo,
>>>
>>> UefiCpuPkg/Include/Register/Cpuid.h defined the CPUID only described in
>> IA32 SDM.
>>> UefiCpuPkg/Include/Register/ArchitecturalMsr.h defined the IA32
>>> Architectural MSRs in IA32 SDM UefiCpuPkg/Include/Register/Msr/xxxxMsr.h
>> defined the IA32 Model-specific MSRs in IA32 SDM.
>>>
>>> I am not sure if Brijesh/Leo has some idea to place SEV specific
>> CPUID/MSRs definitions.
>>> I think one new file or new folder is better.
>>
>> I agree, both would work for me. My main point is that this feature
>> depends on physical processor attributes, not on emulated (virtual)
>> hardware or on various hypervisors, plus it is defined in a public industry
>> spec, so it seems to belong under UefiCpuPkg, not OvmfPkg.
>>
>> How about
>>
>>   UefiCpuPkg/Include/AmdRegister/Cpuid.h
>>   UefiCpuPkg/Include/AmdRegister/ArchitecturalMsr.h
>>   UefiCpuPkg/Include/AmdRegister/Msr/xxxxMsr.h
>>
>> or else:
>>
>>   UefiCpuPkg/Include/Register/Amd/Cpuid.h
>>   UefiCpuPkg/Include/Register/Amd/ArchitecturalMsr.h
>>   UefiCpuPkg/Include/Register/Amd/Msr/xxxxMsr.h
>>
>> (as appropriate -- I'm not saying that this patch should create all of
>> these files / subdirectories at once).
>>
>> Thanks
>> Laszlo
>>>
>>> -----Original Message-----
>>> From: edk2-devel [mailto:edk2-devel-bounces@lists.01.org] On Behalf Of
>>> Laszlo Ersek
>>> Sent: Thursday, March 23, 2017 12:04 AM
>>> To: Brijesh Singh; Kinney, Michael D; Justen, Jordan L;
>>> edk2-devel@ml01.01.org; Gao, Liming; Fan, Jeff
>>> Cc: leo.duran@amd.com; brijesh.singh@amd.com; Thomas.Lendacky@amd.com
>>> Subject: Re: [edk2] [RFC PATCH v2 01/10] OvmfPkg/Include: Define SEV
>>> specific CPUID and MSR
>>>
>>> Adding Jeff
>>>
>>> On 03/21/17 22:12, Brijesh Singh wrote:
>>>> The patch defines AMD's Memory Encryption Information CPUID leaf
>> (0x8000_001F).
>>>> The complete description for this CPUID leaf is available in APM
>>>> volume 2 [1] Section 15.34 (Secure Encrypted Virtualization).
>>>>
>>>> [1] http://support.amd.com/TechDocs/24593.pdf
>>>>
>>>> Signed-off-by: Brijesh Singh <brijesh.singh@amd.com>
>>>> ---
>>>>  OvmfPkg/Include/Register/AmdSevMap.h |  133
>>>> ++++++++++++++++++++++++++++++++++
>>>>  1 file changed, 133 insertions(+)
>>>>  create mode 100644 OvmfPkg/Include/Register/AmdSevMap.h
>>>>
>>>> diff --git a/OvmfPkg/Include/Register/AmdSevMap.h
>>>> b/OvmfPkg/Include/Register/AmdSevMap.h
>>>> new file mode 100644
>>>> index 0000000..de80f39
>>>> --- /dev/null
>>>> +++ b/OvmfPkg/Include/Register/AmdSevMap.h
>>>> @@ -0,0 +1,133 @@
>>>> +/** @file
>>>> +
>>>> +AMD Secure Encrypted Virtualization (SEV) specific CPUID and MSR
>>>> +definitions
>>>> +
>>>> +The complete description for this CPUID leaf is available in APM
>>>> +volume 2 (Section 15.34) http://support.amd.com/TechDocs/24593.pdf
>>>> +
>>>> +Copyright (c) 2017, Advanced Micro Devices. All rights reserved.<BR>
>>>> +
>>>> +This program and the accompanying materials are licensed and made
>>>> +available under the terms and conditions of the BSD License which
>>>> +accompanies this distribution.  The full text of the license may be
>>>> +found at http://opensource.org/licenses/bsd-license.php
>>>> +
>>>> +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS"
>>>> +BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER
>> EXPRESS OR IMPLIED.
>>>> +
>>>> +**/
>>>> +
>>>> +#ifndef __AMD_SEV_MAP_H__
>>>> +#define __AMD_SEV_MAP_H__
>>>> +
>>>> +#pragma pack (1)
>>>> +
>>>> +#define CPUID_MEMORY_ENCRYPTION_INFO             0x8000001F
>>>> +
>>>> +/**
>>>> +  CPUID Memory Encryption support information EAX for CPUID leaf
>>>> +  #CPUID_MEMORY_ENCRYPTION_INFO.
>>>> +**/
>>>> +typedef union {
>>>> +  ///
>>>> +  /// Individual bit fields
>>>> +  ///
>>>> +  struct {
>>>> +    ///
>>>> +    /// [Bit 0] Secure Memory Encryption (Sme) Support
>>>> +    ///
>>>> +    UINT32  SmeBit:1;
>>>> +
>>>> +    ///
>>>> +    /// [Bit 1] Secure Encrypted Virtualization (Sev) Support
>>>> +    ///
>>>> +    UINT32  SevBit:1;
>>>> +
>>>> +    ///
>>>> +    /// [Bit 2] Page flush MSR support
>>>> +    ///
>>>> +    UINT32  PageFlushMsrBit:1;
>>>> +
>>>> +    ///
>>>> +    /// [Bit 3] Encrypted state support
>>>> +    ///
>>>> +    UINT32  SevEsBit:1;
>>>> +
>>>> +    ///
>>>> +    /// [Bit 4:31] Reserved
>>>> +    ///
>>>> +    UINT32  ReservedBits:28;
>>>> +  } Bits;
>>>> +  ///
>>>> +  /// All bit fields as a 32-bit value
>>>> +  ///
>>>> +  UINT32  Uint32;
>>>> +} CPUID_MEMORY_ENCRYPTION_INFO_EAX;
>>>> +
>>>> +/**
>>>> +  CPUID Memory Encryption support information EBX for CPUID leaf
>>>> +  #CPUID_MEMORY_ENCRYPTION_INFO.
>>>> +**/
>>>> +typedef union {
>>>> +  ///
>>>> +  /// Individual bit fields
>>>> +  ///
>>>> +  struct {
>>>> +    ///
>>>> +    /// [Bit 0:5] Page table bit number used to enable memory
>> encryption
>>>> +    ///
>>>> +    UINT32  PtePosBits:6;
>>>> +
>>>> +    ///
>>>> +    /// [Bit 6:11] Reduction of system physical address space bits
>> when memory encryption is enabled
>>>> +    ///
>>>> +    UINT32  ReducedPhysBits:5;
>>>> +
>>>> +    ///
>>>> +    /// [Bit 12:31] Reserved
>>>> +    ///
>>>> +    UINT32  ReservedBits:21;
>>>> +  } Bits;
>>>> +  ///
>>>> +  /// All bit fields as a 32-bit value
>>>> +  ///
>>>> +  UINT32  Uint32;
>>>> +} CPUID_MEMORY_ENCRYPTION_INFO_EBX;
>>>> +
>>>> +/**
>>>> +  Secure Encrypted Virtualization (SEV) status register
>>>> +
>>>> +**/
>>>> +#define MSR_SEV_STATUS                     0xc0010131
>>>> +
>>>> +/**
>>>> +  MSR information returned for #MSR_SEV_STATUS **/ typedef union {
>>>> +  ///
>>>> +  /// Individual bit fields
>>>> +  ///
>>>> +  struct {
>>>> +    ///
>>>> +    /// [Bit 0] Secure Encrypted Virtualization (Sev) is enabled
>>>> +    ///
>>>> +    UINT32  SevBit:1;
>>>> +
>>>> +    ///
>>>> +    /// [Bit 1] Secure Encrypted Virtualization Encrypted State
>> (SevEs) is enabled
>>>> +    ///
>>>> +    UINT32  SevEsBit:1;
>>>> +
>>>> +    UINT32  Reserved:30;
>>>> +  } Bits;
>>>> +  ///
>>>> +  /// All bit fields as a 32-bit value
>>>> +  ///
>>>> +  UINT32  Uint32;
>>>> +  ///
>>>> +  /// All bit fields as a 64-bit value
>>>> +  ///
>>>> +  UINT64  Uint64;
>>>> +} MSR_SEV_STATUS_REGISTER;
>>>> +
>>>> +#endif
>>>>
>>>> _______________________________________________
>>>> edk2-devel mailing list
>>>> edk2-devel@lists.01.org
>>>> https://lists.01.org/mailman/listinfo/edk2-devel
>>>>
>>>
>>> I feel that these definitions should be added to
>> "UefiCpuPkg/Include/Register/Cpuid.h", or else to another (new) header
>> file in that directory.
>>>
>>> Jeff, what do you think?
>>>
>>> Thanks!
>>> Laszlo
>>> _______________________________________________
>>> edk2-devel mailing list
>>> edk2-devel@lists.01.org
>>> https://lists.01.org/mailman/listinfo/edk2-devel
>>>
>>
>>
> 



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

* Re: [RFC PATCH v2 06/10] OvmfPkg/DxeBmDmaLib: Fix AllocateBounceBuffer parameter
  2017-03-27  9:21   ` Laszlo Ersek
@ 2017-03-27 18:40     ` Brijesh Singh
  0 siblings, 0 replies; 44+ messages in thread
From: Brijesh Singh @ 2017-03-27 18:40 UTC (permalink / raw)
  To: Laszlo Ersek
  Cc: Kinney, Michael D, Justen, Jordan L, edk2-devel, Gao, Liming,
	Singh, Brijesh, Leo Duran, Tom Lendacky

On Mon, Mar 27, 2017 at 4:21 AM, Laszlo Ersek <lersek@redhat.com> wrote:

> On 03/21/17 22:13, Brijesh Singh wrote:
> > The patch fixes AllocateBounceBuffer parameters.
> >
> > Signed-off-by: Brijesh Singh <brijesh.singh@amd.com>
> > ---
> >  OvmfPkg/Library/DxeBmDmaLib/DxeBmDmaLib.c |    2 +-
> >  1 file changed, 1 insertion(+), 1 deletion(-)
> >
> > diff --git a/OvmfPkg/Library/DxeBmDmaLib/DxeBmDmaLib.c
> b/OvmfPkg/Library/DxeBmDmaLib/DxeBmDmaLib.c
> > index a342c9e..0d960a8 100644
> > --- a/OvmfPkg/Library/DxeBmDmaLib/DxeBmDmaLib.c
> > +++ b/OvmfPkg/Library/DxeBmDmaLib/DxeBmDmaLib.c
> > @@ -192,8 +192,8 @@ BmDmaMap (
> >    }
> >
> >    return AllocateBounceBuffer (
> > -           Operation,
> >             FORCE_BELOW_4GB_TRUE,
> > +           Operation,
> >             PhysicalAddress,
> >             NumberOfBytes,
> >             DeviceAddress,
> >
> > _______________________________________________
> > edk2-devel mailing list
> > edk2-devel@lists.01.org
> > https://lists.01.org/mailman/listinfo/edk2-devel
> >
>
> I'm not yet convinced that we should copy DxeBmDmaLib to OvmfPkg at all,
> but even if we do, the argument order should be fixed in the original
> first (under MdeModulePkg), and then copied to OvmfPkg.
>
>
Like you said, BmDmaLib is not final and accepted solution in upstream.

Jiewen submitted RFC to provide an alternative way of clearing the
encryption bit mask.
We will need to look at that approach as well. In this RFC, i was trying to
show if BmDmaLib
gets accepted then how SEV will make use of it.


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

* Re: [RFC PATCH v2 04/10] OvmfPkg/BaseMemcryptSevLib: Add SEV helper library
  2017-03-27 10:07     ` Laszlo Ersek
@ 2017-03-27 18:44       ` Brijesh Singh
  2017-03-28  8:14         ` Laszlo Ersek
  0 siblings, 1 reply; 44+ messages in thread
From: Brijesh Singh @ 2017-03-27 18:44 UTC (permalink / raw)
  To: Laszlo Ersek
  Cc: Kinney, Michael D, Justen, Jordan L, edk2-devel, Gao, Liming,
	Singh, Brijesh, Leo Duran, Tom Lendacky

On Mon, Mar 27, 2017 at 5:07 AM, Laszlo Ersek <lersek@redhat.com> wrote:

> On 03/27/17 11:19, Laszlo Ersek wrote:
> > On 03/21/17 22:13, Brijesh Singh wrote:
>
> >> +  Returns a boolean to indicate whether SEV is enabled
> >> +
> >> +  @retval TRUE           When SEV is active
> >> +  @retval FALSE          When SEV is not enabled
> >> +  **/
> >> +BOOLEAN
> >> +EFIAPI
> >> +MemEncryptSevIsEnabled (
> >> +  VOID
> >> +  );
> >
> > Would it make sense to call this library function in PlatformPei, rather
> > than add a separate SevIsEnabled() function to it (in patch #3)? The
> > implementations look nearly identical.
>
> I realize that earlier I seemingly suggested the opposite:
>
> http://mid.mail-archive.com/dd9436dc-415c-9fab-081c-
> 39dd2cd71fd5@redhat.com
>
> http://mid.mail-archive.com/9193d837-6a78-b1c4-42c0-
> 427fbc1f2364@redhat.com
>
> However, at that time, my understanding was that this library would only
> be used in PlatformPei (hence the single user wouldn't justify the new
> library instance). Now it seems that there are going to be several
> client modules that check on SEV enablement. Is that right?
>
>

Yes, I do expect several client module link against this library to check
whether the SEV is enabled.
Are you okay if we link MemEncryptSevLib in PlatformPei and make use of
MemEncryptSevIsEnabled()
routine instead of having a local copy ? I was not sure which way to go
hence I still have PlatformPei
and QemuFwCfgPei using the local implementation of the same functions. My
personal perference would
be to link with MemEncryptSevLib instead of having local function. But as
always I am open to suggestions.

Thanks
Brijesh


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

* Re: [RFC PATCH v2 09/10] OvmfPkg/QemuFwCfgLib: Add Secure Encrypted Virtualization (SEV) support
  2017-03-27 10:19   ` Laszlo Ersek
@ 2017-03-27 19:24     ` Brijesh Singh
  2017-03-28  8:12       ` Laszlo Ersek
  0 siblings, 1 reply; 44+ messages in thread
From: Brijesh Singh @ 2017-03-27 19:24 UTC (permalink / raw)
  To: Laszlo Ersek
  Cc: Kinney, Michael D, Justen, Jordan L, edk2-devel, Gao, Liming,
	Singh, Brijesh, Leo Duran, Tom Lendacky

On Mon, Mar 27, 2017 at 5:19 AM, Laszlo Ersek <lersek@redhat.com> wrote:

> On 03/21/17 22:13, Brijesh Singh wrote:
> > The patch adds SEV support in QemuFwCfgLib. When SEV is enabled:
> >
> >  * Pei phase support IO-style operations. This is mainly because we need
> to
> >    use a bounce buffer inorder to support DMA operation. Allocate a
> memory
> >    for bounce buffer can get painful in Pei phase hence if we detect
> FWCfg DMA
> >    support then silently fallback to IO.
> >
> > * Dxe phase supports both IO and DMA style operations.
> > ---
> >  OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgDxe.c        |   73 +++++++++++++
> >  OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgDxeLib.inf   |    2
> >  OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgLib.c        |  112
> ++++++++++++++++++++
> >  .../Library/QemuFwCfgLib/QemuFwCfgLibInternal.h    |   38 +++++++
> >  OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgPei.c        |   93
> +++++++++++++++++
> >  OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgPeiLib.inf   |    2
> >  OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgSec.c        |   82
> +++++++++++++++
> >  7 files changed, 402 insertions(+)
>
> Can you please split this patch into 5 patches?
> - new interfaces in QemuFwCfgLibInternal.h
> - implementation of new APIs for SEC instance
> - implementation of new APIs for PEI instance
> - implementation of new APIs for DXE instance
> - call new APIs from common code
>
> If that is possible. Otherwise, it's quite hard to review & compare the
> instances for the different firmware phases.
>
>
Sure I will divide into multiple patches.



> Anyway, some things I've noticed:
>
> - InternalQemuFwCfgSevIsEnabled() should use global variables in the PEI
> instance as well. Possibly the appropriate interface from
> BaseMemcryptSevLib could be called from both the PEI and DXE instances
> here. (I think the DXE instance already does that.)
>
>
Id tou are okay with it then I will perfer to use BaseMemEncryptSevLib's
provided function in both PEI and DXE phases.



> - regarding InternalQemuFwCfgDmaBytes(): would it be possible to hook
> the SEV-related tricks into the existent function, rather than
> copy+modify the entire function as InternalQemuFwCfgSevDmaBytes()? It
> seems to me that a conditional "prologue" and "epilogue" in
> InternalQemuFwCfgDmaBytes() could do the trick.
>
>
I wanted to reuse the existing function but I was not sure how do you
wanted me to handle static allocation of "Access" variable inside
the InternalQemuFwCfgDmaBytes()

 VOID
 InternalQemuFwCfgDmaBytes (
   IN     UINT32   Size,
   IN OUT VOID     *Buffer OPTIONAL,
   IN     UINT32   Control
   )
 {
   volatile FW_CFG_DMA_ACCESS Access;
   UINT32                     AccessHigh, AccessLow;
   UINT32                     Status;


The "Access" variable is statically allocated inside this function, in case
of SEV the Dma "Access" control variable need to be dynamically allocated
because hypervisor read/writes data into Access->status.

I could convert Access into FW_CFG_DMA_ACCESS pointer for non SEV case and
then integerate the SEV specific changes inside the same function.

I was just not sure which approach is prefrered hence decided to create a
new function for now and at least start the discussion.




> ... From skimming this patch, I think those are the only
> functionality-related comments I have at this point, beyond the remarks
> I made elsewhere in this series (like: line length, DEBUG_* macros, and
> so on). Please recheck all patches for those comments.
>
>
I will revist all the patches and fix those DEBUG_* macros.



> >
> > diff --git a/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgDxe.c
> b/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgDxe.c
> > index ac05f4c..be8e945 100644
> > --- a/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgDxe.c
> > +++ b/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgDxe.c
> > @@ -4,6 +4,7 @@
> >
> >    Copyright (C) 2013, Red Hat, Inc.
> >    Copyright (c) 2011 - 2013, Intel Corporation. All rights reserved.<BR>
> > +  Copyright (c) 2017, Advanced Micro Devices. All rights reserved.<BR>
> >
> >    This program and the accompanying materials are licensed and made
> available
> >    under the terms and conditions of the BSD License which accompanies
> this
> > @@ -14,14 +15,34 @@
> >    WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
> >  **/
> >
> > +#include "Uefi.h"
> > +
> > +#include <Library/BaseLib.h>
> >  #include <Library/DebugLib.h>
> >  #include <Library/QemuFwCfgLib.h>
> > +#include <Library/UefiBootServicesTableLib.h>
> > +#include <Library/MemEncryptSevLib.h>
> > +#include <Library/BmDmaLib.h>
> >
> >  #include "QemuFwCfgLibInternal.h"
> >
> >  STATIC BOOLEAN mQemuFwCfgSupported = FALSE;
> >  STATIC BOOLEAN mQemuFwCfgDmaSupported;
> > +STATIC BOOLEAN mQemuFwCfgSevIsEnabled = FALSE;
> > +
> > +/**
> > + Returns a boolean indicating whether the SEV is enabled
> >
> > + @retval    TRUE    SEV is enabled
> > + @retval    FALSE   SEV is not enabled
> > +**/
> > +BOOLEAN
> > +InternalQemuFwCfgSevIsEnabled (
> > +  VOID
> > +  )
> > +{
> > +  return mQemuFwCfgSevIsEnabled;
> > +}
> >
> >  /**
> >    Returns a boolean indicating if the firmware configuration interface
> > @@ -79,6 +100,9 @@ QemuFwCfgInitialize (
> >      mQemuFwCfgDmaSupported = TRUE;
> >      DEBUG ((DEBUG_INFO, "QemuFwCfg interface (DMA) is supported.\n"));
> >    }
> > +
> > +  mQemuFwCfgSevIsEnabled = MemEncryptSevIsEnabled ();
> > +
> >    return RETURN_SUCCESS;
> >  }
> >
> > @@ -114,3 +138,52 @@ InternalQemuFwCfgDmaIsAvailable (
> >  {
> >    return mQemuFwCfgDmaSupported;
> >  }
> > +
> > +/**
> > + Allocate a bounce buffer for SEV DMA.
> > +
>
> Please document that this function either succeeds or doesn't return.
>
> > +  @param[in]     NumPage  Number of pages.
> > +  @param[out]    Buffer   Allocated DMA Buffer pointer
> > +
> > +**/
> > +VOID
> > +InternalQemuFwCfgSevDmaAllocateBuffer (
> > +  IN     UINT32   NumPages,
> > +  OUT    VOID     **Buffer
> > +  )
> > +{
> > +  EFI_STATUS  Status;
> > +
> > +  //
> > +  // Allocate DMA bounce buffer
> > +  //
> > +  Status = BmDmaAllocateBuffer (TRUE, EfiBootServicesData, NumPages,
> Buffer);
> > +  if (EFI_ERROR(Status)) {
> > +    DEBUG ((EFI_D_ERROR, "SEV: Failed to allocate bounce buffer %d
> pages\n", NumPages));
> > +    ASSERT_EFI_ERROR (Status);
> > +    CpuDeadLoop ();
> > +  }
> > +
> > +  DEBUG ((EFI_D_VERBOSE, "QemuFwCfgSevDma allocate buffer 0x%Lx Pages
> %d\n", (UINTN)Buffer, NumPages));
> > +}
> > +
> > +/**
> > + Free the DMA buffer allocated using InternalQemuFwCfgSevDmaAllocat
> eBuffer
> > +
> > +  @param[in]     NumPage  Number of pages.
> > +  @param[in]     Buffer   DMA Buffer pointer
> > +
> > +**/
> > +VOID
> > +InternalQemuFwCfgSevDmaFreeBuffer (
> > +  IN     VOID     *Buffer,
> > +  IN     UINT32   NumPages
> > +  )
> > +{
> > +  //
> > +  // Free the bounce buffer
> > +  //
> > +  DEBUG ((EFI_D_VERBOSE, "QemuFwCfgSevDma free buffer 0x%Lx Pages
> %d\n", (UINTN)Buffer, NumPages));
> > +  BmDmaFreeBuffer (Buffer, NumPages);
> > +}
> > +
> > diff --git a/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgDxeLib.inf
> b/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgDxeLib.inf
> > index 346bb88..536887f 100644
> > --- a/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgDxeLib.inf
> > +++ b/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgDxeLib.inf
> > @@ -47,4 +47,6 @@
> >    DebugLib
> >    IoLib
> >    MemoryAllocationLib
> > +  MemEncryptSevLib
> > +  BmDmaLib
> >
> > diff --git a/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgLib.c
> b/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgLib.c
> > index 1bf725d..d2560a3 100644
> > --- a/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgLib.c
> > +++ b/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgLib.c
> > @@ -47,6 +47,111 @@ QemuFwCfgSelectItem (
> >
> >
> >  /**
> > +  Transfer an array of bytes, or skip a number of bytes, using the SEV
> DMA bounce
> > +  interface. The function is same as InternalQemuFwCfgDmaBytes with
> excpetion that
> > +  it uses bounce buffer
> > +
> > +  @param[in]     Size     Size in bytes to transfer or skip.
> > +
> > +  @param[in,out] HostBuffer Buffer to read data into or write data
> from. Ignored,
> > +                            and may be NULL, if Size is zero, or
> Control is
> > +                            FW_CFG_DMA_CTL_SKIP.
> > +
> > +  @param[in]     Control  One of the following:
> > +                          FW_CFG_DMA_CTL_WRITE - write to fw_cfg from
> Buffer.
> > +                          FW_CFG_DMA_CTL_READ  - read from fw_cfg into
> Buffer.
> > +                          FW_CFG_DMA_CTL_SKIP  - skip bytes in fw_cfg.
> > +**/
> > +VOID
> > +InternalQemuFwCfgSevDmaBytes (
> > +  IN     UINT32   Size,
> > +  IN OUT VOID     *HostBuffer OPTIONAL,
> > +  IN     UINT32   Control
> > +  )
> > +{
> > +  volatile FW_CFG_DMA_ACCESS *Access;
> > +  UINT32                     AccessHigh, AccessLow;
> > +  UINT32                     Status;
> > +  UINT32                     NumPages;
> > +  VOID                       *DmaBuffer, *Buffer;
> > +
> > +  //
> > +  // Calculate number of pages we need to allocate for this operation
> > +  //
> > +  if (Control == FW_CFG_DMA_CTL_SKIP) {
> > +    //
> > +    // Control data does not need the actual buffer
> > +    //
> > +    NumPages = EFI_SIZE_TO_PAGES (sizeof (*Access));
> > +  } else {
> > +    NumPages = EFI_SIZE_TO_PAGES (sizeof (*Access) + Size);
> > +  }
> > +
> > +  //
> > +  // Allocate DMA bounce buffer
> > +  //
> > +  InternalQemuFwCfgSevDmaAllocateBuffer (NumPages, &DmaBuffer);
> > +
> > +  Access = (FW_CFG_DMA_ACCESS *)DmaBuffer;
> > +  Buffer = DmaBuffer + sizeof(*Access);
> > +
> > +  Access->Control = SwapBytes32 (Control);
> > +  Access->Length  = SwapBytes32 (Size);
> > +  Access->Address = SwapBytes64 ((UINTN)Buffer);
> > +
> > +  //
> > +  // Copy data from Host buffer into DMA buffer
> > +  //
> > +  if (HostBuffer && (Control == FW_CFG_DMA_CTL_WRITE)) {
> > +    CopyMem (Buffer, HostBuffer, Size);
> > +  }
> > +
> > +  //
> > +  // Delimit the transfer from (a) modifications to Access, (b) in case
> of a
> > +  // write, from writes to Buffer by the caller.
> > +  //
> > +  MemoryFence ();
> > +
> > +  //
> > +  // Start the transfer.
> > +  //
> > +  AccessHigh = (UINT32)RShiftU64 ((UINTN)Access, 32);
> > +  AccessLow  = (UINT32)(UINTN)Access;
> > +  IoWrite32 (FW_CFG_IO_DMA_ADDRESS,     SwapBytes32 (AccessHigh));
> > +  IoWrite32 (FW_CFG_IO_DMA_ADDRESS + 4, SwapBytes32 (AccessLow));
> > +
> > +  //
> > +  // Don't look at Access->Control before starting the transfer.
> > +  //
> > +  MemoryFence ();
> > +
> > +  //
> > +  // Wait for the transfer to complete.
> > +  //
> > +  do {
> > +    Status = SwapBytes32 (Access->Control);
> > +    ASSERT ((Status & FW_CFG_DMA_CTL_ERROR) == 0);
> > +  } while (Status != 0);
> > +
> > +  //
> > +  // After a read, the caller will want to use Buffer.
> > +  //
> > +  MemoryFence ();
> > +
> > +  //
> > +  // Copy data from DMA buffer into Host Buffer
> > +  //
> > +  if (HostBuffer && (Control == FW_CFG_DMA_CTL_READ)) {
> > +    CopyMem (HostBuffer, Buffer, Size);
> > +  }
> > +
> > +  //
> > +  // Free the DMA bounce buffer
> > +  //
> > +  InternalQemuFwCfgSevDmaFreeBuffer (DmaBuffer, NumPages);
> > +}
> > +
> > +/**
> >    Transfer an array of bytes, or skip a number of bytes, using the DMA
> >    interface.
> >
> > @@ -79,6 +184,13 @@ InternalQemuFwCfgDmaBytes (
> >      return;
> >    }
> >
> > +  //
> > +  // When SEV is enabled then use SEV version of DmaReadWrite
> > +  //
> > +  if (InternalQemuFwCfgSevIsEnabled ()) {
> > +    return InternalQemuFwCfgSevDmaBytes (Size, Buffer, Control);
> > +  }
> > +
> >    Access.Control = SwapBytes32 (Control);
> >    Access.Length  = SwapBytes32 (Size);
> >    Access.Address = SwapBytes64 ((UINTN)Buffer);
> > diff --git a/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgLibInternal.h
> b/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgLibInternal.h
> > index 6e87c62..8e2ff45 100644
> > --- a/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgLibInternal.h
> > +++ b/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgLibInternal.h
> > @@ -2,6 +2,7 @@
> >    Internal interfaces specific to the QemuFwCfgLib instances in OvmfPkg.
> >
> >    Copyright (C) 2016, Red Hat, Inc.
> > +  Copyright (C) 2017, Advanced Micro Devices.
> >
> >    This program and the accompanying materials are licensed and made
> available
> >    under the terms and conditions of the BSD License which accompanies
> this
> > @@ -43,4 +44,41 @@ InternalQemuFwCfgDmaIsAvailable (
> >    VOID
> >    );
> >
> > +/**
> > + Returns a boolean indicating whether the SEV is enabled
> > +
> > + @retval    TRUE    SEV is enabled
> > + @retval    FALSE   SEV is not enabled
> > +**/
> > +BOOLEAN
> > +InternalQemuFwCfgSevIsEnabled (
> > +  VOID
> > +  );
> > +
> > +/**
> > + Allocate a bounce buffer for SEV DMA.
> > +
> > +  @param[in]     NumPage  Number of pages.
> > +  @param[out]    Buffer   Allocated DMA Buffer pointer
> > +
> > +**/
> > +VOID
> > +InternalQemuFwCfgSevDmaAllocateBuffer (
> > +  IN     UINT32   NumPages,
> > +  OUT    VOID     **Buffer
> > +  );
> > +
> > +/**
> > + Free the DMA buffer allocated using InternalQemuFwCfgSevDmaAllocat
> eBuffer
> > +
> > +  @param[in]     NumPage  Number of pages.
> > +  @param[in]     Buffer   DMA Buffer pointer
> > +
> > +**/
> > +VOID
> > +InternalQemuFwCfgSevDmaFreeBuffer (
> > +  IN     VOID     *Buffer,
> > +  IN     UINT32   NumPages
> > +  );
> > +
> >  #endif
> > diff --git a/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgPei.c
> b/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgPei.c
> > index ac05f4c..3dc9270 100644
> > --- a/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgPei.c
> > +++ b/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgPei.c
> > @@ -4,6 +4,7 @@
> >
> >    Copyright (C) 2013, Red Hat, Inc.
> >    Copyright (c) 2011 - 2013, Intel Corporation. All rights reserved.<BR>
> > +  Copyright (c) 2017, Advanced Micro Devices. All rights reserved.<BR>
> >
> >    This program and the accompanying materials are licensed and made
> available
> >    under the terms and conditions of the BSD License which accompanies
> this
> > @@ -14,14 +15,55 @@
> >    WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
> >  **/
> >
> > +#include <Library/BaseLib.h>
> >  #include <Library/DebugLib.h>
> >  #include <Library/QemuFwCfgLib.h>
> > +#include <Register/Cpuid.h>
> > +#include <Register/AmdSevMap.h>
> >
> >  #include "QemuFwCfgLibInternal.h"
> >
> >  STATIC BOOLEAN mQemuFwCfgSupported = FALSE;
> >  STATIC BOOLEAN mQemuFwCfgDmaSupported;
> >
> > +/**
> > + Returns a boolean indicating whether the SEV is enabled
> > +
> > + @retval    TRUE    SEV is enabled
> > + @retval    FALSE   SEV is not enabled
> > +**/
> > +BOOLEAN
> > +InternalQemuFwCfgSevIsEnabled (
> > +  VOID
> > +  )
> > +{
> > +  UINT32 RegEax;
> > +  MSR_SEV_STATUS_REGISTER Msr;
> > +  CPUID_MEMORY_ENCRYPTION_INFO_EAX  Eax;
> > +
> > +  //
> > +  // Check if memory encryption leaf exist
> > +  //
> > +  AsmCpuid (CPUID_EXTENDED_FUNCTION, &RegEax, NULL, NULL, NULL);
> > +  if (RegEax >= CPUID_MEMORY_ENCRYPTION_INFO) {
> > +    //
> > +    // CPUID Fn8000_001F[EAX] Bit 1 (Sev supported)
> > +    //
> > +    AsmCpuid (CPUID_MEMORY_ENCRYPTION_INFO, &Eax.Uint32, NULL, NULL,
> NULL);
> > +
> > +    if (Eax.Bits.SevBit) {
> > +      //
> > +      // Check MSR_0xC0010131 Bit 0 (Sev Enabled)
> > +      //
> > +      Msr.Uint32 = AsmReadMsr32 (MSR_SEV_STATUS);
> > +      if (Msr.Bits.SevBit) {
> > +        return TRUE;
> > +      }
> > +    }
> > +  }
> > +
> > +  return FALSE;
> > +}
> >
> >  /**
> >    Returns a boolean indicating if the firmware configuration interface
> > @@ -79,6 +121,17 @@ QemuFwCfgInitialize (
> >      mQemuFwCfgDmaSupported = TRUE;
> >      DEBUG ((DEBUG_INFO, "QemuFwCfg interface (DMA) is supported.\n"));
> >    }
> > +
> > +  //
> > +  // When SEV is enabled then we do not support DMA interface.
> > +  // This is because we need to use bounce buffer to support DMA
> operation in SEV guest.
> > +  // Allocating memory for bounce buffer can get painful in Pei phase
> > +  //
> > +  if (mQemuFwCfgDmaSupported && InternalQemuFwCfgSevIsEnabled ()) {
> > +    mQemuFwCfgDmaSupported = FALSE;
> > +    DEBUG ((DEBUG_INFO, "QemuFwCfg disabling DMA interface and
> defaulting to IO Port.\n"));
> > +  }
> > +
> >    return RETURN_SUCCESS;
> >  }
> >
> > @@ -114,3 +167,43 @@ InternalQemuFwCfgDmaIsAvailable (
> >  {
> >    return mQemuFwCfgDmaSupported;
> >  }
> > +
> > +/**
> > + Allocate a bounce buffer for SEV DMA.
> > +
> > +  @param[in]     NumPage  Number of pages.
> > +  @param[out]    Buffer   Allocated DMA Buffer pointer
> > +
> > +**/
> > +VOID
> > +InternalQemuFwCfgSevDmaAllocateBuffer (
> > +  IN     UINT32   NumPages,
> > +  OUT    VOID     **Buffer
> > +  )
> > +{
> > +  //
> > +  // We should never reach here
> > +  //
> > +  ASSERT (FALSE);
> > +  CpuDeadLoop ();
> > +}
> > +
> > +/**
> > + Free the DMA buffer allocated using InternalQemuFwCfgSevDmaAllocat
> eBuffer
> > +
> > +  @param[in]     NumPage  Number of pages.
> > +  @param[in]     Buffer   DMA Buffer pointer
> > +
> > +**/
> > +VOID
> > +InternalQemuFwCfgSevDmaFreeBuffer (
> > +  IN     VOID     *Buffer,
> > +  IN     UINT32   NumPages
> > +  )
> > +{
> > +  //
> > +  // We should never reach here
> > +  //
> > +  ASSERT (FALSE);
> > +  CpuDeadLoop ();
> > +}
> > diff --git a/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgPeiLib.inf
> b/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgPeiLib.inf
> > index 4f966a8..83cc0de 100644
> > --- a/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgPeiLib.inf
> > +++ b/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgPeiLib.inf
> > @@ -39,7 +39,9 @@
> >
> >  [Packages]
> >    MdePkg/MdePkg.dec
> > +  MdeModulePkg/MdeModulePkg.dec
> >    OvmfPkg/OvmfPkg.dec
> > +  UefiCpuPkg/UefiCpuPkg.dec
> >
> >  [LibraryClasses]
> >    BaseLib
> > diff --git a/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgSec.c
> b/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgSec.c
> > index 465ccbe..70b0a47 100644
> > --- a/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgSec.c
> > +++ b/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgSec.c
> > @@ -16,8 +16,11 @@
> >    WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
> >  **/
> >
> > +#include <Library/BaseLib.h>
> >  #include <Library/DebugLib.h>
> >  #include <Library/QemuFwCfgLib.h>
> > +#include <Register/Cpuid.h>
> > +#include <Register/AmdSevMap.h>
> >
> >  #include "QemuFwCfgLibInternal.h"
> >
> > @@ -94,3 +97,82 @@ InternalQemuFwCfgDmaIsAvailable (
> >  {
> >    return FALSE;
> >  }
> > +
> > +/**
> > + Returns a boolean indicating whether the SEV is enabled
> > +
> > + @retval    TRUE    SEV is enabled
> > + @retval    FALSE   SEV is not enabled
> > +**/
> > +BOOLEAN
> > +InternalQemuFwCfgSevIsEnabled (
> > +  VOID
> > +  )
> > +{
> > +  UINT32 RegEax;
> > +  MSR_SEV_STATUS_REGISTER Msr;
> > +  CPUID_MEMORY_ENCRYPTION_INFO_EAX  Eax;
> > +
> > +  //
> > +  // Check if memory encryption leaf exist
> > +  //
> > +  AsmCpuid (CPUID_EXTENDED_FUNCTION, &RegEax, NULL, NULL, NULL);
> > +  if (RegEax >= CPUID_MEMORY_ENCRYPTION_INFO) {
> > +    //
> > +    // CPUID Fn8000_001F[EAX] Bit 1 (Sev supported)
> > +    //
> > +    AsmCpuid (CPUID_MEMORY_ENCRYPTION_INFO, &Eax.Uint32, NULL, NULL,
> NULL);
> > +
> > +    if (Eax.Bits.SevBit) {
> > +      //
> > +      // Check MSR_0xC0010131 Bit 0 (Sev Enabled)
> > +      //
> > +      Msr.Uint32 = AsmReadMsr32 (MSR_SEV_STATUS);
> > +      if (Msr.Bits.SevBit) {
> > +        return TRUE;
> > +      }
> > +    }
> > +  }
> > +
> > +  return FALSE;
> > +}
> > +
> > +/**
> > + Allocate a bounce buffer for SEV DMA.
> > +
> > +  @param[in]     NumPage  Number of pages.
> > +  @param[out]    Buffer   Allocated DMA Buffer pointer
> > +
> > +**/
> > +VOID
> > +InternalQemuFwCfgSevDmaAllocateBuffer (
> > +  IN     UINT32   NumPages,
> > +  OUT    VOID     **Buffer
> > +  )
> > +{
> > +  //
> > +  // We should never reach here
> > +  //
> > +  ASSERT (FALSE);
> > +  CpuDeadLoop ();
> > +}
> > +
> > +/**
> > + Free the DMA buffer allocated using InternalQemuFwCfgSevDmaAllocat
> eBuffer
> > +
> > +  @param[in]     NumPage  Number of pages.
> > +  @param[in]     Buffer   DMA Buffer pointer
> > +
> > +**/
> > +VOID
> > +InternalQemuFwCfgSevDmaFreeBuffer (
> > +  IN     VOID     *Buffer,
> > +  IN     UINT32   NumPages
> > +  )
> > +{
> > +  //
> > +  // We should never reach here
> > +  //
> > +  ASSERT (FALSE);
> > +  CpuDeadLoop ();
> > +}
> >
> > _______________________________________________
> > edk2-devel mailing list
> > edk2-devel@lists.01.org
> > https://lists.01.org/mailman/listinfo/edk2-devel
> >
>
>


-- 
Confusion is always the most honest response.


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

* Re: [RFC PATCH v2 01/10] OvmfPkg/Include: Define SEV specific CPUID and MSR
  2017-03-27 11:58           ` Brijesh Singh
  2017-03-27 17:33             ` Laszlo Ersek
@ 2017-03-28  0:45             ` Fan, Jeff
  2017-03-28  2:19               ` Duran, Leo
  1 sibling, 1 reply; 44+ messages in thread
From: Fan, Jeff @ 2017-03-28  0:45 UTC (permalink / raw)
  To: Brijesh Singh
  Cc: Laszlo Ersek, Kinney, Michael D, Justen, Jordan L,
	edk2-devel@ml01.01.org, Gao, Liming, leo.duran@amd.com,
	brijesh.singh@amd.com, Thomas.Lendacky@amd.com

Brijesh,

UefiCpuPkg/Include/Register/Cpuid.h declared to support one version of Intel SDM.

Before the new SDM publishing, we cannot assume what CPUID naming and definitions are.
If new SDM adopts the exactly same definitions of CPUID in the future, we could simply include UefiCpuPkg/Include/Register/Cpuid.h and remove old definitions.

Thanks!
Jeff

From: Brijesh Singh [mailto:brijesh.ksingh@gmail.com]
Sent: Monday, March 27, 2017 7:59 PM
To: Fan, Jeff
Cc: Laszlo Ersek; Kinney, Michael D; Justen, Jordan L; edk2-devel@ml01.01.org; Gao, Liming; leo.duran@amd.com; brijesh.singh@amd.com; Thomas.Lendacky@amd.com
Subject: Re: [edk2] [RFC PATCH v2 01/10] OvmfPkg/Include: Define SEV specific CPUID and MSR



On Mon, Mar 27, 2017 at 2:57 AM, Fan, Jeff <jeff.fan@intel.com<mailto:jeff.fan@intel.com>> wrote:
Laszlo,

One Amd directory under UefiCpuPkg/Include/Register is better.

Does Brijesh/Leo have any comments, or have other suggestions?



I am not sure if creating a new UefiCpuPkg/Include/Register/Amd/Cpuid is a good idea, CPUID Fn8000_001F
leaf can go in UefiCpuPkg/Include/Register/Cpuid.h. Looking at UefiCpuPkg/Include/Register/Cpuid.h indicates
that this file defines the standard x86 CPUID's. The definition of CPUID's listed in this file are same on both Intel
and AMD platforms. I was told by our architecture team that if Intel ever decides to support the new leaf then it will
comply to the exact same bit definition.

I am a bit unsure about where the MSR_SEV_STATUS should go, one part of me thinks that this MSR should be
defined in OvmfPkg and other part thinks that it can go into UefiCpuPkg/Include/Amd/Msr.h. It is a read-only MSR
and has meaning in a virtualization context hence I was more inclined towards defining into OvmfPkg instead of UefiCpuPkg.

Leo,  any comments/suggestions ?

-Brijesh

-----Original Message-----
From: Laszlo Ersek [mailto:lersek@redhat.com<mailto:lersek@redhat.com>]
Sent: Thursday, March 23, 2017 5:20 PM
To: Fan, Jeff; Brijesh Singh; Kinney, Michael D; Justen, Jordan L; edk2-devel@ml01.01.org<mailto:edk2-devel@ml01.01.org>; Gao, Liming
Cc: leo.duran@amd.com<mailto:leo.duran@amd.com>; brijesh.singh@amd.com<mailto:brijesh.singh@amd.com>; Thomas.Lendacky@amd.com<mailto:Thomas.Lendacky@amd.com>
Subject: Re: [edk2] [RFC PATCH v2 01/10] OvmfPkg/Include: Define SEV specific CPUID and MSR

On 03/23/17 08:42, Fan, Jeff wrote:
> Laszlo,
>
> UefiCpuPkg/Include/Register/Cpuid.h defined the CPUID only described in IA32 SDM.
> UefiCpuPkg/Include/Register/ArchitecturalMsr.h defined the IA32
> Architectural MSRs in IA32 SDM UefiCpuPkg/Include/Register/Msr/xxxxMsr.h defined the IA32 Model-specific MSRs in IA32 SDM.
>
> I am not sure if Brijesh/Leo has some idea to place SEV specific CPUID/MSRs definitions.
> I think one new file or new folder is better.

I agree, both would work for me. My main point is that this feature depends on physical processor attributes, not on emulated (virtual) hardware or on various hypervisors, plus it is defined in a public industry spec, so it seems to belong under UefiCpuPkg, not OvmfPkg.

How about

  UefiCpuPkg/Include/AmdRegister/Cpuid.h
  UefiCpuPkg/Include/AmdRegister/ArchitecturalMsr.h
  UefiCpuPkg/Include/AmdRegister/Msr/xxxxMsr.h

or else:

  UefiCpuPkg/Include/Register/Amd/Cpuid.h
  UefiCpuPkg/Include/Register/Amd/ArchitecturalMsr.h
  UefiCpuPkg/Include/Register/Amd/Msr/xxxxMsr.h

(as appropriate -- I'm not saying that this patch should create all of these files / subdirectories at once).

Thanks
Laszlo
>
> -----Original Message-----
> From: edk2-devel [mailto:edk2-devel-bounces@lists.01.org<mailto:edk2-devel-bounces@lists.01.org>] On Behalf Of
> Laszlo Ersek
> Sent: Thursday, March 23, 2017 12:04 AM
> To: Brijesh Singh; Kinney, Michael D; Justen, Jordan L;
> edk2-devel@ml01.01.org<mailto:edk2-devel@ml01.01.org>; Gao, Liming; Fan, Jeff
> Cc: leo.duran@amd.com<mailto:leo.duran@amd.com>; brijesh.singh@amd.com<mailto:brijesh.singh@amd.com>; Thomas.Lendacky@amd.com<mailto:Thomas.Lendacky@amd.com>
> Subject: Re: [edk2] [RFC PATCH v2 01/10] OvmfPkg/Include: Define SEV
> specific CPUID and MSR
>
> Adding Jeff
>
> On 03/21/17 22:12, Brijesh Singh wrote:
>> The patch defines AMD's Memory Encryption Information CPUID leaf (0x8000_001F).
>> The complete description for this CPUID leaf is available in APM
>> volume 2 [1] Section 15.34 (Secure Encrypted Virtualization).
>>
>> [1] http://support.amd.com/TechDocs/24593.pdf
>>
>> Signed-off-by: Brijesh Singh <brijesh.singh@amd.com<mailto:brijesh.singh@amd.com>>
>> ---
>>  OvmfPkg/Include/Register/AmdSevMap.h |  133
>> ++++++++++++++++++++++++++++++++++
>>  1 file changed, 133 insertions(+)
>>  create mode 100644 OvmfPkg/Include/Register/AmdSevMap.h
>>
>> diff --git a/OvmfPkg/Include/Register/AmdSevMap.h
>> b/OvmfPkg/Include/Register/AmdSevMap.h
>> new file mode 100644
>> index 0000000..de80f39
>> --- /dev/null
>> +++ b/OvmfPkg/Include/Register/AmdSevMap.h
>> @@ -0,0 +1,133 @@
>> +/** @file
>> +
>> +AMD Secure Encrypted Virtualization (SEV) specific CPUID and MSR
>> +definitions
>> +
>> +The complete description for this CPUID leaf is available in APM
>> +volume 2 (Section 15.34) http://support.amd.com/TechDocs/24593.pdf
>> +
>> +Copyright (c) 2017, Advanced Micro Devices. All rights reserved.<BR>
>> +
>> +This program and the accompanying materials are licensed and made
>> +available under the terms and conditions of the BSD License which
>> +accompanies this distribution.  The full text of the license may be
>> +found at http://opensource.org/licenses/bsd-license.php
>> +
>> +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS"
>> +BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
>> +
>> +**/
>> +
>> +#ifndef __AMD_SEV_MAP_H__
>> +#define __AMD_SEV_MAP_H__
>> +
>> +#pragma pack (1)
>> +
>> +#define CPUID_MEMORY_ENCRYPTION_INFO             0x8000001F
>> +
>> +/**
>> +  CPUID Memory Encryption support information EAX for CPUID leaf
>> +  #CPUID_MEMORY_ENCRYPTION_INFO.
>> +**/
>> +typedef union {
>> +  ///
>> +  /// Individual bit fields
>> +  ///
>> +  struct {
>> +    ///
>> +    /// [Bit 0] Secure Memory Encryption (Sme) Support
>> +    ///
>> +    UINT32  SmeBit:1;
>> +
>> +    ///
>> +    /// [Bit 1] Secure Encrypted Virtualization (Sev) Support
>> +    ///
>> +    UINT32  SevBit:1;
>> +
>> +    ///
>> +    /// [Bit 2] Page flush MSR support
>> +    ///
>> +    UINT32  PageFlushMsrBit:1;
>> +
>> +    ///
>> +    /// [Bit 3] Encrypted state support
>> +    ///
>> +    UINT32  SevEsBit:1;
>> +
>> +    ///
>> +    /// [Bit 4:31] Reserved
>> +    ///
>> +    UINT32  ReservedBits:28;
>> +  } Bits;
>> +  ///
>> +  /// All bit fields as a 32-bit value
>> +  ///
>> +  UINT32  Uint32;
>> +} CPUID_MEMORY_ENCRYPTION_INFO_EAX;
>> +
>> +/**
>> +  CPUID Memory Encryption support information EBX for CPUID leaf
>> +  #CPUID_MEMORY_ENCRYPTION_INFO.
>> +**/
>> +typedef union {
>> +  ///
>> +  /// Individual bit fields
>> +  ///
>> +  struct {
>> +    ///
>> +    /// [Bit 0:5] Page table bit number used to enable memory encryption
>> +    ///
>> +    UINT32  PtePosBits:6;
>> +
>> +    ///
>> +    /// [Bit 6:11] Reduction of system physical address space bits when memory encryption is enabled
>> +    ///
>> +    UINT32  ReducedPhysBits:5;
>> +
>> +    ///
>> +    /// [Bit 12:31] Reserved
>> +    ///
>> +    UINT32  ReservedBits:21;
>> +  } Bits;
>> +  ///
>> +  /// All bit fields as a 32-bit value
>> +  ///
>> +  UINT32  Uint32;
>> +} CPUID_MEMORY_ENCRYPTION_INFO_EBX;
>> +
>> +/**
>> +  Secure Encrypted Virtualization (SEV) status register
>> +
>> +**/
>> +#define MSR_SEV_STATUS                     0xc0010131
>> +
>> +/**
>> +  MSR information returned for #MSR_SEV_STATUS **/ typedef union {
>> +  ///
>> +  /// Individual bit fields
>> +  ///
>> +  struct {
>> +    ///
>> +    /// [Bit 0] Secure Encrypted Virtualization (Sev) is enabled
>> +    ///
>> +    UINT32  SevBit:1;
>> +
>> +    ///
>> +    /// [Bit 1] Secure Encrypted Virtualization Encrypted State (SevEs) is enabled
>> +    ///
>> +    UINT32  SevEsBit:1;
>> +
>> +    UINT32  Reserved:30;
>> +  } Bits;
>> +  ///
>> +  /// All bit fields as a 32-bit value
>> +  ///
>> +  UINT32  Uint32;
>> +  ///
>> +  /// All bit fields as a 64-bit value
>> +  ///
>> +  UINT64  Uint64;
>> +} MSR_SEV_STATUS_REGISTER;
>> +
>> +#endif
>>
>> _______________________________________________
>> edk2-devel mailing list
>> edk2-devel@lists.01.org<mailto:edk2-devel@lists.01.org>
>> https://lists.01.org/mailman/listinfo/edk2-devel
>>
>
> I feel that these definitions should be added to "UefiCpuPkg/Include/Register/Cpuid.h", or else to another (new) header file in that directory.
>
> Jeff, what do you think?
>
> Thanks!
> Laszlo
> _______________________________________________
> edk2-devel mailing list
> edk2-devel@lists.01.org<mailto:edk2-devel@lists.01.org>
> https://lists.01.org/mailman/listinfo/edk2-devel
>



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

* Re: [RFC PATCH v2 01/10] OvmfPkg/Include: Define SEV specific CPUID and MSR
  2017-03-28  0:45             ` Fan, Jeff
@ 2017-03-28  2:19               ` Duran, Leo
  2017-03-28  2:25                 ` Fan, Jeff
  0 siblings, 1 reply; 44+ messages in thread
From: Duran, Leo @ 2017-03-28  2:19 UTC (permalink / raw)
  To: Fan, Jeff, Brijesh Singh
  Cc: Laszlo Ersek, Kinney, Michael D, Justen, Jordan L,
	edk2-devel@ml01.01.org, Gao, Liming, Singh, Brijesh,
	Lendacky, Thomas

Jeff,
Perhaps you missed my response to this earlier today… Here it is again:
Leo


Given that:

1) UefiCpuPkg/Include/Register/Cpuid.h... Does reference an Intel SDM

2) UefiCpuPkg/Include/Register/Msr... Includes intel SoC's



I vote for:

1) UefiCpuPkg/Include/Register/Amd/Cpuid.h

2) UefiCpuPkg/Include/Register/Amd/Msr.h + UefiCpuPkg/Include/Register/Amd/Msr/XxxMsr.h



Leo.


From: Fan, Jeff [mailto:jeff.fan@intel.com]
Sent: Monday, March 27, 2017 7:46 PM
To: Brijesh Singh <brijesh.ksingh@gmail.com>
Cc: Laszlo Ersek <lersek@redhat.com>; Kinney, Michael D <michael.d.kinney@intel.com>; Justen, Jordan L <jordan.l.justen@intel.com>; edk2-devel@ml01.01.org; Gao, Liming <liming.gao@intel.com>; Duran, Leo <leo.duran@amd.com>; Singh, Brijesh <brijesh.singh@amd.com>; Lendacky, Thomas <Thomas.Lendacky@amd.com>
Subject: RE: [edk2] [RFC PATCH v2 01/10] OvmfPkg/Include: Define SEV specific CPUID and MSR

Brijesh,

UefiCpuPkg/Include/Register/Cpuid.h declared to support one version of Intel SDM.

Before the new SDM publishing, we cannot assume what CPUID naming and definitions are.
If new SDM adopts the exactly same definitions of CPUID in the future, we could simply include UefiCpuPkg/Include/Register/Cpuid.h and remove old definitions.

Thanks!
Jeff

From: Brijesh Singh [mailto:brijesh.ksingh@gmail.com]
Sent: Monday, March 27, 2017 7:59 PM
To: Fan, Jeff
Cc: Laszlo Ersek; Kinney, Michael D; Justen, Jordan L; edk2-devel@ml01.01.org<mailto:edk2-devel@ml01.01.org>; Gao, Liming; leo.duran@amd.com<mailto:leo.duran@amd.com>; brijesh.singh@amd.com<mailto:brijesh.singh@amd.com>; Thomas.Lendacky@amd.com<mailto:Thomas.Lendacky@amd.com>
Subject: Re: [edk2] [RFC PATCH v2 01/10] OvmfPkg/Include: Define SEV specific CPUID and MSR



On Mon, Mar 27, 2017 at 2:57 AM, Fan, Jeff <jeff.fan@intel.com<mailto:jeff.fan@intel.com>> wrote:
Laszlo,

One Amd directory under UefiCpuPkg/Include/Register is better.

Does Brijesh/Leo have any comments, or have other suggestions?



I am not sure if creating a new UefiCpuPkg/Include/Register/Amd/Cpuid is a good idea, CPUID Fn8000_001F
leaf can go in UefiCpuPkg/Include/Register/Cpuid.h. Looking at UefiCpuPkg/Include/Register/Cpuid.h indicates
that this file defines the standard x86 CPUID's. The definition of CPUID's listed in this file are same on both Intel
and AMD platforms. I was told by our architecture team that if Intel ever decides to support the new leaf then it will
comply to the exact same bit definition.

I am a bit unsure about where the MSR_SEV_STATUS should go, one part of me thinks that this MSR should be
defined in OvmfPkg and other part thinks that it can go into UefiCpuPkg/Include/Amd/Msr.h. It is a read-only MSR
and has meaning in a virtualization context hence I was more inclined towards defining into OvmfPkg instead of UefiCpuPkg.

Leo,  any comments/suggestions ?

-Brijesh

-----Original Message-----
From: Laszlo Ersek [mailto:lersek@redhat.com<mailto:lersek@redhat.com>]
Sent: Thursday, March 23, 2017 5:20 PM
To: Fan, Jeff; Brijesh Singh; Kinney, Michael D; Justen, Jordan L; edk2-devel@ml01.01.org<mailto:edk2-devel@ml01.01.org>; Gao, Liming
Cc: leo.duran@amd.com<mailto:leo.duran@amd.com>; brijesh.singh@amd.com<mailto:brijesh.singh@amd.com>; Thomas.Lendacky@amd.com<mailto:Thomas.Lendacky@amd.com>
Subject: Re: [edk2] [RFC PATCH v2 01/10] OvmfPkg/Include: Define SEV specific CPUID and MSR

On 03/23/17 08:42, Fan, Jeff wrote:
> Laszlo,
>
> UefiCpuPkg/Include/Register/Cpuid.h defined the CPUID only described in IA32 SDM.
> UefiCpuPkg/Include/Register/ArchitecturalMsr.h defined the IA32
> Architectural MSRs in IA32 SDM UefiCpuPkg/Include/Register/Msr/xxxxMsr.h defined the IA32 Model-specific MSRs in IA32 SDM.
>
> I am not sure if Brijesh/Leo has some idea to place SEV specific CPUID/MSRs definitions.
> I think one new file or new folder is better.

I agree, both would work for me. My main point is that this feature depends on physical processor attributes, not on emulated (virtual) hardware or on various hypervisors, plus it is defined in a public industry spec, so it seems to belong under UefiCpuPkg, not OvmfPkg.

How about

  UefiCpuPkg/Include/AmdRegister/Cpuid.h
  UefiCpuPkg/Include/AmdRegister/ArchitecturalMsr.h
  UefiCpuPkg/Include/AmdRegister/Msr/xxxxMsr.h

or else:

  UefiCpuPkg/Include/Register/Amd/Cpuid.h
  UefiCpuPkg/Include/Register/Amd/ArchitecturalMsr.h
  UefiCpuPkg/Include/Register/Amd/Msr/xxxxMsr.h

(as appropriate -- I'm not saying that this patch should create all of these files / subdirectories at once).

Thanks
Laszlo
>
> -----Original Message-----
> From: edk2-devel [mailto:edk2-devel-bounces@lists.01.org<mailto:edk2-devel-bounces@lists.01.org>] On Behalf Of
> Laszlo Ersek
> Sent: Thursday, March 23, 2017 12:04 AM
> To: Brijesh Singh; Kinney, Michael D; Justen, Jordan L;
> edk2-devel@ml01.01.org<mailto:edk2-devel@ml01.01.org>; Gao, Liming; Fan, Jeff
> Cc: leo.duran@amd.com<mailto:leo.duran@amd.com>; brijesh.singh@amd.com<mailto:brijesh.singh@amd.com>; Thomas.Lendacky@amd.com<mailto:Thomas.Lendacky@amd.com>
> Subject: Re: [edk2] [RFC PATCH v2 01/10] OvmfPkg/Include: Define SEV
> specific CPUID and MSR
>
> Adding Jeff
>
> On 03/21/17 22:12, Brijesh Singh wrote:
>> The patch defines AMD's Memory Encryption Information CPUID leaf (0x8000_001F).
>> The complete description for this CPUID leaf is available in APM
>> volume 2 [1] Section 15.34 (Secure Encrypted Virtualization).
>>
>> [1] http://support.amd.com/TechDocs/24593.pdf
>>
>> Signed-off-by: Brijesh Singh <brijesh.singh@amd.com<mailto:brijesh.singh@amd.com>>
>> ---
>>  OvmfPkg/Include/Register/AmdSevMap.h |  133
>> ++++++++++++++++++++++++++++++++++
>>  1 file changed, 133 insertions(+)
>>  create mode 100644 OvmfPkg/Include/Register/AmdSevMap.h
>>
>> diff --git a/OvmfPkg/Include/Register/AmdSevMap.h
>> b/OvmfPkg/Include/Register/AmdSevMap.h
>> new file mode 100644
>> index 0000000..de80f39
>> --- /dev/null
>> +++ b/OvmfPkg/Include/Register/AmdSevMap.h
>> @@ -0,0 +1,133 @@
>> +/** @file
>> +
>> +AMD Secure Encrypted Virtualization (SEV) specific CPUID and MSR
>> +definitions
>> +
>> +The complete description for this CPUID leaf is available in APM
>> +volume 2 (Section 15.34) http://support.amd.com/TechDocs/24593.pdf
>> +
>> +Copyright (c) 2017, Advanced Micro Devices. All rights reserved.<BR>
>> +
>> +This program and the accompanying materials are licensed and made
>> +available under the terms and conditions of the BSD License which
>> +accompanies this distribution.  The full text of the license may be
>> +found at http://opensource.org/licenses/bsd-license.php
>> +
>> +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS"
>> +BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
>> +
>> +**/
>> +
>> +#ifndef __AMD_SEV_MAP_H__
>> +#define __AMD_SEV_MAP_H__
>> +
>> +#pragma pack (1)
>> +
>> +#define CPUID_MEMORY_ENCRYPTION_INFO             0x8000001F
>> +
>> +/**
>> +  CPUID Memory Encryption support information EAX for CPUID leaf
>> +  #CPUID_MEMORY_ENCRYPTION_INFO.
>> +**/
>> +typedef union {
>> +  ///
>> +  /// Individual bit fields
>> +  ///
>> +  struct {
>> +    ///
>> +    /// [Bit 0] Secure Memory Encryption (Sme) Support
>> +    ///
>> +    UINT32  SmeBit:1;
>> +
>> +    ///
>> +    /// [Bit 1] Secure Encrypted Virtualization (Sev) Support
>> +    ///
>> +    UINT32  SevBit:1;
>> +
>> +    ///
>> +    /// [Bit 2] Page flush MSR support
>> +    ///
>> +    UINT32  PageFlushMsrBit:1;
>> +
>> +    ///
>> +    /// [Bit 3] Encrypted state support
>> +    ///
>> +    UINT32  SevEsBit:1;
>> +
>> +    ///
>> +    /// [Bit 4:31] Reserved
>> +    ///
>> +    UINT32  ReservedBits:28;
>> +  } Bits;
>> +  ///
>> +  /// All bit fields as a 32-bit value
>> +  ///
>> +  UINT32  Uint32;
>> +} CPUID_MEMORY_ENCRYPTION_INFO_EAX;
>> +
>> +/**
>> +  CPUID Memory Encryption support information EBX for CPUID leaf
>> +  #CPUID_MEMORY_ENCRYPTION_INFO.
>> +**/
>> +typedef union {
>> +  ///
>> +  /// Individual bit fields
>> +  ///
>> +  struct {
>> +    ///
>> +    /// [Bit 0:5] Page table bit number used to enable memory encryption
>> +    ///
>> +    UINT32  PtePosBits:6;
>> +
>> +    ///
>> +    /// [Bit 6:11] Reduction of system physical address space bits when memory encryption is enabled
>> +    ///
>> +    UINT32  ReducedPhysBits:5;
>> +
>> +    ///
>> +    /// [Bit 12:31] Reserved
>> +    ///
>> +    UINT32  ReservedBits:21;
>> +  } Bits;
>> +  ///
>> +  /// All bit fields as a 32-bit value
>> +  ///
>> +  UINT32  Uint32;
>> +} CPUID_MEMORY_ENCRYPTION_INFO_EBX;
>> +
>> +/**
>> +  Secure Encrypted Virtualization (SEV) status register
>> +
>> +**/
>> +#define MSR_SEV_STATUS                     0xc0010131
>> +
>> +/**
>> +  MSR information returned for #MSR_SEV_STATUS **/ typedef union {
>> +  ///
>> +  /// Individual bit fields
>> +  ///
>> +  struct {
>> +    ///
>> +    /// [Bit 0] Secure Encrypted Virtualization (Sev) is enabled
>> +    ///
>> +    UINT32  SevBit:1;
>> +
>> +    ///
>> +    /// [Bit 1] Secure Encrypted Virtualization Encrypted State (SevEs) is enabled
>> +    ///
>> +    UINT32  SevEsBit:1;
>> +
>> +    UINT32  Reserved:30;
>> +  } Bits;
>> +  ///
>> +  /// All bit fields as a 32-bit value
>> +  ///
>> +  UINT32  Uint32;
>> +  ///
>> +  /// All bit fields as a 64-bit value
>> +  ///
>> +  UINT64  Uint64;
>> +} MSR_SEV_STATUS_REGISTER;
>> +
>> +#endif
>>
>> _______________________________________________
>> edk2-devel mailing list
>> edk2-devel@lists.01.org<mailto:edk2-devel@lists.01.org>
>> https://lists.01.org/mailman/listinfo/edk2-devel
>>
>
> I feel that these definitions should be added to "UefiCpuPkg/Include/Register/Cpuid.h", or else to another (new) header file in that directory.
>
> Jeff, what do you think?
>
> Thanks!
> Laszlo
> _______________________________________________
> edk2-devel mailing list
> edk2-devel@lists.01.org<mailto:edk2-devel@lists.01.org>
> https://lists.01.org/mailman/listinfo/edk2-devel
>



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

* Re: [RFC PATCH v2 01/10] OvmfPkg/Include: Define SEV specific CPUID and MSR
  2017-03-28  2:19               ` Duran, Leo
@ 2017-03-28  2:25                 ` Fan, Jeff
  0 siblings, 0 replies; 44+ messages in thread
From: Fan, Jeff @ 2017-03-28  2:25 UTC (permalink / raw)
  To: Duran, Leo, Brijesh Singh
  Cc: Laszlo Ersek, Kinney, Michael D, Justen, Jordan L,
	edk2-devel@ml01.01.org, Gao, Liming, Singh, Brijesh,
	Lendacky, Thomas

Leo,

Yes. I got your mail.

This is my suggestion also.

Thanks!
Jeff

From: Duran, Leo [mailto:leo.duran@amd.com]
Sent: Tuesday, March 28, 2017 10:19 AM
To: Fan, Jeff; Brijesh Singh
Cc: Laszlo Ersek; Kinney, Michael D; Justen, Jordan L; edk2-devel@ml01.01.org; Gao, Liming; Singh, Brijesh; Lendacky, Thomas
Subject: RE: [edk2] [RFC PATCH v2 01/10] OvmfPkg/Include: Define SEV specific CPUID and MSR

Jeff,
Perhaps you missed my response to this earlier today… Here it is again:
Leo


Given that:

1) UefiCpuPkg/Include/Register/Cpuid.h... Does reference an Intel SDM

2) UefiCpuPkg/Include/Register/Msr... Includes intel SoC's



I vote for:

1) UefiCpuPkg/Include/Register/Amd/Cpuid.h

2) UefiCpuPkg/Include/Register/Amd/Msr.h + UefiCpuPkg/Include/Register/Amd/Msr/XxxMsr.h



Leo.


From: Fan, Jeff [mailto:jeff.fan@intel.com]
Sent: Monday, March 27, 2017 7:46 PM
To: Brijesh Singh <brijesh.ksingh@gmail.com<mailto:brijesh.ksingh@gmail.com>>
Cc: Laszlo Ersek <lersek@redhat.com<mailto:lersek@redhat.com>>; Kinney, Michael D <michael.d.kinney@intel.com<mailto:michael.d.kinney@intel.com>>; Justen, Jordan L <jordan.l.justen@intel.com<mailto:jordan.l.justen@intel.com>>; edk2-devel@ml01.01.org<mailto:edk2-devel@ml01.01.org>; Gao, Liming <liming.gao@intel.com<mailto:liming.gao@intel.com>>; Duran, Leo <leo.duran@amd.com<mailto:leo.duran@amd.com>>; Singh, Brijesh <brijesh.singh@amd.com<mailto:brijesh.singh@amd.com>>; Lendacky, Thomas <Thomas.Lendacky@amd.com<mailto:Thomas.Lendacky@amd.com>>
Subject: RE: [edk2] [RFC PATCH v2 01/10] OvmfPkg/Include: Define SEV specific CPUID and MSR

Brijesh,

UefiCpuPkg/Include/Register/Cpuid.h declared to support one version of Intel SDM.

Before the new SDM publishing, we cannot assume what CPUID naming and definitions are.
If new SDM adopts the exactly same definitions of CPUID in the future, we could simply include UefiCpuPkg/Include/Register/Cpuid.h and remove old definitions.

Thanks!
Jeff

From: Brijesh Singh [mailto:brijesh.ksingh@gmail.com]
Sent: Monday, March 27, 2017 7:59 PM
To: Fan, Jeff
Cc: Laszlo Ersek; Kinney, Michael D; Justen, Jordan L; edk2-devel@ml01.01.org<mailto:edk2-devel@ml01.01.org>; Gao, Liming; leo.duran@amd.com<mailto:leo.duran@amd.com>; brijesh.singh@amd.com<mailto:brijesh.singh@amd.com>; Thomas.Lendacky@amd.com<mailto:Thomas.Lendacky@amd.com>
Subject: Re: [edk2] [RFC PATCH v2 01/10] OvmfPkg/Include: Define SEV specific CPUID and MSR



On Mon, Mar 27, 2017 at 2:57 AM, Fan, Jeff <jeff.fan@intel.com<mailto:jeff.fan@intel.com>> wrote:
Laszlo,

One Amd directory under UefiCpuPkg/Include/Register is better.

Does Brijesh/Leo have any comments, or have other suggestions?



I am not sure if creating a new UefiCpuPkg/Include/Register/Amd/Cpuid is a good idea, CPUID Fn8000_001F
leaf can go in UefiCpuPkg/Include/Register/Cpuid.h. Looking at UefiCpuPkg/Include/Register/Cpuid.h indicates
that this file defines the standard x86 CPUID's. The definition of CPUID's listed in this file are same on both Intel
and AMD platforms. I was told by our architecture team that if Intel ever decides to support the new leaf then it will
comply to the exact same bit definition.

I am a bit unsure about where the MSR_SEV_STATUS should go, one part of me thinks that this MSR should be
defined in OvmfPkg and other part thinks that it can go into UefiCpuPkg/Include/Amd/Msr.h. It is a read-only MSR
and has meaning in a virtualization context hence I was more inclined towards defining into OvmfPkg instead of UefiCpuPkg.

Leo,  any comments/suggestions ?

-Brijesh

-----Original Message-----
From: Laszlo Ersek [mailto:lersek@redhat.com<mailto:lersek@redhat.com>]
Sent: Thursday, March 23, 2017 5:20 PM
To: Fan, Jeff; Brijesh Singh; Kinney, Michael D; Justen, Jordan L; edk2-devel@ml01.01.org<mailto:edk2-devel@ml01.01.org>; Gao, Liming
Cc: leo.duran@amd.com<mailto:leo.duran@amd.com>; brijesh.singh@amd.com<mailto:brijesh.singh@amd.com>; Thomas.Lendacky@amd.com<mailto:Thomas.Lendacky@amd.com>
Subject: Re: [edk2] [RFC PATCH v2 01/10] OvmfPkg/Include: Define SEV specific CPUID and MSR

On 03/23/17 08:42, Fan, Jeff wrote:
> Laszlo,
>
> UefiCpuPkg/Include/Register/Cpuid.h defined the CPUID only described in IA32 SDM.
> UefiCpuPkg/Include/Register/ArchitecturalMsr.h defined the IA32
> Architectural MSRs in IA32 SDM UefiCpuPkg/Include/Register/Msr/xxxxMsr.h defined the IA32 Model-specific MSRs in IA32 SDM.
>
> I am not sure if Brijesh/Leo has some idea to place SEV specific CPUID/MSRs definitions.
> I think one new file or new folder is better.

I agree, both would work for me. My main point is that this feature depends on physical processor attributes, not on emulated (virtual) hardware or on various hypervisors, plus it is defined in a public industry spec, so it seems to belong under UefiCpuPkg, not OvmfPkg.

How about

  UefiCpuPkg/Include/AmdRegister/Cpuid.h
  UefiCpuPkg/Include/AmdRegister/ArchitecturalMsr.h
  UefiCpuPkg/Include/AmdRegister/Msr/xxxxMsr.h

or else:

  UefiCpuPkg/Include/Register/Amd/Cpuid.h
  UefiCpuPkg/Include/Register/Amd/ArchitecturalMsr.h
  UefiCpuPkg/Include/Register/Amd/Msr/xxxxMsr.h

(as appropriate -- I'm not saying that this patch should create all of these files / subdirectories at once).

Thanks
Laszlo
>
> -----Original Message-----
> From: edk2-devel [mailto:edk2-devel-bounces@lists.01.org<mailto:edk2-devel-bounces@lists.01.org>] On Behalf Of
> Laszlo Ersek
> Sent: Thursday, March 23, 2017 12:04 AM
> To: Brijesh Singh; Kinney, Michael D; Justen, Jordan L;
> edk2-devel@ml01.01.org<mailto:edk2-devel@ml01.01.org>; Gao, Liming; Fan, Jeff
> Cc: leo.duran@amd.com<mailto:leo.duran@amd.com>; brijesh.singh@amd.com<mailto:brijesh.singh@amd.com>; Thomas.Lendacky@amd.com<mailto:Thomas.Lendacky@amd.com>
> Subject: Re: [edk2] [RFC PATCH v2 01/10] OvmfPkg/Include: Define SEV
> specific CPUID and MSR
>
> Adding Jeff
>
> On 03/21/17 22:12, Brijesh Singh wrote:
>> The patch defines AMD's Memory Encryption Information CPUID leaf (0x8000_001F).
>> The complete description for this CPUID leaf is available in APM
>> volume 2 [1] Section 15.34 (Secure Encrypted Virtualization).
>>
>> [1] http://support.amd.com/TechDocs/24593.pdf
>>
>> Signed-off-by: Brijesh Singh <brijesh.singh@amd.com<mailto:brijesh.singh@amd.com>>
>> ---
>>  OvmfPkg/Include/Register/AmdSevMap.h |  133
>> ++++++++++++++++++++++++++++++++++
>>  1 file changed, 133 insertions(+)
>>  create mode 100644 OvmfPkg/Include/Register/AmdSevMap.h
>>
>> diff --git a/OvmfPkg/Include/Register/AmdSevMap.h
>> b/OvmfPkg/Include/Register/AmdSevMap.h
>> new file mode 100644
>> index 0000000..de80f39
>> --- /dev/null
>> +++ b/OvmfPkg/Include/Register/AmdSevMap.h
>> @@ -0,0 +1,133 @@
>> +/** @file
>> +
>> +AMD Secure Encrypted Virtualization (SEV) specific CPUID and MSR
>> +definitions
>> +
>> +The complete description for this CPUID leaf is available in APM
>> +volume 2 (Section 15.34) http://support.amd.com/TechDocs/24593.pdf
>> +
>> +Copyright (c) 2017, Advanced Micro Devices. All rights reserved.<BR>
>> +
>> +This program and the accompanying materials are licensed and made
>> +available under the terms and conditions of the BSD License which
>> +accompanies this distribution.  The full text of the license may be
>> +found at http://opensource.org/licenses/bsd-license.php
>> +
>> +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS"
>> +BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
>> +
>> +**/
>> +
>> +#ifndef __AMD_SEV_MAP_H__
>> +#define __AMD_SEV_MAP_H__
>> +
>> +#pragma pack (1)
>> +
>> +#define CPUID_MEMORY_ENCRYPTION_INFO             0x8000001F
>> +
>> +/**
>> +  CPUID Memory Encryption support information EAX for CPUID leaf
>> +  #CPUID_MEMORY_ENCRYPTION_INFO.
>> +**/
>> +typedef union {
>> +  ///
>> +  /// Individual bit fields
>> +  ///
>> +  struct {
>> +    ///
>> +    /// [Bit 0] Secure Memory Encryption (Sme) Support
>> +    ///
>> +    UINT32  SmeBit:1;
>> +
>> +    ///
>> +    /// [Bit 1] Secure Encrypted Virtualization (Sev) Support
>> +    ///
>> +    UINT32  SevBit:1;
>> +
>> +    ///
>> +    /// [Bit 2] Page flush MSR support
>> +    ///
>> +    UINT32  PageFlushMsrBit:1;
>> +
>> +    ///
>> +    /// [Bit 3] Encrypted state support
>> +    ///
>> +    UINT32  SevEsBit:1;
>> +
>> +    ///
>> +    /// [Bit 4:31] Reserved
>> +    ///
>> +    UINT32  ReservedBits:28;
>> +  } Bits;
>> +  ///
>> +  /// All bit fields as a 32-bit value
>> +  ///
>> +  UINT32  Uint32;
>> +} CPUID_MEMORY_ENCRYPTION_INFO_EAX;
>> +
>> +/**
>> +  CPUID Memory Encryption support information EBX for CPUID leaf
>> +  #CPUID_MEMORY_ENCRYPTION_INFO.
>> +**/
>> +typedef union {
>> +  ///
>> +  /// Individual bit fields
>> +  ///
>> +  struct {
>> +    ///
>> +    /// [Bit 0:5] Page table bit number used to enable memory encryption
>> +    ///
>> +    UINT32  PtePosBits:6;
>> +
>> +    ///
>> +    /// [Bit 6:11] Reduction of system physical address space bits when memory encryption is enabled
>> +    ///
>> +    UINT32  ReducedPhysBits:5;
>> +
>> +    ///
>> +    /// [Bit 12:31] Reserved
>> +    ///
>> +    UINT32  ReservedBits:21;
>> +  } Bits;
>> +  ///
>> +  /// All bit fields as a 32-bit value
>> +  ///
>> +  UINT32  Uint32;
>> +} CPUID_MEMORY_ENCRYPTION_INFO_EBX;
>> +
>> +/**
>> +  Secure Encrypted Virtualization (SEV) status register
>> +
>> +**/
>> +#define MSR_SEV_STATUS                     0xc0010131
>> +
>> +/**
>> +  MSR information returned for #MSR_SEV_STATUS **/ typedef union {
>> +  ///
>> +  /// Individual bit fields
>> +  ///
>> +  struct {
>> +    ///
>> +    /// [Bit 0] Secure Encrypted Virtualization (Sev) is enabled
>> +    ///
>> +    UINT32  SevBit:1;
>> +
>> +    ///
>> +    /// [Bit 1] Secure Encrypted Virtualization Encrypted State (SevEs) is enabled
>> +    ///
>> +    UINT32  SevEsBit:1;
>> +
>> +    UINT32  Reserved:30;
>> +  } Bits;
>> +  ///
>> +  /// All bit fields as a 32-bit value
>> +  ///
>> +  UINT32  Uint32;
>> +  ///
>> +  /// All bit fields as a 64-bit value
>> +  ///
>> +  UINT64  Uint64;
>> +} MSR_SEV_STATUS_REGISTER;
>> +
>> +#endif
>>
>> _______________________________________________
>> edk2-devel mailing list
>> edk2-devel@lists.01.org<mailto:edk2-devel@lists.01.org>
>> https://lists.01.org/mailman/listinfo/edk2-devel
>>
>
> I feel that these definitions should be added to "UefiCpuPkg/Include/Register/Cpuid.h", or else to another (new) header file in that directory.
>
> Jeff, what do you think?
>
> Thanks!
> Laszlo
> _______________________________________________
> edk2-devel mailing list
> edk2-devel@lists.01.org<mailto:edk2-devel@lists.01.org>
> https://lists.01.org/mailman/listinfo/edk2-devel
>



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

* Re: [RFC PATCH v2 09/10] OvmfPkg/QemuFwCfgLib: Add Secure Encrypted Virtualization (SEV) support
  2017-03-27 19:24     ` Brijesh Singh
@ 2017-03-28  8:12       ` Laszlo Ersek
  0 siblings, 0 replies; 44+ messages in thread
From: Laszlo Ersek @ 2017-03-28  8:12 UTC (permalink / raw)
  To: Brijesh Singh
  Cc: Kinney, Michael D, Justen, Jordan L, edk2-devel, Gao, Liming,
	Singh, Brijesh, Leo Duran, Tom Lendacky

On 03/27/17 21:24, Brijesh Singh wrote:
> On Mon, Mar 27, 2017 at 5:19 AM, Laszlo Ersek <lersek@redhat.com> wrote:

>> - regarding InternalQemuFwCfgDmaBytes(): would it be possible to hook
>> the SEV-related tricks into the existent function, rather than
>> copy+modify the entire function as InternalQemuFwCfgSevDmaBytes()? It
>> seems to me that a conditional "prologue" and "epilogue" in
>> InternalQemuFwCfgDmaBytes() could do the trick.
>>
>>
> I wanted to reuse the existing function but I was not sure how do you
> wanted me to handle static allocation of "Access" variable inside
> the InternalQemuFwCfgDmaBytes()
> 
>  VOID
>  InternalQemuFwCfgDmaBytes (
>    IN     UINT32   Size,
>    IN OUT VOID     *Buffer OPTIONAL,
>    IN     UINT32   Control
>    )
>  {
>    volatile FW_CFG_DMA_ACCESS Access;
>    UINT32                     AccessHigh, AccessLow;
>    UINT32                     Status;
> 
> 
> The "Access" variable is statically allocated inside this function,

The storage duration of "Access" is not "static", it is "automatic".
(Put more colloquially, it is on the stack, it is not a global variable.)

But, I do understand the point; for the SEV case, you need it to be
dynamically allocated *and* exposed to the hypervisor, with
InternalQemuFwCfgSevDmaAllocateBuffer().

So here's my suggestion: in the following (suggested) list of patches:

- new interfaces in QemuFwCfgLibInternal.h
- implementation of new APIs for SEC instance
- implementation of new APIs for PEI instance
- implementation of new APIs for DXE instance
- call new APIs from common code

the last part should actually be two patches (so not 5 but 6 patches in
total).

First, please modify InternalQemuFwCfgDmaBytes() so that it works
through a pointer, but without other (functionality) changes:

  volatile FW_CFG_DMA_ACCESS LocalAccess;
  volatile FW_CFG_DMA_ACCESS *Access;

  Access = &LocalAccess;

Second, add the SEV-specific prologue / epilogue that initially set the
"Access" pointer differently, and finally free / unmap it.

> in case
> of SEV the Dma "Access" control variable need to be dynamically allocated
> because hypervisor read/writes data into Access->status.
> 
> I could convert Access into FW_CFG_DMA_ACCESS pointer for non SEV case and
> then integerate the SEV specific changes inside the same function.

Yes, that's the idea.

> 
> I was just not sure which approach is prefrered hence decided to create a
> new function for now and at least start the discussion.

Thank you.
Laszlo

> 
> 
> 
> 
>> ... From skimming this patch, I think those are the only
>> functionality-related comments I have at this point, beyond the remarks
>> I made elsewhere in this series (like: line length, DEBUG_* macros, and
>> so on). Please recheck all patches for those comments.
>>
>>
> I will revist all the patches and fix those DEBUG_* macros.
> 
> 
> 
>>>
>>> diff --git a/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgDxe.c
>> b/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgDxe.c
>>> index ac05f4c..be8e945 100644
>>> --- a/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgDxe.c
>>> +++ b/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgDxe.c
>>> @@ -4,6 +4,7 @@
>>>
>>>    Copyright (C) 2013, Red Hat, Inc.
>>>    Copyright (c) 2011 - 2013, Intel Corporation. All rights reserved.<BR>
>>> +  Copyright (c) 2017, Advanced Micro Devices. All rights reserved.<BR>
>>>
>>>    This program and the accompanying materials are licensed and made
>> available
>>>    under the terms and conditions of the BSD License which accompanies
>> this
>>> @@ -14,14 +15,34 @@
>>>    WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
>>>  **/
>>>
>>> +#include "Uefi.h"
>>> +
>>> +#include <Library/BaseLib.h>
>>>  #include <Library/DebugLib.h>
>>>  #include <Library/QemuFwCfgLib.h>
>>> +#include <Library/UefiBootServicesTableLib.h>
>>> +#include <Library/MemEncryptSevLib.h>
>>> +#include <Library/BmDmaLib.h>
>>>
>>>  #include "QemuFwCfgLibInternal.h"
>>>
>>>  STATIC BOOLEAN mQemuFwCfgSupported = FALSE;
>>>  STATIC BOOLEAN mQemuFwCfgDmaSupported;
>>> +STATIC BOOLEAN mQemuFwCfgSevIsEnabled = FALSE;
>>> +
>>> +/**
>>> + Returns a boolean indicating whether the SEV is enabled
>>>
>>> + @retval    TRUE    SEV is enabled
>>> + @retval    FALSE   SEV is not enabled
>>> +**/
>>> +BOOLEAN
>>> +InternalQemuFwCfgSevIsEnabled (
>>> +  VOID
>>> +  )
>>> +{
>>> +  return mQemuFwCfgSevIsEnabled;
>>> +}
>>>
>>>  /**
>>>    Returns a boolean indicating if the firmware configuration interface
>>> @@ -79,6 +100,9 @@ QemuFwCfgInitialize (
>>>      mQemuFwCfgDmaSupported = TRUE;
>>>      DEBUG ((DEBUG_INFO, "QemuFwCfg interface (DMA) is supported.\n"));
>>>    }
>>> +
>>> +  mQemuFwCfgSevIsEnabled = MemEncryptSevIsEnabled ();
>>> +
>>>    return RETURN_SUCCESS;
>>>  }
>>>
>>> @@ -114,3 +138,52 @@ InternalQemuFwCfgDmaIsAvailable (
>>>  {
>>>    return mQemuFwCfgDmaSupported;
>>>  }
>>> +
>>> +/**
>>> + Allocate a bounce buffer for SEV DMA.
>>> +
>>
>> Please document that this function either succeeds or doesn't return.
>>
>>> +  @param[in]     NumPage  Number of pages.
>>> +  @param[out]    Buffer   Allocated DMA Buffer pointer
>>> +
>>> +**/
>>> +VOID
>>> +InternalQemuFwCfgSevDmaAllocateBuffer (
>>> +  IN     UINT32   NumPages,
>>> +  OUT    VOID     **Buffer
>>> +  )
>>> +{
>>> +  EFI_STATUS  Status;
>>> +
>>> +  //
>>> +  // Allocate DMA bounce buffer
>>> +  //
>>> +  Status = BmDmaAllocateBuffer (TRUE, EfiBootServicesData, NumPages,
>> Buffer);
>>> +  if (EFI_ERROR(Status)) {
>>> +    DEBUG ((EFI_D_ERROR, "SEV: Failed to allocate bounce buffer %d
>> pages\n", NumPages));
>>> +    ASSERT_EFI_ERROR (Status);
>>> +    CpuDeadLoop ();
>>> +  }
>>> +
>>> +  DEBUG ((EFI_D_VERBOSE, "QemuFwCfgSevDma allocate buffer 0x%Lx Pages
>> %d\n", (UINTN)Buffer, NumPages));
>>> +}
>>> +
>>> +/**
>>> + Free the DMA buffer allocated using InternalQemuFwCfgSevDmaAllocat
>> eBuffer
>>> +
>>> +  @param[in]     NumPage  Number of pages.
>>> +  @param[in]     Buffer   DMA Buffer pointer
>>> +
>>> +**/
>>> +VOID
>>> +InternalQemuFwCfgSevDmaFreeBuffer (
>>> +  IN     VOID     *Buffer,
>>> +  IN     UINT32   NumPages
>>> +  )
>>> +{
>>> +  //
>>> +  // Free the bounce buffer
>>> +  //
>>> +  DEBUG ((EFI_D_VERBOSE, "QemuFwCfgSevDma free buffer 0x%Lx Pages
>> %d\n", (UINTN)Buffer, NumPages));
>>> +  BmDmaFreeBuffer (Buffer, NumPages);
>>> +}
>>> +
>>> diff --git a/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgDxeLib.inf
>> b/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgDxeLib.inf
>>> index 346bb88..536887f 100644
>>> --- a/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgDxeLib.inf
>>> +++ b/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgDxeLib.inf
>>> @@ -47,4 +47,6 @@
>>>    DebugLib
>>>    IoLib
>>>    MemoryAllocationLib
>>> +  MemEncryptSevLib
>>> +  BmDmaLib
>>>
>>> diff --git a/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgLib.c
>> b/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgLib.c
>>> index 1bf725d..d2560a3 100644
>>> --- a/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgLib.c
>>> +++ b/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgLib.c
>>> @@ -47,6 +47,111 @@ QemuFwCfgSelectItem (
>>>
>>>
>>>  /**
>>> +  Transfer an array of bytes, or skip a number of bytes, using the SEV
>> DMA bounce
>>> +  interface. The function is same as InternalQemuFwCfgDmaBytes with
>> excpetion that
>>> +  it uses bounce buffer
>>> +
>>> +  @param[in]     Size     Size in bytes to transfer or skip.
>>> +
>>> +  @param[in,out] HostBuffer Buffer to read data into or write data
>> from. Ignored,
>>> +                            and may be NULL, if Size is zero, or
>> Control is
>>> +                            FW_CFG_DMA_CTL_SKIP.
>>> +
>>> +  @param[in]     Control  One of the following:
>>> +                          FW_CFG_DMA_CTL_WRITE - write to fw_cfg from
>> Buffer.
>>> +                          FW_CFG_DMA_CTL_READ  - read from fw_cfg into
>> Buffer.
>>> +                          FW_CFG_DMA_CTL_SKIP  - skip bytes in fw_cfg.
>>> +**/
>>> +VOID
>>> +InternalQemuFwCfgSevDmaBytes (
>>> +  IN     UINT32   Size,
>>> +  IN OUT VOID     *HostBuffer OPTIONAL,
>>> +  IN     UINT32   Control
>>> +  )
>>> +{
>>> +  volatile FW_CFG_DMA_ACCESS *Access;
>>> +  UINT32                     AccessHigh, AccessLow;
>>> +  UINT32                     Status;
>>> +  UINT32                     NumPages;
>>> +  VOID                       *DmaBuffer, *Buffer;
>>> +
>>> +  //
>>> +  // Calculate number of pages we need to allocate for this operation
>>> +  //
>>> +  if (Control == FW_CFG_DMA_CTL_SKIP) {
>>> +    //
>>> +    // Control data does not need the actual buffer
>>> +    //
>>> +    NumPages = EFI_SIZE_TO_PAGES (sizeof (*Access));
>>> +  } else {
>>> +    NumPages = EFI_SIZE_TO_PAGES (sizeof (*Access) + Size);
>>> +  }
>>> +
>>> +  //
>>> +  // Allocate DMA bounce buffer
>>> +  //
>>> +  InternalQemuFwCfgSevDmaAllocateBuffer (NumPages, &DmaBuffer);
>>> +
>>> +  Access = (FW_CFG_DMA_ACCESS *)DmaBuffer;
>>> +  Buffer = DmaBuffer + sizeof(*Access);
>>> +
>>> +  Access->Control = SwapBytes32 (Control);
>>> +  Access->Length  = SwapBytes32 (Size);
>>> +  Access->Address = SwapBytes64 ((UINTN)Buffer);
>>> +
>>> +  //
>>> +  // Copy data from Host buffer into DMA buffer
>>> +  //
>>> +  if (HostBuffer && (Control == FW_CFG_DMA_CTL_WRITE)) {
>>> +    CopyMem (Buffer, HostBuffer, Size);
>>> +  }
>>> +
>>> +  //
>>> +  // Delimit the transfer from (a) modifications to Access, (b) in case
>> of a
>>> +  // write, from writes to Buffer by the caller.
>>> +  //
>>> +  MemoryFence ();
>>> +
>>> +  //
>>> +  // Start the transfer.
>>> +  //
>>> +  AccessHigh = (UINT32)RShiftU64 ((UINTN)Access, 32);
>>> +  AccessLow  = (UINT32)(UINTN)Access;
>>> +  IoWrite32 (FW_CFG_IO_DMA_ADDRESS,     SwapBytes32 (AccessHigh));
>>> +  IoWrite32 (FW_CFG_IO_DMA_ADDRESS + 4, SwapBytes32 (AccessLow));
>>> +
>>> +  //
>>> +  // Don't look at Access->Control before starting the transfer.
>>> +  //
>>> +  MemoryFence ();
>>> +
>>> +  //
>>> +  // Wait for the transfer to complete.
>>> +  //
>>> +  do {
>>> +    Status = SwapBytes32 (Access->Control);
>>> +    ASSERT ((Status & FW_CFG_DMA_CTL_ERROR) == 0);
>>> +  } while (Status != 0);
>>> +
>>> +  //
>>> +  // After a read, the caller will want to use Buffer.
>>> +  //
>>> +  MemoryFence ();
>>> +
>>> +  //
>>> +  // Copy data from DMA buffer into Host Buffer
>>> +  //
>>> +  if (HostBuffer && (Control == FW_CFG_DMA_CTL_READ)) {
>>> +    CopyMem (HostBuffer, Buffer, Size);
>>> +  }
>>> +
>>> +  //
>>> +  // Free the DMA bounce buffer
>>> +  //
>>> +  InternalQemuFwCfgSevDmaFreeBuffer (DmaBuffer, NumPages);
>>> +}
>>> +
>>> +/**
>>>    Transfer an array of bytes, or skip a number of bytes, using the DMA
>>>    interface.
>>>
>>> @@ -79,6 +184,13 @@ InternalQemuFwCfgDmaBytes (
>>>      return;
>>>    }
>>>
>>> +  //
>>> +  // When SEV is enabled then use SEV version of DmaReadWrite
>>> +  //
>>> +  if (InternalQemuFwCfgSevIsEnabled ()) {
>>> +    return InternalQemuFwCfgSevDmaBytes (Size, Buffer, Control);
>>> +  }
>>> +
>>>    Access.Control = SwapBytes32 (Control);
>>>    Access.Length  = SwapBytes32 (Size);
>>>    Access.Address = SwapBytes64 ((UINTN)Buffer);
>>> diff --git a/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgLibInternal.h
>> b/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgLibInternal.h
>>> index 6e87c62..8e2ff45 100644
>>> --- a/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgLibInternal.h
>>> +++ b/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgLibInternal.h
>>> @@ -2,6 +2,7 @@
>>>    Internal interfaces specific to the QemuFwCfgLib instances in OvmfPkg.
>>>
>>>    Copyright (C) 2016, Red Hat, Inc.
>>> +  Copyright (C) 2017, Advanced Micro Devices.
>>>
>>>    This program and the accompanying materials are licensed and made
>> available
>>>    under the terms and conditions of the BSD License which accompanies
>> this
>>> @@ -43,4 +44,41 @@ InternalQemuFwCfgDmaIsAvailable (
>>>    VOID
>>>    );
>>>
>>> +/**
>>> + Returns a boolean indicating whether the SEV is enabled
>>> +
>>> + @retval    TRUE    SEV is enabled
>>> + @retval    FALSE   SEV is not enabled
>>> +**/
>>> +BOOLEAN
>>> +InternalQemuFwCfgSevIsEnabled (
>>> +  VOID
>>> +  );
>>> +
>>> +/**
>>> + Allocate a bounce buffer for SEV DMA.
>>> +
>>> +  @param[in]     NumPage  Number of pages.
>>> +  @param[out]    Buffer   Allocated DMA Buffer pointer
>>> +
>>> +**/
>>> +VOID
>>> +InternalQemuFwCfgSevDmaAllocateBuffer (
>>> +  IN     UINT32   NumPages,
>>> +  OUT    VOID     **Buffer
>>> +  );
>>> +
>>> +/**
>>> + Free the DMA buffer allocated using InternalQemuFwCfgSevDmaAllocat
>> eBuffer
>>> +
>>> +  @param[in]     NumPage  Number of pages.
>>> +  @param[in]     Buffer   DMA Buffer pointer
>>> +
>>> +**/
>>> +VOID
>>> +InternalQemuFwCfgSevDmaFreeBuffer (
>>> +  IN     VOID     *Buffer,
>>> +  IN     UINT32   NumPages
>>> +  );
>>> +
>>>  #endif
>>> diff --git a/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgPei.c
>> b/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgPei.c
>>> index ac05f4c..3dc9270 100644
>>> --- a/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgPei.c
>>> +++ b/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgPei.c
>>> @@ -4,6 +4,7 @@
>>>
>>>    Copyright (C) 2013, Red Hat, Inc.
>>>    Copyright (c) 2011 - 2013, Intel Corporation. All rights reserved.<BR>
>>> +  Copyright (c) 2017, Advanced Micro Devices. All rights reserved.<BR>
>>>
>>>    This program and the accompanying materials are licensed and made
>> available
>>>    under the terms and conditions of the BSD License which accompanies
>> this
>>> @@ -14,14 +15,55 @@
>>>    WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
>>>  **/
>>>
>>> +#include <Library/BaseLib.h>
>>>  #include <Library/DebugLib.h>
>>>  #include <Library/QemuFwCfgLib.h>
>>> +#include <Register/Cpuid.h>
>>> +#include <Register/AmdSevMap.h>
>>>
>>>  #include "QemuFwCfgLibInternal.h"
>>>
>>>  STATIC BOOLEAN mQemuFwCfgSupported = FALSE;
>>>  STATIC BOOLEAN mQemuFwCfgDmaSupported;
>>>
>>> +/**
>>> + Returns a boolean indicating whether the SEV is enabled
>>> +
>>> + @retval    TRUE    SEV is enabled
>>> + @retval    FALSE   SEV is not enabled
>>> +**/
>>> +BOOLEAN
>>> +InternalQemuFwCfgSevIsEnabled (
>>> +  VOID
>>> +  )
>>> +{
>>> +  UINT32 RegEax;
>>> +  MSR_SEV_STATUS_REGISTER Msr;
>>> +  CPUID_MEMORY_ENCRYPTION_INFO_EAX  Eax;
>>> +
>>> +  //
>>> +  // Check if memory encryption leaf exist
>>> +  //
>>> +  AsmCpuid (CPUID_EXTENDED_FUNCTION, &RegEax, NULL, NULL, NULL);
>>> +  if (RegEax >= CPUID_MEMORY_ENCRYPTION_INFO) {
>>> +    //
>>> +    // CPUID Fn8000_001F[EAX] Bit 1 (Sev supported)
>>> +    //
>>> +    AsmCpuid (CPUID_MEMORY_ENCRYPTION_INFO, &Eax.Uint32, NULL, NULL,
>> NULL);
>>> +
>>> +    if (Eax.Bits.SevBit) {
>>> +      //
>>> +      // Check MSR_0xC0010131 Bit 0 (Sev Enabled)
>>> +      //
>>> +      Msr.Uint32 = AsmReadMsr32 (MSR_SEV_STATUS);
>>> +      if (Msr.Bits.SevBit) {
>>> +        return TRUE;
>>> +      }
>>> +    }
>>> +  }
>>> +
>>> +  return FALSE;
>>> +}
>>>
>>>  /**
>>>    Returns a boolean indicating if the firmware configuration interface
>>> @@ -79,6 +121,17 @@ QemuFwCfgInitialize (
>>>      mQemuFwCfgDmaSupported = TRUE;
>>>      DEBUG ((DEBUG_INFO, "QemuFwCfg interface (DMA) is supported.\n"));
>>>    }
>>> +
>>> +  //
>>> +  // When SEV is enabled then we do not support DMA interface.
>>> +  // This is because we need to use bounce buffer to support DMA
>> operation in SEV guest.
>>> +  // Allocating memory for bounce buffer can get painful in Pei phase
>>> +  //
>>> +  if (mQemuFwCfgDmaSupported && InternalQemuFwCfgSevIsEnabled ()) {
>>> +    mQemuFwCfgDmaSupported = FALSE;
>>> +    DEBUG ((DEBUG_INFO, "QemuFwCfg disabling DMA interface and
>> defaulting to IO Port.\n"));
>>> +  }
>>> +
>>>    return RETURN_SUCCESS;
>>>  }
>>>
>>> @@ -114,3 +167,43 @@ InternalQemuFwCfgDmaIsAvailable (
>>>  {
>>>    return mQemuFwCfgDmaSupported;
>>>  }
>>> +
>>> +/**
>>> + Allocate a bounce buffer for SEV DMA.
>>> +
>>> +  @param[in]     NumPage  Number of pages.
>>> +  @param[out]    Buffer   Allocated DMA Buffer pointer
>>> +
>>> +**/
>>> +VOID
>>> +InternalQemuFwCfgSevDmaAllocateBuffer (
>>> +  IN     UINT32   NumPages,
>>> +  OUT    VOID     **Buffer
>>> +  )
>>> +{
>>> +  //
>>> +  // We should never reach here
>>> +  //
>>> +  ASSERT (FALSE);
>>> +  CpuDeadLoop ();
>>> +}
>>> +
>>> +/**
>>> + Free the DMA buffer allocated using InternalQemuFwCfgSevDmaAllocat
>> eBuffer
>>> +
>>> +  @param[in]     NumPage  Number of pages.
>>> +  @param[in]     Buffer   DMA Buffer pointer
>>> +
>>> +**/
>>> +VOID
>>> +InternalQemuFwCfgSevDmaFreeBuffer (
>>> +  IN     VOID     *Buffer,
>>> +  IN     UINT32   NumPages
>>> +  )
>>> +{
>>> +  //
>>> +  // We should never reach here
>>> +  //
>>> +  ASSERT (FALSE);
>>> +  CpuDeadLoop ();
>>> +}
>>> diff --git a/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgPeiLib.inf
>> b/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgPeiLib.inf
>>> index 4f966a8..83cc0de 100644
>>> --- a/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgPeiLib.inf
>>> +++ b/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgPeiLib.inf
>>> @@ -39,7 +39,9 @@
>>>
>>>  [Packages]
>>>    MdePkg/MdePkg.dec
>>> +  MdeModulePkg/MdeModulePkg.dec
>>>    OvmfPkg/OvmfPkg.dec
>>> +  UefiCpuPkg/UefiCpuPkg.dec
>>>
>>>  [LibraryClasses]
>>>    BaseLib
>>> diff --git a/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgSec.c
>> b/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgSec.c
>>> index 465ccbe..70b0a47 100644
>>> --- a/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgSec.c
>>> +++ b/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgSec.c
>>> @@ -16,8 +16,11 @@
>>>    WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
>>>  **/
>>>
>>> +#include <Library/BaseLib.h>
>>>  #include <Library/DebugLib.h>
>>>  #include <Library/QemuFwCfgLib.h>
>>> +#include <Register/Cpuid.h>
>>> +#include <Register/AmdSevMap.h>
>>>
>>>  #include "QemuFwCfgLibInternal.h"
>>>
>>> @@ -94,3 +97,82 @@ InternalQemuFwCfgDmaIsAvailable (
>>>  {
>>>    return FALSE;
>>>  }
>>> +
>>> +/**
>>> + Returns a boolean indicating whether the SEV is enabled
>>> +
>>> + @retval    TRUE    SEV is enabled
>>> + @retval    FALSE   SEV is not enabled
>>> +**/
>>> +BOOLEAN
>>> +InternalQemuFwCfgSevIsEnabled (
>>> +  VOID
>>> +  )
>>> +{
>>> +  UINT32 RegEax;
>>> +  MSR_SEV_STATUS_REGISTER Msr;
>>> +  CPUID_MEMORY_ENCRYPTION_INFO_EAX  Eax;
>>> +
>>> +  //
>>> +  // Check if memory encryption leaf exist
>>> +  //
>>> +  AsmCpuid (CPUID_EXTENDED_FUNCTION, &RegEax, NULL, NULL, NULL);
>>> +  if (RegEax >= CPUID_MEMORY_ENCRYPTION_INFO) {
>>> +    //
>>> +    // CPUID Fn8000_001F[EAX] Bit 1 (Sev supported)
>>> +    //
>>> +    AsmCpuid (CPUID_MEMORY_ENCRYPTION_INFO, &Eax.Uint32, NULL, NULL,
>> NULL);
>>> +
>>> +    if (Eax.Bits.SevBit) {
>>> +      //
>>> +      // Check MSR_0xC0010131 Bit 0 (Sev Enabled)
>>> +      //
>>> +      Msr.Uint32 = AsmReadMsr32 (MSR_SEV_STATUS);
>>> +      if (Msr.Bits.SevBit) {
>>> +        return TRUE;
>>> +      }
>>> +    }
>>> +  }
>>> +
>>> +  return FALSE;
>>> +}
>>> +
>>> +/**
>>> + Allocate a bounce buffer for SEV DMA.
>>> +
>>> +  @param[in]     NumPage  Number of pages.
>>> +  @param[out]    Buffer   Allocated DMA Buffer pointer
>>> +
>>> +**/
>>> +VOID
>>> +InternalQemuFwCfgSevDmaAllocateBuffer (
>>> +  IN     UINT32   NumPages,
>>> +  OUT    VOID     **Buffer
>>> +  )
>>> +{
>>> +  //
>>> +  // We should never reach here
>>> +  //
>>> +  ASSERT (FALSE);
>>> +  CpuDeadLoop ();
>>> +}
>>> +
>>> +/**
>>> + Free the DMA buffer allocated using InternalQemuFwCfgSevDmaAllocat
>> eBuffer
>>> +
>>> +  @param[in]     NumPage  Number of pages.
>>> +  @param[in]     Buffer   DMA Buffer pointer
>>> +
>>> +**/
>>> +VOID
>>> +InternalQemuFwCfgSevDmaFreeBuffer (
>>> +  IN     VOID     *Buffer,
>>> +  IN     UINT32   NumPages
>>> +  )
>>> +{
>>> +  //
>>> +  // We should never reach here
>>> +  //
>>> +  ASSERT (FALSE);
>>> +  CpuDeadLoop ();
>>> +}
>>>
>>> _______________________________________________
>>> edk2-devel mailing list
>>> edk2-devel@lists.01.org
>>> https://lists.01.org/mailman/listinfo/edk2-devel
>>>
>>
>>
> 
> 



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

* Re: [RFC PATCH v2 04/10] OvmfPkg/BaseMemcryptSevLib: Add SEV helper library
  2017-03-27 18:44       ` Brijesh Singh
@ 2017-03-28  8:14         ` Laszlo Ersek
  0 siblings, 0 replies; 44+ messages in thread
From: Laszlo Ersek @ 2017-03-28  8:14 UTC (permalink / raw)
  To: Brijesh Singh
  Cc: Kinney, Michael D, Justen, Jordan L, edk2-devel, Gao, Liming,
	Singh, Brijesh, Leo Duran, Tom Lendacky

On 03/27/17 20:44, Brijesh Singh wrote:
> On Mon, Mar 27, 2017 at 5:07 AM, Laszlo Ersek <lersek@redhat.com> wrote:
> 
>> On 03/27/17 11:19, Laszlo Ersek wrote:
>>> On 03/21/17 22:13, Brijesh Singh wrote:
>>
>>>> +  Returns a boolean to indicate whether SEV is enabled
>>>> +
>>>> +  @retval TRUE           When SEV is active
>>>> +  @retval FALSE          When SEV is not enabled
>>>> +  **/
>>>> +BOOLEAN
>>>> +EFIAPI
>>>> +MemEncryptSevIsEnabled (
>>>> +  VOID
>>>> +  );
>>>
>>> Would it make sense to call this library function in PlatformPei, rather
>>> than add a separate SevIsEnabled() function to it (in patch #3)? The
>>> implementations look nearly identical.
>>
>> I realize that earlier I seemingly suggested the opposite:
>>
>> http://mid.mail-archive.com/dd9436dc-415c-9fab-081c-
>> 39dd2cd71fd5@redhat.com
>>
>> http://mid.mail-archive.com/9193d837-6a78-b1c4-42c0-
>> 427fbc1f2364@redhat.com
>>
>> However, at that time, my understanding was that this library would only
>> be used in PlatformPei (hence the single user wouldn't justify the new
>> library instance). Now it seems that there are going to be several
>> client modules that check on SEV enablement. Is that right?
>>
>>
> 
> Yes, I do expect several client module link against this library to check
> whether the SEV is enabled.
> Are you okay if we link MemEncryptSevLib in PlatformPei and make use of
> MemEncryptSevIsEnabled()
> routine instead of having a local copy ? I was not sure which way to go
> hence I still have PlatformPei
> and QemuFwCfgPei using the local implementation of the same functions. My
> personal perference would
> be to link with MemEncryptSevLib instead of having local function. But as
> always I am open to suggestions.

I think the library function should be used (caching the CPUID detection
results) whenever we have writeable memory (PEI and onwards).

Thanks
Laszlo



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

end of thread, other threads:[~2017-03-28  8:14 UTC | newest]

Thread overview: 44+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2017-03-21 21:12 [RESEND] [RFC PATCH v2 00/10] x86: Secure Encrypted Virtualization (AMD) Brijesh Singh
2017-03-21 21:12 ` [RFC PATCH v2 01/10] OvmfPkg/Include: Define SEV specific CPUID and MSR Brijesh Singh
2017-03-22 16:03   ` Laszlo Ersek
2017-03-23  7:42     ` Fan, Jeff
2017-03-23  9:19       ` Laszlo Ersek
2017-03-27  7:57         ` Fan, Jeff
2017-03-27 11:58           ` Brijesh Singh
2017-03-27 17:33             ` Laszlo Ersek
2017-03-28  0:45             ` Fan, Jeff
2017-03-28  2:19               ` Duran, Leo
2017-03-28  2:25                 ` Fan, Jeff
2017-03-27 15:59           ` Duran, Leo
2017-03-27 16:07             ` Brijesh Singh
2017-03-21 21:12 ` [RFC PATCH v2 02/10] OvmfPkg/ResetVector: add memory encryption mask when SEV is enabled Brijesh Singh
2017-03-22 20:20   ` Laszlo Ersek
2017-03-23 15:05     ` Brijesh Singh
2017-03-23 16:16       ` Laszlo Ersek
2017-03-23 16:48         ` Brijesh Singh
2017-03-23 16:54           ` Laszlo Ersek
2017-03-23 17:44             ` Brijesh Singh
2017-03-21 21:13 ` [RFC PATCH v2 03/10] OvmfPkg/PlatformPei: Add Secure Encrypted Virutualization (SEV) support Brijesh Singh
2017-03-27  8:23   ` Laszlo Ersek
2017-03-27 12:22     ` Brijesh Singh
2017-03-21 21:13 ` [RFC PATCH v2 04/10] OvmfPkg/BaseMemcryptSevLib: Add SEV helper library Brijesh Singh
2017-03-27  9:19   ` Laszlo Ersek
2017-03-27 10:07     ` Laszlo Ersek
2017-03-27 18:44       ` Brijesh Singh
2017-03-28  8:14         ` Laszlo Ersek
2017-03-21 21:13 ` [RFC PATCH v2 05/10] OvmfPkg/DxeBmDmaLib: Import DxeBmDmaLib package Brijesh Singh
2017-03-27  9:22   ` Laszlo Ersek
2017-03-21 21:13 ` [RFC PATCH v2 06/10] OvmfPkg/DxeBmDmaLib: Fix AllocateBounceBuffer parameter Brijesh Singh
2017-03-27  9:21   ` Laszlo Ersek
2017-03-27 18:40     ` Brijesh Singh
2017-03-21 21:13 ` [RFC PATCH v2 07/10] OvmfPkg/BmDmaLib: Add SEV support Brijesh Singh
2017-03-27  9:28   ` Laszlo Ersek
2017-03-21 21:13 ` [RFC PATCH v2 08/10] OvmfPkg/QemuFwCfgLib: Provide Pei and Dxe specific library support Brijesh Singh
2017-03-27  9:41   ` Laszlo Ersek
2017-03-21 21:13 ` [RFC PATCH v2 09/10] OvmfPkg/QemuFwCfgLib: Add Secure Encrypted Virtualization (SEV) support Brijesh Singh
2017-03-27 10:19   ` Laszlo Ersek
2017-03-27 19:24     ` Brijesh Singh
2017-03-28  8:12       ` Laszlo Ersek
2017-03-21 21:13 ` [RFC PATCH v2 10/10] OvmfPkg/QemuVideoDxe: Clear the C-bit from framebuffer region when SEV is enabled Brijesh Singh
2017-03-27 10:29   ` Laszlo Ersek
  -- strict thread matches above, loose matches on Subject: below --
2017-03-21 20:59 [RFC PATCH v2 00/10] x86: Secure Encrypted Virtualization (AMD) Brijesh Singh
2017-03-21 20:59 ` [RFC PATCH v2 06/10] OvmfPkg/DxeBmDmaLib: Fix AllocateBounceBuffer parameter Brijesh Singh

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