[edk2-devel] [PATCH V2 3/3] OvmfPkg: Implement library support for TdxLib SEC and DXE on OVMF

Min Xu min.m.xu at intel.com
Tue Mar 9 03:16:58 UTC 2021


The base TdxLib in MdePkg/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 TDX in OVMF.

Cc: Jordan Justen <jordan.l.justen at intel.com>
Cc: Laszlo Ersek <lersek at redhat.com>
Cc: Jiewen Yao <jiewen.yao at intel.com>

Signed-off-by: Min Xu <min.m.xu at intel.com>
Signed-off-by: Doug Reiland <doug.reiland at intel.com>
---
 OvmfPkg/Library/TdxLib/AcceptPages.c     |  68 ++++++++
 OvmfPkg/Library/TdxLib/Rtmr.c            |  80 +++++++++
 OvmfPkg/Library/TdxLib/TdReport.c        | 102 +++++++++++
 OvmfPkg/Library/TdxLib/TdxLib.inf        |  48 ++++++
 OvmfPkg/Library/TdxLib/TdxLibSec.inf     |  45 +++++
 OvmfPkg/Library/TdxLib/X64/Tdcall.nasm   | 125 ++++++++++++++
 OvmfPkg/Library/TdxLib/X64/Tdvmcall.nasm | 211 +++++++++++++++++++++++
 7 files changed, 679 insertions(+)
 create mode 100644 OvmfPkg/Library/TdxLib/AcceptPages.c
 create mode 100644 OvmfPkg/Library/TdxLib/Rtmr.c
 create mode 100644 OvmfPkg/Library/TdxLib/TdReport.c
 create mode 100644 OvmfPkg/Library/TdxLib/TdxLib.inf
 create mode 100644 OvmfPkg/Library/TdxLib/TdxLibSec.inf
 create mode 100644 OvmfPkg/Library/TdxLib/X64/Tdcall.nasm
 create mode 100644 OvmfPkg/Library/TdxLib/X64/Tdvmcall.nasm

diff --git a/OvmfPkg/Library/TdxLib/AcceptPages.c b/OvmfPkg/Library/TdxLib/AcceptPages.c
new file mode 100644
index 000000000000..3848bb6a95a4
--- /dev/null
+++ b/OvmfPkg/Library/TdxLib/AcceptPages.c
@@ -0,0 +1,68 @@
+/** @file
+
+  There are 4 defined types in TD memory.
+  Unaccepted memory is a special type of private memory. The OVMF must
+  invoke TDCALL [TDG.MEM.PAGE.ACCEPT] the unaccepted memory before use it.
+
+  Copyright (c) 2020 - 2021, Intel Corporation. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <Library/BaseLib.h>
+#include <Library/DebugLib.h>
+#include <IndustryStandard/Tdx.h>
+#include <Library/TdxLib.h>
+#include <Library/BaseMemoryLib.h>
+
+UINT64  mNumberOfDuplicatedAcceptedPages;
+
+/**
+  This function accept a pending private page, and initialize the page to
+  all-0 using the TD ephemeral private key.
+
+  @param[in]  StartAddress           Guest physical address of the private
+                                     page to accept.
+  @param[in]  NumberOfPages          Number of the pages to be accepted.
+
+  @return EFI_SUCCESS
+**/
+EFI_STATUS
+EFIAPI
+TdAcceptPages (
+  IN UINT64  StartAddress,
+  IN UINT64  NumberOfPages
+  )
+{
+  UINT64  Address;
+  UINT64  Status;
+  UINT64  Index;
+
+  //
+  // Determine if we need to accept pages before use
+  //
+  if (FixedPcdGetBool(PcdUseTdxAcceptPage) == FALSE) {
+     return EFI_SUCCESS;
+  }
+
+  Address = StartAddress;
+
+  for( Index = 0; Index < NumberOfPages; Index++) {
+    Status = TdCall(TDCALL_TDACCEPTPAGE,Address, 0, 0, 0);
+    if (Status != TDX_EXIT_REASON_SUCCESS) {
+        if ((Status & ~0xFFULL) == TDX_EXIT_REASON_PAGE_ALREADY_ACCEPTED) {
+          ++mNumberOfDuplicatedAcceptedPages;
+          DEBUG((DEBUG_VERBOSE, "Address %llx already accepted. Total number of already accepted pages %ld\n",
+            Address, mNumberOfDuplicatedAcceptedPages));
+        } else {
+          DEBUG((DEBUG_ERROR, "Address %llx failed to be accepted. Error = %ld\n",
+            Address, Status));
+          ASSERT(Status == TDX_EXIT_REASON_SUCCESS);
+        }
+    }
+    Address += EFI_PAGE_SIZE;
+  }
+  return EFI_SUCCESS;
+}
+
diff --git a/OvmfPkg/Library/TdxLib/Rtmr.c b/OvmfPkg/Library/TdxLib/Rtmr.c
new file mode 100644
index 000000000000..a4b36b6c4bef
--- /dev/null
+++ b/OvmfPkg/Library/TdxLib/Rtmr.c
@@ -0,0 +1,80 @@
+/** @file
+
+  Extends one of the RTMR measurement registers in TDCS with the provided
+  extension data in memory.
+
+  Copyright (c) 2020 - 2021, Intel Corporation. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <Library/BaseLib.h>
+#include <Library/DebugLib.h>
+#include <Library/TdxLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <IndustryStandard/Tpm20.h>
+#include <IndustryStandard/Tdx.h>
+#include <Protocol/Tdx.h>
+
+#define RTMR_COUNT  4
+
+/**
+  This function extends one of the RTMR measurement register
+  in TDCS with the provided extension data in memory.
+  RTMR extending supports SHA384 which length is 48 bytes.
+
+  @param[in]  Data      Point to the data to be extended
+  @param[in]  DataLen   Length of the data. Must be 48
+  @param[in]  Index     RTMR index
+
+  @return EFI_SUCCESS
+  @return EFI_INVALID_PARAMETER
+  @return EFI_DEVICE_ERROR
+
+**/
+EFI_STATUS
+EFIAPI
+TdExtendRtmr(
+  IN  UINT32  *Data,
+  IN  UINT32  DataLen,
+  IN  UINT8   Index
+  )
+{
+  EFI_STATUS            Status;
+  UINT64                *Buffer;
+  UINT64                TdCallStatus;
+
+  Status = EFI_SUCCESS;
+
+  ASSERT(Index >= 0 && Index < RTMR_COUNT);
+  ASSERT(DataLen == SHA384_DIGEST_SIZE);
+
+  //
+  // Allocate 64B aligned mem to hold the sha384 hash value
+  //
+  Buffer = AllocateAlignedPages(EFI_SIZE_TO_PAGES(SHA384_DIGEST_SIZE), 64);
+  if(Data == NULL){
+    return EFI_OUT_OF_RESOURCES;
+  }
+  CopyMem(Buffer, Data, SHA384_DIGEST_SIZE);
+
+  TdCallStatus = TdCall(TDCALL_TDEXTENDRTMR, (UINT64)Buffer, Index, 0, 0);
+
+  if(TdCallStatus == TDX_EXIT_REASON_SUCCESS){
+    Status = EFI_SUCCESS;
+  }else if(TdCallStatus == TDX_EXIT_REASON_OPERAND_INVALID){
+    Status = EFI_INVALID_PARAMETER;
+  }else{
+    Status = EFI_DEVICE_ERROR;
+  }
+
+  if(Status != EFI_SUCCESS){
+    DEBUG((DEBUG_ERROR, "Error returned from TdExtendRtmr call - 0x%lx\n", TdCallStatus));
+  }
+
+  FreeAlignedPages(Buffer, EFI_SIZE_TO_PAGES(SHA384_DIGEST_SIZE));
+
+  return Status;
+}
diff --git a/OvmfPkg/Library/TdxLib/TdReport.c b/OvmfPkg/Library/TdxLib/TdReport.c
new file mode 100644
index 000000000000..ace213bcf467
--- /dev/null
+++ b/OvmfPkg/Library/TdxLib/TdReport.c
@@ -0,0 +1,102 @@
+/** @file
+
+  Retrieve TDREPORT_STRUCT structure from TDX
+
+  Copyright (c) 2020 - 2021, Intel Corporation. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <Library/BaseLib.h>
+#include <Library/DebugLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <IndustryStandard/Tdx.h>
+#include <Library/TdxLib.h>
+
+#define REPORT_STRUCT_SIZE    1024
+#define ADDITIONAL_DATA_SIZE  64
+
+/**
+  This function retrieve TDREPORT_STRUCT structure from TDX.
+  The struct contains the measurements/configuration information of
+  the guest TD that called the function, measurements/configuratio
+  information of the TDX-SEAM module and a REPORTMACSTRUCT.
+  The REPORTMACSTRUCT is integrity protected with a MAC and
+  contains the hash of the measurements and configuration
+  as well as additional REPORTDATA provided by the TD software.
+
+  AdditionalData, a 64-byte value, is provided by the guest TD
+  to be included in the TDREPORT
+
+  @param[in,out]  Report             Holds the TEREPORT_STRUCT.
+  @param[in]      ReportSize         Size of the report. It must be
+                                     larger than 1024B.
+  @param[in]      AdditionalData     Point to the additional data.
+  @param[in]      AdditionalDataSize Size of the additional data.
+                                     If AdditionalData != NULL, then
+                                     this value must be 64B.
+
+  @return EFI_SUCCESS
+  @return EFI_INVALID_PARAMETER
+  @return EFI_DEVICE_ERROR
+
+**/
+EFI_STATUS
+EFIAPI
+TdReport(
+  IN OUT UINT8  *Report,
+  IN  UINT32    ReportSize,
+  IN  UINT8     *AdditionalData,
+  IN  UINT32    AdditionalDataSize
+  )
+
+{
+  EFI_STATUS  Status;
+  UINT64      *Data;
+  UINT64      *Report_Struct;
+  UINT64      *Report_Data;
+  UINT64      TdCallStatus;
+
+  if(ReportSize < REPORT_STRUCT_SIZE){
+    return EFI_INVALID_PARAMETER;
+  }
+
+  if(AdditionalData != NULL && AdditionalDataSize != ADDITIONAL_DATA_SIZE){
+    return EFI_INVALID_PARAMETER;
+  }
+
+  Data = AllocatePages(EFI_SIZE_TO_PAGES(REPORT_STRUCT_SIZE + ADDITIONAL_DATA_SIZE));
+  if(Data == NULL){
+    return EFI_OUT_OF_RESOURCES;
+  }
+
+  Report_Struct = Data;
+  Report_Data = Data + REPORT_STRUCT_SIZE;
+  if(AdditionalData != NULL){
+    CopyMem(Report_Data, AdditionalData, ADDITIONAL_DATA_SIZE);
+  }else{
+    ZeroMem(Report_Data, ADDITIONAL_DATA_SIZE);
+  }
+
+  TdCallStatus = TdCall(TDCALL_TDREPORT, (UINT64)Report_Struct, (UINT64)Report_Data, 0, 0);
+
+  if(TdCallStatus == TDX_EXIT_REASON_SUCCESS){
+    Status = EFI_SUCCESS;
+  }else if(TdCallStatus == TDX_EXIT_REASON_OPERAND_INVALID){
+    Status = EFI_INVALID_PARAMETER;
+  }else{
+    Status = EFI_DEVICE_ERROR;
+  }
+
+  if(Status != EFI_SUCCESS){
+    DEBUG((DEBUG_ERROR, "Error returned from TdReport call - 0x%lx\n", TdCallStatus));
+  }else{
+    CopyMem(Report, Data, REPORT_STRUCT_SIZE);
+  }
+
+  FreePages(Data, EFI_SIZE_TO_PAGES(REPORT_STRUCT_SIZE + ADDITIONAL_DATA_SIZE));
+
+  return Status;
+}
diff --git a/OvmfPkg/Library/TdxLib/TdxLib.inf b/OvmfPkg/Library/TdxLib/TdxLib.inf
new file mode 100644
index 000000000000..f642de9e3a5f
--- /dev/null
+++ b/OvmfPkg/Library/TdxLib/TdxLib.inf
@@ -0,0 +1,48 @@
+## @file
+# Tdx library
+#
+# Copyright (c) 2020- 2021, Intel Corporation. All rights reserved.<BR>
+# This program and the accompanying materials
+# are licensed and made available under the terms and conditions of the BSD License
+# which accompanies this distribution.  The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php.
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = TdxLib
+  FILE_GUID                      = 032A8E0D-0C27-40C0-9CAA-23B731C1B223
+  MODULE_TYPE                    = BASE
+  VERSION_STRING                 = 1.0
+  LIBRARY_CLASS                  = TdxLib|PEI_CORE PEIM DXE_CORE DXE_DRIVER DXE_RUNTIME_DRIVER DXE_SMM_DRIVER UEFI_DRIVER UEFI_APPLICATION
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+#  VALID_ARCHITECTURES           = X64
+#
+
+[Sources]
+  Rtmr.c
+  TdReport.c
+  AcceptPages.c
+  X64/Tdcall.nasm
+  X64/Tdvmcall.nasm
+
+[Packages]
+  MdePkg/MdePkg.dec
+  OvmfPkg/OvmfPkg.dec
+
+[LibraryClasses]
+  BaseLib
+  BaseMemoryLib
+  DebugLib
+  MemoryAllocationLib
+
+[Pcd]
+  gUefiOvmfPkgTokenSpaceGuid.PcdUseTdxAcceptPage
+  gUefiOvmfPkgTokenSpaceGuid.PcdUseTdxEmulation
diff --git a/OvmfPkg/Library/TdxLib/TdxLibSec.inf b/OvmfPkg/Library/TdxLib/TdxLibSec.inf
new file mode 100644
index 000000000000..82ef4f08be8c
--- /dev/null
+++ b/OvmfPkg/Library/TdxLib/TdxLibSec.inf
@@ -0,0 +1,45 @@
+## @file
+# Tdx library for SEC phase.
+#
+# Copyright (c) 2020 - 2021, Intel Corporation. All rights reserved.<BR>
+# This program and the accompanying materials
+# are licensed and made available under the terms and conditions of the BSD License
+# which accompanies this distribution.  The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php.
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = TdxLibSec
+  FILE_GUID                      = 498E8E1E-5B11-41F3-9083-EEE3A32B009D
+  MODULE_TYPE                    = BASE
+  VERSION_STRING                 = 1.0
+  LIBRARY_CLASS                  = TdxLib|SEC
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+#  VALID_ARCHITECTURES           = X64
+#
+
+[Sources]
+  AcceptPages.c
+  X64/Tdcall.nasm
+  X64/Tdvmcall.nasm
+
+[Packages]
+  MdePkg/MdePkg.dec
+  OvmfPkg/OvmfPkg.dec
+
+[LibraryClasses]
+  BaseLib
+  BaseMemoryLib
+  DebugLib
+
+[Pcd]
+  gUefiOvmfPkgTokenSpaceGuid.PcdUseTdxAcceptPage
+  gUefiOvmfPkgTokenSpaceGuid.PcdUseTdxEmulation
diff --git a/OvmfPkg/Library/TdxLib/X64/Tdcall.nasm b/OvmfPkg/Library/TdxLib/X64/Tdcall.nasm
new file mode 100644
index 000000000000..d0d55e2a9443
--- /dev/null
+++ b/OvmfPkg/Library/TdxLib/X64/Tdcall.nasm
@@ -0,0 +1,125 @@
+;------------------------------------------------------------------------------
+;*
+;*   Copyright (c) 2020, Intel Corporation. All rights reserved.<BR>
+;*   This program and the accompanying materials
+;*   are licensed and made available under the terms and conditions of the BSD License
+;*   which accompanies this distribution.  The full text of the license may be found at
+;*   http://opensource.org/licenses/bsd-license.php
+;*
+;*   THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+;*   WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+;*
+;*
+;------------------------------------------------------------------------------
+
+DEFAULT REL
+SECTION .text
+
+%macro tdcall 0
+%if (FixedPcdGet32 (PcdUseTdxEmulation) != 0)
+    vmcall
+%else
+    db 0x66,0x0f,0x01,0xcc
+%endif
+%endmacro
+
+%macro tdcall_push_regs 0
+    push rbp
+    mov  rbp, rsp
+    push r15
+    push r14
+    push r13
+    push r12
+    push rbx
+    push rsi
+    push rdi
+%endmacro
+
+%macro tdcall_pop_regs 0
+    pop rdi
+    pop rsi
+    pop rbx
+    pop r12
+    pop r13
+    pop r14
+    pop r15
+    pop rbp
+%endmacro
+
+%define number_of_regs_pushed 8
+%define number_of_parameters  4
+
+; Keep these in sync for push_regs/pop_regs, code below uses them to find 5th or greater parameters
+%define first_variable_on_stack_offset  (number_of_regs_pushed * 8) + (number_of_parameters * 8) + 8
+%define second_variable_on_stack_offset (first_variable_on_stack_offset) + 8
+
+%macro tdcall_regs_preamble 2
+    mov rax, %1
+
+    mov ecx, %2
+
+    ; R10 = 0 (standard TDVMCALL)
+
+    xor r10d, r10d
+
+    ; Zero out unused (for standard TDVMCALL) registers to avoid leaking
+    ; secrets to the VMM.
+
+    xor ebx, ebx
+    xor esi, esi
+    xor edi, edi
+
+    xor edx, edx
+    xor ebp, ebp
+    xor r8d, r8d
+    xor r9d, r9d
+%endmacro
+
+%macro tdcall_regs_postamble 0
+    xor ebx, ebx
+    xor esi, esi
+    xor edi, edi
+
+    xor ecx, ecx
+    xor edx, edx
+    xor r8d,  r8d
+    xor r9d,  r9d
+    xor r10d, r10d
+    xor r11d, r11d
+%endmacro
+
+;  TdCall (
+;    UINT64  Leaf,  // Rcx
+;    UINT64  P1,  // Rdx
+;    UINT64  P2,  // R8
+;    UINT64  P3,  // R9
+;    UINT64  Results,  // rsp + 0x28
+;    )
+global ASM_PFX(TdCall)
+ASM_PFX(TdCall):
+       tdcall_push_regs
+
+       mov rax, rcx
+       mov rcx, rdx
+       mov rdx, r8
+       mov r8, r9
+
+       tdcall
+
+       ; exit if tdcall reports failure.
+       test rax, rax
+       jnz .exit
+
+       ; test if caller wanted results
+       mov r12, [rsp + first_variable_on_stack_offset ]
+       test r12, r12
+       jz .exit
+       mov [r12 + 0 ], rcx
+       mov [r12 + 8 ], rdx
+       mov [r12 + 16], r8
+       mov [r12 + 24], r9
+       mov [r12 + 32], r10
+       mov [r12 + 40], r11
+.exit:
+       tdcall_pop_regs
+       ret
diff --git a/OvmfPkg/Library/TdxLib/X64/Tdvmcall.nasm b/OvmfPkg/Library/TdxLib/X64/Tdvmcall.nasm
new file mode 100644
index 000000000000..e1da9b4fbdd6
--- /dev/null
+++ b/OvmfPkg/Library/TdxLib/X64/Tdvmcall.nasm
@@ -0,0 +1,211 @@
+;------------------------------------------------------------------------------
+;*
+;*   Copyright (c) 2020, Intel Corporation. All rights reserved.<BR>
+;*   This program and the accompanying materials
+;*   are licensed and made available under the terms and conditions of the BSD License
+;*   which accompanies this distribution.  The full text of the license may be found at
+;*   http://opensource.org/licenses/bsd-license.php
+;*
+;*   THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+;*   WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+;*
+;*
+;------------------------------------------------------------------------------
+
+DEFAULT REL
+SECTION .text
+
+%define TDVMCALL_EXPOSE_REGS_MASK       0xffec
+%define TDVMCALL                        0x0
+%define EXIT_REASON_CPUID               0xa
+
+%macro tdcall 0
+%if (FixedPcdGet32 (PcdUseTdxEmulation) != 0)
+    vmcall
+%else
+    db 0x66,0x0f,0x01,0xcc
+%endif
+%endmacro
+
+%macro tdcall_push_regs 0
+    push rbp
+    mov  rbp, rsp
+    push r15
+    push r14
+    push r13
+    push r12
+    push rbx
+    push rsi
+    push rdi
+%endmacro
+
+%macro tdcall_pop_regs 0
+    pop rdi
+    pop rsi
+    pop rbx
+    pop r12
+    pop r13
+    pop r14
+    pop r15
+    pop rbp
+%endmacro
+
+%define number_of_regs_pushed 8
+%define number_of_parameters  4
+
+; Keep these in sync for push_regs/pop_regs, code below uses them to find 5th or greater parameters
+%define first_variable_on_stack_offset  (number_of_regs_pushed * 8) + (number_of_parameters * 8) + 8
+%define second_variable_on_stack_offset (first_variable_on_stack_offset) + 8
+
+%macro tdcall_regs_preamble 2
+    mov rax, %1
+
+    mov ecx, %2
+
+    ; R10 = 0 (standard TDVMCALL)
+
+    xor r10d, r10d
+
+    ; Zero out unused (for standard TDVMCALL) registers to avoid leaking
+    ; secrets to the VMM.
+
+    xor ebx, ebx
+    xor esi, esi
+    xor edi, edi
+
+    xor edx, edx
+    xor ebp, ebp
+    xor r8d, r8d
+    xor r9d, r9d
+%endmacro
+
+%macro tdcall_regs_postamble 0
+    xor ebx, ebx
+    xor esi, esi
+    xor edi, edi
+
+    xor ecx, ecx
+    xor edx, edx
+    xor r8d,  r8d
+    xor r9d,  r9d
+    xor r10d, r10d
+    xor r11d, r11d
+%endmacro
+
+;------------------------------------------------------------------------------
+; 0   => RAX = TDCALL leaf
+; M   => RCX = TDVMCALL register behavior
+; 1   => R10 = standard vs. vendor
+; RDI => R11 = TDVMCALL function / nr
+; RSI =  R12 = p1
+; RDX => R13 = p2
+; RCX => R14 = p3
+; R8  => R15 = p4
+
+;  UINT64
+;  EFIAPI
+;  TdVmCall (
+;    UINT64  Leaf,  // Rcx
+;    UINT64  P1,  // Rdx
+;    UINT64  P2,  // R8
+;    UINT64  P3,  // R9
+;    UINT64  P4,  // rsp + 0x28
+;    UINT64  *Val // rsp + 0x30
+;    )
+global ASM_PFX(TdVmCall)
+ASM_PFX(TdVmCall):
+       tdcall_push_regs
+
+       mov r11, rcx
+       mov r12, rdx
+       mov r13, r8
+       mov r14, r9
+       mov r15, [rsp + first_variable_on_stack_offset ]
+
+       tdcall_regs_preamble TDVMCALL, TDVMCALL_EXPOSE_REGS_MASK
+
+       tdcall
+
+       ; ignore return dataif TDCALL reports failure.
+       test rax, rax
+       jnz .no_return_data
+
+       ; Propagate TDVMCALL success/failure to return value.
+       mov rax, r10
+
+       ; Retrieve the Val pointer.
+       mov r9, [rsp + second_variable_on_stack_offset ]
+       test r9, r9
+       jz .no_return_data
+
+       ; On success, propagate TDVMCALL output value to output param
+       test rax, rax
+       jnz .no_return_data
+       mov [r9], r11
+.no_return_data:
+       tdcall_regs_postamble
+
+       tdcall_pop_regs
+
+       ret
+
+;------------------------------------------------------------------------------
+; 0   => RAX = TDCALL leaf
+; M   => RCX = TDVMCALL register behavior
+; 1   => R10 = standard vs. vendor
+; RDI => R11 = TDVMCALL function / nr
+; RSI =  R12 = p1
+; RDX => R13 = p2
+; RCX => R14 = p3
+; R8  => R15 = p4
+
+;  UINT64
+;  EFIAPI
+;  TdVmCallCpuid (
+;    UINT64  EaxIn,  // Rcx
+;    UINT64  EcxIn,  // Rdx
+;    UINT64  *Results  // R8
+;    )
+global ASM_PFX(TdVmCallCpuid)
+ASM_PFX(TdVmCallCpuid):
+       tdcall_push_regs
+
+       mov r11, EXIT_REASON_CPUID
+       mov r12, rcx
+       mov r13, rdx
+
+       tdcall_regs_preamble TDVMCALL, TDVMCALL_EXPOSE_REGS_MASK
+
+       ; Save *results pointers
+       push r8
+
+       tdcall
+
+       ; Panic if TDCALL reports failure.
+       test rax, rax
+       jnz .no_return_data
+
+       ; Propagate TDVMCALL success/failure to return value.
+       mov rax, r10
+       test rax, rax
+       jnz .no_return_data
+
+       ; Retrieve *Results
+       pop r8
+       test r8, r8
+       jnz .no_return_data
+       ; Caller pass in buffer so store results r12-r15 contains eax-edx
+       mov [r8 +  0], r12
+       mov [r8 +  8], r13
+       mov [r8 + 16], r14
+       mov [r8 + 24], r15
+
+.no_return_data:
+       tdcall_regs_postamble
+
+       tdcall_pop_regs
+
+       ret
+
+.panic:
+       ud2
-- 
2.29.2.windows.2



-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#72561): https://edk2.groups.io/g/devel/message/72561
Mute This Topic: https://groups.io/mt/81193347/1813853
Group Owner: devel+owner at edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [edk2-devel-archive at redhat.com]
-=-=-=-=-=-=-=-=-=-=-=-





More information about the edk2-devel-archive mailing list