MdePkg: Introduce basic Tdx functions in BaseLib
RFC: https://bugzilla.tianocore.org/show_bug.cgi?id=3429 Introduce basic Tdx functions in BaseLib: - TdCall () - TdVmCall () - TdIsEnabled () Cc: Michael D Kinney <michael.d.kinney@intel.com> Cc: Liming Gao <gaoliming@byosoft.com.cn> Cc: Zhiguang Liu <zhiguang.liu@intel.com> Cc: Brijesh Singh <brijesh.singh@amd.com> Cc: Erdem Aktas <erdemaktas@google.com> Cc: James Bottomley <jejb@linux.ibm.com> Cc: Jiewen Yao <jiewen.yao@intel.com> Cc: Tom Lendacky <thomas.lendacky@amd.com> Cc: Gerd Hoffmann <kraxel@redhat.com> Acked-by: Gerd Hoffmann <kraxel@redhat.com> Reviewed-by: Liming Gao <gaoliming@byosoft.com.cn> Reviewed-by: Jiewen Yao <jiewen.yao@intel.com> Signed-off-by: Min Xu <min.m.xu@intel.com>
This commit is contained in:
@@ -4759,6 +4759,72 @@ SpeculationBarrier (
|
|||||||
VOID
|
VOID
|
||||||
);
|
);
|
||||||
|
|
||||||
|
#if defined (MDE_CPU_X64) || defined (MDE_CPU_IA32)
|
||||||
|
|
||||||
|
/**
|
||||||
|
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 0 A successful call
|
||||||
|
@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 the
|
||||||
|
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 0 A successful call
|
||||||
|
@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
|
||||||
|
);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
#if defined (MDE_CPU_X64)
|
#if defined (MDE_CPU_X64)
|
||||||
//
|
//
|
||||||
// The page size for the PVALIDATE instruction
|
// The page size for the PVALIDATE instruction
|
||||||
|
@@ -210,6 +210,7 @@
|
|||||||
X86RdRand.c
|
X86RdRand.c
|
||||||
X86PatchInstruction.c
|
X86PatchInstruction.c
|
||||||
X86SpeculationBarrier.c
|
X86SpeculationBarrier.c
|
||||||
|
IntelTdxNull.c
|
||||||
|
|
||||||
[Sources.X64]
|
[Sources.X64]
|
||||||
X64/Thunk16.nasm
|
X64/Thunk16.nasm
|
||||||
@@ -293,6 +294,9 @@
|
|||||||
X64/ReadCr0.nasm| MSFT
|
X64/ReadCr0.nasm| MSFT
|
||||||
X64/ReadEflags.nasm| MSFT
|
X64/ReadEflags.nasm| MSFT
|
||||||
|
|
||||||
|
X64/TdCall.nasm
|
||||||
|
X64/TdVmcall.nasm
|
||||||
|
X64/TdProbe.c
|
||||||
|
|
||||||
X64/Non-existing.c
|
X64/Non-existing.c
|
||||||
Math64.c
|
Math64.c
|
||||||
|
83
MdePkg/Library/BaseLib/IntelTdxNull.c
Normal file
83
MdePkg/Library/BaseLib/IntelTdxNull.c
Normal file
@@ -0,0 +1,83 @@
|
|||||||
|
/** @file
|
||||||
|
|
||||||
|
Null stub of TdxLib
|
||||||
|
|
||||||
|
Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
|
||||||
|
SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||||
|
|
||||||
|
**/
|
||||||
|
|
||||||
|
#include <Library/BaseLib.h>
|
||||||
|
#include <Uefi/UefiBaseType.h>
|
||||||
|
|
||||||
|
/**
|
||||||
|
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 <https://software.intel.com/content/
|
||||||
|
www/us/en/develop/articles/intel-trust-domain-extensions.html>
|
||||||
|
|
||||||
|
@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 the
|
||||||
|
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;
|
||||||
|
}
|
85
MdePkg/Library/BaseLib/X64/TdCall.nasm
Normal file
85
MdePkg/Library/BaseLib/X64/TdCall.nasm
Normal file
@@ -0,0 +1,85 @@
|
|||||||
|
;------------------------------------------------------------------------------
|
||||||
|
;*
|
||||||
|
;* Copyright (c) 2020 - 2021, Intel Corporation. All rights reserved.<BR>
|
||||||
|
;* 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
|
63
MdePkg/Library/BaseLib/X64/TdProbe.c
Normal file
63
MdePkg/Library/BaseLib/X64/TdProbe.c
Normal file
@@ -0,0 +1,63 @@
|
|||||||
|
/** @file
|
||||||
|
|
||||||
|
Copyright (c) 2020-2021, Intel Corporation. All rights reserved.<BR>
|
||||||
|
SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||||
|
|
||||||
|
**/
|
||||||
|
|
||||||
|
#include <Library/BaseLib.h>
|
||||||
|
#include <Register/Intel/Cpuid.h>
|
||||||
|
|
||||||
|
/**
|
||||||
|
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;
|
||||||
|
CPUID_VERSION_INFO_ECX CpuIdVersionInfoEcx;
|
||||||
|
|
||||||
|
TdEnabled = FALSE;
|
||||||
|
|
||||||
|
do {
|
||||||
|
AsmCpuid (CPUID_SIGNATURE, &LargestEax, &Ebx, &Ecx, &Edx);
|
||||||
|
|
||||||
|
if ( (Ebx != CPUID_SIGNATURE_GENUINE_INTEL_EBX)
|
||||||
|
|| (Edx != CPUID_SIGNATURE_GENUINE_INTEL_EDX)
|
||||||
|
|| (Ecx != CPUID_SIGNATURE_GENUINE_INTEL_ECX))
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
AsmCpuid (CPUID_VERSION_INFO, NULL, NULL, &CpuIdVersionInfoEcx.Uint32, NULL);
|
||||||
|
if (CpuIdVersionInfoEcx.Bits.ParaVirtualized == 0) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (LargestEax < CPUID_GUESTTD_RUNTIME_ENVIRONMENT) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
AsmCpuidEx (CPUID_GUESTTD_RUNTIME_ENVIRONMENT, 0, &Eax, &Ebx, &Ecx, &Edx);
|
||||||
|
if ( (Ebx != CPUID_GUESTTD_SIGNATURE_GENUINE_INTEL_EBX)
|
||||||
|
|| (Edx != CPUID_GUESTTD_SIGNATURE_GENUINE_INTEL_EDX)
|
||||||
|
|| (Ecx != CPUID_GUESTTD_SIGNATURE_GENUINE_INTEL_ECX))
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
TdEnabled = TRUE;
|
||||||
|
} while (FALSE);
|
||||||
|
|
||||||
|
return TdEnabled;
|
||||||
|
}
|
145
MdePkg/Library/BaseLib/X64/TdVmcall.nasm
Normal file
145
MdePkg/Library/BaseLib/X64/TdVmcall.nasm
Normal file
@@ -0,0 +1,145 @@
|
|||||||
|
;------------------------------------------------------------------------------
|
||||||
|
;*
|
||||||
|
;* Copyright (c) 2020 - 2021, Intel Corporation. All rights reserved.<BR>
|
||||||
|
;* 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 = 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
|
Reference in New Issue
Block a user