On 6/10/20 7:26 AM, Laszlo Ersek wrote:
> Hi Tom,
> 
> On 06/05/20 15:27, Tom Lendacky wrote:
>> The base VmgExitLib library provides a default limited interface. As it
>> does not provide full support, create an OVMF version of this library to
>> begin the process of providing full support of SEV-ES within OVMF.
>>
>> SEV-ES support is only provided for X64 builds, so only OvmfPkgX64.dsc is
>> updated to make use of the OvmfPkg version of the library.
>>
>> Cc: Jordan Justen <jordan.l.jus...@intel.com>
>> Cc: Laszlo Ersek <ler...@redhat.com>
>> Cc: Ard Biesheuvel <ard.biesheu...@arm.com>
>> Acked-by: Laszlo Ersek <ler...@redhat.com>
>> Signed-off-by: Tom Lendacky <thomas.lenda...@amd.com>
>> ---
>>  OvmfPkg/OvmfPkgX64.dsc                        |   2 +-
>>  OvmfPkg/Library/VmgExitLib/VmgExitLib.inf     |  36 +++++
>>  OvmfPkg/Library/VmgExitLib/VmgExitLib.c       | 159 ++++++++++++++++++++
>>  OvmfPkg/Library/VmgExitLib/VmgExitVcHandler.c |  81 ++++++++++
>>  4 files changed, 277 insertions(+), 1 deletion(-)
>>
>> diff --git a/OvmfPkg/OvmfPkgX64.dsc b/OvmfPkg/OvmfPkgX64.dsc
>> index 0b9189ab1e38..b5f3859420d0 100644
>> --- a/OvmfPkg/OvmfPkgX64.dsc
>> +++ b/OvmfPkg/OvmfPkgX64.dsc
>> @@ -232,7 +232,7 @@ [LibraryClasses]
>>
>>  [LibraryClasses.common]
>>    BaseCryptLib|CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf
>> -  VmgExitLib|UefiCpuPkg/Library/VmgExitLibNull/VmgExitLibNull.inf
>> +  VmgExitLib|OvmfPkg/Library/VmgExitLib/VmgExitLib.inf
>>
>>  [LibraryClasses.common.SEC]
>>    TimerLib|OvmfPkg/Library/AcpiTimerLib/BaseRomAcpiTimerLib.inf
>> diff --git a/OvmfPkg/Library/VmgExitLib/VmgExitLib.inf 
>> b/OvmfPkg/Library/VmgExitLib/VmgExitLib.inf
>> new file mode 100644
>> index 000000000000..8acdee2349b4
>> --- /dev/null
>> +++ b/OvmfPkg/Library/VmgExitLib/VmgExitLib.inf
>> @@ -0,0 +1,36 @@
>> +## @file
>> +#  VMGEXIT Support Library.
>> +#
>> +#  Copyright (C) 2020, Advanced Micro Devices, Inc. All rights reserved.<BR>
>> +#  SPDX-License-Identifier: BSD-2-Clause-Patent
>> +#
>> +##
>> +
>> +[Defines]
>> +  INF_VERSION                    = 0x00010005
>> +  BASE_NAME                      = VmgExitLib
>> +  FILE_GUID                      = 0e923c25-13cd-430b-8714-ffe85652a97b
>> +  MODULE_TYPE                    = BASE
>> +  VERSION_STRING                 = 1.0
>> +  LIBRARY_CLASS                  = VmgExitLib
>> +
>> +#
>> +# The following information is for reference only and not required by the 
>> build tools.
>> +#
>> +#  VALID_ARCHITECTURES           = X64
>> +#
>> +
>> +[Sources.common]
>> +  VmgExitLib.c
>> +  VmgExitVcHandler.c
>> +
>> +[Packages]
>> +  MdePkg/MdePkg.dec
>> +  UefiCpuPkg/UefiCpuPkg.dec
>> +  OvmfPkg/OvmfPkg.dec
>> +
>> +[LibraryClasses]
>> +  BaseLib
>> +  DebugLib
>> +  BaseMemoryLib
>> +
> 
> (1) Please keep the individual sections sorted alphabetically.

Will do.

> 
>> diff --git a/OvmfPkg/Library/VmgExitLib/VmgExitLib.c 
>> b/OvmfPkg/Library/VmgExitLib/VmgExitLib.c
>> new file mode 100644
>> index 000000000000..0ca164a33eb4
>> --- /dev/null
>> +++ b/OvmfPkg/Library/VmgExitLib/VmgExitLib.c
>> @@ -0,0 +1,159 @@
>> +/** @file
>> +  VMGEXIT Support Library.
>> +
>> +  Copyright (C) 2020, Advanced Micro Devices, Inc. All rights reserved.<BR>
>> +  SPDX-License-Identifier: BSD-2-Clause-Patent
>> +
>> +**/
>> +
>> +#include <Base.h>
>> +#include <Uefi.h>
>> +#include <Library/BaseMemoryLib.h>
>> +#include <Library/VmgExitLib.h>
>> +#include <Register/Amd/Msr.h>
>> +
>> +/**
>> +  Check for VMGEXIT error
>> +
>> +  Check if the hypervisor has returned an error after completion of the 
>> VMGEXIT
>> +  by examining the SwExitInfo1 field of the GHCB.
>> +
>> +  @param[in]  Ghcb       A pointer to the GHCB
>> +
>> +  @return  0             VMGEXIT succeeded.
>> +  @return  Others        VMGEXIT processing did not succeed. Exception 
>> number to
>> +                         be propagated.
> 
> (2) You misunderstood my @return / @retval explanation from v8:
> 
>   
> https://nam11.safelinks.protection.outlook.com/?url=http%3A%2F%2Fmid.mail-archive.com%2F23c7dfb3-56ac-b080-2736-687cd11d51a0%40redhat.com&amp;data=02%7C01%7Cthomas.lendacky%40amd.com%7C23a76c28475f4b34b57208d80d39989b%7C3dd8961fe4884e608e11a82d994e183d%7C0%7C0%7C637273888322294989&amp;sdata=bgpq7w3kRE4ZVgnu9vgSDxvbvrHmBUio3urYWP%2B5qWE%3D&amp;reserved=0
>   
> https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Fedk2.groups.io%2Fg%2Fdevel%2Fmessage%2F60047&amp;data=02%7C01%7Cthomas.lendacky%40amd.com%7C23a76c28475f4b34b57208d80d39989b%7C3dd8961fe4884e608e11a82d994e183d%7C0%7C0%7C637273888322294989&amp;sdata=i7lzz2cYm3bdyC06bLBqwOguzMi%2BPHSeJV%2BU%2BzDqSOM%3D&amp;reserved=0
> 
> We have two formats.
> 
> (2a) "@return  Natural language explanation"
> 
> In this format, there is *NO CONSTANT* in the documentation. The comment
> only explains in natural language what the function returns. In the
> message linked above, I brought the example:
> 
>   @return  IOIO event information values.
> 
> That was *not* a typo.
> 
> (2b) The other format is "@retval CONSTANT  Natural language
> explanation".
> 
> In this case, the exact return value is given, and then explained.
> 
> 
> In the v8 review, I mentioned that "@retval Others" is wrong, even
> though it is used in several places in the edk2 tree. That's because
> "Others" is not a constant. The right way to put "@retval Others" is to
> replace it with *just* "@return". In other words, *drop* the "Others"
> non-constant, replace "@retval" with "@return", and reformulate the
> natural language text.
> 
> In the v8 review, I also mentioned that "@retval Natural language
> explanation" is also wrong, because it's either missing a constant, or
> it should use "@return".
> 
> Unfortunately, in response, you seem to have replaced
> 
>   @retval  0
>   @retval  Others
> 
> with
> 
>   @return  0
>   @return  Others
> 
> (i.e., just replaced "@retval" with "@return"). And that update is
> wrong, on *both* lines:
> 
> - "@retval 0" was correct. It should not have been updated.
> 
> - "@retval  Others" was indeed wrong, but "@return  Others" is *also*
> wrong. It should be just "@return", not "@return Others".
> 
> Specifically, the right comment would be:
> 
>   @retval 0  VMGEXIT succeeded.
> 
>   @return    Exception number to be propagated. VMGEXIT processing did
>              not succeed.
> 
> If you read it aloud, it will make sense.
> 
> Anyway, I'm exhausted. We can address this in a follow-up series, if we
> want to. Keep the ACK, and no v10 is needed just for these comments.

Ok, I've made the changes throughout the series in the OvmfPkg library and
in the UefiCpuPkg NULL library. If there's a v10, then they'll be
incorporated.

Thanks,
Tom

> 
> Thanks
> Laszlo
> 
> 
>> +
>> +**/
>> +STATIC
>> +UINT64
>> +VmgExitErrorCheck (
>> +  IN GHCB                *Ghcb
>> +  )
>> +{
>> +  GHCB_EVENT_INJECTION  Event;
>> +  GHCB_EXIT_INFO        ExitInfo;
>> +  UINT64                Status;
>> +
>> +  ExitInfo.Uint64 = Ghcb->SaveArea.SwExitInfo1;
>> +  ASSERT ((ExitInfo.Elements.Lower32Bits == 0) ||
>> +          (ExitInfo.Elements.Lower32Bits == 1));
>> +
>> +  Status = 0;
>> +  if (ExitInfo.Elements.Lower32Bits == 0) {
>> +    return Status;
>> +  }
>> +
>> +  if (ExitInfo.Elements.Lower32Bits == 1) {
>> +    ASSERT (Ghcb->SaveArea.SwExitInfo2 != 0);
>> +
>> +    //
>> +    // Check that the return event is valid
>> +    //
>> +    Event.Uint64 = Ghcb->SaveArea.SwExitInfo2;
>> +    if (Event.Elements.Valid &&
>> +        Event.Elements.Type == GHCB_EVENT_INJECTION_TYPE_EXCEPTION) {
>> +      switch (Event.Elements.Vector) {
>> +      case GP_EXCEPTION:
>> +      case UD_EXCEPTION:
>> +        //
>> +        // Use returned event as return code
>> +        //
>> +        Status = Event.Uint64;
>> +      }
>> +    }
>> +  }
>> +
>> +  if (Status == 0) {
>> +    GHCB_EVENT_INJECTION  GpEvent;
>> +
>> +    GpEvent.Uint64 = 0;
>> +    GpEvent.Elements.Vector = GP_EXCEPTION;
>> +    GpEvent.Elements.Type   = GHCB_EVENT_INJECTION_TYPE_EXCEPTION;
>> +    GpEvent.Elements.Valid  = 1;
>> +
>> +    Status = GpEvent.Uint64;
>> +  }
>> +
>> +  return Status;
>> +}
>> +
>> +/**
>> +  Perform VMGEXIT.
>> +
>> +  Sets the necessary fields of the GHCB, invokes the VMGEXIT instruction and
>> +  then handles the return actions.
>> +
>> +  @param[in, out]  Ghcb       A pointer to the GHCB
>> +  @param[in]       ExitCode   VMGEXIT code to be assigned to the SwExitCode
>> +                              field of the GHCB.
>> +  @param[in]       ExitInfo1  VMGEXIT information to be assigned to the
>> +                              SwExitInfo1 field of the GHCB.
>> +  @param[in]       ExitInfo2  VMGEXIT information to be assigned to the
>> +                              SwExitInfo2 field of the GHCB.
>> +
>> +  @return  0                  VMGEXIT succeeded.
>> +  @return  Others             VMGEXIT processing did not succeed. Exception
>> +                              event to be propagated.
>> +
>> +**/
>> +UINT64
>> +EFIAPI
>> +VmgExit (
>> +  IN OUT GHCB                *Ghcb,
>> +  IN     UINT64              ExitCode,
>> +  IN     UINT64              ExitInfo1,
>> +  IN     UINT64              ExitInfo2
>> +  )
>> +{
>> +  Ghcb->SaveArea.SwExitCode = ExitCode;
>> +  Ghcb->SaveArea.SwExitInfo1 = ExitInfo1;
>> +  Ghcb->SaveArea.SwExitInfo2 = ExitInfo2;
>> +
>> +  //
>> +  // Guest memory is used for the guest-hypervisor communication, so fence
>> +  // the invocation of the VMGEXIT instruction to ensure GHCB accesses are
>> +  // synchronized properly.
>> +  //
>> +  MemoryFence ();
>> +  AsmVmgExit ();
>> +  MemoryFence ();
>> +
>> +  return VmgExitErrorCheck (Ghcb);
>> +}
>> +
>> +/**
>> +  Perform pre-VMGEXIT initialization/preparation.
>> +
>> +  Performs the necessary steps in preparation for invoking VMGEXIT. Must be
>> +  called before setting any fields within the GHCB.
>> +
>> +  @param[in, out]  Ghcb       A pointer to the GHCB
>> +
>> +**/
>> +VOID
>> +EFIAPI
>> +VmgInit (
>> +  IN OUT GHCB                *Ghcb
>> +  )
>> +{
>> +  SetMem (&Ghcb->SaveArea, sizeof (Ghcb->SaveArea), 0);
>> +}
>> +
>> +/**
>> +  Perform post-VMGEXIT cleanup.
>> +
>> +  Performs the necessary steps to cleanup after invoking VMGEXIT. Must be
>> +  called after obtaining needed fields within the GHCB.
>> +
>> +  @param[in, out]  Ghcb       A pointer to the GHCB
>> +
>> +**/
>> +VOID
>> +EFIAPI
>> +VmgDone (
>> +  IN OUT GHCB                *Ghcb
>> +  )
>> +{
>> +}
>> +
>> diff --git a/OvmfPkg/Library/VmgExitLib/VmgExitVcHandler.c 
>> b/OvmfPkg/Library/VmgExitLib/VmgExitVcHandler.c
>> new file mode 100644
>> index 000000000000..b6a955ed8088
>> --- /dev/null
>> +++ b/OvmfPkg/Library/VmgExitLib/VmgExitVcHandler.c
>> @@ -0,0 +1,81 @@
>> +/** @file
>> +  X64 #VC Exception Handler functon.
>> +
>> +  Copyright (C) 2020, Advanced Micro Devices, Inc. All rights reserved.<BR>
>> +  SPDX-License-Identifier: BSD-2-Clause-Patent
>> +
>> +**/
>> +
>> +#include <Base.h>
>> +#include <Uefi.h>
>> +#include <Library/BaseMemoryLib.h>
>> +#include <Library/VmgExitLib.h>
>> +#include <Register/Amd/Msr.h>
>> +
>> +/**
>> +  Handle a #VC exception.
>> +
>> +  Performs the necessary processing to handle a #VC exception.
>> +
>> +  @param[in, out]  ExceptionType  Pointer to an EFI_EXCEPTION_TYPE to be set
>> +                                  as value to use on error.
>> +  @param[in, out]  SystemContext  Pointer to EFI_SYSTEM_CONTEXT
>> +
>> +  @retval  EFI_SUCCESS            Exception handled
>> +  @retval  EFI_UNSUPPORTED        #VC not supported, (new) exception value 
>> to
>> +                                  propagate provided
>> +  @retval  EFI_PROTOCOL_ERROR     #VC handling failed, (new) exception 
>> value to
>> +                                  propagate provided
>> +
>> +**/
>> +EFI_STATUS
>> +EFIAPI
>> +VmgExitHandleVc (
>> +  IN OUT EFI_EXCEPTION_TYPE  *ExceptionType,
>> +  IN OUT EFI_SYSTEM_CONTEXT  SystemContext
>> +  )
>> +{
>> +  MSR_SEV_ES_GHCB_REGISTER  Msr;
>> +  EFI_SYSTEM_CONTEXT_X64    *Regs;
>> +  GHCB                      *Ghcb;
>> +  UINT64                    ExitCode, Status;
>> +  EFI_STATUS                VcRet;
>> +
>> +  VcRet = EFI_SUCCESS;
>> +
>> +  Msr.GhcbPhysicalAddress = AsmReadMsr64 (MSR_SEV_ES_GHCB);
>> +  ASSERT (Msr.GhcbInfo.Function == 0);
>> +  ASSERT (Msr.Ghcb != 0);
>> +
>> +  Regs = SystemContext.SystemContextX64;
>> +  Ghcb = Msr.Ghcb;
>> +
>> +  VmgInit (Ghcb);
>> +
>> +  ExitCode = Regs->ExceptionData;
>> +  switch (ExitCode) {
>> +  default:
>> +    Status = VmgExit (Ghcb, SVM_EXIT_UNSUPPORTED, ExitCode, 0);
>> +    if (Status == 0) {
>> +      Regs->ExceptionData = 0;
>> +      *ExceptionType = GP_EXCEPTION;
>> +    } else {
>> +      GHCB_EVENT_INJECTION  Event;
>> +
>> +      Event.Uint64 = Status;
>> +      if (Event.Elements.ErrorCodeValid != 0) {
>> +        Regs->ExceptionData = Event.Elements.ErrorCode;
>> +      } else {
>> +        Regs->ExceptionData = 0;
>> +      }
>> +
>> +      *ExceptionType = Event.Elements.Vector;
>> +    }
>> +
>> +    VcRet = EFI_PROTOCOL_ERROR;
>> +  }
>> +
>> +  VmgDone (Ghcb);
>> +
>> +  return VcRet;
>> +}
>>
> 

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

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

Reply via email to