Re: [edk2-devel] [RFC PATCH v2 06/44] OvmfPkg: Create a GHCB page for use during Sec phase

2019-09-25 Thread Lendacky, Thomas
On 9/25/19 3:09 AM, Laszlo Ersek wrote:
> On 09/19/19 21:52, Lendacky, Thomas wrote:
>> From: Tom Lendacky 
>>
>> BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=2198
>>
>> A GHCB page is needed during the Sec phase, so this new page must be
>> created.  Since the GHCB must be marked as an un-encrypted, or shared,
>> page, an additional pagetable page is required to break down the 2MB
>> region where the GHCB page lives into 4K pagetable entries.
>>
>> Create a new entry in the OVMF memory layout for the new page table
>> page and for the SEC GHCB page. After breaking down the 2MB page, update
>> the GHCB page table entry to remove the encryption mask.
>>
>> Cc: Jordan Justen 
>> Cc: Laszlo Ersek 
>> Cc: Ard Biesheuvel 
>> Signed-off-by: Tom Lendacky 
>> ---
>>  OvmfPkg/OvmfPkg.dec   | 10 +++
>>  OvmfPkg/OvmfPkgX64.fdf|  6 ++
>>  OvmfPkg/ResetVector/ResetVector.inf   |  4 ++
>>  OvmfPkg/ResetVector/Ia32/PageTables64.asm | 79 +++
>>  OvmfPkg/ResetVector/ResetVector.nasmb | 12 
>>  5 files changed, 111 insertions(+)
>>
>> diff --git a/OvmfPkg/OvmfPkg.dec b/OvmfPkg/OvmfPkg.dec
>> index 9640360f6245..b9287a023c94 100644
>> --- a/OvmfPkg/OvmfPkg.dec
>> +++ b/OvmfPkg/OvmfPkg.dec
>> @@ -218,6 +218,16 @@ [PcdsFixedAtBuild]
>>#  The value should be a multiple of 4KB.
>>gUefiOvmfPkgTokenSpaceGuid.PcdHighPmmMemorySize|0x40|UINT32|0x31
>>  
>> +  ## Specify the extra page table needed to mark the GHCB as unencrypted.
>> +  #  The value should be a multiple of 4KB for each.
>> +  gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecGhcbPageTableBase|0x0|UINT32|0x32
>> +  gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecGhcbPageTableSize|0x0|UINT32|0x33
>> +
>> +  ## Specify the GHCB base address and size.
>> +  #  The value should be a multiple of 4KB for each.
>> +  gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecGhcbBase|0x0|UINT32|0x34
>> +  gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecGhcbSize|0x0|UINT32|0x35
>> +
>>  [PcdsDynamic, PcdsDynamicEx]
>>gUefiOvmfPkgTokenSpaceGuid.PcdEmuVariableEvent|0|UINT64|2
>>gUefiOvmfPkgTokenSpaceGuid.PcdOvmfFlashVariablesEnable|FALSE|BOOLEAN|0x10
>> diff --git a/OvmfPkg/OvmfPkgX64.fdf b/OvmfPkg/OvmfPkgX64.fdf
>> index 74407072563b..a567131a0591 100644
>> --- a/OvmfPkg/OvmfPkgX64.fdf
>> +++ b/OvmfPkg/OvmfPkgX64.fdf
>> @@ -76,6 +76,12 @@ [FD.MEMFD]
>>  0x007000|0x001000
>>  
>> gEfiMdePkgTokenSpaceGuid.PcdGuidedExtractHandlerTableAddress|gUefiOvmfPkgTokenSpaceGuid.PcdGuidedExtractHandlerTableSize
>>  
>> +0x008000|0x001000
>> +gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecGhcbPageTableBase|gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecGhcbPageTableSize
>> +
>> +0x009000|0x001000
>> +gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecGhcbBase|gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecGhcbSize
>> +
>>  0x01|0x01
>>  
>> gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecPeiTempRamBase|gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecPeiTempRamSize
>>  
>> diff --git a/OvmfPkg/ResetVector/ResetVector.inf 
>> b/OvmfPkg/ResetVector/ResetVector.inf
>> index 960b47cd0797..80c971354176 100644
>> --- a/OvmfPkg/ResetVector/ResetVector.inf
>> +++ b/OvmfPkg/ResetVector/ResetVector.inf
>> @@ -37,3 +37,7 @@ [Pcd]
>>gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecPageTablesSize
>>gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecPeiTempRamBase
>>gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecPeiTempRamSize
>> +  gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecGhcbPageTableBase
>> +  gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecGhcbPageTableSize
>> +  gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecGhcbBase
>> +  gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecGhcbSize
>> diff --git a/OvmfPkg/ResetVector/Ia32/PageTables64.asm 
>> b/OvmfPkg/ResetVector/Ia32/PageTables64.asm
>> index 40f7814c1134..7e346661f2c8 100644
>> --- a/OvmfPkg/ResetVector/Ia32/PageTables64.asm
>> +++ b/OvmfPkg/ResetVector/Ia32/PageTables64.asm
>> @@ -21,6 +21,11 @@ BITS32
>>  %define PAGE_2M_MBO0x080
>>  %define PAGE_2M_PAT  0x01000
>>  
>> +%define PAGE_4K_PDE_ATTR (PAGE_ACCESSED + \
>> +  PAGE_DIRTY + \
>> +  PAGE_READ_WRITE + \
>> +  PAGE_PRESENT)
>> +
>>  %define PAGE_2M_PDE_ATTR (PAGE_2M_MBO + \
>>PAGE_ACCESSED + \
>>PAGE_DIRTY + \
>> @@ -95,6 +100,37 @@ SevExit:
>>  
>>  OneTimeCallRet CheckSevFeature
>>  
>> +; Check if Secure Encrypted Virtualization - Encrypted State (SEV-ES) 
>> feature
>> +; is enabled.
>> +;
>> +; Modified:  EAX, EBX, ECX, EDX
> 
> (1) I think we should remove EDX from this list. It is restored at the
> end of the routine. And, in pageTableEntries4kLoop, we rely on EDX
> containing the encryption mask.

Yup, I'll remove that one.

> 
>> +;
>> +; If SEV-ES is enabled then EAX will be non-zero.
>> +; If SEV-ES is disabled then EAX will be zero.
>> +;
>> +CheckSevEsFeature:
>> +xor   eax, eax
>> +
>> +; SEV-ES can't be enabled if SEV isn't, so first check the encryption
>> +; mask.
>> +test  

Re: [edk2-devel] [RFC PATCH v2 06/44] OvmfPkg: Create a GHCB page for use during Sec phase

2019-09-25 Thread Laszlo Ersek
On 09/19/19 21:52, Lendacky, Thomas wrote:
> From: Tom Lendacky 
> 
> BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=2198
> 
> A GHCB page is needed during the Sec phase, so this new page must be
> created.  Since the GHCB must be marked as an un-encrypted, or shared,
> page, an additional pagetable page is required to break down the 2MB
> region where the GHCB page lives into 4K pagetable entries.
> 
> Create a new entry in the OVMF memory layout for the new page table
> page and for the SEC GHCB page. After breaking down the 2MB page, update
> the GHCB page table entry to remove the encryption mask.
> 
> Cc: Jordan Justen 
> Cc: Laszlo Ersek 
> Cc: Ard Biesheuvel 
> Signed-off-by: Tom Lendacky 
> ---
>  OvmfPkg/OvmfPkg.dec   | 10 +++
>  OvmfPkg/OvmfPkgX64.fdf|  6 ++
>  OvmfPkg/ResetVector/ResetVector.inf   |  4 ++
>  OvmfPkg/ResetVector/Ia32/PageTables64.asm | 79 +++
>  OvmfPkg/ResetVector/ResetVector.nasmb | 12 
>  5 files changed, 111 insertions(+)
> 
> diff --git a/OvmfPkg/OvmfPkg.dec b/OvmfPkg/OvmfPkg.dec
> index 9640360f6245..b9287a023c94 100644
> --- a/OvmfPkg/OvmfPkg.dec
> +++ b/OvmfPkg/OvmfPkg.dec
> @@ -218,6 +218,16 @@ [PcdsFixedAtBuild]
>#  The value should be a multiple of 4KB.
>gUefiOvmfPkgTokenSpaceGuid.PcdHighPmmMemorySize|0x40|UINT32|0x31
>  
> +  ## Specify the extra page table needed to mark the GHCB as unencrypted.
> +  #  The value should be a multiple of 4KB for each.
> +  gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecGhcbPageTableBase|0x0|UINT32|0x32
> +  gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecGhcbPageTableSize|0x0|UINT32|0x33
> +
> +  ## Specify the GHCB base address and size.
> +  #  The value should be a multiple of 4KB for each.
> +  gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecGhcbBase|0x0|UINT32|0x34
> +  gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecGhcbSize|0x0|UINT32|0x35
> +
>  [PcdsDynamic, PcdsDynamicEx]
>gUefiOvmfPkgTokenSpaceGuid.PcdEmuVariableEvent|0|UINT64|2
>gUefiOvmfPkgTokenSpaceGuid.PcdOvmfFlashVariablesEnable|FALSE|BOOLEAN|0x10
> diff --git a/OvmfPkg/OvmfPkgX64.fdf b/OvmfPkg/OvmfPkgX64.fdf
> index 74407072563b..a567131a0591 100644
> --- a/OvmfPkg/OvmfPkgX64.fdf
> +++ b/OvmfPkg/OvmfPkgX64.fdf
> @@ -76,6 +76,12 @@ [FD.MEMFD]
>  0x007000|0x001000
>  
> gEfiMdePkgTokenSpaceGuid.PcdGuidedExtractHandlerTableAddress|gUefiOvmfPkgTokenSpaceGuid.PcdGuidedExtractHandlerTableSize
>  
> +0x008000|0x001000
> +gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecGhcbPageTableBase|gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecGhcbPageTableSize
> +
> +0x009000|0x001000
> +gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecGhcbBase|gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecGhcbSize
> +
>  0x01|0x01
>  
> gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecPeiTempRamBase|gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecPeiTempRamSize
>  
> diff --git a/OvmfPkg/ResetVector/ResetVector.inf 
> b/OvmfPkg/ResetVector/ResetVector.inf
> index 960b47cd0797..80c971354176 100644
> --- a/OvmfPkg/ResetVector/ResetVector.inf
> +++ b/OvmfPkg/ResetVector/ResetVector.inf
> @@ -37,3 +37,7 @@ [Pcd]
>gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecPageTablesSize
>gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecPeiTempRamBase
>gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecPeiTempRamSize
> +  gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecGhcbPageTableBase
> +  gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecGhcbPageTableSize
> +  gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecGhcbBase
> +  gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecGhcbSize
> diff --git a/OvmfPkg/ResetVector/Ia32/PageTables64.asm 
> b/OvmfPkg/ResetVector/Ia32/PageTables64.asm
> index 40f7814c1134..7e346661f2c8 100644
> --- a/OvmfPkg/ResetVector/Ia32/PageTables64.asm
> +++ b/OvmfPkg/ResetVector/Ia32/PageTables64.asm
> @@ -21,6 +21,11 @@ BITS32
>  %define PAGE_2M_MBO0x080
>  %define PAGE_2M_PAT  0x01000
>  
> +%define PAGE_4K_PDE_ATTR (PAGE_ACCESSED + \
> +  PAGE_DIRTY + \
> +  PAGE_READ_WRITE + \
> +  PAGE_PRESENT)
> +
>  %define PAGE_2M_PDE_ATTR (PAGE_2M_MBO + \
>PAGE_ACCESSED + \
>PAGE_DIRTY + \
> @@ -95,6 +100,37 @@ SevExit:
>  
>  OneTimeCallRet CheckSevFeature
>  
> +; Check if Secure Encrypted Virtualization - Encrypted State (SEV-ES) feature
> +; is enabled.
> +;
> +; Modified:  EAX, EBX, ECX, EDX

(1) I think we should remove EDX from this list. It is restored at the
end of the routine. And, in pageTableEntries4kLoop, we rely on EDX
containing the encryption mask.

> +;
> +; If SEV-ES is enabled then EAX will be non-zero.
> +; If SEV-ES is disabled then EAX will be zero.
> +;
> +CheckSevEsFeature:
> +xor   eax, eax
> +
> +; SEV-ES can't be enabled if SEV isn't, so first check the encryption
> +; mask.
> +test  edx, edx
> +jzNoSevEs
> +
> +; Save current value of encryption mask
> +mov   ebx, edx
> +
> +; Check if SEV-ES is enabled
> +;  MSR_0xC0010131 - Bit 1 (SEV-ES 

[edk2-devel] [RFC PATCH v2 06/44] OvmfPkg: Create a GHCB page for use during Sec phase

2019-09-19 Thread Lendacky, Thomas
From: Tom Lendacky 

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

A GHCB page is needed during the Sec phase, so this new page must be
created.  Since the GHCB must be marked as an un-encrypted, or shared,
page, an additional pagetable page is required to break down the 2MB
region where the GHCB page lives into 4K pagetable entries.

Create a new entry in the OVMF memory layout for the new page table
page and for the SEC GHCB page. After breaking down the 2MB page, update
the GHCB page table entry to remove the encryption mask.

Cc: Jordan Justen 
Cc: Laszlo Ersek 
Cc: Ard Biesheuvel 
Signed-off-by: Tom Lendacky 
---
 OvmfPkg/OvmfPkg.dec   | 10 +++
 OvmfPkg/OvmfPkgX64.fdf|  6 ++
 OvmfPkg/ResetVector/ResetVector.inf   |  4 ++
 OvmfPkg/ResetVector/Ia32/PageTables64.asm | 79 +++
 OvmfPkg/ResetVector/ResetVector.nasmb | 12 
 5 files changed, 111 insertions(+)

diff --git a/OvmfPkg/OvmfPkg.dec b/OvmfPkg/OvmfPkg.dec
index 9640360f6245..b9287a023c94 100644
--- a/OvmfPkg/OvmfPkg.dec
+++ b/OvmfPkg/OvmfPkg.dec
@@ -218,6 +218,16 @@ [PcdsFixedAtBuild]
   #  The value should be a multiple of 4KB.
   gUefiOvmfPkgTokenSpaceGuid.PcdHighPmmMemorySize|0x40|UINT32|0x31
 
+  ## Specify the extra page table needed to mark the GHCB as unencrypted.
+  #  The value should be a multiple of 4KB for each.
+  gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecGhcbPageTableBase|0x0|UINT32|0x32
+  gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecGhcbPageTableSize|0x0|UINT32|0x33
+
+  ## Specify the GHCB base address and size.
+  #  The value should be a multiple of 4KB for each.
+  gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecGhcbBase|0x0|UINT32|0x34
+  gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecGhcbSize|0x0|UINT32|0x35
+
 [PcdsDynamic, PcdsDynamicEx]
   gUefiOvmfPkgTokenSpaceGuid.PcdEmuVariableEvent|0|UINT64|2
   gUefiOvmfPkgTokenSpaceGuid.PcdOvmfFlashVariablesEnable|FALSE|BOOLEAN|0x10
diff --git a/OvmfPkg/OvmfPkgX64.fdf b/OvmfPkg/OvmfPkgX64.fdf
index 74407072563b..a567131a0591 100644
--- a/OvmfPkg/OvmfPkgX64.fdf
+++ b/OvmfPkg/OvmfPkgX64.fdf
@@ -76,6 +76,12 @@ [FD.MEMFD]
 0x007000|0x001000
 
gEfiMdePkgTokenSpaceGuid.PcdGuidedExtractHandlerTableAddress|gUefiOvmfPkgTokenSpaceGuid.PcdGuidedExtractHandlerTableSize
 
+0x008000|0x001000
+gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecGhcbPageTableBase|gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecGhcbPageTableSize
+
+0x009000|0x001000
+gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecGhcbBase|gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecGhcbSize
+
 0x01|0x01
 
gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecPeiTempRamBase|gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecPeiTempRamSize
 
diff --git a/OvmfPkg/ResetVector/ResetVector.inf 
b/OvmfPkg/ResetVector/ResetVector.inf
index 960b47cd0797..80c971354176 100644
--- a/OvmfPkg/ResetVector/ResetVector.inf
+++ b/OvmfPkg/ResetVector/ResetVector.inf
@@ -37,3 +37,7 @@ [Pcd]
   gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecPageTablesSize
   gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecPeiTempRamBase
   gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecPeiTempRamSize
+  gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecGhcbPageTableBase
+  gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecGhcbPageTableSize
+  gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecGhcbBase
+  gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecGhcbSize
diff --git a/OvmfPkg/ResetVector/Ia32/PageTables64.asm 
b/OvmfPkg/ResetVector/Ia32/PageTables64.asm
index 40f7814c1134..7e346661f2c8 100644
--- a/OvmfPkg/ResetVector/Ia32/PageTables64.asm
+++ b/OvmfPkg/ResetVector/Ia32/PageTables64.asm
@@ -21,6 +21,11 @@ BITS32
 %define PAGE_2M_MBO0x080
 %define PAGE_2M_PAT  0x01000
 
+%define PAGE_4K_PDE_ATTR (PAGE_ACCESSED + \
+  PAGE_DIRTY + \
+  PAGE_READ_WRITE + \
+  PAGE_PRESENT)
+
 %define PAGE_2M_PDE_ATTR (PAGE_2M_MBO + \
   PAGE_ACCESSED + \
   PAGE_DIRTY + \
@@ -95,6 +100,37 @@ SevExit:
 
 OneTimeCallRet CheckSevFeature
 
+; Check if Secure Encrypted Virtualization - Encrypted State (SEV-ES) feature
+; is enabled.
+;
+; Modified:  EAX, EBX, ECX, EDX
+;
+; If SEV-ES is enabled then EAX will be non-zero.
+; If SEV-ES is disabled then EAX will be zero.
+;
+CheckSevEsFeature:
+xor   eax, eax
+
+; SEV-ES can't be enabled if SEV isn't, so first check the encryption
+; mask.
+test  edx, edx
+jzNoSevEs
+
+; Save current value of encryption mask
+mov   ebx, edx
+
+; Check if SEV-ES is enabled
+;  MSR_0xC0010131 - Bit 1 (SEV-ES enabled)
+mov   ecx, 0xc0010131
+rdmsr
+and   eax, 2
+
+; Restore encryption mask
+mov   edx, ebx
+
+NoSevEs:
+OneTimeCallRet CheckSevEsFeature
+
 ;
 ; Modified:  EAX, EBX, ECX, EDX
 ;
@@ -159,6 +195,49 @@ pageTableEntriesLoop:
 mov [(ecx * 8 + PT_ADDR (0x2000 - 8)) + 4], edx
 looppageTableEntriesLoop
 
+OneTimeCall   CheckSevEsFeature
+testeax, eax
+jz  SetCr3
+
+;
+; The