On 11/21/19 22:11, Tom Lendacky wrote:
> On 11/21/19 6:31 AM, Laszlo Ersek via Groups.Io wrote:
>> On 11/20/19 21:06, Lendacky, Thomas wrote:
>>> The flash detection routine will attempt to determine how the flash
>>> device behaves (e.g. ROM, RAM, Flash). But when SEV-ES is enabled and
>>> the flash device behaves as a ROM device (meaning it is marked read-only
>>> by the hypervisor), this check may result in an infinite nested page fault
>>> because of the attempted write. Since the instruction cannot be emulated
>>> when SEV-ES is enabled, the RIP is never advanced, resulting in repeated
>>> nested page faults.
>>>
>>> When SEV-ES is enabled, exit the flash detection early and assume that
>>> the FD behaves as Flash. This will result in QemuFlashWrite() being called
>>> to store EFI variables, which will also result in an infinite nested page
>>> fault when the write is performed. In this case, update QemuFlashWrite()
>>> to use the VmgMmioWrite function from the VmgExitLib library to have the
>>> hypervisor perform the write without having to emulate the instruction.
>>
>> (1) Please include the Bugzilla link in the commit message:
>>
>> https://bugzilla.tianocore.org/show_bug.cgi?id=2198
> 
> Yup, will do. I'm also missing the Cc:'s, so I'll add those as well.
> 
>>
>>>
>>> Signed-off-by: Tom Lendacky <thomas.lenda...@amd.com>
>>> ---
>>>  OvmfPkg/OvmfPkgIa32.dsc                       |  1 +
>>>  OvmfPkg/OvmfPkgIa32X64.dsc                    |  1 +
>>>  OvmfPkg/OvmfPkgX64.dsc                        |  1 +
>>>  .../FvbServicesRuntimeDxe.inf                 |  2 +
>>>  .../QemuFlash.c                               | 38 +++++++++++++++++--
>>>  5 files changed, 40 insertions(+), 3 deletions(-)
>>>
>>> diff --git a/OvmfPkg/OvmfPkgIa32.dsc b/OvmfPkg/OvmfPkgIa32.dsc
>>> index 56670eefde6b..ff2814c6246e 100644
>>> --- a/OvmfPkg/OvmfPkgIa32.dsc
>>> +++ b/OvmfPkg/OvmfPkgIa32.dsc
>>> @@ -320,6 +320,7 @@ [LibraryClasses.common.DXE_RUNTIME_DRIVER]
>>>    BaseCryptLib|CryptoPkg/Library/BaseCryptLib/RuntimeCryptLib.inf
>>>    PciLib|OvmfPkg/Library/DxePciLibI440FxQ35/DxePciLibI440FxQ35.inf
>>>    QemuFwCfgS3Lib|OvmfPkg/Library/QemuFwCfgS3Lib/DxeQemuFwCfgS3LibFwCfg.inf
>>> +  VmgExitLib|UefiCpuPkg/Library/VmgExitLib/VmgExitLib.inf
>>>
>>>  [LibraryClasses.common.UEFI_DRIVER]
>>>    PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf
>>> diff --git a/OvmfPkg/OvmfPkgIa32X64.dsc b/OvmfPkg/OvmfPkgIa32X64.dsc
>>> index 9897e6889573..212952cfaacd 100644
>>> --- a/OvmfPkg/OvmfPkgIa32X64.dsc
>>> +++ b/OvmfPkg/OvmfPkgIa32X64.dsc
>>> @@ -325,6 +325,7 @@ [LibraryClasses.common.DXE_RUNTIME_DRIVER]
>>>    BaseCryptLib|CryptoPkg/Library/BaseCryptLib/RuntimeCryptLib.inf
>>>    PciLib|OvmfPkg/Library/DxePciLibI440FxQ35/DxePciLibI440FxQ35.inf
>>>    QemuFwCfgS3Lib|OvmfPkg/Library/QemuFwCfgS3Lib/DxeQemuFwCfgS3LibFwCfg.inf
>>> +  VmgExitLib|UefiCpuPkg/Library/VmgExitLib/VmgExitLib.inf
>>>
>>>  [LibraryClasses.common.UEFI_DRIVER]
>>>    PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf
>>> diff --git a/OvmfPkg/OvmfPkgX64.dsc b/OvmfPkg/OvmfPkgX64.dsc
>>> index 59c4f9207fc3..8331fc0b663e 100644
>>> --- a/OvmfPkg/OvmfPkgX64.dsc
>>> +++ b/OvmfPkg/OvmfPkgX64.dsc
>>> @@ -325,6 +325,7 @@ [LibraryClasses.common.DXE_RUNTIME_DRIVER]
>>>    BaseCryptLib|CryptoPkg/Library/BaseCryptLib/RuntimeCryptLib.inf
>>>    PciLib|OvmfPkg/Library/DxePciLibI440FxQ35/DxePciLibI440FxQ35.inf
>>>    QemuFwCfgS3Lib|OvmfPkg/Library/QemuFwCfgS3Lib/DxeQemuFwCfgS3LibFwCfg.inf
>>> +  VmgExitLib|UefiCpuPkg/Library/VmgExitLib/VmgExitLib.inf
>>>
>>>  [LibraryClasses.common.UEFI_DRIVER]
>>>    PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf
>>> diff --git 
>>> a/OvmfPkg/QemuFlashFvbServicesRuntimeDxe/FvbServicesRuntimeDxe.inf 
>>> b/OvmfPkg/QemuFlashFvbServicesRuntimeDxe/FvbServicesRuntimeDxe.inf
>>> index ca6326e833ed..0b7741ac07f8 100644
>>> --- a/OvmfPkg/QemuFlashFvbServicesRuntimeDxe/FvbServicesRuntimeDxe.inf
>>> +++ b/OvmfPkg/QemuFlashFvbServicesRuntimeDxe/FvbServicesRuntimeDxe.inf
>>> @@ -38,6 +38,7 @@ [Sources]
>>>  [Packages]
>>>    MdePkg/MdePkg.dec
>>>    MdeModulePkg/MdeModulePkg.dec
>>> +  UefiCpuPkg/UefiCpuPkg.dec
>>>    OvmfPkg/OvmfPkg.dec
>>>
>>>  [LibraryClasses]
>>> @@ -52,6 +53,7 @@ [LibraryClasses]
>>>    UefiBootServicesTableLib
>>>    UefiDriverEntryPoint
>>>    UefiRuntimeLib
>>> +  VmgExitLib
>>>
>>>  [Guids]
>>>    gEfiEventVirtualAddressChangeGuid   # ALWAYS_CONSUMED
>>
>> These hunks look good.
>>
>>> diff --git a/OvmfPkg/QemuFlashFvbServicesRuntimeDxe/QemuFlash.c 
>>> b/OvmfPkg/QemuFlashFvbServicesRuntimeDxe/QemuFlash.c
>>> index c81c58972bf2..4f3bf690fcad 100644
>>> --- a/OvmfPkg/QemuFlashFvbServicesRuntimeDxe/QemuFlash.c
>>> +++ b/OvmfPkg/QemuFlashFvbServicesRuntimeDxe/QemuFlash.c
>>> @@ -9,7 +9,9 @@
>>>
>>>  #include <Library/BaseMemoryLib.h>
>>>  #include <Library/DebugLib.h>
>>> +#include <Library/MemEncryptSevLib.h>
>>>  #include <Library/PcdLib.h>
>>> +#include <Library/VmgExitLib.h>
>>>
>>>  #include "QemuFlash.h"
>>>
>>> @@ -80,6 +82,20 @@ QemuFlashDetected (
>>>
>>>    DEBUG ((EFI_D_INFO, "QEMU Flash: Attempting flash detection at %p\n", 
>>> Ptr));
>>>
>>> +  if (MemEncryptSevEsIsEnabled()) {
>>> +    //
>>> +    // When SEV-ES is enabled, the check below can result in an infinite
>>> +    // loop with respect to a nested page fault. When the FD behaves as
>>> +    // a ROM, the nested page table entry is read-only. The check below
>>
>> (2) I suggest a slight change to the wording above. Please replace
>>
>>   when the FD behaves as a ROM
>>
>> with
>>
>>   when the memslot is mapped read-only
>>
>> (It's OK to make qemu / kvm references in this code: the name of the
>> file includes "Qemu".)
> 
> Ok.
> 
>>
>>> +    // will cause a nested page fault that cannot be emulated, causing
>>> +    // the instruction to retried over and over. For SEV-ES, assume that
>>> +    // the FD does not behave as FLASH.
>>
>> (3) I would recommend
>>
>>   For SEV-ES, acknowledge that the FD appears as ROM and not as FLASH,
>>   but report FLASH anyway.
> 
> How about if I expand on this to add "because FLASH behavior can be
> simulated using VMGEXIT.", too.

Sure! Thanks!
Laszlo

> 
>>
>>> +    //
>>> +    DEBUG ((DEBUG_INFO,
>>> +      "QEMU Flash: SEV-ES enabled, assuming FD behaves as FLASH\n"));
>>> +    return TRUE;
>>> +  }
>>> +
>>>    OriginalUint8 = *Ptr;
>>>    *Ptr = CLEAR_STATUS_CMD;
>>>    ProbeUint8 = *Ptr;
>>> @@ -147,6 +163,21 @@ QemuFlashRead (
>>>  }
>>>
>>>
>>> +STATIC
>>> +VOID
>>> +QemuFlashPtrWrite (
>>> +  IN        volatile UINT8                      *Ptr,
>>> +  IN        UINT8                               Value
>>> +  )
>>> +{
>>> +  if (MemEncryptSevEsIsEnabled()) {
>>> +    VmgMmioWrite ((UINT8 *) Ptr, &Value, 1);
>>> +  } else {
>>> +    *Ptr = Value;
>>> +  }
>>> +}
>>> +
>>> +
>>>  /**
>>>    Write to QEMU Flash
>>>
>>
>> (4) This change will break the "FvbServicesSmm.inf" build of this module.
>>
>> (Because, you have -- correctly -- added the VmgExitLib class to
>> "FvbServicesRuntimeDxe.inf" only.)
>>
>> Please:
>>
>> - create two implementations of the QemuFlashPtrWrite() function, one in
>> "QemuFlashDxe.c", and another in "QemuFlashSmm.c".
>>
>> - the former should be the function shown above, the latter should only
>> perform the direct assignment.
>>
>> - the '#include <Library/VmgExitLib.h>' directive should also be moved
>> to "QemuFlashDxe.c".
>>
>> - the prototype for QemuFlashPtrWrite() should be added to "QemuFlash.h"
>> please.
> 
> Ah, nice catch.  I'll do that.
> 
> Thanks,
> Tom
> 
>>
>>> @@ -181,8 +212,9 @@ QemuFlashWrite (
>>>    //
>>>    Ptr = QemuFlashPtr (Lba, Offset);
>>>    for (Loop = 0; Loop < *NumBytes; Loop++) {
>>> -    *Ptr = WRITE_BYTE_CMD;
>>> -    *Ptr = Buffer[Loop];
>>> +    QemuFlashPtrWrite (Ptr, WRITE_BYTE_CMD);
>>> +    QemuFlashPtrWrite (Ptr, Buffer[Loop]);
>>> +
>>>      Ptr++;
>>>    }
>>>
>>> @@ -190,7 +222,7 @@ QemuFlashWrite (
>>>    // Restore flash to read mode
>>>    //
>>>    if (*NumBytes > 0) {
>>> -    *(Ptr - 1) = READ_ARRAY_CMD;
>>> +    QemuFlashPtrWrite (Ptr - 1, READ_ARRAY_CMD);
>>>    }
>>>
>>>    return EFI_SUCCESS;
>>>
>>
>> With (1) and (4) fixed, and with (2) and (3) optionally fixed (i.e., if
>> you agree):
>>
>> Reviewed-by: Laszlo Ersek <ler...@redhat.com>
>>
>> Thanks
>> Laszlo
>>
>>
>> 
>>
> 


-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.

View/Reply Online (#51187): https://edk2.groups.io/g/devel/message/51187
Mute This Topic: https://groups.io/mt/60973139/21656
Group Owner: devel+ow...@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub  [arch...@mail-archive.com]
-=-=-=-=-=-=-=-=-=-=-=-

Reply via email to