On Mar 25, 2021, at 3:54 AM, Brijesh Singh <brijesh.singh@amd.com> wrote:

On 3/24/21 9:49 PM, gaoliming wrote:
Is this API X64 only? Or IA32 and X64 both?


Theoretically the instruction is available on both IA32 and X64 but its
used only in X64. AMD SEV, SEV-ES and SEV-SNP support is available for
X64 arch only. I was not sure if the EDK2 community is okay with the
dead-code. Do you think it still makes sense to add the IA32 API for it ?


If this is only implemented for MDE_CPU_X64 should it be only defined in BaseLIib.h for MDE_CPU_X64? vs. "#endif // defined (MDE_CPU_IA32) || defined (MDE_CPU_X64)”?

I think today we may only have types in MDE_CPU_X64 only and all the lib functions are in "#if defined (MDE_CPU_IA32) || defined (MDE_CPU_X64)”. So we should think about adding an IA32 function implementation or not defining the function to exist for MDE_CPU_IA32 in BaseLib.h?

What do other people think?

Thanks,

Andrew Fish



Thanks
Liming
-----邮件原件-----
发件人: devel@edk2.groups.io <devel@edk2.groups.io> 代表 Brijesh Singh
发送时间: 2021年3月24日 23:32
收件人: devel@edk2.groups.io
抄送: Brijesh Singh <brijesh.singh@amd.com>; James Bottomley
<jejb@linux.ibm.com>; Min Xu <min.m.xu@intel.com>; Jiewen Yao
<jiewen.yao@intel.com>; Tom Lendacky <thomas.lendacky@amd.com>;
Jordan Justen <jordan.l.justen@intel.com>; Ard Biesheuvel
<ardb+tianocore@kernel.org>; Laszlo Ersek <lersek@redhat.com>
主题: [edk2-devel] [RFC PATCH 09/19] MdePkg: Add AsmPvalidate() support

BZ: https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Fbugzilla.tianocore.org%2Fshow_bug.cgi%3Fid%3D3275&amp;data=04%7C01%7Cbrijesh.singh%40amd.com%7C125d11ea64cf4f4ecd2108d8ef38a8e7%7C3dd8961fe4884e608e11a82d994e183d%7C0%7C0%7C637522373939810930%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C1000&amp;sdata=f3fM%2Fnw3X1lHhf7SPKTxDOLo0GcnU465yvyf0IIyD80%3D&amp;reserved=0

The PVALIDATE instruction validates or rescinds validation of a guest
page RMP entry. Upon completion, a return code is stored in EAX, rFLAGS
bits OF, ZF, AF, PF and SF are set based on this return code. If the
instruction completed succesfully, the rFLAGS bit CF indicates if the
contents of the RMP entry were changed or not.

For more information about the instruction see AMD APM volume 3.

Cc: James Bottomley <jejb@linux.ibm.com>
Cc: Min Xu <min.m.xu@intel.com>
Cc: Jiewen Yao <jiewen.yao@intel.com>
Cc: Tom Lendacky <thomas.lendacky@amd.com>
Cc: Jordan Justen <jordan.l.justen@intel.com>
Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
Cc: Laszlo Ersek <lersek@redhat.com>
Signed-off-by: Brijesh Singh <brijesh.singh@amd.com>
---
MdePkg/Include/Library/BaseLib.h          | 37 +++++++++++++++++
MdePkg/Library/BaseLib/BaseLib.inf        |  1 +
MdePkg/Library/BaseLib/X64/Pvalidate.nasm | 43 ++++++++++++++++++++
3 files changed, 81 insertions(+)

diff --git a/MdePkg/Include/Library/BaseLib.h
b/MdePkg/Include/Library/BaseLib.h
index 1171a0ffb5..fee27e9a1b 100644
--- a/MdePkg/Include/Library/BaseLib.h
+++ b/MdePkg/Include/Library/BaseLib.h
@@ -7495,5 +7495,42 @@ PatchInstructionX86 (
  IN  UINTN                    ValueSize
  );

+/**
+ Execute a PVALIDATE instruction to validate or rescnids validation of a
guest
+ page's RMP entry.
+
+ Upon completion, in addition to the return value the instruction also
updates
+ the eFlags. A caller must check both the return code as well as eFlags
to
+ determine if the RMP entry has been updated.
+
+ The function is available on x64.
+
+ @param[in]    Address        The guest virtual address to validate.
+ @param[in]    PageSize       The page size to use.
+ @param[i]     Validate       Validate or rescinds.
+ @param[out]   Eflags         The value of Eflags after PVALIDATE
completion.
+
+ @retval       PvalidateRetValue  The return value from the PVALIDATE
instruction.
+**/
+typedef enum {
+  PVALIDATE_PAGE_SIZE_4K = 0,
+  PVALIDATE_PAGE_SIZE_2M,
+} PvalidatePageSize;
+
+typedef enum {
+  PVALIDATE_RET_SUCCESS = 0,
+  PVALIDATE_RET_FAIL_INPUT = 1,
+  PVALIDATE_RET_FAIL_SIZEMISMATCH = 6,
+} PvalidateRetValue;
+
+PvalidateRetValue
+EFIAPI
+AsmPvalidate (
+  IN   PvalidatePageSize       PageSize,
+  IN   BOOLEAN                 Validate,
+  IN   UINTN                   Address,
+  OUT  IA32_EFLAGS32           *Eflags
+  );
+
#endif // defined (MDE_CPU_IA32) || defined (MDE_CPU_X64)
#endif // !defined (__BASE_LIB__)
diff --git a/MdePkg/Library/BaseLib/BaseLib.inf
b/MdePkg/Library/BaseLib/BaseLib.inf
index 3b85c56c3c..01aa5cc7a4 100644
--- a/MdePkg/Library/BaseLib/BaseLib.inf
+++ b/MdePkg/Library/BaseLib/BaseLib.inf
@@ -319,6 +319,7 @@
  X64/RdRand.nasm
  X64/XGetBv.nasm
  X64/VmgExit.nasm
+  X64/Pvalidate.nasm
  ChkStkGcc.c  | GCC

[Sources.EBC]
diff --git a/MdePkg/Library/BaseLib/X64/Pvalidate.nasm
b/MdePkg/Library/BaseLib/X64/Pvalidate.nasm
new file mode 100644
index 0000000000..f2aba114ac
--- /dev/null
+++ b/MdePkg/Library/BaseLib/X64/Pvalidate.nasm
@@ -0,0 +1,43 @@

+;--------------------------------------------------------------------------
---
+;
+; Copyright (c) 2020-2021, AMD. All rights reserved.<BR>
+; SPDX-License-Identifier: BSD-2-Clause-Patent
+;
+; Module Name:
+;
+;   Pvalidate.Asm
+;
+; Abstract:
+;
+;   AsmPvalidate function
+;
+; Notes:
+;

+;--------------------------------------------------------------------------
---
+
+    SECTION .text
+

+;--------------------------------------------------------------------------
---
+;  PvalidateRetValue
+;  EFIAPI
+;  AsmPvalidate (
+;    IN   UINT32  RmpPageSize
+;    IN   UINT32  Validate,
+;    IN   UINTN   Address,
+;    OUT  UINTN  *Eflags,
+;    )

+;--------------------------------------------------------------------------
---
+global ASM_PFX(AsmPvalidate)
+ASM_PFX(AsmPvalidate):
+  mov     rax, r8
+
+  ; PVALIDATE instruction opcode
+  DB      0xF2, 0x0F, 0x01, 0xFF
+
+  ; Read the Eflags
+  pushfq
+  pop     r8
+  mov     [r9], r8
+
+  ; The PVALIDATE instruction returns the status in rax register.
+  ret
--
2.17.1