* [PATCH V2 0/3] Add TdxLib support for Intel TDX
@ 2021-03-09 3:16 min.m.xu
2021-03-09 3:16 ` [PATCH V2 1/3] MdePkg: Add Tdx support lib Min Xu
` (2 more replies)
0 siblings, 3 replies; 4+ messages in thread
From: min.m.xu @ 2021-03-09 3:16 UTC (permalink / raw)
To: devel
Cc: Min Xu, Liming Gao, Zhiguang Liu, Jordan Justen, Laszlo Ersek,
Jiewen Yao
REF: https://bugzilla.tianocore.org/show_bug.cgi?id=3249
The patch series provides lib support for Intel Trust Domain Extensions
(Intel TDX).
Intel's Trust Domain Extensions (Intel TDX) refers to an Intel technology
that extends Virtual Machines Extensions (VMX) and Multi-Key Total Memory
Encryption (MKTME) with a new kind of virutal machines guest called a
Trust Domain (TD). A TD is desinged to run in a CPU mode that protects the
confidentiality of TD memory contents and the TD's CPU state from other
software, including the hosting Virtual-Machine Monitor (VMM), unless
explicitly shared by the TD itself.
The Intel TDX module uses the instruction-set architecture for Intel TDX
and the MKTME engine in the SOC to help serve as an intermediary between
the host VMM and the guest TD. TDCALL is the instruction which allows TD
guest privileged software to make a call for service into an underlying
TDX-module.
TdxLib is created with functions to perform the related Tdx operation.
This includes functions for:
- TdCall : to cause a VM exit to the Intel TDX module
- TdVmCall : it is a leaf function 0 for TDCALL
- TdVmCallCpuid : enable the TD guest to request VMM to emulate CPUID
- TdReport : to retrieve TDREPORT_STRUCT
- TdAcceptPages : to accept pending private pages
- TdExtendRtmr : to extend one of the RTMR registers
The base function in MdePkg will not do anything and will return an error
if a return value is required. It is expected that other packages
(like OvmfPkg) will create a version of the library to fully support a TD
guest.
We create an OVMF version of this library to begin the process of providing
full support of TDX in OVMF.
To support the emulation and test purpose, 2 PCDs are added in OvmfPkg.dec
- PcdUseTdxAcceptPage
Indicate whether TdCall(AcceptPage) is used.
- PcdUseTdxEmulation
Indicate whether TdxEmulation is used.
See <https://software.intel.com/content/www/us/en/develop/articles/
intel-trust-domain-extensions.html>
Cc: Liming Gao <gaoliming@byosoft.com.cn>
Cc: Zhiguang Liu <zhiguang.liu@intel.com>
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>
Min Xu (3):
MdePkg: Add Tdx support lib
OvmfPkg: Add PCDs for TdxLib
OvmfPkg: Implement library support for TdxLib SEC and DXE on OVMF
MdePkg/Include/IndustryStandard/Tdx.h | 201 +++++++++++++++++++++
MdePkg/Include/Library/TdxLib.h | 165 ++++++++++++++++++
MdePkg/Include/Protocol/Tdx.h | 22 +++
MdePkg/Library/TdxLib/TdxLibNull.c | 155 +++++++++++++++++
MdePkg/Library/TdxLib/TdxLibNull.inf | 33 ++++
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 +++++++++++++++++++++++
OvmfPkg/OvmfPkg.dec | 6 +
13 files changed, 1261 insertions(+)
create mode 100644 MdePkg/Include/IndustryStandard/Tdx.h
create mode 100644 MdePkg/Include/Library/TdxLib.h
create mode 100644 MdePkg/Include/Protocol/Tdx.h
create mode 100644 MdePkg/Library/TdxLib/TdxLibNull.c
create mode 100644 MdePkg/Library/TdxLib/TdxLibNull.inf
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
--
2.29.2.windows.2
^ permalink raw reply [flat|nested] 4+ messages in thread
* [PATCH V2 1/3] MdePkg: Add Tdx support lib
2021-03-09 3:16 [PATCH V2 0/3] Add TdxLib support for Intel TDX min.m.xu
@ 2021-03-09 3:16 ` Min Xu
2021-03-09 3:16 ` [PATCH V2 2/3] OvmfPkg: Add PCDs for TdxLib Min Xu
2021-03-09 3:16 ` [PATCH V2 3/3] OvmfPkg: Implement library support for TdxLib SEC and DXE on OVMF Min Xu
2 siblings, 0 replies; 4+ messages in thread
From: Min Xu @ 2021-03-09 3:16 UTC (permalink / raw)
To: devel; +Cc: Min Xu, Liming Gao, Zhiguang Liu, Jiewen Yao, Doug Reiland
Intel Trust Domain Extension (Intel TDX) refers to an Intel technology
that extends Virtual Machines Extensions (VMX) and Multi-Key Total
Memory Encryption (MKTME) with a new kind of virtual machine guest
called a Trust Domain (TD).
TdxLib is created with functions to perform the related Tdx operation.
This includes functions for:
- TdCall : to cause a VM exit to the Intel TDX module
- TdVmCall : it is a leaf function 0 for TDCALL
- TdVmCallCpuid : enable the TD guest to request VMM to emulate CPUID
- TdReport : to retrieve TDREPORT_STRUCT
- TdAcceptPages : to accept pending private pages
- TdExtendRtmr : to extend one of the RTMR registers
The base function in this dirver will not do anything and will return
an error if a return value is required. It is expected that other
packages (like OvmfPkg) will create a version of the library to fully
support a TD guest.
Cc: Liming Gao <gaoliming@byosoft.com.cn>
Cc: Zhiguang Liu <zhiguang.liu@intel.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>
---
MdePkg/Include/IndustryStandard/Tdx.h | 201 ++++++++++++++++++++++++++
MdePkg/Include/Library/TdxLib.h | 165 +++++++++++++++++++++
MdePkg/Include/Protocol/Tdx.h | 22 +++
MdePkg/Library/TdxLib/TdxLibNull.c | 155 ++++++++++++++++++++
MdePkg/Library/TdxLib/TdxLibNull.inf | 33 +++++
5 files changed, 576 insertions(+)
create mode 100644 MdePkg/Include/IndustryStandard/Tdx.h
create mode 100644 MdePkg/Include/Library/TdxLib.h
create mode 100644 MdePkg/Include/Protocol/Tdx.h
create mode 100644 MdePkg/Library/TdxLib/TdxLibNull.c
create mode 100644 MdePkg/Library/TdxLib/TdxLibNull.inf
diff --git a/MdePkg/Include/IndustryStandard/Tdx.h b/MdePkg/Include/IndustryStandard/Tdx.h
new file mode 100644
index 000000000000..dbcc31c26528
--- /dev/null
+++ b/MdePkg/Include/IndustryStandard/Tdx.h
@@ -0,0 +1,201 @@
+/** @file
+ Intel Trust Domain Extension definitions
+
+ 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.
+
+**/
+
+#ifndef _TDX_H_
+#define _TDX_H_
+
+#define EXIT_REASON_EXTERNAL_INTERRUPT 1
+#define EXIT_REASON_TRIPLE_FAULT 2
+
+#define EXIT_REASON_PENDING_INTERRUPT 7
+#define EXIT_REASON_NMI_WINDOW 8
+#define EXIT_REASON_TASK_SWITCH 9
+#define EXIT_REASON_CPUID 10
+#define EXIT_REASON_HLT 12
+#define EXIT_REASON_INVD 13
+#define EXIT_REASON_INVLPG 14
+#define EXIT_REASON_RDPMC 15
+#define EXIT_REASON_RDTSC 16
+#define EXIT_REASON_VMCALL 18
+#define EXIT_REASON_VMCLEAR 19
+#define EXIT_REASON_VMLAUNCH 20
+#define EXIT_REASON_VMPTRLD 21
+#define EXIT_REASON_VMPTRST 22
+#define EXIT_REASON_VMREAD 23
+#define EXIT_REASON_VMRESUME 24
+#define EXIT_REASON_VMWRITE 25
+#define EXIT_REASON_VMOFF 26
+#define EXIT_REASON_VMON 27
+#define EXIT_REASON_CR_ACCESS 28
+#define EXIT_REASON_DR_ACCESS 29
+#define EXIT_REASON_IO_INSTRUCTION 30
+#define EXIT_REASON_MSR_READ 31
+#define EXIT_REASON_MSR_WRITE 32
+#define EXIT_REASON_INVALID_STATE 33
+#define EXIT_REASON_MSR_LOAD_FAIL 34
+#define EXIT_REASON_MWAIT_INSTRUCTION 36
+#define EXIT_REASON_MONITOR_TRAP_FLAG 37
+#define EXIT_REASON_MONITOR_INSTRUCTION 39
+#define EXIT_REASON_PAUSE_INSTRUCTION 40
+#define EXIT_REASON_MCE_DURING_VMENTRY 41
+#define EXIT_REASON_TPR_BELOW_THRESHOLD 43
+#define EXIT_REASON_APIC_ACCESS 44
+#define EXIT_REASON_EOI_INDUCED 45
+#define EXIT_REASON_GDTR_IDTR 46
+#define EXIT_REASON_LDTR_TR 47
+#define EXIT_REASON_EPT_VIOLATION 48
+#define EXIT_REASON_EPT_MISCONFIG 49
+#define EXIT_REASON_INVEPT 50
+#define EXIT_REASON_RDTSCP 51
+#define EXIT_REASON_PREEMPTION_TIMER 52
+#define EXIT_REASON_INVVPID 53
+#define EXIT_REASON_WBINVD 54
+#define EXIT_REASON_XSETBV 55
+#define EXIT_REASON_APIC_WRITE 56
+#define EXIT_REASON_RDRAND 57
+#define EXIT_REASON_INVPCID 58
+#define EXIT_REASON_VMFUNC 59
+#define EXIT_REASON_ENCLS 60
+#define EXIT_REASON_RDSEED 61
+#define EXIT_REASON_PML_FULL 62
+#define EXIT_REASON_XSAVES 63
+#define EXIT_REASON_XRSTORS 64
+
+// TDCALL API Function Completion Status Codes
+#define TDX_EXIT_REASON_SUCCESS 0x0000000000000000
+#define TDX_EXIT_REASON_PAGE_ALREADY_ACCEPTED 0x00000B0A00000000
+#define TDX_EXIT_REASON_OPERAND_INVALID 0xC000010000000000
+#define TDX_EXIT_REASON_OPERAND_BUSY 0x8000020000000000
+
+#define TDCALL_TDVMCALL 0
+#define TDCALL_TDINFO 1
+#define TDCALL_TDEXTENDRTMR 2
+#define TDCALL_TDGETVEINFO 3
+#define TDCALL_TDREPORT 4
+#define TDCALL_TDSETCPUIDVE 5
+#define TDCALL_TDACCEPTPAGE 6
+
+#define TDVMCALL_CPUID 0x0000a
+#define TDVMCALL_HALT 0x0000c
+#define TDVMCALL_IO 0x0001e
+#define TDVMCALL_RDMSR 0x0001f
+#define TDVMCALL_WRMSR 0x00020
+#define TDVMCALL_MMIO 0x00030
+#define TDVMCALL_PCONFIG 0x00041
+
+#define TDVMCALL_GET_TDVMCALL_INFO 0x10000
+#define TDVMCALL_MAPGPA 0x10001
+#define TDVMCALL_GET_QUOTE 0x10002
+#define TDVMCALL_REPORT_FATAL_ERR 0x10003
+#define TDVMCALL_SETUP_EVENT_NOTIFY 0x10004
+
+#pragma pack(1)
+typedef struct {
+ UINT64 Data[6];
+} TDCALL_GENERIC_RETURN_DATA;
+
+typedef struct {
+ UINT64 Gpaw;
+ UINT64 Attributes;
+ UINT32 MaxVcpus;
+ UINT32 NumVcpus;
+ UINT64 Resv[3];
+} TDCALL_INFO_RETURN_DATA;
+
+typedef union {
+ UINT64 Val;
+ struct {
+ UINT32 Size:3;
+ UINT32 Direction:1;
+ UINT32 String:1;
+ UINT32 Rep:1;
+ UINT32 Encoding:1;
+ UINT32 Resv:9;
+ UINT32 Port:16;
+ UINT32 Resv2;
+ } Io;
+} VMX_EXIT_QUALIFICATION;
+
+typedef struct {
+ UINT32 ExitReason;
+ UINT32 Resv;
+ VMX_EXIT_QUALIFICATION ExitQualification;
+ UINT64 GuestLA;
+ UINT64 GuestPA;
+ UINT32 ExitInstructionLength;
+ UINT32 ExitInstructionInfo;
+ UINT32 Resv1;
+} TDCALL_VEINFO_RETURN_DATA;
+
+typedef union {
+ TDCALL_GENERIC_RETURN_DATA Generic;
+ TDCALL_INFO_RETURN_DATA TdInfo;
+ TDCALL_VEINFO_RETURN_DATA VeInfo;
+} TD_RETURN_DATA;
+
+/* data structure used in TDREPORT_STRUCT */
+typedef struct{
+ UINT8 Type;
+ UINT8 Subtype;
+ UINT8 Version;
+ UINT8 Rsvd;
+}TD_REPORT_TYPE;
+
+typedef struct{
+ TD_REPORT_TYPE ReportType;
+ UINT8 Rsvd1[12];
+ UINT8 CpuSvn[16];
+ UINT8 TeeTcbInfoHash[48];
+ UINT8 TeeInfoHash[48];
+ UINT8 ReportData[64];
+ UINT8 Rsvd2[32];
+ UINT8 Mac[32];
+}REPORTMACSTRUCT;
+
+typedef struct{
+ UINT8 Seam[2];
+ UINT8 Rsvd[14];
+}TEE_TCB_SVN;
+
+typedef struct{
+ UINT8 Valid[8];
+ TEE_TCB_SVN TeeTcbSvn;
+ UINT8 Mrseam[48];
+ UINT8 Mrsignerseam[48];
+ UINT8 Attributes[8];
+ UINT8 Rsvd[111];
+}TEE_TCB_INFO;
+
+typedef struct{
+ UINT8 Attributes[8];
+ UINT8 Xfam[8];
+ UINT8 Mrtd[48];
+ UINT8 Mrconfigid[48];
+ UINT8 Mrowner[48];
+ UINT8 Mrownerconfig[48];
+ UINT8 Rtmrs[4][48];
+ UINT8 Rsvd[112];
+}TDINFO;
+
+typedef struct{
+ REPORTMACSTRUCT ReportMacStruct;
+ TEE_TCB_INFO TeeTcbInfo;
+ UINT8 Rsvd[17];
+ TDINFO Tdinfo;
+}TDREPORT_STRUCT;
+
+#pragma pack()
+
+#endif
+
diff --git a/MdePkg/Include/Library/TdxLib.h b/MdePkg/Include/Library/TdxLib.h
new file mode 100644
index 000000000000..5e8634c6df79
--- /dev/null
+++ b/MdePkg/Include/Library/TdxLib.h
@@ -0,0 +1,165 @@
+/** @file
+ TdxLib definitions
+
+ 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.
+
+**/
+
+#ifndef _TDX_LIB_H_
+#define _TDX_LIB_H_
+
+#include <Library/BaseLib.h>
+#include <Uefi/UefiBaseType.h>
+#include <Library/DebugLib.h>
+#include <Protocol/DebugSupport.h>
+
+/**
+ 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
+);
+
+/**
+ 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
+ );
+
+/**
+ 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 PcrIndex
+ );
+
+/**
+ 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
+**/
+EFI_STATUS
+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 EFI_SUCCESS
+ @return Other See individual sub-functions
+
+**/
+EFI_STATUS
+EFIAPI
+TdVmCall (
+ IN UINT64 Leaf,
+ IN UINT64 Arg1,
+ IN UINT64 Arg2,
+ IN UINT64 Arg3,
+ IN UINT64 Arg4,
+ IN OUT VOID *Results
+ );
+
+/**
+ This function enable the TD guest to request the VMM to emulate CPUID
+ operation, especially for non-architectural, CPUID leaves.
+
+ @param[in] Eax Main leaf of the CPUID
+ @param[in] Ecx Sub-leaf of the CPUID
+ @param[out] Results Returned result of CPUID operation
+
+ @return EFI_SUCCESS
+**/
+EFI_STATUS
+EFIAPI
+TdVmCallCpuid (
+ IN UINT64 Eax,
+ IN UINT64 Ecx,
+ OUT VOID *Results
+ );
+#endif
diff --git a/MdePkg/Include/Protocol/Tdx.h b/MdePkg/Include/Protocol/Tdx.h
new file mode 100644
index 000000000000..d3e1eae13559
--- /dev/null
+++ b/MdePkg/Include/Protocol/Tdx.h
@@ -0,0 +1,22 @@
+/** @file
+ Tcg for Intel TDX definitions.
+
+Copyright (c) 2020 - 2021, Intel Corporation. All rights reserved.<BR>
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+
+#ifndef __TCG_TDX_H__
+#define __TCG_TDX_H__
+
+#include <Uefi/UefiBaseType.h>
+
+#define TCG_TDX_EVENT_DATA_SIGNATURE SIGNATURE_32 ('T', 'D', 'X', 'S')
+
+#define TD_TCG2_PROTOCOL_GUID \
+ {0x96751a3d, 0x72f4, 0x41a6, { 0xa7, 0x94, 0xed, 0x5d, 0x0e, 0x67, 0xae, 0x6b }}
+extern EFI_GUID gTdTcg2ProtocolGuid;
+
+
+#endif
diff --git a/MdePkg/Library/TdxLib/TdxLibNull.c b/MdePkg/Library/TdxLib/TdxLibNull.c
new file mode 100644
index 000000000000..8d759e4d33a4
--- /dev/null
+++ b/MdePkg/Library/TdxLib/TdxLibNull.c
@@ -0,0 +1,155 @@
+/** @file
+ Null instance of TdxLib.
+
+ 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.
+
+**/
+
+
+#include <Library/BaseLib.h>
+#include <Library/DebugLib.h>
+#include <IndustryStandard/Tdx.h>
+#include <Library/TdxLib.h>
+
+/**
+ 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
+ )
+{
+ return EFI_UNSUPPORTED;
+}
+
+/**
+ 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_UNSUPPORTED
+**/
+EFI_STATUS
+EFIAPI
+TdAcceptPages (
+ IN UINT64 StartAddress,
+ IN UINT64 NumberOfPages
+ )
+{
+ return EFI_UNSUPPORTED;
+}
+
+/**
+ 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
+**/
+EFI_STATUS
+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
+
+**/
+EFI_STATUS
+EFIAPI
+TdVmCall (
+ IN UINT64 Leaf,
+ IN UINT64 Arg1,
+ IN UINT64 Arg2,
+ IN UINT64 Arg3,
+ IN UINT64 Arg4,
+ IN OUT VOID *Results
+ )
+{
+ return EFI_UNSUPPORTED;
+}
+
+/**
+ This function enable the TD guest to request the VMM to emulate CPUID
+ operation, especially for non-architectural, CPUID leaves.
+
+ @param[in] Eax Main leaf of the CPUID
+ @param[in] Ecx Sub-leaf of the CPUID
+ @param[in,out] Results Returned result of CPUID operation
+
+ @return EFI_SUCCESS
+**/
+EFI_STATUS
+EFIAPI
+TdVmCallCpuid (
+ IN UINT64 Eax,
+ IN UINT64 Ecx,
+ IN OUT VOID *Results
+ )
+{
+ return EFI_UNSUPPORTED;
+}
diff --git a/MdePkg/Library/TdxLib/TdxLibNull.inf b/MdePkg/Library/TdxLib/TdxLibNull.inf
new file mode 100644
index 000000000000..0d07595a8c3e
--- /dev/null
+++ b/MdePkg/Library/TdxLib/TdxLibNull.inf
@@ -0,0 +1,33 @@
+## @file
+# Null Tdx library instance
+#
+# 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 = TdxLibNull
+ FILE_GUID = 05C5E621-FC66-4420-9C80-F0DE9E5B95FF
+ MODULE_TYPE = BASE
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = TdxLib
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+# VALID_ARCHITECTURES = X64
+#
+
+[Sources]
+ TdxLibNull.c
+
+[Packages]
+ MdePkg/MdePkg.dec
--
2.29.2.windows.2
^ permalink raw reply related [flat|nested] 4+ messages in thread
* [PATCH V2 2/3] OvmfPkg: Add PCDs for TdxLib
2021-03-09 3:16 [PATCH V2 0/3] Add TdxLib support for Intel TDX min.m.xu
2021-03-09 3:16 ` [PATCH V2 1/3] MdePkg: Add Tdx support lib Min Xu
@ 2021-03-09 3:16 ` Min Xu
2021-03-09 3:16 ` [PATCH V2 3/3] OvmfPkg: Implement library support for TdxLib SEC and DXE on OVMF Min Xu
2 siblings, 0 replies; 4+ messages in thread
From: Min Xu @ 2021-03-09 3:16 UTC (permalink / raw)
To: devel; +Cc: Min Xu, Jordan Justen, Laszlo Ersek, Jiewen Yao, Doug Reiland
TdxLib for OvmfPkg depends on the below PCDs
- PcdUseTdxAcceptPage
Indicate whether TdCall(AcceptPage) is used.
- PcdUseTdxEmulation
Indicate whether TdxEmulation is used.
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/OvmfPkg.dec | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/OvmfPkg/OvmfPkg.dec b/OvmfPkg/OvmfPkg.dec
index 4348bb45c64a..68b3fd86d516 100644
--- a/OvmfPkg/OvmfPkg.dec
+++ b/OvmfPkg/OvmfPkg.dec
@@ -317,6 +317,12 @@
gUefiOvmfPkgTokenSpaceGuid.PcdSevLaunchSecretBase|0x0|UINT32|0x42
gUefiOvmfPkgTokenSpaceGuid.PcdSevLaunchSecretSize|0x0|UINT32|0x43
+ ## Indicate whether TdCall(AcceptPage) is used.
+ gUefiOvmfPkgTokenSpaceGuid.PcdUseTdxAcceptPage|TRUE|BOOLEAN|0x44
+ ## Indicate whether TdxEmulation is used.
+ gUefiOvmfPkgTokenSpaceGuid.PcdUseTdxEmulation|0x1|UINT32|0x45
+
+
[PcdsDynamic, PcdsDynamicEx]
gUefiOvmfPkgTokenSpaceGuid.PcdEmuVariableEvent|0|UINT64|2
gUefiOvmfPkgTokenSpaceGuid.PcdOvmfFlashVariablesEnable|FALSE|BOOLEAN|0x10
--
2.29.2.windows.2
^ permalink raw reply related [flat|nested] 4+ messages in thread
* [PATCH V2 3/3] OvmfPkg: Implement library support for TdxLib SEC and DXE on OVMF
2021-03-09 3:16 [PATCH V2 0/3] Add TdxLib support for Intel TDX min.m.xu
2021-03-09 3:16 ` [PATCH V2 1/3] MdePkg: Add Tdx support lib Min Xu
2021-03-09 3:16 ` [PATCH V2 2/3] OvmfPkg: Add PCDs for TdxLib Min Xu
@ 2021-03-09 3:16 ` Min Xu
2 siblings, 0 replies; 4+ messages in thread
From: Min Xu @ 2021-03-09 3:16 UTC (permalink / raw)
To: devel; +Cc: Min Xu, Jordan Justen, Laszlo Ersek, Jiewen Yao, Doug Reiland
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
^ permalink raw reply related [flat|nested] 4+ messages in thread
end of thread, other threads:[~2021-03-09 3:17 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2021-03-09 3:16 [PATCH V2 0/3] Add TdxLib support for Intel TDX min.m.xu
2021-03-09 3:16 ` [PATCH V2 1/3] MdePkg: Add Tdx support lib Min Xu
2021-03-09 3:16 ` [PATCH V2 2/3] OvmfPkg: Add PCDs for TdxLib Min Xu
2021-03-09 3:16 ` [PATCH V2 3/3] OvmfPkg: Implement library support for TdxLib SEC and DXE on OVMF Min Xu
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox