From nobody Mon Feb 9 09:00:35 2026 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) client-ip=66.175.222.108; envelope-from=bounce+27952+87050+1787277+3901457@groups.io; helo=mail02.groups.io; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) smtp.mailfrom=bounce+27952+87050+1787277+3901457@groups.io; dmarc=fail(p=none dis=none) header.from=intel.com ARC-Seal: i=1; a=rsa-sha256; t=1646032891; cv=none; d=zohomail.com; s=zohoarc; b=BCDxAQ7wezSKWjHmJbO0SNrBN/yXOlffOXEswsARQUMZzo3Lb8vaHNsx3yjqQBI19irnCBTjed0h557p6hnxL08bU6QYwhW+mUwOSWZH22dy00MIuFVZ6VlrDTF+l0b58aqpt6snHPc9awWvSC9kybbf7B+KewKRCnow5Z6NObs= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1646032891; h=Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Id:List-Help:List-Unsubscribe:MIME-Version:Message-ID:Reply-To:References:Sender:Subject:To; bh=Iv8aExre6WyA9V6lrrNudKr4EUh+bcRY7C2XIbMnGdE=; b=L53+947EMBIBtJOaXRrLqf8p1QRR2wmDeS+vIqA6ZKQzNsh2KoaqHlORL8iV+KUSlPtrlBuaHeyTc6IK7YvZ6Bt12I5EO3IELvdcG/BVbo9SOi+3o2KbUWPfzvXrmay41UNL7BE1LlWIb6UT7zQSiWtJRZz0WmAni/DNw4DNgk4= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) smtp.mailfrom=bounce+27952+87050+1787277+3901457@groups.io; dmarc=fail header.from= (p=none dis=none) Received: from mail02.groups.io (mail02.groups.io [66.175.222.108]) by mx.zohomail.com with SMTPS id 164603289173714.45335611102007; Sun, 27 Feb 2022 23:21:31 -0800 (PST) Return-Path: X-Received: by 127.0.0.2 with SMTP id UsHlYY1788612xVk9jXLsJj5; Sun, 27 Feb 2022 23:21:31 -0800 X-Received: from mga09.intel.com (mga09.intel.com [134.134.136.24]) by mx.groups.io with SMTP id smtpd.web09.17699.1646032885667369347 for ; Sun, 27 Feb 2022 23:21:30 -0800 X-IronPort-AV: E=McAfee;i="6200,9189,10271"; a="252552577" X-IronPort-AV: E=Sophos;i="5.90,142,1643702400"; d="scan'208";a="252552577" X-Received: from orsmga007.jf.intel.com ([10.7.209.58]) by orsmga102.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 27 Feb 2022 23:21:30 -0800 X-IronPort-AV: E=Sophos;i="5.90,142,1643702400"; d="scan'208";a="534340715" X-Received: from mxu9-mobl1.ccr.corp.intel.com ([10.238.2.184]) by orsmga007-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 27 Feb 2022 23:21:27 -0800 From: "Min Xu" To: devel@edk2.groups.io Cc: Min Xu , Michael D Kinney , Liming Gao , Zhiguang Liu , Brijesh Singh , Erdem Aktas , James Bottomley , Jiewen Yao , Tom Lendacky , Gerd Hoffmann Subject: [edk2-devel] [PATCH V7 02/37] MdePkg: Introduce basic Tdx functions in BaseLib Date: Mon, 28 Feb 2022 15:20:34 +0800 Message-Id: <38ad7b1dad977d9dbe9eb00651a7231a896542c3.1646031164.git.min.m.xu@intel.com> In-Reply-To: References: MIME-Version: 1.0 Precedence: Bulk List-Unsubscribe: List-Subscribe: List-Help: Sender: devel@edk2.groups.io List-Id: Mailing-List: list devel@edk2.groups.io; contact devel+owner@edk2.groups.io Reply-To: devel@edk2.groups.io,min.m.xu@intel.com X-Gm-Message-State: AwVEZ21e0tYXYU9oa99ZWeSdx1787277AA= Content-Transfer-Encoding: quoted-printable DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=groups.io; q=dns/txt; s=20140610; t=1646032891; bh=a6zx+ya4Y4upKUPGvc53pA8Dc0L5TMGWsJ6YP+tliZI=; h=Cc:Date:From:Reply-To:Subject:To; b=uDYRfbIIs0fn91t50ecUrXt29GY306d3ONLGmVgdPTaVgd2TQhjoXes9986qlAd7Ej6 384FxU5YtrAQ/KlqNHdiBYatnCbvysK9gFQrsk8sN0x1FgEYtWm61gSpfAKVqj0AlgZf0 6XJwKdoArQl97L7ArdC2ve2XQRjIgte1rmo= X-ZohoMail-DKIM: pass (identity @groups.io) X-ZM-MESSAGEID: 1646032892299100007 Content-Type: text/plain; charset="utf-8" RFC: https://bugzilla.tianocore.org/show_bug.cgi?id=3D3429 Introduce basic Tdx functions in BaseLib: - TdCall () - TdVmCall () - TdIsEnabled () Cc: Michael D Kinney Cc: Liming Gao Cc: Zhiguang Liu Cc: Brijesh Singh Cc: Erdem Aktas Cc: James Bottomley Cc: Jiewen Yao Cc: Tom Lendacky Cc: Gerd Hoffmann Acked-by: Gerd Hoffmann Signed-off-by: Min Xu --- MdePkg/Include/Library/BaseLib.h | 62 ++++++++++ MdePkg/Library/BaseLib/BaseLib.inf | 11 ++ MdePkg/Library/BaseLib/IntelTdxNull.c | 83 +++++++++++++ MdePkg/Library/BaseLib/X64/TdCall.nasm | 85 +++++++++++++ MdePkg/Library/BaseLib/X64/TdProbe.c | 62 ++++++++++ MdePkg/Library/BaseLib/X64/TdVmcall.nasm | 145 +++++++++++++++++++++++ 6 files changed, 448 insertions(+) create mode 100644 MdePkg/Library/BaseLib/IntelTdxNull.c create mode 100644 MdePkg/Library/BaseLib/X64/TdCall.nasm create mode 100644 MdePkg/Library/BaseLib/X64/TdProbe.c create mode 100644 MdePkg/Library/BaseLib/X64/TdVmcall.nasm diff --git a/MdePkg/Include/Library/BaseLib.h b/MdePkg/Include/Library/Base= Lib.h index 6aa0d972186e..bd762843198f 100644 --- a/MdePkg/Include/Library/BaseLib.h +++ b/MdePkg/Include/Library/BaseLib.h @@ -4759,6 +4759,68 @@ SpeculationBarrier ( VOID ); =20 +/** + The TDCALL instruction causes a VM exit to the Intel TDX module. It is + used to call guest-side Intel TDX functions, either local or a TD exit + to the host VMM, as selected by Leaf. + + @param[in] Leaf Leaf number of TDCALL instruction + @param[in] Arg1 Arg1 + @param[in] Arg2 Arg2 + @param[in] Arg3 Arg3 + @param[in,out] Results Returned result of the Leaf function + + @return EFI_SUCCESS + @return Other See individual leaf functions +**/ +UINTN +EFIAPI +TdCall ( + IN UINT64 Leaf, + IN UINT64 Arg1, + IN UINT64 Arg2, + IN UINT64 Arg3, + IN OUT VOID *Results + ); + +/** + TDVMALL is a leaf function 0 for TDCALL. It helps invoke services from t= he + host VMM to pass/receive information. + + @param[in] Leaf Number of sub-functions + @param[in] Arg1 Arg1 + @param[in] Arg2 Arg2 + @param[in] Arg3 Arg3 + @param[in] Arg4 Arg4 + @param[in,out] Results Returned result of the sub-function + + @return EFI_SUCCESS + @return Other See individual sub-functions + +**/ +UINTN +EFIAPI +TdVmCall ( + IN UINT64 Leaf, + IN UINT64 Arg1, + IN UINT64 Arg2, + IN UINT64 Arg3, + IN UINT64 Arg4, + IN OUT VOID *Results + ); + +/** + Probe if TD is enabled. + + @return TRUE TD is enabled. + @return FALSE TD is not enabled. +**/ +BOOLEAN +EFIAPI +TdIsEnabled ( + VOID + ); + #if defined (MDE_CPU_X64) // // The page size for the PVALIDATE instruction diff --git a/MdePkg/Library/BaseLib/BaseLib.inf b/MdePkg/Library/BaseLib/Ba= seLib.inf index cebda3b210c1..1185f13204df 100644 --- a/MdePkg/Library/BaseLib/BaseLib.inf +++ b/MdePkg/Library/BaseLib/BaseLib.inf @@ -210,6 +210,7 @@ X86RdRand.c X86PatchInstruction.c X86SpeculationBarrier.c + IntelTdxNull.c =20 [Sources.X64] X64/Thunk16.nasm @@ -293,6 +294,9 @@ X64/ReadCr0.nasm| MSFT X64/ReadEflags.nasm| MSFT =20 + X64/TdCall.nasm + X64/TdVmcall.nasm + X64/TdProbe.c =20 X64/Non-existing.c Math64.c @@ -333,6 +337,7 @@ Ebc/SpeculationBarrier.c Unaligned.c Math64.c + IntelTdxNull.c =20 [Sources.ARM] Arm/InternalSwitchStack.c @@ -370,6 +375,8 @@ Arm/MemoryFence.S | GCC Arm/SpeculationBarrier.S | GCC =20 + IntelTdxNull.c + [Sources.AARCH64] Arm/InternalSwitchStack.c Arm/Unaligned.c @@ -393,6 +400,8 @@ AArch64/CpuBreakpoint.asm | MSFT AArch64/SpeculationBarrier.asm | MSFT =20 + IntelTdxNull.c + [Sources.RISCV64] Math64.c Unaligned.c @@ -409,6 +418,8 @@ RiscV64/RiscVInterrupt.S | GCC RiscV64/FlushCache.S | GCC =20 + IntelTdxNull.c + [Packages] MdePkg/MdePkg.dec =20 diff --git a/MdePkg/Library/BaseLib/IntelTdxNull.c b/MdePkg/Library/BaseLib= /IntelTdxNull.c new file mode 100644 index 000000000000..ec95470bd43e --- /dev/null +++ b/MdePkg/Library/BaseLib/IntelTdxNull.c @@ -0,0 +1,83 @@ +/** @file + + Null stub of TdxLib + + Copyright (c) 2021, Intel Corporation. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include +#include + +/** + The TDCALL instruction causes a VM exit to the Intel TDX module. It is + used to call guest-side Intel TDX functions, either local or a TD exit + to the host VMM, as selected by Leaf. + Leaf functions are described at + + @param[in] Leaf Leaf number of TDCALL instruction + @param[in] Arg1 Arg1 + @param[in] Arg2 Arg2 + @param[in] Arg3 Arg3 + @param[in,out] Results Returned result of the Leaf function + + @return EFI_SUCCESS + @return Other See individual leaf functions +**/ +UINTN +EFIAPI +TdCall ( + IN UINT64 Leaf, + IN UINT64 Arg1, + IN UINT64 Arg2, + IN UINT64 Arg3, + IN OUT VOID *Results + ) +{ + return EFI_UNSUPPORTED; +} + +/** + TDVMALL is a leaf function 0 for TDCALL. It helps invoke services from t= he + host VMM to pass/receive information. + + @param[in] Leaf Number of sub-functions + @param[in] Arg1 Arg1 + @param[in] Arg2 Arg2 + @param[in] Arg3 Arg3 + @param[in] Arg4 Arg4 + @param[in,out] Results Returned result of the sub-function + + @return EFI_SUCCESS + @return Other See individual sub-functions + +**/ +UINTN +EFIAPI +TdVmCall ( + IN UINT64 Leaf, + IN UINT64 Arg1, + IN UINT64 Arg2, + IN UINT64 Arg3, + IN UINT64 Arg4, + IN OUT VOID *Results + ) +{ + return EFI_UNSUPPORTED; +} + +/** + Probe if TD is enabled. + + @return TRUE TD is enabled. + @return FALSE TD is not enabled. +**/ +BOOLEAN +EFIAPI +TdIsEnabled ( + ) +{ + return FALSE; +} diff --git a/MdePkg/Library/BaseLib/X64/TdCall.nasm b/MdePkg/Library/BaseLi= b/X64/TdCall.nasm new file mode 100644 index 000000000000..e8a094b0eb3f --- /dev/null +++ b/MdePkg/Library/BaseLib/X64/TdCall.nasm @@ -0,0 +1,85 @@ +;-------------------------------------------------------------------------= ----- +;* +;* Copyright (c) 2020 - 2021, Intel Corporation. All rights reserved.
+;* SPDX-License-Identifier: BSD-2-Clause-Patent +;* +;* +;-------------------------------------------------------------------------= ----- + +DEFAULT REL +SECTION .text + +%macro tdcall 0 + db 0x66,0x0f,0x01,0xcc +%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) + +; 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/MdePkg/Library/BaseLib/X64/TdProbe.c b/MdePkg/Library/BaseLib/= X64/TdProbe.c new file mode 100644 index 000000000000..a1cf02717bf2 --- /dev/null +++ b/MdePkg/Library/BaseLib/X64/TdProbe.c @@ -0,0 +1,62 @@ +/** @file + + Copyright (c) 2020-2021, Intel Corporation. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include +#include + +/** + Probe if TD is enabled. + + @return TRUE TD is enabled. + @return FALSE TD is not enabled. +**/ +BOOLEAN +EFIAPI +TdIsEnabled ( + ) +{ + UINT32 Eax; + UINT32 Ebx; + UINT32 Ecx; + UINT32 Edx; + UINT32 LargestEax; + BOOLEAN TdEnabled; + + TdEnabled =3D FALSE; + + do { + AsmCpuid (CPUID_SIGNATURE, &LargestEax, &Ebx, &Ecx, &Edx); + + if ( (Ebx !=3D CPUID_SIGNATURE_GENUINE_INTEL_EBX) + || (Edx !=3D CPUID_SIGNATURE_GENUINE_INTEL_EDX) + || (Ecx !=3D CPUID_SIGNATURE_GENUINE_INTEL_ECX)) + { + break; + } + + AsmCpuid (CPUID_VERSION_INFO, NULL, NULL, &Ecx, NULL); + if ((Ecx & BIT31) =3D=3D 0) { + break; + } + + if (LargestEax < 0x21) { + break; + } + + AsmCpuidEx (0x21, 0, &Eax, &Ebx, &Ecx, &Edx); + if ( (Ebx !=3D SIGNATURE_32 ('I', 'n', 't', 'e')) + || (Edx !=3D SIGNATURE_32 ('l', 'T', 'D', 'X')) + || (Ecx !=3D SIGNATURE_32 (' ', ' ', ' ', ' '))) + { + break; + } + + TdEnabled =3D TRUE; + } while (FALSE); + + return TdEnabled; +} diff --git a/MdePkg/Library/BaseLib/X64/TdVmcall.nasm b/MdePkg/Library/Base= Lib/X64/TdVmcall.nasm new file mode 100644 index 000000000000..5ecc10b17193 --- /dev/null +++ b/MdePkg/Library/BaseLib/X64/TdVmcall.nasm @@ -0,0 +1,145 @@ +;-------------------------------------------------------------------------= ----- +;* +;* Copyright (c) 2020 - 2021, Intel Corporation. All rights reserved.
+;* SPDX-License-Identifier: BSD-2-Clause-Patent +;* +;* +;-------------------------------------------------------------------------= ----- + +DEFAULT REL +SECTION .text + +%define TDVMCALL_EXPOSE_REGS_MASK 0xffec +%define TDVMCALL 0x0 + +%macro tdcall 0 + db 0x66,0x0f,0x01,0xcc +%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 + + xor rcx, rcx + mov ecx, %2 + + ; R10 =3D 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 =3D> RAX =3D TDCALL leaf +; M =3D> RCX =3D TDVMCALL register behavior +; 1 =3D> R10 =3D standard vs. vendor +; RDI =3D> R11 =3D TDVMCALL function / nr +; RSI =3D R12 =3D p1 +; RDX =3D> R13 =3D p2 +; RCX =3D> R14 =3D p3 +; R8 =3D> R15 =3D 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 --=20 2.29.2.windows.2 -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#87050): https://edk2.groups.io/g/devel/message/87050 Mute This Topic: https://groups.io/mt/89446148/1787277 Group Owner: devel+owner@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [importer@patchew.org] -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-