Hi Would you please try to merge TdxLib and TdxLibSec? I am not sure if we really need two instance.
Also, can we remove MemoryAllocationLib ? If it is just used to allocate aligned memory, can we allocate aligned memory in stack instead of heap ? > -----Original Message----- > From: Xu, Min M <min.m...@intel.com> > Sent: Tuesday, March 9, 2021 2:13 PM > To: devel@edk2.groups.io > Cc: Xu, Min M <min.m...@intel.com>; Justen, Jordan L > <jordan.l.jus...@intel.com>; Laszlo Ersek <ler...@redhat.com>; Yao, Jiewen > <jiewen....@intel.com>; Reiland, Doug <doug.reil...@intel.com> > Subject: [PATCH V3 3/3] OvmfPkg: Implement library support for TdxLib SEC and > DXE on OVMF > > 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.jus...@intel.com> > Cc: Laszlo Ersek <ler...@redhat.com> > Cc: Jiewen Yao <jiewen....@intel.com> > > Signed-off-by: Min Xu <min.m...@intel.com> > Signed-off-by: Doug Reiland <doug.reil...@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 (#72572): https://edk2.groups.io/g/devel/message/72572 Mute This Topic: https://groups.io/mt/81195559/21656 Group Owner: devel+ow...@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [arch...@mail-archive.com] -=-=-=-=-=-=-=-=-=-=-=-