[edk2] [PATCH 2/2] OvmfPkg/QemuFlashFvbServicesRuntimeDxe: Clear C-bit when SEV is active

Brijesh Singh posted 2 patches 6 years, 10 months ago
There is a newer version of this series
[edk2] [PATCH 2/2] OvmfPkg/QemuFlashFvbServicesRuntimeDxe: Clear C-bit when SEV is active
Posted by Brijesh Singh 6 years, 10 months ago
Commit:24e4ad7 (OvmfPkg: Add AmdSevDxe driver) added a driver which runs
early in PEI phase and clears the C-bit from all MMIO regions (including
Qemu Flash). When SMM is enabled, we build two sets of page tables; first
page table is used when executing code in non SMM mode (SMM-less-pgtable)
and second page table is used when we are executing code in SMM mode
(SMM-pgtable).

During boot time, AmdSevDxe driver clears the C-bit from the
SMM-less-pgtable. But when SMM is enabled, Qemu Flash services are used
from SMM mode.

In this patch we explicitly clear the C-bit from Qemu flash MMIO range
before we probe the flash. When OVMF is built with SMM_REQUIRE then
call to initialize the flash services happen after the SMM-pgtable is
created and processor is serving the first SMI. At this time we will
have access to the SMM-pgtable.

Cc: Jordan Justen <jordan.l.justen@intel.com>
Cc: Laszlo Ersek <lersek@redhat.com>
Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Brijesh Singh <brijesh.singh@amd.com>
---
 OvmfPkg/QemuFlashFvbServicesRuntimeDxe/FvbServicesSmm.inf  |  1 +
 OvmfPkg/QemuFlashFvbServicesRuntimeDxe/FwBlockService.h    |  5 +++
 OvmfPkg/QemuFlashFvbServicesRuntimeDxe/FwBlockService.c    |  5 +++
 OvmfPkg/QemuFlashFvbServicesRuntimeDxe/FwBlockServiceDxe.c | 10 ++++++
 OvmfPkg/QemuFlashFvbServicesRuntimeDxe/FwBlockServiceSmm.c | 35 ++++++++++++++++++++
 5 files changed, 56 insertions(+)

diff --git a/OvmfPkg/QemuFlashFvbServicesRuntimeDxe/FvbServicesSmm.inf b/OvmfPkg/QemuFlashFvbServicesRuntimeDxe/FvbServicesSmm.inf
index ba2d3679a46d..d365e27cbe59 100644
--- a/OvmfPkg/QemuFlashFvbServicesRuntimeDxe/FvbServicesSmm.inf
+++ b/OvmfPkg/QemuFlashFvbServicesRuntimeDxe/FvbServicesSmm.inf
@@ -53,6 +53,7 @@ [LibraryClasses]
   DevicePathLib
   DxeServicesTableLib
   MemoryAllocationLib
+  MemEncryptSevLib
   PcdLib
   SmmServicesTableLib
   UefiBootServicesTableLib
diff --git a/OvmfPkg/QemuFlashFvbServicesRuntimeDxe/FwBlockService.h b/OvmfPkg/QemuFlashFvbServicesRuntimeDxe/FwBlockService.h
index 1f9287b08769..704ed477ba14 100644
--- a/OvmfPkg/QemuFlashFvbServicesRuntimeDxe/FwBlockService.h
+++ b/OvmfPkg/QemuFlashFvbServicesRuntimeDxe/FwBlockService.h
@@ -189,4 +189,9 @@ VOID
 InstallVirtualAddressChangeHandler (
   VOID
   );
+
+VOID
+FvbBeforeFlashProbe (
+  VOID
+  );
 #endif
diff --git a/OvmfPkg/QemuFlashFvbServicesRuntimeDxe/FwBlockService.c b/OvmfPkg/QemuFlashFvbServicesRuntimeDxe/FwBlockService.c
index 558b395dff4a..b7b9bf1fb8d9 100644
--- a/OvmfPkg/QemuFlashFvbServicesRuntimeDxe/FwBlockService.c
+++ b/OvmfPkg/QemuFlashFvbServicesRuntimeDxe/FwBlockService.c
@@ -967,6 +967,11 @@ FvbInitialize (
   UINTN                               NumOfBlocks;
   RETURN_STATUS                       PcdStatus;
 
+  //
+  // execute platform specific hooks before probing the flash
+  //
+  FvbBeforeFlashProbe ();
+
   if (EFI_ERROR (QemuFlashInitialize ())) {
     //
     // Return an error so image will be unloaded
diff --git a/OvmfPkg/QemuFlashFvbServicesRuntimeDxe/FwBlockServiceDxe.c b/OvmfPkg/QemuFlashFvbServicesRuntimeDxe/FwBlockServiceDxe.c
index 63b308658e36..7d274c08ad12 100644
--- a/OvmfPkg/QemuFlashFvbServicesRuntimeDxe/FwBlockServiceDxe.c
+++ b/OvmfPkg/QemuFlashFvbServicesRuntimeDxe/FwBlockServiceDxe.c
@@ -155,3 +155,13 @@ InstallVirtualAddressChangeHandler (
                   );
   ASSERT_EFI_ERROR (Status);
 }
+
+VOID
+FvbBeforeFlashProbe (
+  VOID
+  )
+{
+  //
+  // Do nothing
+  //
+}
diff --git a/OvmfPkg/QemuFlashFvbServicesRuntimeDxe/FwBlockServiceSmm.c b/OvmfPkg/QemuFlashFvbServicesRuntimeDxe/FwBlockServiceSmm.c
index e0617f2503a2..d97b13f47bf7 100644
--- a/OvmfPkg/QemuFlashFvbServicesRuntimeDxe/FwBlockServiceSmm.c
+++ b/OvmfPkg/QemuFlashFvbServicesRuntimeDxe/FwBlockServiceSmm.c
@@ -17,6 +17,7 @@
 #include <Library/DebugLib.h>
 #include <Library/PcdLib.h>
 #include <Library/SmmServicesTableLib.h>
+#include <Library/MemEncryptSevLib.h>
 #include <Protocol/DevicePath.h>
 #include <Protocol/SmmFirmwareVolumeBlock.h>
 
@@ -67,3 +68,37 @@ InstallVirtualAddressChangeHandler (
   // Nothing.
   //
 }
+
+VOID
+FvbBeforeFlashProbe (
+  VOID
+  )
+{
+
+  ASSERT (FeaturePcdGet (PcdSmmSmramRequire));
+
+  //
+  // When SEV is enabled, AmdSevDxe runs early in PEI phase and clears the C-bit
+  // from the MMIO space (including flash ranges) but the driver runs in non SMM
+  // context hence it cleared the flash ranges from non SMM page table.
+  // When SMM is enabled, the flash services are accessed from the SMM mode
+  // hence we explicitly clear the C-bit on flash ranges from SMM page table.
+  //
+  if (MemEncryptSevIsEnabled ()) {
+    EFI_STATUS              Status;
+    EFI_PHYSICAL_ADDRESS    BaseAddress;
+    UINTN                   FdBlockSize, FdBlockCount;
+
+    BaseAddress = (EFI_PHYSICAL_ADDRESS) PcdGet32 (PcdOvmfFdBaseAddress);
+    FdBlockSize = PcdGet32 (PcdOvmfFirmwareBlockSize);
+    FdBlockCount = PcdGet32 (PcdOvmfFirmwareFdSize) / FdBlockSize;
+
+    Status = MemEncryptSevClearPageEncMask (
+               0,
+               BaseAddress,
+               EFI_SIZE_TO_PAGES (FdBlockSize * FdBlockCount),
+               FALSE
+              );
+    ASSERT_EFI_ERROR (Status);
+  }
+}
-- 
2.14.3

_______________________________________________
edk2-devel mailing list
edk2-devel@lists.01.org
https://lists.01.org/mailman/listinfo/edk2-devel
Re: [edk2] [PATCH 2/2] OvmfPkg/QemuFlashFvbServicesRuntimeDxe: Clear C-bit when SEV is active
Posted by Laszlo Ersek 6 years, 10 months ago
On 02/21/18 17:52, Brijesh Singh wrote:
> Commit:24e4ad7 (OvmfPkg: Add AmdSevDxe driver) added a driver which runs
> early in PEI phase and clears the C-bit from all MMIO regions (including

s/PEI/DXE/


> Qemu Flash). When SMM is enabled, we build two sets of page tables; first
> page table is used when executing code in non SMM mode (SMM-less-pgtable)
> and second page table is used when we are executing code in SMM mode
> (SMM-pgtable).
> 
> During boot time, AmdSevDxe driver clears the C-bit from the
> SMM-less-pgtable. But when SMM is enabled, Qemu Flash services are used
> from SMM mode.
> 
> In this patch we explicitly clear the C-bit from Qemu flash MMIO range
> before we probe the flash. When OVMF is built with SMM_REQUIRE then
> call to initialize the flash services happen after the SMM-pgtable is
> created and processor is serving the first SMI. At this time we will
> have access to the SMM-pgtable.

The problem statement is good (including the comment in the code).

However, I would prefer if we could reflect the full AmdSevDxe logic to
the SMM page tables. In other words, when -- or shortly after -- the SMM
page tables are built, we should clear the C-bit in all those PTEs that
cover known MMIO and as-yet NonExistent memory ranges. We already have a
bunch of "mAddressEncMask" usage in PiSmmCpuDxeSmm.

Can we investigate this a bit? If it turns out to be impossible, I guess
I might be OK with this patch.

I have more comments:


> 
> Cc: Jordan Justen <jordan.l.justen@intel.com>
> Cc: Laszlo Ersek <lersek@redhat.com>
> Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
> Contributed-under: TianoCore Contribution Agreement 1.1
> Signed-off-by: Brijesh Singh <brijesh.singh@amd.com>
> ---
>  OvmfPkg/QemuFlashFvbServicesRuntimeDxe/FvbServicesSmm.inf  |  1 +
>  OvmfPkg/QemuFlashFvbServicesRuntimeDxe/FwBlockService.h    |  5 +++
>  OvmfPkg/QemuFlashFvbServicesRuntimeDxe/FwBlockService.c    |  5 +++
>  OvmfPkg/QemuFlashFvbServicesRuntimeDxe/FwBlockServiceDxe.c | 10 ++++++
>  OvmfPkg/QemuFlashFvbServicesRuntimeDxe/FwBlockServiceSmm.c | 35 ++++++++++++++++++++
>  5 files changed, 56 insertions(+)
> 
> diff --git a/OvmfPkg/QemuFlashFvbServicesRuntimeDxe/FvbServicesSmm.inf b/OvmfPkg/QemuFlashFvbServicesRuntimeDxe/FvbServicesSmm.inf
> index ba2d3679a46d..d365e27cbe59 100644
> --- a/OvmfPkg/QemuFlashFvbServicesRuntimeDxe/FvbServicesSmm.inf
> +++ b/OvmfPkg/QemuFlashFvbServicesRuntimeDxe/FvbServicesSmm.inf
> @@ -53,6 +53,7 @@ [LibraryClasses]
>    DevicePathLib
>    DxeServicesTableLib
>    MemoryAllocationLib
> +  MemEncryptSevLib
>    PcdLib
>    SmmServicesTableLib
>    UefiBootServicesTableLib
> diff --git a/OvmfPkg/QemuFlashFvbServicesRuntimeDxe/FwBlockService.h b/OvmfPkg/QemuFlashFvbServicesRuntimeDxe/FwBlockService.h
> index 1f9287b08769..704ed477ba14 100644
> --- a/OvmfPkg/QemuFlashFvbServicesRuntimeDxe/FwBlockService.h
> +++ b/OvmfPkg/QemuFlashFvbServicesRuntimeDxe/FwBlockService.h
> @@ -189,4 +189,9 @@ VOID
>  InstallVirtualAddressChangeHandler (
>    VOID
>    );
> +
> +VOID
> +FvbBeforeFlashProbe (
> +  VOID
> +  );
>  #endif

Please drop the "Fvb" prefix; this function is not an FVB protocol member.


> diff --git a/OvmfPkg/QemuFlashFvbServicesRuntimeDxe/FwBlockService.c b/OvmfPkg/QemuFlashFvbServicesRuntimeDxe/FwBlockService.c
> index 558b395dff4a..b7b9bf1fb8d9 100644
> --- a/OvmfPkg/QemuFlashFvbServicesRuntimeDxe/FwBlockService.c
> +++ b/OvmfPkg/QemuFlashFvbServicesRuntimeDxe/FwBlockService.c
> @@ -967,6 +967,11 @@ FvbInitialize (
>    UINTN                               NumOfBlocks;
>    RETURN_STATUS                       PcdStatus;
>  
> +  //
> +  // execute platform specific hooks before probing the flash
> +  //
> +  FvbBeforeFlashProbe ();
> +
>    if (EFI_ERROR (QemuFlashInitialize ())) {
>      //
>      // Return an error so image will be unloaded
> diff --git a/OvmfPkg/QemuFlashFvbServicesRuntimeDxe/FwBlockServiceDxe.c b/OvmfPkg/QemuFlashFvbServicesRuntimeDxe/FwBlockServiceDxe.c
> index 63b308658e36..7d274c08ad12 100644
> --- a/OvmfPkg/QemuFlashFvbServicesRuntimeDxe/FwBlockServiceDxe.c
> +++ b/OvmfPkg/QemuFlashFvbServicesRuntimeDxe/FwBlockServiceDxe.c
> @@ -155,3 +155,13 @@ InstallVirtualAddressChangeHandler (
>                    );
>    ASSERT_EFI_ERROR (Status);
>  }
> +
> +VOID
> +FvbBeforeFlashProbe (
> +  VOID
> +  )
> +{
> +  //
> +  // Do nothing
> +  //
> +}
> diff --git a/OvmfPkg/QemuFlashFvbServicesRuntimeDxe/FwBlockServiceSmm.c b/OvmfPkg/QemuFlashFvbServicesRuntimeDxe/FwBlockServiceSmm.c
> index e0617f2503a2..d97b13f47bf7 100644
> --- a/OvmfPkg/QemuFlashFvbServicesRuntimeDxe/FwBlockServiceSmm.c
> +++ b/OvmfPkg/QemuFlashFvbServicesRuntimeDxe/FwBlockServiceSmm.c
> @@ -17,6 +17,7 @@
>  #include <Library/DebugLib.h>
>  #include <Library/PcdLib.h>
>  #include <Library/SmmServicesTableLib.h>
> +#include <Library/MemEncryptSevLib.h>
>  #include <Protocol/DevicePath.h>
>  #include <Protocol/SmmFirmwareVolumeBlock.h>
>  
> @@ -67,3 +68,37 @@ InstallVirtualAddressChangeHandler (
>    // Nothing.
>    //
>  }
> +
> +VOID
> +FvbBeforeFlashProbe (
> +  VOID
> +  )
> +{
> +
> +  ASSERT (FeaturePcdGet (PcdSmmSmramRequire));
> +
> +  //
> +  // When SEV is enabled, AmdSevDxe runs early in PEI phase and clears the C-bit

s/PEI/DXE/


> +  // from the MMIO space (including flash ranges) but the driver runs in non SMM
> +  // context hence it cleared the flash ranges from non SMM page table.
> +  // When SMM is enabled, the flash services are accessed from the SMM mode
> +  // hence we explicitly clear the C-bit on flash ranges from SMM page table.
> +  //
> +  if (MemEncryptSevIsEnabled ()) {
> +    EFI_STATUS              Status;
> +    EFI_PHYSICAL_ADDRESS    BaseAddress;
> +    UINTN                   FdBlockSize, FdBlockCount;
> +
> +    BaseAddress = (EFI_PHYSICAL_ADDRESS) PcdGet32 (PcdOvmfFdBaseAddress);
> +    FdBlockSize = PcdGet32 (PcdOvmfFirmwareBlockSize);
> +    FdBlockCount = PcdGet32 (PcdOvmfFirmwareFdSize) / FdBlockSize;
> +
> +    Status = MemEncryptSevClearPageEncMask (
> +               0,
> +               BaseAddress,
> +               EFI_SIZE_TO_PAGES (FdBlockSize * FdBlockCount),
> +               FALSE
> +              );
> +    ASSERT_EFI_ERROR (Status);
> +  }
> +}
> 

I think it would be better to hook this logic into
QemuFlashInitialize(). That function already computes mFlashBase,
mFdBlockSize and mFdBlockCount. Right before the call to
QemuFlashDetected(), we could call BeforeFlashProbe(). The latter could
take the base address, the block size and count as parameters, or just
use the global variables.


But, again, my preference would be to mirror the AmdSevDxe logic into
(or right after) the SMM page table setup. Perhaps that can be done in
SmmCpuFeaturesInitializeProcessor(), when IsMonarch is TRUE -- this
function is called from SmmInitHandler(), and at that point, the SMM
page tables are already in use. (See above the SmmInitHandler() call
site in "UefiCpuPkg/PiSmmCpuDxeSmm/X64/SmmInit.nasm".)

Thanks,
Laszlo
_______________________________________________
edk2-devel mailing list
edk2-devel@lists.01.org
https://lists.01.org/mailman/listinfo/edk2-devel
Re: [edk2] [PATCH 2/2] OvmfPkg/QemuFlashFvbServicesRuntimeDxe: Clear C-bit when SEV is active
Posted by Brijesh Singh 6 years, 9 months ago

On 2/22/18 6:08 AM, Laszlo Ersek wrote:
> On 02/21/18 17:52, Brijesh Singh wrote:
>> Commit:24e4ad7 (OvmfPkg: Add AmdSevDxe driver) added a driver which runs
>> early in PEI phase and clears the C-bit from all MMIO regions (including
> s/PEI/DXE/
>
>
>> Qemu Flash). When SMM is enabled, we build two sets of page tables; first
>> page table is used when executing code in non SMM mode (SMM-less-pgtable)
>> and second page table is used when we are executing code in SMM mode
>> (SMM-pgtable).
>>
>> During boot time, AmdSevDxe driver clears the C-bit from the
>> SMM-less-pgtable. But when SMM is enabled, Qemu Flash services are used
>> from SMM mode.
>>
>> In this patch we explicitly clear the C-bit from Qemu flash MMIO range
>> before we probe the flash. When OVMF is built with SMM_REQUIRE then
>> call to initialize the flash services happen after the SMM-pgtable is
>> created and processor is serving the first SMI. At this time we will
>> have access to the SMM-pgtable.
> The problem statement is good (including the comment in the code).
>
> However, I would prefer if we could reflect the full AmdSevDxe logic to
> the SMM page tables. In other words, when -- or shortly after -- the SMM
> page tables are built, we should clear the C-bit in all those PTEs that
> cover known MMIO and as-yet NonExistent memory ranges. We already have a
> bunch of "mAddressEncMask" usage in PiSmmCpuDxeSmm.
>
> Can we investigate this a bit? If it turns out to be impossible, I guess
> I might be OK with this patch.

I will investigate this a bit. The reason why I didn't replicated full
AmdSevDxe logic is because I thought in SMM world we don't need to do
all those MMIO accesses etc but if its not the case then I agree we
should implement the full logic here.


>
> I have more comments:
>
>
>> Cc: Jordan Justen <jordan.l.justen@intel.com>
>> Cc: Laszlo Ersek <lersek@redhat.com>
>> Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
>> Contributed-under: TianoCore Contribution Agreement 1.1
>> Signed-off-by: Brijesh Singh <brijesh.singh@amd.com>
>> ---
>>  OvmfPkg/QemuFlashFvbServicesRuntimeDxe/FvbServicesSmm.inf  |  1 +
>>  OvmfPkg/QemuFlashFvbServicesRuntimeDxe/FwBlockService.h    |  5 +++
>>  OvmfPkg/QemuFlashFvbServicesRuntimeDxe/FwBlockService.c    |  5 +++
>>  OvmfPkg/QemuFlashFvbServicesRuntimeDxe/FwBlockServiceDxe.c | 10 ++++++
>>  OvmfPkg/QemuFlashFvbServicesRuntimeDxe/FwBlockServiceSmm.c | 35 ++++++++++++++++++++
>>  5 files changed, 56 insertions(+)
>>
>> diff --git a/OvmfPkg/QemuFlashFvbServicesRuntimeDxe/FvbServicesSmm.inf b/OvmfPkg/QemuFlashFvbServicesRuntimeDxe/FvbServicesSmm.inf
>> index ba2d3679a46d..d365e27cbe59 100644
>> --- a/OvmfPkg/QemuFlashFvbServicesRuntimeDxe/FvbServicesSmm.inf
>> +++ b/OvmfPkg/QemuFlashFvbServicesRuntimeDxe/FvbServicesSmm.inf
>> @@ -53,6 +53,7 @@ [LibraryClasses]
>>    DevicePathLib
>>    DxeServicesTableLib
>>    MemoryAllocationLib
>> +  MemEncryptSevLib
>>    PcdLib
>>    SmmServicesTableLib
>>    UefiBootServicesTableLib
>> diff --git a/OvmfPkg/QemuFlashFvbServicesRuntimeDxe/FwBlockService.h b/OvmfPkg/QemuFlashFvbServicesRuntimeDxe/FwBlockService.h
>> index 1f9287b08769..704ed477ba14 100644
>> --- a/OvmfPkg/QemuFlashFvbServicesRuntimeDxe/FwBlockService.h
>> +++ b/OvmfPkg/QemuFlashFvbServicesRuntimeDxe/FwBlockService.h
>> @@ -189,4 +189,9 @@ VOID
>>  InstallVirtualAddressChangeHandler (
>>    VOID
>>    );
>> +
>> +VOID
>> +FvbBeforeFlashProbe (
>> +  VOID
>> +  );
>>  #endif
> Please drop the "Fvb" prefix; this function is not an FVB protocol member.

Will do.

>
>
>> diff --git a/OvmfPkg/QemuFlashFvbServicesRuntimeDxe/FwBlockService.c b/OvmfPkg/QemuFlashFvbServicesRuntimeDxe/FwBlockService.c
>> index 558b395dff4a..b7b9bf1fb8d9 100644
>> --- a/OvmfPkg/QemuFlashFvbServicesRuntimeDxe/FwBlockService.c
>> +++ b/OvmfPkg/QemuFlashFvbServicesRuntimeDxe/FwBlockService.c
>> @@ -967,6 +967,11 @@ FvbInitialize (
>>    UINTN                               NumOfBlocks;
>>    RETURN_STATUS                       PcdStatus;
>>  
>> +  //
>> +  // execute platform specific hooks before probing the flash
>> +  //
>> +  FvbBeforeFlashProbe ();
>> +
>>    if (EFI_ERROR (QemuFlashInitialize ())) {
>>      //
>>      // Return an error so image will be unloaded
>> diff --git a/OvmfPkg/QemuFlashFvbServicesRuntimeDxe/FwBlockServiceDxe.c b/OvmfPkg/QemuFlashFvbServicesRuntimeDxe/FwBlockServiceDxe.c
>> index 63b308658e36..7d274c08ad12 100644
>> --- a/OvmfPkg/QemuFlashFvbServicesRuntimeDxe/FwBlockServiceDxe.c
>> +++ b/OvmfPkg/QemuFlashFvbServicesRuntimeDxe/FwBlockServiceDxe.c
>> @@ -155,3 +155,13 @@ InstallVirtualAddressChangeHandler (
>>                    );
>>    ASSERT_EFI_ERROR (Status);
>>  }
>> +
>> +VOID
>> +FvbBeforeFlashProbe (
>> +  VOID
>> +  )
>> +{
>> +  //
>> +  // Do nothing
>> +  //
>> +}
>> diff --git a/OvmfPkg/QemuFlashFvbServicesRuntimeDxe/FwBlockServiceSmm.c b/OvmfPkg/QemuFlashFvbServicesRuntimeDxe/FwBlockServiceSmm.c
>> index e0617f2503a2..d97b13f47bf7 100644
>> --- a/OvmfPkg/QemuFlashFvbServicesRuntimeDxe/FwBlockServiceSmm.c
>> +++ b/OvmfPkg/QemuFlashFvbServicesRuntimeDxe/FwBlockServiceSmm.c
>> @@ -17,6 +17,7 @@
>>  #include <Library/DebugLib.h>
>>  #include <Library/PcdLib.h>
>>  #include <Library/SmmServicesTableLib.h>
>> +#include <Library/MemEncryptSevLib.h>
>>  #include <Protocol/DevicePath.h>
>>  #include <Protocol/SmmFirmwareVolumeBlock.h>
>>  
>> @@ -67,3 +68,37 @@ InstallVirtualAddressChangeHandler (
>>    // Nothing.
>>    //
>>  }
>> +
>> +VOID
>> +FvbBeforeFlashProbe (
>> +  VOID
>> +  )
>> +{
>> +
>> +  ASSERT (FeaturePcdGet (PcdSmmSmramRequire));
>> +
>> +  //
>> +  // When SEV is enabled, AmdSevDxe runs early in PEI phase and clears the C-bit
> s/PEI/DXE/

Will do.
>
>
>> +  // from the MMIO space (including flash ranges) but the driver runs in non SMM
>> +  // context hence it cleared the flash ranges from non SMM page table.
>> +  // When SMM is enabled, the flash services are accessed from the SMM mode
>> +  // hence we explicitly clear the C-bit on flash ranges from SMM page table.
>> +  //
>> +  if (MemEncryptSevIsEnabled ()) {
>> +    EFI_STATUS              Status;
>> +    EFI_PHYSICAL_ADDRESS    BaseAddress;
>> +    UINTN                   FdBlockSize, FdBlockCount;
>> +
>> +    BaseAddress = (EFI_PHYSICAL_ADDRESS) PcdGet32 (PcdOvmfFdBaseAddress);
>> +    FdBlockSize = PcdGet32 (PcdOvmfFirmwareBlockSize);
>> +    FdBlockCount = PcdGet32 (PcdOvmfFirmwareFdSize) / FdBlockSize;
>> +
>> +    Status = MemEncryptSevClearPageEncMask (
>> +               0,
>> +               BaseAddress,
>> +               EFI_SIZE_TO_PAGES (FdBlockSize * FdBlockCount),
>> +               FALSE
>> +              );
>> +    ASSERT_EFI_ERROR (Status);
>> +  }
>> +}
>>
> I think it would be better to hook this logic into
> QemuFlashInitialize(). That function already computes mFlashBase,
> mFdBlockSize and mFdBlockCount. Right before the call to
> QemuFlashDetected(), we could call BeforeFlashProbe(). The latter could
> take the base address, the block size and count as parameters, or just
> use the global variables.
>

Let me see what I can do.

> But, again, my preference would be to mirror the AmdSevDxe logic into
> (or right after) the SMM page table setup. Perhaps that can be done in
> SmmCpuFeaturesInitializeProcessor(), when IsMonarch is TRUE -- this
> function is called from SmmInitHandler(), and at that point, the SMM
> page tables are already in use. (See above the SmmInitHandler() call
> site in "UefiCpuPkg/PiSmmCpuDxeSmm/X64/SmmInit.nasm".)

Ah, I didn't know this one. I got SMM working with very small patch set
hence never looked in UefiCpuPkg for complete understanding of various
SmmFeatureLib routines but now I am looking more into it and I think we
may able to use SmmCpuFeatureInitializeProcessor() routines.

> Thanks,
> Laszlo

_______________________________________________
edk2-devel mailing list
edk2-devel@lists.01.org
https://lists.01.org/mailman/listinfo/edk2-devel
Re: [edk2] [PATCH 2/2] OvmfPkg/QemuFlashFvbServicesRuntimeDxe: Clear C-bit when SEV is active
Posted by Laszlo Ersek 6 years, 9 months ago
Hi Brijesh,

you provided a lot of information (and it seems like your analysis was
advancing in parallel with your email -- I too do that sometimes :) ),
so it's not easy for me to write a concise response.

* Regarding the C-bit that covers the relocated save state area (esp.
considering that the area is not page aligned and/or contains executable
code):

I think (a) adding any code (under OvmfPkg, or under the core) that sets
the C-bit "correctly", and in turn, (b) lacking any code in edk2 that
actually *exercises* the "correct" C-bit setting, is counter-productive.
Unless the C-bit is actively exercised, we're just adding *dead* code,
which is a bad thing -- it's very easy to regress (without anyone
noticing), and it leads to developer confusion.

On the other hand, I wouldn't want your analysis to be lost (remember: I
asked for the explanation because I didn't understand the behavior). So
I'm thinking your analysis should be captured in both a commit message,
and a large comment *somewhere*. Possibly near the code (wherever it may
end up, AmdSevDxe or SmmCpuFeaturesLib) where you manage the C-bit for
the *initial* save state map.

I mean, wherever you manage the C-bit for the initial save state map
(which is required), you can also make a large comment on the *future*
location and behavior.

IMO it's OK if we don't guarantee the guest with functional access into
the relocated save state map -- there is no actual code relying on that!
-- as long as we document this gap.

Does this suggestion make sense to you?

* Regarding mapping all the NonExistent and MMIO GCD entries in the SMM
page table as plaintext: I think we should really be on par with
AmdSevDxe here. This is code that *will* be exercised, and if we cut
corners here, next time we add another MMIO range or device that needs
to be accessed from SMM too (for whatever reason), we'll go crazy otherwise.

* In general, regarding how and when SmmCpuFeaturesLib APIs are hooked
into PiSmmCpuDxeSmm: please ask questions -- and ask them to Mike :)
OVMF's instance of this lib class is Paolo's work (thanks again for
that!), so I always defer to Mike and Paolo whenever this lib class and
instance come up. SmmCpuFeaturesInitializeProcessor() looked suitable to
me, for implementing the previous bullet, but it's really just my
"shopping" for a good pre-existent hook point. If we need something
better, let's discuss it with Mike.

I'm sorry if the above is a bit too vague; please post some new patches,
even if only RFCs :)

Thanks!
Laszlo
_______________________________________________
edk2-devel mailing list
edk2-devel@lists.01.org
https://lists.01.org/mailman/listinfo/edk2-devel
Re: [edk2] [PATCH 2/2] OvmfPkg/QemuFlashFvbServicesRuntimeDxe: Clear C-bit when SEV is active
Posted by Brijesh Singh 6 years, 9 months ago
Hi Laszlo,


On 2/27/18 11:17 AM, Laszlo Ersek wrote:
> Hi Brijesh,
>
> you provided a lot of information (and it seems like your analysis was
> advancing in parallel with your email -- I too do that sometimes :) ),
> so it's not easy for me to write a concise response.
>
> * Regarding the C-bit that covers the relocated save state area (esp.
> considering that the area is not page aligned and/or contains executable
> code):
>
> I think (a) adding any code (under OvmfPkg, or under the core) that sets
> the C-bit "correctly", and in turn, (b) lacking any code in edk2 that
> actually *exercises* the "correct" C-bit setting, is counter-productive.
> Unless the C-bit is actively exercised, we're just adding *dead* code,
> which is a bad thing -- it's very easy to regress (without anyone
> noticing), and it leads to developer confusion.
>
> On the other hand, I wouldn't want your analysis to be lost (remember: I
> asked for the explanation because I didn't understand the behavior). So
> I'm thinking your analysis should be captured in both a commit message,
> and a large comment *somewhere*. Possibly near the code (wherever it may
> end up, AmdSevDxe or SmmCpuFeaturesLib) where you manage the C-bit for
> the *initial* save state map.
>
> I mean, wherever you manage the C-bit for the initial save state map
> (which is required), you can also make a large comment on the *future*
> location and behavior.
>
> IMO it's OK if we don't guarantee the guest with functional access into
> the relocated save state map -- there is no actual code relying on that!
> -- as long as we document this gap.
>
> Does this suggestion make sense to you?

I am good with this approach. I will add my analysis detail in commit
message and also put the similar thing in AmdSevDxe. In future if EDKII
makes use to SmmSavedArea after the SMBASE relocation then we can
revisit it.

>
> * Regarding mapping all the NonExistent and MMIO GCD entries in the SMM
> page table as plaintext: I think we should really be on par with
> AmdSevDxe here. This is code that *will* be exercised, and if we cut
> corners here, next time we add another MMIO range or device that needs
> to be accessed from SMM too (for whatever reason), we'll go crazy otherwise.

Sounds good, I will make the necessary changes and send the update
patch. thanks for your help.

>
> * In general, regarding how and when SmmCpuFeaturesLib APIs are hooked
> into PiSmmCpuDxeSmm: please ask questions -- and ask them to Mike :)
> OVMF's instance of this lib class is Paolo's work (thanks again for
> that!), so I always defer to Mike and Paolo whenever this lib class and
> instance come up. SmmCpuFeaturesInitializeProcessor() looked suitable to
> me, for implementing the previous bullet, but it's really just my
> "shopping" for a good pre-existent hook point. If we need something
> better, let's discuss it with Mike.
>
> I'm sorry if the above is a bit too vague; please post some new patches,
> even if only RFCs :)

I think your explanation is very clear to me and I am in agreement. Let
me work on patches.

>
> Thanks!
> Laszlo

_______________________________________________
edk2-devel mailing list
edk2-devel@lists.01.org
https://lists.01.org/mailman/listinfo/edk2-devel
Re: [edk2] [PATCH 2/2] OvmfPkg/QemuFlashFvbServicesRuntimeDxe: Clear C-bit when SEV is active
Posted by Brijesh Singh 6 years, 9 months ago
Hi Laszlo,


On 02/27/2018 02:37 PM, Brijesh Singh wrote:
> Hi Laszlo,
> 
> 
> On 2/27/18 11:17 AM, Laszlo Ersek wrote:
>> Hi Brijesh,
>>
>> you provided a lot of information (and it seems like your analysis was
>> advancing in parallel with your email -- I too do that sometimes :) ),
>> so it's not easy for me to write a concise response.
>>
>> * Regarding the C-bit that covers the relocated save state area (esp.
>> considering that the area is not page aligned and/or contains executable
>> code):
>>
>> I think (a) adding any code (under OvmfPkg, or under the core) that sets
>> the C-bit "correctly", and in turn, (b) lacking any code in edk2 that
>> actually *exercises* the "correct" C-bit setting, is counter-productive.
>> Unless the C-bit is actively exercised, we're just adding *dead* code,
>> which is a bad thing -- it's very easy to regress (without anyone
>> noticing), and it leads to developer confusion.
>>
>> On the other hand, I wouldn't want your analysis to be lost (remember: I
>> asked for the explanation because I didn't understand the behavior). So
>> I'm thinking your analysis should be captured in both a commit message,
>> and a large comment *somewhere*. Possibly near the code (wherever it may
>> end up, AmdSevDxe or SmmCpuFeaturesLib) where you manage the C-bit for
>> the *initial* save state map.
>>
>> I mean, wherever you manage the C-bit for the initial save state map
>> (which is required), you can also make a large comment on the *future*
>> location and behavior.
>>
>> IMO it's OK if we don't guarantee the guest with functional access into
>> the relocated save state map -- there is no actual code relying on that!
>> -- as long as we document this gap.
>>
>> Does this suggestion make sense to you?
> 
> I am good with this approach. I will add my analysis detail in commit
> message and also put the similar thing in AmdSevDxe. In future if EDKII
> makes use to SmmSavedArea after the SMBASE relocation then we can
> revisit it.
> 
>>
>> * Regarding mapping all the NonExistent and MMIO GCD entries in the SMM
>> page table as plaintext: I think we should really be on par with
>> AmdSevDxe here. This is code that *will* be exercised, and if we cut
>> corners here, next time we add another MMIO range or device that needs
>> to be accessed from SMM too (for whatever reason), we'll go crazy otherwise.
> 
> Sounds good, I will make the necessary changes and send the update
> patch. thanks for your help.
> 


OK, I have been trying to implement this and its making things much 
harder than we thought. It seems SMM page table is very minimal and does 
not have PTEs for all those MMIO and NonExistent range. So, when we try 
to clear the C-bit on those range then I have no issue clearing the bits 
(it just cause more fault) but later in boot we get ASSERTs. I have seen 
all kind of assertion but the most of time I get below message

SMM exception at access (0x7FC01000)
It is invoked from the instruction before IP(0x7FFCB6EF) in module 
(/disk-part-1/upstream/edk2/Build/Ovmf3264/DEBUG_GCC5/X64/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm/DEBUG/PiSmmCpuDxeSmm.dll)

or Sometime SMM page table overlap assertion etc.

If we just do Flash range then have no issues. Do you want me to dig 
more deep on this or you are okay with my previous approach.


>>
>> * In general, regarding how and when SmmCpuFeaturesLib APIs are hooked
>> into PiSmmCpuDxeSmm: please ask questions -- and ask them to Mike :)
>> OVMF's instance of this lib class is Paolo's work (thanks again for
>> that!), so I always defer to Mike and Paolo whenever this lib class and
>> instance come up. SmmCpuFeaturesInitializeProcessor() looked suitable to
>> me, for implementing the previous bullet, but it's really just my
>> "shopping" for a good pre-existent hook point. If we need something
>> better, let's discuss it with Mike.
>>
>> I'm sorry if the above is a bit too vague; please post some new patches,
>> even if only RFCs :)
> 
> I think your explanation is very clear to me and I am in agreement. Let
> me work on patches.
> 
>>
>> Thanks!
>> Laszlo
> 
_______________________________________________
edk2-devel mailing list
edk2-devel@lists.01.org
https://lists.01.org/mailman/listinfo/edk2-devel