From: "Min Xu" <min.m.xu@intel.com>
To: devel@edk2.groups.io
Cc: Min Xu <min.m.xu@intel.com>,
Jordan Justen <jordan.l.justen@intel.com>,
Laszlo Ersek <lersek@redhat.com>,
Jiewen Yao <jiewen.yao@intel.com>,
Doug Reiland <doug.reiland@intel.com>
Subject: [PATCH V3 3/3] OvmfPkg: Implement library support for TdxLib SEC and DXE on OVMF
Date: Tue, 9 Mar 2021 14:12:57 +0800 [thread overview]
Message-ID: <6761377c2213ff3c9d1bfa3c3df6ce421af2688b.1615269637.git.min.m.xu@intel.com> (raw)
In-Reply-To: <cover.1615269637.git.min.m.xu@intel.com>
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@intel.com>
Cc: Laszlo Ersek <lersek@redhat.com>
Cc: Jiewen Yao <jiewen.yao@intel.com>
Signed-off-by: Min Xu <min.m.xu@intel.com>
Signed-off-by: Doug Reiland <doug.reiland@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
next prev parent reply other threads:[~2021-03-09 6:13 UTC|newest]
Thread overview: 14+ messages / expand[flat|nested] mbox.gz Atom feed top
2021-03-09 6:12 [PATCH V3 0/3] Add TdxLib support for Intel TDX Min Xu
2021-03-09 6:12 ` [PATCH V3 1/3] MdePkg: Add Tdx support lib Min Xu
2021-03-09 6:25 ` Yao, Jiewen
2021-03-09 8:23 ` Min Xu
2021-03-09 6:12 ` [PATCH V3 2/3] OvmfPkg: Add PCDs for TdxLib Min Xu
2021-03-09 6:44 ` Yao, Jiewen
2021-03-09 8:27 ` Min Xu
2021-03-09 6:12 ` Min Xu [this message]
2021-03-09 6:46 ` [PATCH V3 3/3] OvmfPkg: Implement library support for TdxLib SEC and DXE on OVMF Yao, Jiewen
2021-03-09 12:57 ` [PATCH V3 0/3] Add TdxLib support for Intel TDX Laszlo Ersek
2021-03-09 13:06 ` Laszlo Ersek
2021-03-09 14:38 ` [edk2-devel] " Laszlo Ersek
2021-03-10 0:25 ` Yao, Jiewen
2021-03-10 1:07 ` Brijesh Singh
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-list from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=6761377c2213ff3c9d1bfa3c3df6ce421af2688b.1615269637.git.min.m.xu@intel.com \
--to=devel@edk2.groups.io \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox