Subject: [PATCH v1 0/6] Add TDX Guest Attestation support

Hi All,

Intel's Trust Domain Extensions (TDX) protect guest VMs from malicious
hosts and some physical attacks. VM guest with TDX support is called
as TD Guest.

In TD Guest, the attestation process is used to verify the
trustworthiness of TD guest to the 3rd party servers. Such attestation
process is required by 3rd party servers before sending sensitive
information to TD guests. One usage example is to get encryption keys
from the key server for mounting the encrypted rootfs or secondary drive.

Following patches add the attestation support to TDX guest which
includes attestation user interface driver, user agent example, and
related hypercall support.

In this series, only following patches are in arch/x86 and are
intended for x86 maintainers review.

* x86/tdx: Add TDREPORT TDX Module call support
* x86/tdx: Add GetQuote TDX hypercall support
* x86/tdx: Add SetupEventNotifyInterrupt TDX hypercall support
* x86/tdx: Add TDX Guest event notify interrupt vector support

Patch titled "platform/x86: intel_tdx_attest: Add TDX Guest attestation
interface driver" adds the attestation driver support. This is supposed
to be reviewed by platform-x86 maintainers.

Also, patch titled "tools/tdx: Add a sample attestation user app" adds
a testing app for attestation feature which needs review from
[email protected].

Dependencies:
--------------

This feature has dependency on TDX guest core patch set series.

https://lore.kernel.org/all/[email protected]/T/

History:
----------

Previously this patch set was sent under title "Add TDX Guest
Support (Attestation support)". In the previous version, only the
attestation driver patch was reviewed and got acked. Rest of the
patches need to be reviewed freshly.

https://lore.kernel.org/bpf/20210806000946.2951441-1-sathyanarayanan.kuppuswamy@linux.intel.com/

Changes since previous submission:
* Updated commit log and error handling in TDREPORT, GetQuote and
SetupEventNotifyInterrupt support patches.
* Added locking support in attestation driver.

Kuppuswamy Sathyanarayanan (6):
x86/tdx: Add tdx_mcall_tdreport() API support
x86/tdx: Add tdx_hcall_get_quote() API support
x86/tdx: Add SetupEventNotifyInterrupt TDX hypercall support
platform/x86: intel_tdx_attest: Add TDX Guest attestation interface
driver
x86/tdx: Add TDX Guest event notify interrupt vector support
tools/tdx: Add a sample attestation user app

arch/x86/coco/tdx.c | 170 ++++++++++++
arch/x86/include/asm/hardirq.h | 4 +
arch/x86/include/asm/idtentry.h | 4 +
arch/x86/include/asm/irq_vectors.h | 7 +-
arch/x86/include/asm/tdx.h | 5 +
arch/x86/kernel/irq.c | 7 +
drivers/platform/x86/intel/Kconfig | 1 +
drivers/platform/x86/intel/Makefile | 1 +
drivers/platform/x86/intel/tdx/Kconfig | 13 +
drivers/platform/x86/intel/tdx/Makefile | 3 +
.../platform/x86/intel/tdx/intel_tdx_attest.c | 241 ++++++++++++++++++
include/uapi/misc/tdx.h | 37 +++
tools/Makefile | 13 +-
tools/tdx/Makefile | 19 ++
tools/tdx/attest/.gitignore | 2 +
tools/tdx/attest/Makefile | 24 ++
tools/tdx/attest/tdx-attest-test.c | 240 +++++++++++++++++
17 files changed, 784 insertions(+), 7 deletions(-)
create mode 100644 drivers/platform/x86/intel/tdx/Kconfig
create mode 100644 drivers/platform/x86/intel/tdx/Makefile
create mode 100644 drivers/platform/x86/intel/tdx/intel_tdx_attest.c
create mode 100644 include/uapi/misc/tdx.h
create mode 100644 tools/tdx/Makefile
create mode 100644 tools/tdx/attest/.gitignore
create mode 100644 tools/tdx/attest/Makefile
create mode 100644 tools/tdx/attest/tdx-attest-test.c

--
2.25.1


Subject: [PATCH v1 5/6] x86/tdx: Add TDX Guest event notify interrupt vector support

Allocate 0xec IRQ vector address for TDX guest to receive the event
completion notification from VMM. Since this vector address will be
sent to VMM via hypercall, allocate a fixed address and move
LOCAL_TIMER_VECTOR vector address by 1 byte. Also add related IDT
handler to process the notification event.

It will be mainly used by attestation driver to receive Quote event
completion notification from host.

Add support to track the notification event status via /proc/interrupts.

Reviewed-by: Tony Luck <[email protected]>
Reviewed-by: Andi Kleen <[email protected]>
Signed-off-by: Kuppuswamy Sathyanarayanan <[email protected]>
---
arch/x86/coco/tdx.c | 40 ++++++++++++++++++++++++++++++
arch/x86/include/asm/hardirq.h | 4 +++
arch/x86/include/asm/idtentry.h | 4 +++
arch/x86/include/asm/irq_vectors.h | 7 +++++-
arch/x86/include/asm/tdx.h | 1 +
arch/x86/kernel/irq.c | 7 ++++++
6 files changed, 62 insertions(+), 1 deletion(-)

diff --git a/arch/x86/coco/tdx.c b/arch/x86/coco/tdx.c
index d18508e6150f..a6bf93d943f5 100644
--- a/arch/x86/coco/tdx.c
+++ b/arch/x86/coco/tdx.c
@@ -12,6 +12,10 @@
#include <asm/insn.h>
#include <asm/insn-eval.h>
#include <asm/x86_init.h>
+#include <asm/apic.h>
+#include <asm/idtentry.h>
+#include <asm/irq_regs.h>
+#include <asm/desc.h>

/* TDX module Call Leaf IDs */
#define TDX_GET_INFO 1
@@ -49,6 +53,14 @@ static struct {
unsigned long attributes;
} td_info __ro_after_init;

+/*
+ * Currently it will be used only by the attestation
+ * driver. So, race condition with read/write operation
+ * is not considered.
+ */
+void (*tdx_event_notify_handler)(void);
+EXPORT_SYMBOL_GPL(tdx_event_notify_handler);
+
/*
* Wrapper for standard use of __tdx_hypercall with no output aside from
* return code.
@@ -91,6 +103,28 @@ static inline void tdx_module_call(u64 fn, u64 rcx, u64 rdx, u64 r8, u64 r9,
panic("TDCALL %lld failed (Buggy TDX module!)\n", fn);
}

+/* TDX guest event notification handler */
+DEFINE_IDTENTRY_SYSVEC(sysvec_tdx_event_notify)
+{
+ struct pt_regs *old_regs = set_irq_regs(regs);
+
+ inc_irq_stat(irq_tdx_event_notify_count);
+
+ if (tdx_event_notify_handler)
+ tdx_event_notify_handler();
+
+ /*
+ * The hypervisor requires that the APIC EOI should be acked.
+ * If the APIC EOI is not acked, the APIC ISR bit for the
+ * TDX_GUEST_EVENT_NOTIFY_VECTOR will not be cleared and then it
+ * will block the interrupt whose vector is lower than
+ * TDX_GUEST_EVENT_NOTIFY_VECTOR.
+ */
+ ack_APIC_irq();
+
+ set_irq_regs(old_regs);
+}
+
/*
* tdx_mcall_tdreport() - Generate TDREPORT_STRUCT using TDCALL.
*
@@ -727,5 +761,11 @@ void __init tdx_early_init(void)

swiotlb_force = SWIOTLB_FORCE;

+ alloc_intr_gate(TDX_GUEST_EVENT_NOTIFY_VECTOR,
+ asm_sysvec_tdx_event_notify);
+
+ if (tdx_hcall_set_notify_intr(TDX_GUEST_EVENT_NOTIFY_VECTOR))
+ pr_warn("Setting event notification interrupt failed\n");
+
pr_info("Guest detected\n");
}
diff --git a/arch/x86/include/asm/hardirq.h b/arch/x86/include/asm/hardirq.h
index 275e7fd20310..3955b81f9241 100644
--- a/arch/x86/include/asm/hardirq.h
+++ b/arch/x86/include/asm/hardirq.h
@@ -44,6 +44,10 @@ typedef struct {
unsigned int irq_hv_reenlightenment_count;
unsigned int hyperv_stimer0_count;
#endif
+#if IS_ENABLED(CONFIG_INTEL_TDX_GUEST)
+ unsigned int tdx_ve_count;
+ unsigned int irq_tdx_event_notify_count;
+#endif
} ____cacheline_aligned irq_cpustat_t;

DECLARE_PER_CPU_SHARED_ALIGNED(irq_cpustat_t, irq_stat);
diff --git a/arch/x86/include/asm/idtentry.h b/arch/x86/include/asm/idtentry.h
index 8ccc81d653b3..8ca55780df20 100644
--- a/arch/x86/include/asm/idtentry.h
+++ b/arch/x86/include/asm/idtentry.h
@@ -693,6 +693,10 @@ DECLARE_IDTENTRY_SYSVEC(HYPERVISOR_CALLBACK_VECTOR, sysvec_xen_hvm_callback);
DECLARE_IDTENTRY_SYSVEC(HYPERVISOR_CALLBACK_VECTOR, sysvec_kvm_asyncpf_interrupt);
#endif

+#ifdef CONFIG_INTEL_TDX_GUEST
+DECLARE_IDTENTRY_SYSVEC(TDX_GUEST_EVENT_NOTIFY_VECTOR, sysvec_tdx_event_notify);
+#endif
+
#undef X86_TRAP_OTHER

#endif
diff --git a/arch/x86/include/asm/irq_vectors.h b/arch/x86/include/asm/irq_vectors.h
index 43dcb9284208..82ac0c0a34b1 100644
--- a/arch/x86/include/asm/irq_vectors.h
+++ b/arch/x86/include/asm/irq_vectors.h
@@ -104,7 +104,12 @@
#define HYPERV_STIMER0_VECTOR 0xed
#endif

-#define LOCAL_TIMER_VECTOR 0xec
+#if IS_ENABLED(CONFIG_INTEL_TDX_GUEST)
+/* Vector on which TDX Guest event notification is delivered */
+#define TDX_GUEST_EVENT_NOTIFY_VECTOR 0xec
+#endif
+
+#define LOCAL_TIMER_VECTOR 0xeb

#define NR_VECTORS 256

diff --git a/arch/x86/include/asm/tdx.h b/arch/x86/include/asm/tdx.h
index e93ca229d512..b1eac9bcf808 100644
--- a/arch/x86/include/asm/tdx.h
+++ b/arch/x86/include/asm/tdx.h
@@ -62,6 +62,7 @@ int tdx_mcall_tdreport(void *data, void *reportdata);

int tdx_hcall_get_quote(void *data);

+extern void (*tdx_event_notify_handler)(void);
#else

static inline void tdx_early_init(void) { };
diff --git a/arch/x86/kernel/irq.c b/arch/x86/kernel/irq.c
index 766ffe3ba313..a96ecd866723 100644
--- a/arch/x86/kernel/irq.c
+++ b/arch/x86/kernel/irq.c
@@ -181,6 +181,13 @@ int arch_show_interrupts(struct seq_file *p, int prec)
seq_printf(p, "%10u ",
irq_stats(j)->kvm_posted_intr_wakeup_ipis);
seq_puts(p, " Posted-interrupt wakeup event\n");
+#endif
+#if IS_ENABLED(CONFIG_INTEL_TDX_GUEST)
+ seq_printf(p, "%*s: ", prec, "TGN");
+ for_each_online_cpu(j)
+ seq_printf(p, "%10u ",
+ irq_stats(j)->irq_tdx_event_notify_count);
+ seq_puts(p, " TDX Guest event notification\n");
#endif
return 0;
}
--
2.25.1

Subject: [PATCH v1 2/6] x86/tdx: Add tdx_hcall_get_quote() API support

The second stage in the attestation process is for the guest to request
the VMM generate and sign a quote based on the TDREPORT acquired
earlier. More details about the steps involved in attestation process
can be found in TDX Guest-Host Communication Interface (GHCI) for Intel
TDX 1.5, section titled "TD attestation"

Add tdx_hcall_get_quote() helper function to implement the GetQuote
hypercall.

More details about the GetQuote TDVMCALL are in the Guest-Host
Communication Interface (GHCI) Specification, sec 3.3, titled
"VP.VMCALL<GetQuote>".

This will be used by the TD attestation driver in follow-on patches.

Reviewed-by: Tony Luck <[email protected]>
Reviewed-by: Andi Kleen <[email protected]>
Signed-off-by: Kuppuswamy Sathyanarayanan <[email protected]>
---
arch/x86/coco/tdx.c | 46 ++++++++++++++++++++++++++++++++++++++
arch/x86/include/asm/tdx.h | 2 ++
2 files changed, 48 insertions(+)

diff --git a/arch/x86/coco/tdx.c b/arch/x86/coco/tdx.c
index f01b03e41572..2c07f9551d3b 100644
--- a/arch/x86/coco/tdx.c
+++ b/arch/x86/coco/tdx.c
@@ -21,6 +21,7 @@

/* TDX hypercall Leaf IDs */
#define TDVMCALL_MAP_GPA 0x10001
+#define TDVMCALL_GET_QUOTE 0x10002

/* MMIO direction */
#define EPT_READ 0
@@ -38,6 +39,10 @@
#define TDCALL_INVALID_OPERAND 0x8000000000000000
#define TDCALL_OPERAND_BUSY 0x8000020000000000

+/* TDX hypercall error codes */
+#define TDVMCALL_INVALID_OPERAND 0x8000000000000000
+#define TDVMCALL_GPA_IN_USE 0x8000000000000001
+
static struct {
unsigned int gpa_width;
unsigned long attributes;
@@ -129,6 +134,47 @@ int tdx_mcall_tdreport(void *data, void *reportdata)
}
EXPORT_SYMBOL_GPL(tdx_mcall_tdreport);

+/*
+ * tdx_hcall_get_quote() - Generate TDQUOTE using TDREPORT_STRUCT.
+ *
+ * @data : Address of 8KB GPA memory which contains
+ * TDREPORT_STRUCT.
+ *
+ * return 0 on success or failure error number.
+ */
+int tdx_hcall_get_quote(void *data)
+{
+ u64 ret;
+
+ /*
+ * Use confidential guest TDX check to ensure this API is only
+ * used by TDX guest platforms.
+ */
+ if (!data || !cpu_feature_enabled(X86_FEATURE_TDX_GUEST))
+ return -EINVAL;
+
+ /*
+ * Pass the physical address of tdreport data to the VMM
+ * and trigger the tdquote generation. Quote data will be
+ * stored back in the same physical address space. More info
+ * about ABI can be found in TDX Guest-Host-Communication
+ * Interface (GHCI), sec titled "TDG.VP.VMCALL<GetQuote>".
+ */
+ ret = _tdx_hypercall(TDVMCALL_GET_QUOTE, cc_mkdec(virt_to_phys(data)),
+ 0, 0, 0);
+
+ if (ret) {
+ if (ret == TDVMCALL_INVALID_OPERAND)
+ return -EINVAL;
+ else if (ret == TDVMCALL_GPA_IN_USE)
+ return -EBUSY;
+ return -EIO;
+ }
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(tdx_hcall_get_quote);
+
static void get_info(void)
{
struct tdx_module_output out;
diff --git a/arch/x86/include/asm/tdx.h b/arch/x86/include/asm/tdx.h
index b2e76ae8fdf1..e93ca229d512 100644
--- a/arch/x86/include/asm/tdx.h
+++ b/arch/x86/include/asm/tdx.h
@@ -60,6 +60,8 @@ bool tdx_early_handle_ve(struct pt_regs *regs);

int tdx_mcall_tdreport(void *data, void *reportdata);

+int tdx_hcall_get_quote(void *data);
+
#else

static inline void tdx_early_init(void) { };
--
2.25.1

Subject: [PATCH v1 1/6] x86/tdx: Add tdx_mcall_tdreport() API support

In TDX guest, attestation is mainly used to verify the trust worthiness
of a TD to the 3rd party key servers. First step in attestation process
is to get the TDREPORT data and the generated data is further used in
subsequent steps of attestation process. TDREPORT data contains details
like TDX module version information, measurement of the TD, along with a
TD-specified nonce

Add a wrapper function (tdx_mcall_tdreport()) to get the TDREPORT from
the TDX Module.

More details about the TDREPORT TDCALL can be found in TDX Guest-Host
Communication Interface (GHCI) for Intel TDX 1.5, section titled
"TDCALL [MR.REPORT]".

Steps involved in attestation process can be found in TDX Guest-Host
Communication Interface (GHCI) for Intel TDX 1.5, section titled
"TD attestation"

[Xiaoyao: Proposed error code fix]
Reviewed-by: Tony Luck <[email protected]>
Reviewed-by: Andi Kleen <[email protected]>
Signed-off-by: Kuppuswamy Sathyanarayanan <[email protected]>
---
arch/x86/coco/tdx.c | 51 ++++++++++++++++++++++++++++++++++++++
arch/x86/include/asm/tdx.h | 2 ++
2 files changed, 53 insertions(+)

diff --git a/arch/x86/coco/tdx.c b/arch/x86/coco/tdx.c
index 8a7826fe49e3..f01b03e41572 100644
--- a/arch/x86/coco/tdx.c
+++ b/arch/x86/coco/tdx.c
@@ -16,6 +16,7 @@
/* TDX module Call Leaf IDs */
#define TDX_GET_INFO 1
#define TDX_GET_VEINFO 3
+#define TDX_GET_REPORT 4
#define TDX_ACCEPT_PAGE 6

/* TDX hypercall Leaf IDs */
@@ -31,6 +32,12 @@
#define VE_GET_PORT_NUM(e) ((e) >> 16)
#define VE_IS_IO_STRING(e) ((e) & BIT(4))

+/* TDX Module call error codes */
+#define TDCALL_RETURN_CODE_MASK 0xffffffff00000000
+#define TDCALL_RETURN_CODE(a) ((a) & TDCALL_RETURN_CODE_MASK)
+#define TDCALL_INVALID_OPERAND 0x8000000000000000
+#define TDCALL_OPERAND_BUSY 0x8000020000000000
+
static struct {
unsigned int gpa_width;
unsigned long attributes;
@@ -78,6 +85,50 @@ static inline void tdx_module_call(u64 fn, u64 rcx, u64 rdx, u64 r8, u64 r9,
panic("TDCALL %lld failed (Buggy TDX module!)\n", fn);
}

+/*
+ * tdx_mcall_tdreport() - Generate TDREPORT_STRUCT using TDCALL.
+ *
+ * @data : Address of 1024B aligned data to store
+ * TDREPORT_STRUCT.
+ * @reportdata : Address of 64B aligned report data
+ *
+ * return 0 on success or failure error number.
+ */
+int tdx_mcall_tdreport(void *data, void *reportdata)
+{
+ u64 ret;
+
+ /*
+ * Use confidential guest TDX check to ensure this API is only
+ * used by TDX guest platforms.
+ */
+ if (!data || !reportdata || !cpu_feature_enabled(X86_FEATURE_TDX_GUEST))
+ return -EINVAL;
+
+ /*
+ * Pass the physical address of user generated reportdata
+ * and the physical address of out pointer to store the
+ * tdreport data to the TDX module to generate the
+ * TD report. Generated data contains measurements/configuration
+ * data of the TD guest. More info about ABI can be found in TDX
+ * Guest-Host-Communication Interface (GHCI), sec titled
+ * "TDG.MR.REPORT".
+ */
+ ret = __tdx_module_call(TDX_GET_REPORT, virt_to_phys(data),
+ virt_to_phys(reportdata), 0, 0, NULL);
+
+ if (ret) {
+ if (TDCALL_RETURN_CODE(ret) == TDCALL_INVALID_OPERAND)
+ return -EINVAL;
+ if (TDCALL_RETURN_CODE(ret) == TDCALL_OPERAND_BUSY)
+ return -EBUSY;
+ return -EIO;
+ }
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(tdx_mcall_tdreport);
+
static void get_info(void)
{
struct tdx_module_output out;
diff --git a/arch/x86/include/asm/tdx.h b/arch/x86/include/asm/tdx.h
index 6a97d42b0de9..b2e76ae8fdf1 100644
--- a/arch/x86/include/asm/tdx.h
+++ b/arch/x86/include/asm/tdx.h
@@ -58,6 +58,8 @@ void tdx_safe_halt(void);

bool tdx_early_handle_ve(struct pt_regs *regs);

+int tdx_mcall_tdreport(void *data, void *reportdata);
+
#else

static inline void tdx_early_init(void) { };
--
2.25.1

Subject: [PATCH v1 4/6] platform/x86: intel_tdx_attest: Add TDX Guest attestation interface driver

TDX guest supports encrypted disk as root or secondary drives.
Decryption keys required to access such drives are usually maintained
by 3rd party key servers. Attestation is required by 3rd party key
servers to get the key for an encrypted disk volume, or possibly other
encrypted services. Attestation is used to prove to the key server that
the TD guest is running in a valid TD and the kernel and virtual BIOS
and other environment are secure.

During the boot process various components before the kernel accumulate
hashes in the TDX module, which can then combined into a report. This
would typically include a hash of the bios, bios configuration, boot
loader, command line, kernel, initrd. After checking the hashes the
key server will securely release the keys.

The actual details of the attestation protocol depend on the particular
key server configuration, but some parts are common and need to
communicate with the TDX module.

This communication is implemented in the attestation driver.

The supported steps are:

1. TD guest generates the TDREPORT that contains version information
about the Intel TDX module, measurement of the TD, along with a
TD-specified nonce.
  2. TD guest shares the TDREPORT with TD host via GetQuote hypercall
which is used by the host to generate a quote via quoting
enclave (QE).
  3. Quote generation completion notification is sent to TD OS via
callback interrupt vector configured by TD using
SetupEventNotifyInterrupt hypercall.
  4. After receiving the generated TDQUOTE, a remote verifier can be
used to verify the quote and confirm the trustworthiness of the
TD.

Attestation agent uses IOCTLs implemented by the attestation driver to
complete the various steps of the attestation process.

Also note that, explicit access permissions are not enforced in this
driver because the quote and measurements are not a secret. However
the access permissions of the device node can be used to set any
desired access policy. The udev default is usually root access
only.

TDX_CMD_GEN_QUOTE IOCTL can be used to create an computation on the
host, but TDX assumes that the host is able to deal with malicious
guest flooding it anyways.

The interaction with the TDX module is like a RPM protocol here. There
are several operations (get tdreport, get quote) that need to input a
blob, and then output another blob. It was considered to use a sysfs
interface for this, but it doesn't fit well into the standard sysfs
model for configuring values. It would be possible to do read/write on
files, but it would need multiple file descriptors, which would be
somewhat messy. ioctls seems to be the best fitting and simplest model
here. There is one ioctl per operation, that takes the input blob and
returns the output blob, and as well as auxiliary ioctls to return the
blob lengths. The ioctls are documented in the header file. 

[Chenyi Qiang: Proposed struct tdx_gen_quote for passing user buffer]
Reviewed-by: Tony Luck <[email protected]>
Reviewed-by: Andi Kleen <[email protected]>
Acked-by: Hans de Goede <[email protected]>
Signed-off-by: Kuppuswamy Sathyanarayanan <[email protected]>
---
drivers/platform/x86/intel/Kconfig | 1 +
drivers/platform/x86/intel/Makefile | 1 +
drivers/platform/x86/intel/tdx/Kconfig | 13 +
drivers/platform/x86/intel/tdx/Makefile | 3 +
.../platform/x86/intel/tdx/intel_tdx_attest.c | 241 ++++++++++++++++++
include/uapi/misc/tdx.h | 37 +++
6 files changed, 296 insertions(+)
create mode 100644 drivers/platform/x86/intel/tdx/Kconfig
create mode 100644 drivers/platform/x86/intel/tdx/Makefile
create mode 100644 drivers/platform/x86/intel/tdx/intel_tdx_attest.c
create mode 100644 include/uapi/misc/tdx.h

diff --git a/drivers/platform/x86/intel/Kconfig b/drivers/platform/x86/intel/Kconfig
index 8e65086bb6c8..a2ed17d67052 100644
--- a/drivers/platform/x86/intel/Kconfig
+++ b/drivers/platform/x86/intel/Kconfig
@@ -12,6 +12,7 @@ source "drivers/platform/x86/intel/pmt/Kconfig"
source "drivers/platform/x86/intel/speed_select_if/Kconfig"
source "drivers/platform/x86/intel/telemetry/Kconfig"
source "drivers/platform/x86/intel/wmi/Kconfig"
+source "drivers/platform/x86/intel/tdx/Kconfig"

config INTEL_HID_EVENT
tristate "Intel HID Event"
diff --git a/drivers/platform/x86/intel/Makefile b/drivers/platform/x86/intel/Makefile
index 35f2066578b2..27a6c6c5a83f 100644
--- a/drivers/platform/x86/intel/Makefile
+++ b/drivers/platform/x86/intel/Makefile
@@ -11,6 +11,7 @@ obj-$(CONFIG_INTEL_SKL_INT3472) += int3472/
obj-$(CONFIG_INTEL_PMC_CORE) += pmc/
obj-$(CONFIG_INTEL_PMT_CLASS) += pmt/
obj-$(CONFIG_INTEL_SPEED_SELECT_INTERFACE) += speed_select_if/
+obj-$(CONFIG_INTEL_TDX_GUEST) += tdx/
obj-$(CONFIG_INTEL_TELEMETRY) += telemetry/
obj-$(CONFIG_INTEL_WMI) += wmi/

diff --git a/drivers/platform/x86/intel/tdx/Kconfig b/drivers/platform/x86/intel/tdx/Kconfig
new file mode 100644
index 000000000000..853e3a34c889
--- /dev/null
+++ b/drivers/platform/x86/intel/tdx/Kconfig
@@ -0,0 +1,13 @@
+# SPDX-License-Identifier: GPL-2.0-only
+#
+# X86 TDX Platform Specific Drivers
+#
+
+config INTEL_TDX_ATTESTATION
+ tristate "Intel TDX attestation driver"
+ depends on INTEL_TDX_GUEST
+ help
+ The TDX attestation driver provides IOCTL interfaces to the user to
+ request TDREPORT from the TDX module or request quote from the VMM
+ or to get quote buffer size. It is mainly used to get secure disk
+ decryption keys from the key server.
diff --git a/drivers/platform/x86/intel/tdx/Makefile b/drivers/platform/x86/intel/tdx/Makefile
new file mode 100644
index 000000000000..124d6b7b20a0
--- /dev/null
+++ b/drivers/platform/x86/intel/tdx/Makefile
@@ -0,0 +1,3 @@
+# SPDX-License-Identifier: GPL-2.0-only
+
+obj-$(CONFIG_INTEL_TDX_ATTESTATION) += intel_tdx_attest.o
diff --git a/drivers/platform/x86/intel/tdx/intel_tdx_attest.c b/drivers/platform/x86/intel/tdx/intel_tdx_attest.c
new file mode 100644
index 000000000000..1db6c4f22692
--- /dev/null
+++ b/drivers/platform/x86/intel/tdx/intel_tdx_attest.c
@@ -0,0 +1,241 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * intel_tdx_attest.c - TDX guest attestation interface driver.
+ *
+ * Implements user interface to trigger attestation process and
+ * read the TD Quote result.
+ *
+ * Copyright (C) 2021-2022 Intel Corporation
+ *
+ * Author:
+ * Kuppuswamy Sathyanarayanan <[email protected]>
+ */
+
+#define pr_fmt(fmt) "x86/tdx: attest: " fmt
+
+#include <linux/module.h>
+#include <linux/miscdevice.h>
+#include <linux/uaccess.h>
+#include <linux/fs.h>
+#include <linux/mm.h>
+#include <linux/slab.h>
+#include <linux/set_memory.h>
+#include <linux/dma-mapping.h>
+#include <linux/jiffies.h>
+#include <linux/io.h>
+#include <asm/apic.h>
+#include <asm/tdx.h>
+#include <asm/irq_vectors.h>
+#include <uapi/misc/tdx.h>
+
+/* Used in Quote memory allocation */
+#define QUOTE_SIZE (2 * PAGE_SIZE)
+/* Used in Get Quote request memory allocation */
+#define GET_QUOTE_MAX_SIZE (4 * PAGE_SIZE)
+/* Get Quote timeout in msec */
+#define GET_QUOTE_TIMEOUT (5000)
+
+/* Mutex to synchronize attestation requests */
+static DEFINE_MUTEX(attestation_lock);
+/* Completion object to track attestation status */
+static DECLARE_COMPLETION(attestation_done);
+/* Buffer used to copy report data in attestation handler */
+static u8 report_data[TDX_REPORT_DATA_LEN] __aligned(64);
+/* Data pointer used to get TD Quote data in attestation handler */
+static void *tdquote_data;
+/* Data pointer used to get TDREPORT data in attestation handler */
+static void *tdreport_data;
+/* DMA handle used to allocate and free tdquote DMA buffer */
+dma_addr_t tdquote_dma_handle;
+
+struct tdx_gen_quote {
+ void *buf __user;
+ size_t len;
+};
+
+static void attestation_callback_handler(void)
+{
+ complete(&attestation_done);
+}
+
+static long tdx_attest_ioctl(struct file *file, unsigned int cmd,
+ unsigned long arg)
+{
+ void __user *argp = (void __user *)arg;
+ struct tdx_gen_quote tdquote_req;
+ long ret = 0;
+
+ mutex_lock(&attestation_lock);
+
+ switch (cmd) {
+ case TDX_CMD_GET_TDREPORT:
+ if (copy_from_user(report_data, argp, TDX_REPORT_DATA_LEN)) {
+ ret = -EFAULT;
+ break;
+ }
+
+ /* Generate TDREPORT_STRUCT */
+ if (tdx_mcall_tdreport(tdreport_data, report_data)) {
+ ret = -EIO;
+ break;
+ }
+
+ if (copy_to_user(argp, tdreport_data, TDX_TDREPORT_LEN))
+ ret = -EFAULT;
+ break;
+ case TDX_CMD_GEN_QUOTE:
+ reinit_completion(&attestation_done);
+
+ /* Copy TDREPORT data from user buffer */
+ if (copy_from_user(&tdquote_req, argp, sizeof(struct tdx_gen_quote))) {
+ ret = -EFAULT;
+ break;
+ }
+
+ if (tdquote_req.len <= 0 || tdquote_req.len > GET_QUOTE_MAX_SIZE) {
+ ret = -EINVAL;
+ break;
+ }
+
+ if (copy_from_user(tdquote_data, tdquote_req.buf, tdquote_req.len)) {
+ ret = -EFAULT;
+ break;
+ }
+
+ /* Submit GetQuote Request */
+ if (tdx_hcall_get_quote(tdquote_data)) {
+ ret = -EIO;
+ break;
+ }
+
+ /* Wait for attestation completion */
+ ret = wait_for_completion_interruptible_timeout(
+ &attestation_done,
+ msecs_to_jiffies(GET_QUOTE_TIMEOUT));
+ if (ret <= 0) {
+ ret = -EIO;
+ break;
+ }
+
+ /* ret will be positive if completed. */
+ ret = 0;
+
+ if (copy_to_user(tdquote_req.buf, tdquote_data, tdquote_req.len))
+ ret = -EFAULT;
+
+ break;
+ case TDX_CMD_GET_QUOTE_SIZE:
+ ret = put_user(QUOTE_SIZE, (u64 __user *)argp);
+ break;
+ default:
+ pr_err("cmd %d not supported\n", cmd);
+ break;
+ }
+
+ mutex_unlock(&attestation_lock);
+
+ return ret;
+}
+
+static const struct file_operations tdx_attest_fops = {
+ .owner = THIS_MODULE,
+ .unlocked_ioctl = tdx_attest_ioctl,
+ .llseek = no_llseek,
+};
+
+static struct miscdevice tdx_attest_device = {
+ .minor = MISC_DYNAMIC_MINOR,
+ .name = "tdx-attest",
+ .fops = &tdx_attest_fops,
+};
+
+static int __init tdx_attest_init(void)
+{
+ dma_addr_t handle;
+ long ret = 0;
+
+ mutex_lock(&attestation_lock);
+
+ ret = misc_register(&tdx_attest_device);
+ if (ret) {
+ pr_err("misc device registration failed\n");
+ mutex_unlock(&attestation_lock);
+ return ret;
+ }
+
+ /*
+ * tdreport_data needs to be 64-byte aligned.
+ * Full page alignment is more than enough.
+ */
+ tdreport_data = (void *)__get_free_pages(GFP_KERNEL | __GFP_ZERO, 0);
+ if (!tdreport_data) {
+ ret = -ENOMEM;
+ goto failed;
+ }
+
+ ret = dma_set_coherent_mask(tdx_attest_device.this_device,
+ DMA_BIT_MASK(64));
+ if (ret) {
+ pr_err("dma set coherent mask failed\n");
+ goto failed;
+ }
+
+ /* Allocate DMA buffer to get TDQUOTE data from the VMM */
+ tdquote_data = dma_alloc_coherent(tdx_attest_device.this_device,
+ GET_QUOTE_MAX_SIZE, &handle,
+ GFP_KERNEL | __GFP_ZERO);
+ if (!tdquote_data) {
+ ret = -ENOMEM;
+ goto failed;
+ }
+
+ tdquote_dma_handle = handle;
+
+ /*
+ * Currently tdx_event_notify_handler is only used in attestation
+ * driver. But, WRITE_ONCE is used as benign data race notice.
+ */
+ WRITE_ONCE(tdx_event_notify_handler, attestation_callback_handler);
+
+ mutex_unlock(&attestation_lock);
+
+ pr_debug("module initialization success\n");
+
+ return 0;
+
+failed:
+ if (tdreport_data)
+ free_pages((unsigned long)tdreport_data, 0);
+
+ misc_deregister(&tdx_attest_device);
+
+ mutex_unlock(&attestation_lock);
+
+ pr_debug("module initialization failed\n");
+
+ return ret;
+}
+
+static void __exit tdx_attest_exit(void)
+{
+ mutex_lock(&attestation_lock);
+
+ dma_free_coherent(tdx_attest_device.this_device, GET_QUOTE_MAX_SIZE,
+ tdquote_data, tdquote_dma_handle);
+ free_pages((unsigned long)tdreport_data, 0);
+ misc_deregister(&tdx_attest_device);
+ /*
+ * Currently tdx_event_notify_handler is only used in attestation
+ * driver. But, WRITE_ONCE is used as benign data race notice.
+ */
+ WRITE_ONCE(tdx_event_notify_handler, NULL);
+ mutex_unlock(&attestation_lock);
+ pr_debug("module is successfully removed\n");
+}
+
+module_init(tdx_attest_init);
+module_exit(tdx_attest_exit);
+
+MODULE_AUTHOR("Kuppuswamy Sathyanarayanan <[email protected]>");
+MODULE_DESCRIPTION("TDX attestation driver");
+MODULE_LICENSE("GPL");
diff --git a/include/uapi/misc/tdx.h b/include/uapi/misc/tdx.h
new file mode 100644
index 000000000000..da4b3866ea1b
--- /dev/null
+++ b/include/uapi/misc/tdx.h
@@ -0,0 +1,37 @@
+/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
+#ifndef _UAPI_MISC_TDX_H
+#define _UAPI_MISC_TDX_H
+
+#include <linux/types.h>
+#include <linux/ioctl.h>
+
+/* Input report data length for TDX_CMD_GET_TDREPORT IOCTL request */
+#define TDX_REPORT_DATA_LEN 64
+
+/* Output TD report data length after TDX_CMD_GET_TDREPORT IOCTL execution */
+#define TDX_TDREPORT_LEN 1024
+
+/*
+ * TDX_CMD_GET_TDREPORT IOCTL is used to get TDREPORT data from the TDX
+ * Module. Users should pass report data of size TDX_REPORT_DATA_LEN bytes
+ * via user input buffer of size TDX_TDREPORT_LEN. Once IOCTL is successful
+ * TDREPORT data is copied to the user buffer.
+ */
+#define TDX_CMD_GET_TDREPORT _IOWR('T', 0x01, __u64)
+
+/*
+ * TDX_CMD_GEN_QUOTE IOCTL is used to request TD QUOTE from the VMM. User
+ * should pass TD report data of size TDX_TDREPORT_LEN bytes via user input
+ * buffer of quote size. Once IOCTL is successful quote data is copied back to
+ * the user buffer.
+ */
+#define TDX_CMD_GEN_QUOTE _IOR('T', 0x02, __u64)
+
+/*
+ * TDX_CMD_GET_QUOTE_SIZE IOCTL is used to get the TD Quote size info in bytes.
+ * This will be used for determining the input buffer allocation size when
+ * using TDX_CMD_GEN_QUOTE IOCTL.
+ */
+#define TDX_CMD_GET_QUOTE_SIZE _IOR('T', 0x03, __u64)
+
+#endif /* _UAPI_MISC_TDX_H */
--
2.25.1

Subject: [PATCH v1 3/6] x86/tdx: Add SetupEventNotifyInterrupt TDX hypercall support

SetupEventNotifyInterrupt TDX hypercall is used by guest TD to specify
which interrupt vector to use as an event-notify vector to the VMM.
Such registered vector is also used by Host VMM to notify about
completion of GetQuote requests to the Guest TD.

Add tdx_hcall_set_notify_intr() helper function to implement the
SetupEventNotifyInterrupt hypercall.

This will be used by the TD guest attestation driver.

Details about the SetupEventNotifyInterrupt TDVMCALL can be found in
TDX Guest-Host Communication Interface (GHCI) Specification, sec 3.5
"VP.VMCALL<SetupEventNotifyInterrupt>".

Reviewed-by: Tony Luck <[email protected]>
Reviewed-by: Andi Kleen <[email protected]>
Signed-off-by: Kuppuswamy Sathyanarayanan <[email protected]>
---
arch/x86/coco/tdx.c | 33 +++++++++++++++++++++++++++++++++
1 file changed, 33 insertions(+)

diff --git a/arch/x86/coco/tdx.c b/arch/x86/coco/tdx.c
index 2c07f9551d3b..d18508e6150f 100644
--- a/arch/x86/coco/tdx.c
+++ b/arch/x86/coco/tdx.c
@@ -22,6 +22,7 @@
/* TDX hypercall Leaf IDs */
#define TDVMCALL_MAP_GPA 0x10001
#define TDVMCALL_GET_QUOTE 0x10002
+#define TDVMCALL_SETUP_NOTIFY_INTR 0x10004

/* MMIO direction */
#define EPT_READ 0
@@ -175,6 +176,38 @@ int tdx_hcall_get_quote(void *data)
}
EXPORT_SYMBOL_GPL(tdx_hcall_get_quote);

+/*
+ * tdx_hcall_set_notify_intr() - Setup Event Notify Interrupt Vector.
+ *
+ * @vector : Vector address to be used for notification.
+ *
+ * return 0 on success or failure error number.
+ */
+static int tdx_hcall_set_notify_intr(u8 vector)
+{
+ u64 ret;
+
+ /* Minimum vector value allowed is 32 */
+ if (vector < 32)
+ return -EINVAL;
+
+ /*
+ * Register callback vector address with VMM. More details
+ * about the ABI can be found in TDX Guest-Host-Communication
+ * Interface (GHCI), sec titled
+ * "TDG.VP.VMCALL<SetupEventNotifyInterrupt>".
+ */
+ ret = _tdx_hypercall(TDVMCALL_SETUP_NOTIFY_INTR, vector, 0, 0, 0);
+
+ if (ret) {
+ if (ret == TDCALL_INVALID_OPERAND)
+ return -EINVAL;
+ return -EIO;
+ }
+
+ return 0;
+}
+
static void get_info(void)
{
struct tdx_module_output out;
--
2.25.1

Subject: [PATCH v1 6/6] tools/tdx: Add a sample attestation user app

This application uses the misc device /dev/tdx-attest to get TDREPORT
from the TDX Module or request quote from the VMM.

It tests following attestation features:

- Get report using TDX_CMD_GET_TDREPORT IOCTL.
- Using report data request quote from VMM using TDX_CMD_GEN_QUOTE IOCTL.
- Get the quote size using TDX_CMD_GET_QUOTE_SIZE IOCTL.

Reviewed-by: Tony Luck <[email protected]>
Reviewed-by: Andi Kleen <[email protected]>
Signed-off-by: Kuppuswamy Sathyanarayanan <[email protected]>
---
tools/Makefile | 13 +-
tools/tdx/Makefile | 19 +++
tools/tdx/attest/.gitignore | 2 +
tools/tdx/attest/Makefile | 24 +++
tools/tdx/attest/tdx-attest-test.c | 240 +++++++++++++++++++++++++++++
5 files changed, 292 insertions(+), 6 deletions(-)
create mode 100644 tools/tdx/Makefile
create mode 100644 tools/tdx/attest/.gitignore
create mode 100644 tools/tdx/attest/Makefile
create mode 100644 tools/tdx/attest/tdx-attest-test.c

diff --git a/tools/Makefile b/tools/Makefile
index db2f7b8ebed5..e40783b7726d 100644
--- a/tools/Makefile
+++ b/tools/Makefile
@@ -30,6 +30,7 @@ help:
@echo ' selftests - various kernel selftests'
@echo ' bootconfig - boot config tool'
@echo ' spi - spi tools'
+ @echo ' tdx - TDX related test tools'
@echo ' tmon - thermal monitoring and tuning tool'
@echo ' tracing - misc tracing tools'
@echo ' turbostat - Intel CPU idle stats and freq reporting tool'
@@ -65,7 +66,7 @@ acpi: FORCE
cpupower: FORCE
$(call descend,power/$@)

-cgroup counter firewire hv guest bootconfig spi usb virtio vm bpf iio gpio objtool leds wmi pci firmware debugging tracing: FORCE
+cgroup counter firewire hv guest bootconfig spi usb virtio vm bpf iio gpio objtool leds wmi pci firmware debugging tracing tdx: FORCE
$(call descend,$@)

bpf/%: FORCE
@@ -101,7 +102,7 @@ all: acpi cgroup counter cpupower gpio hv firewire \
perf selftests bootconfig spi turbostat usb \
virtio vm bpf x86_energy_perf_policy \
tmon freefall iio objtool kvm_stat wmi \
- pci debugging tracing
+ pci debugging tracing tdx

acpi_install:
$(call descend,power/$(@:_install=),install)
@@ -109,7 +110,7 @@ acpi_install:
cpupower_install:
$(call descend,power/$(@:_install=),install)

-cgroup_install counter_install firewire_install gpio_install hv_install iio_install perf_install bootconfig_install spi_install usb_install virtio_install vm_install bpf_install objtool_install wmi_install pci_install debugging_install tracing_install:
+cgroup_install counter_install firewire_install gpio_install hv_install iio_install perf_install bootconfig_install spi_install usb_install virtio_install vm_install bpf_install objtool_install wmi_install pci_install debugging_install tracing_install tdx_install:
$(call descend,$(@:_install=),install)

selftests_install:
@@ -133,7 +134,7 @@ install: acpi_install cgroup_install counter_install cpupower_install gpio_insta
virtio_install vm_install bpf_install x86_energy_perf_policy_install \
tmon_install freefall_install objtool_install kvm_stat_install \
wmi_install pci_install debugging_install intel-speed-select_install \
- tracing_install
+ tracing_install tdx_install

acpi_clean:
$(call descend,power/acpi,clean)
@@ -141,7 +142,7 @@ acpi_clean:
cpupower_clean:
$(call descend,power/cpupower,clean)

-cgroup_clean counter_clean hv_clean firewire_clean bootconfig_clean spi_clean usb_clean virtio_clean vm_clean wmi_clean bpf_clean iio_clean gpio_clean objtool_clean leds_clean pci_clean firmware_clean debugging_clean tracing_clean:
+cgroup_clean counter_clean hv_clean firewire_clean bootconfig_clean spi_clean usb_clean virtio_clean vm_clean wmi_clean bpf_clean iio_clean gpio_clean objtool_clean leds_clean pci_clean firmware_clean debugging_clean tracing_clean tdx_clean:
$(call descend,$(@:_clean=),clean)

libapi_clean:
@@ -177,6 +178,6 @@ clean: acpi_clean cgroup_clean counter_clean cpupower_clean hv_clean firewire_cl
vm_clean bpf_clean iio_clean x86_energy_perf_policy_clean tmon_clean \
freefall_clean build_clean libbpf_clean libsubcmd_clean \
gpio_clean objtool_clean leds_clean wmi_clean pci_clean firmware_clean debugging_clean \
- intel-speed-select_clean tracing_clean
+ intel-speed-select_clean tracing_clean tdx_clean

.PHONY: FORCE
diff --git a/tools/tdx/Makefile b/tools/tdx/Makefile
new file mode 100644
index 000000000000..e2564557d463
--- /dev/null
+++ b/tools/tdx/Makefile
@@ -0,0 +1,19 @@
+# SPDX-License-Identifier: GPL-2.0
+include ../scripts/Makefile.include
+
+all: attest
+
+clean: attest_clean
+
+install: attest_install
+
+attest:
+ $(call descend,attest)
+
+attest_install:
+ $(call descend,attest,install)
+
+attest_clean:
+ $(call descend,attest,clean)
+
+.PHONY: all install clean attest latency_install latency_clean
diff --git a/tools/tdx/attest/.gitignore b/tools/tdx/attest/.gitignore
new file mode 100644
index 000000000000..5f819a8a6c49
--- /dev/null
+++ b/tools/tdx/attest/.gitignore
@@ -0,0 +1,2 @@
+# SPDX-License-Identifier: GPL-2.0
+tdx-attest-test
diff --git a/tools/tdx/attest/Makefile b/tools/tdx/attest/Makefile
new file mode 100644
index 000000000000..bf47ba718386
--- /dev/null
+++ b/tools/tdx/attest/Makefile
@@ -0,0 +1,24 @@
+# SPDX-License-Identifier: GPL-2.0
+# Makefile for vm tools
+#
+VAR_CFLAGS := $(shell pkg-config --cflags libtracefs 2>/dev/null)
+VAR_LDLIBS := $(shell pkg-config --libs libtracefs 2>/dev/null)
+
+TARGETS = tdx-attest-test
+CFLAGS = -static -Wall -Wextra -g -O2 $(VAR_CFLAGS)
+LDFLAGS = -lpthread $(VAR_LDLIBS)
+
+all: $(TARGETS)
+
+%: %.c
+ $(CC) $(CFLAGS) -o $@ $< $(LDFLAGS)
+
+clean:
+ $(RM) tdx-attest-test
+
+prefix ?= /usr/local
+sbindir ?= ${prefix}/sbin
+
+install: all
+ install -d $(DESTDIR)$(sbindir)
+ install -m 755 -p $(TARGETS) $(DESTDIR)$(sbindir)
diff --git a/tools/tdx/attest/tdx-attest-test.c b/tools/tdx/attest/tdx-attest-test.c
new file mode 100644
index 000000000000..08f776f6802a
--- /dev/null
+++ b/tools/tdx/attest/tdx-attest-test.c
@@ -0,0 +1,240 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * tdx-attest-test.c - utility to test TDX attestation feature.
+ *
+ * Copyright (C) 2021 - 2022 Intel Corporation. All rights reserved.
+ *
+ * Author: Kuppuswamy Sathyanarayanan <[email protected]>
+ *
+ */
+
+#include <linux/types.h>
+#include <linux/ioctl.h>
+#include <sys/ioctl.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <stdio.h>
+#include <ctype.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <limits.h>
+#include <stdbool.h>
+#include <getopt.h>
+#include <stdint.h> /* uintmax_t */
+#include <sys/mman.h>
+#include <time.h>
+
+#include "../../../include/uapi/misc/tdx.h"
+
+#define devname "/dev/tdx-attest"
+
+#define HEX_DUMP_SIZE 16
+#define MAX_ROW_SIZE 70
+
+#define ATTESTATION_TEST_BIN_VERSION "0.1"
+
+struct tdx_attest_args {
+ bool is_dump_data;
+ bool is_get_tdreport;
+ bool is_get_quote_size;
+ bool is_gen_quote;
+ bool debug_mode;
+ char *out_file;
+};
+
+struct tdx_gen_quote {
+ void *buf;
+ size_t len;
+};
+
+static void print_hex_dump(const char *title, const char *prefix_str,
+ const void *buf, int len)
+{
+ const __u8 *ptr = buf;
+ int i, rowsize = HEX_DUMP_SIZE;
+
+ if (!len || !buf)
+ return;
+
+ printf("\t\t%s", title);
+
+ for (i = 0; i < len; i++) {
+ if (!(i % rowsize))
+ printf("\n%s%.8x:", prefix_str, i);
+ printf(" %.2x", ptr[i]);
+ }
+
+ printf("\n");
+}
+
+static void gen_report_data(__u8 *report_data, bool dump_data)
+{
+ int i;
+
+ srand(time(NULL));
+
+ for (i = 0; i < TDX_REPORT_DATA_LEN; i++)
+ report_data[i] = rand();
+
+ if (dump_data)
+ print_hex_dump("\n\t\tTDX report data\n", " ",
+ report_data, TDX_REPORT_DATA_LEN);
+}
+
+static int get_tdreport(int devfd, bool dump_data, __u8 *report_data)
+{
+ __u8 tdrdata[TDX_TDREPORT_LEN] = {0};
+ int ret;
+
+ if (!report_data)
+ report_data = tdrdata;
+
+ gen_report_data(report_data, dump_data);
+
+ ret = ioctl(devfd, TDX_CMD_GET_TDREPORT, report_data);
+ if (ret) {
+ printf("TDX_CMD_GET_TDREPORT ioctl() %d failed\n", ret);
+ return -EIO;
+ }
+
+ if (dump_data)
+ print_hex_dump("\n\t\tTDX tdreport data\n", " ", report_data,
+ TDX_TDREPORT_LEN);
+
+ return 0;
+}
+
+static __u64 get_quote_size(int devfd)
+{
+ int ret;
+ __u64 quote_size;
+
+ ret = ioctl(devfd, TDX_CMD_GET_QUOTE_SIZE, &quote_size);
+ if (ret) {
+ printf("TDX_CMD_GET_QUOTE_SIZE ioctl() %d failed\n", ret);
+ return -EIO;
+ }
+
+ printf("Quote size: %lld\n", quote_size);
+
+ return quote_size;
+}
+
+static int gen_quote(int devfd, bool dump_data)
+{
+ __u8 *quote_data;
+ __u64 quote_size;
+ int ret;
+ struct tdx_gen_quote getquote_arg;
+
+ quote_size = get_quote_size(devfd);
+
+ quote_data = malloc(sizeof(char) * quote_size);
+ if (!quote_data) {
+ printf("%s queue data alloc failed\n", devname);
+ return -ENOMEM;
+ }
+
+ ret = get_tdreport(devfd, dump_data, quote_data);
+ if (ret) {
+ printf("TDX_CMD_GET_TDREPORT ioctl() %d failed\n", ret);
+ goto done;
+ }
+
+ getquote_arg.buf = quote_data;
+ getquote_arg.len = quote_size;
+
+ ret = ioctl(devfd, TDX_CMD_GEN_QUOTE, &getquote_arg);
+ if (ret) {
+ printf("TDX_CMD_GEN_QUOTE ioctl() %d failed\n", ret);
+ goto done;
+ }
+
+ print_hex_dump("\n\t\tTDX Quote data\n", " ", quote_data,
+ quote_size);
+
+done:
+ free(quote_data);
+
+ return ret;
+}
+
+static void usage(void)
+{
+ puts("\nUsage:\n");
+ puts("tdx_attest [options] \n");
+
+ puts("Attestation device test utility.");
+
+ puts("\nOptions:\n");
+ puts(" -d, --dump Dump tdreport/tdquote data");
+ puts(" -r, --get-tdreport Get TDREPORT data");
+ puts(" -g, --gen-quote Generate TDQUOTE");
+ puts(" -s, --get-quote-size Get TDQUOTE size");
+}
+
+int main(int argc, char **argv)
+{
+ int ret, devfd;
+ struct tdx_attest_args args = {0};
+
+ static const struct option longopts[] = {
+ { "dump", no_argument, NULL, 'd' },
+ { "get-tdreport", required_argument, NULL, 'r' },
+ { "gen-quote", required_argument, NULL, 'g' },
+ { "gen-quote-size", required_argument, NULL, 's' },
+ { "version", no_argument, NULL, 'V' },
+ { NULL, 0, NULL, 0 }
+ };
+
+ while ((ret = getopt_long(argc, argv, "hdrgsV", longopts,
+ NULL)) != -1) {
+ switch (ret) {
+ case 'd':
+ args.is_dump_data = true;
+ break;
+ case 'r':
+ args.is_get_tdreport = true;
+ break;
+ case 'g':
+ args.is_gen_quote = true;
+ break;
+ case 's':
+ args.is_get_quote_size = true;
+ break;
+ case 'h':
+ usage();
+ return 0;
+ case 'V':
+ printf("Version: %s\n", ATTESTATION_TEST_BIN_VERSION);
+ return 0;
+ default:
+ printf("Invalid options\n");
+ usage();
+ return -EINVAL;
+ }
+ }
+
+ devfd = open(devname, O_RDWR | O_SYNC);
+ if (devfd < 0) {
+ printf("%s open() failed\n", devname);
+ return -ENODEV;
+ }
+
+ if (args.is_get_quote_size)
+ get_quote_size(devfd);
+
+ if (args.is_get_tdreport)
+ get_tdreport(devfd, args.is_dump_data, NULL);
+
+ if (args.is_gen_quote)
+ gen_quote(devfd, args.is_dump_data);
+
+ close(devfd);
+
+ return 0;
+}
--
2.25.1

Subject: Re: [PATCH v1 0/6] Add TDX Guest Attestation support



On 2/24/22 7:32 AM, Hans de Goede wrote:
>> Patch titled "platform/x86: intel_tdx_attest: Add TDX Guest attestation
>> interface driver" adds the attestation driver support. This is supposed
>> to be reviewed by platform-x86 maintainers.
> At a quick glance this looks ok to me, but I really know very little
> about TDX. I assume the rest of the series will be reviewed by someone
> with more detailed knowledge of TDX as such I believe it would be good
> if the platform/x86 patch is also reviewed as part of that.
>
> Since the platform/x86 patch depends on the other patches I believe
> it is also best if the entire series is merged in one go by the x86/tip
> maintainers here is my ack for this:
>
> Acked-by: Hans de Goede<[email protected]>

Thanks.

>
>> Also, patch titled "tools/tdx: Add a sample attestation user app" adds
>> a testing app for attestation feature which needs review from
>> [email protected].
> I think that tool should be moved to tools/arch/x86/tdx regardless of
> moving it, tools are typically reviewed together with the kernel side
> and this has nothing to do with bpf.

I am fine with moving it to tools/arch/x86/*. I will do it in next
version. I have included bpf because this is what I got out of
./scripts/get_maintainer.pl.

>
> Regards,
>
> Hans
>

--
Sathyanarayanan Kuppuswamy
Linux Kernel Developer

2022-02-24 16:24:28

by Hans de Goede

[permalink] [raw]
Subject: Re: [PATCH v1 0/6] Add TDX Guest Attestation support

Hi,

On 2/23/22 00:17, Kuppuswamy Sathyanarayanan wrote:
> Hi All,
>
> Intel's Trust Domain Extensions (TDX) protect guest VMs from malicious
> hosts and some physical attacks. VM guest with TDX support is called
> as TD Guest.
>
> In TD Guest, the attestation process is used to verify the
> trustworthiness of TD guest to the 3rd party servers. Such attestation
> process is required by 3rd party servers before sending sensitive
> information to TD guests. One usage example is to get encryption keys
> from the key server for mounting the encrypted rootfs or secondary drive.
>
> Following patches add the attestation support to TDX guest which
> includes attestation user interface driver, user agent example, and
> related hypercall support.
>
> In this series, only following patches are in arch/x86 and are
> intended for x86 maintainers review.
>
> * x86/tdx: Add TDREPORT TDX Module call support
> * x86/tdx: Add GetQuote TDX hypercall support
> * x86/tdx: Add SetupEventNotifyInterrupt TDX hypercall support
> * x86/tdx: Add TDX Guest event notify interrupt vector support
>
> Patch titled "platform/x86: intel_tdx_attest: Add TDX Guest attestation
> interface driver" adds the attestation driver support. This is supposed
> to be reviewed by platform-x86 maintainers.

At a quick glance this looks ok to me, but I really know very little
about TDX. I assume the rest of the series will be reviewed by someone
with more detailed knowledge of TDX as such I believe it would be good
if the platform/x86 patch is also reviewed as part of that.

Since the platform/x86 patch depends on the other patches I believe
it is also best if the entire series is merged in one go by the x86/tip
maintainers here is my ack for this:

Acked-by: Hans de Goede <[email protected]>

> Also, patch titled "tools/tdx: Add a sample attestation user app" adds
> a testing app for attestation feature which needs review from
> [email protected].

I think that tool should be moved to tools/arch/x86/tdx regardless of
moving it, tools are typically reviewed together with the kernel side
and this has nothing to do with bpf.

Regards,

Hans

>
> Dependencies:
> --------------
>
> This feature has dependency on TDX guest core patch set series.
>
> https://lore.kernel.org/all/[email protected]/T/
>
> History:
> ----------
>
> Previously this patch set was sent under title "Add TDX Guest
> Support (Attestation support)". In the previous version, only the
> attestation driver patch was reviewed and got acked. Rest of the
> patches need to be reviewed freshly.
>
> https://lore.kernel.org/bpf/20210806000946.2951441-1-sathyanarayanan.kuppuswamy@linux.intel.com/
>
> Changes since previous submission:
> * Updated commit log and error handling in TDREPORT, GetQuote and
> SetupEventNotifyInterrupt support patches.
> * Added locking support in attestation driver.
>
> Kuppuswamy Sathyanarayanan (6):
> x86/tdx: Add tdx_mcall_tdreport() API support
> x86/tdx: Add tdx_hcall_get_quote() API support
> x86/tdx: Add SetupEventNotifyInterrupt TDX hypercall support
> platform/x86: intel_tdx_attest: Add TDX Guest attestation interface
> driver
> x86/tdx: Add TDX Guest event notify interrupt vector support
> tools/tdx: Add a sample attestation user app
>
> arch/x86/coco/tdx.c | 170 ++++++++++++
> arch/x86/include/asm/hardirq.h | 4 +
> arch/x86/include/asm/idtentry.h | 4 +
> arch/x86/include/asm/irq_vectors.h | 7 +-
> arch/x86/include/asm/tdx.h | 5 +
> arch/x86/kernel/irq.c | 7 +
> drivers/platform/x86/intel/Kconfig | 1 +
> drivers/platform/x86/intel/Makefile | 1 +
> drivers/platform/x86/intel/tdx/Kconfig | 13 +
> drivers/platform/x86/intel/tdx/Makefile | 3 +
> .../platform/x86/intel/tdx/intel_tdx_attest.c | 241 ++++++++++++++++++
> include/uapi/misc/tdx.h | 37 +++
> tools/Makefile | 13 +-
> tools/tdx/Makefile | 19 ++
> tools/tdx/attest/.gitignore | 2 +
> tools/tdx/attest/Makefile | 24 ++
> tools/tdx/attest/tdx-attest-test.c | 240 +++++++++++++++++
> 17 files changed, 784 insertions(+), 7 deletions(-)
> create mode 100644 drivers/platform/x86/intel/tdx/Kconfig
> create mode 100644 drivers/platform/x86/intel/tdx/Makefile
> create mode 100644 drivers/platform/x86/intel/tdx/intel_tdx_attest.c
> create mode 100644 include/uapi/misc/tdx.h
> create mode 100644 tools/tdx/Makefile
> create mode 100644 tools/tdx/attest/.gitignore
> create mode 100644 tools/tdx/attest/Makefile
> create mode 100644 tools/tdx/attest/tdx-attest-test.c
>

Subject: Re: [PATCH v1 4/6] platform/x86: intel_tdx_attest: Add TDX Guest attestation interface driver



On 3/10/22 6:55 AM, Aubrey Li wrote:
> There seems to be a mismatch with
> https://github.com/intel/qemu-tdx/blob/tdx/target/i386/kvm/tdx.c#L1262
>
> It looks like qemu expects a tdx_get_quote_header before the raw TDREPORT data?

Yes, this is a recent change. I have modified the attestation test app
to accommodate it. It will be submitted in next version.

--
Sathyanarayanan Kuppuswamy
Linux Kernel Developer

Subject: Re: [PATCH v1 0/6] Add TDX Guest Attestation support



On 3/10/22 6:45 AM, Aubrey Li wrote:
>> This feature has dependency on TDX guest core patch set series.
>>
>> https://lore.kernel.org/all/[email protected]/T/
> Does this feature also have dependency on QEMU tdx support?
>

Yes, for end-to-end attestation testing it will have dependency
on QEMU. But for testing the operation of GetQuote and TDREPORT
TDCALLs/Hypercall, we don't need the QEMU attestation support.

--
Sathyanarayanan Kuppuswamy
Linux Kernel Developer

2022-03-10 23:52:38

by Li, Aubrey

[permalink] [raw]
Subject: Re: [PATCH v1 4/6] platform/x86: intel_tdx_attest: Add TDX Guest attestation interface driver

On 2022/2/23 上午7:17, Kuppuswamy Sathyanarayanan wrote:
> TDX guest supports encrypted disk as root or secondary drives.
> Decryption keys required to access such drives are usually maintained
> by 3rd party key servers. Attestation is required by 3rd party key
> servers to get the key for an encrypted disk volume, or possibly other
> encrypted services. Attestation is used to prove to the key server that
> the TD guest is running in a valid TD and the kernel and virtual BIOS
> and other environment are secure.
>
> During the boot process various components before the kernel accumulate
> hashes in the TDX module, which can then combined into a report. This
> would typically include a hash of the bios, bios configuration, boot
> loader, command line, kernel, initrd. After checking the hashes the
> key server will securely release the keys.
>
> The actual details of the attestation protocol depend on the particular
> key server configuration, but some parts are common and need to
> communicate with the TDX module.
>
> This communication is implemented in the attestation driver.
>
> The supported steps are:
>
> 1. TD guest generates the TDREPORT that contains version information
> about the Intel TDX module, measurement of the TD, along with a
> TD-specified nonce.
>   2. TD guest shares the TDREPORT with TD host via GetQuote hypercall
> which is used by the host to generate a quote via quoting
> enclave (QE).
>   3. Quote generation completion notification is sent to TD OS via
> callback interrupt vector configured by TD using
> SetupEventNotifyInterrupt hypercall.
>   4. After receiving the generated TDQUOTE, a remote verifier can be
> used to verify the quote and confirm the trustworthiness of the
> TD.
>
> Attestation agent uses IOCTLs implemented by the attestation driver to
> complete the various steps of the attestation process.
>
> Also note that, explicit access permissions are not enforced in this
> driver because the quote and measurements are not a secret. However
> the access permissions of the device node can be used to set any
> desired access policy. The udev default is usually root access
> only.
>
> TDX_CMD_GEN_QUOTE IOCTL can be used to create an computation on the
> host, but TDX assumes that the host is able to deal with malicious
> guest flooding it anyways.
>
> The interaction with the TDX module is like a RPM protocol here. There
> are several operations (get tdreport, get quote) that need to input a
> blob, and then output another blob. It was considered to use a sysfs
> interface for this, but it doesn't fit well into the standard sysfs
> model for configuring values. It would be possible to do read/write on
> files, but it would need multiple file descriptors, which would be
> somewhat messy. ioctls seems to be the best fitting and simplest model
> here. There is one ioctl per operation, that takes the input blob and
> returns the output blob, and as well as auxiliary ioctls to return the
> blob lengths. The ioctls are documented in the header file. 
>
> [Chenyi Qiang: Proposed struct tdx_gen_quote for passing user buffer]
> Reviewed-by: Tony Luck <[email protected]>
> Reviewed-by: Andi Kleen <[email protected]>
> Acked-by: Hans de Goede <[email protected]>
> Signed-off-by: Kuppuswamy Sathyanarayanan <[email protected]>
> ---
> drivers/platform/x86/intel/Kconfig | 1 +
> drivers/platform/x86/intel/Makefile | 1 +
> drivers/platform/x86/intel/tdx/Kconfig | 13 +
> drivers/platform/x86/intel/tdx/Makefile | 3 +
> .../platform/x86/intel/tdx/intel_tdx_attest.c | 241 ++++++++++++++++++
> include/uapi/misc/tdx.h | 37 +++
> 6 files changed, 296 insertions(+)
> create mode 100644 drivers/platform/x86/intel/tdx/Kconfig
> create mode 100644 drivers/platform/x86/intel/tdx/Makefile
> create mode 100644 drivers/platform/x86/intel/tdx/intel_tdx_attest.c
> create mode 100644 include/uapi/misc/tdx.h
>
> diff --git a/drivers/platform/x86/intel/Kconfig b/drivers/platform/x86/intel/Kconfig
> index 8e65086bb6c8..a2ed17d67052 100644
> --- a/drivers/platform/x86/intel/Kconfig
> +++ b/drivers/platform/x86/intel/Kconfig
> @@ -12,6 +12,7 @@ source "drivers/platform/x86/intel/pmt/Kconfig"
> source "drivers/platform/x86/intel/speed_select_if/Kconfig"
> source "drivers/platform/x86/intel/telemetry/Kconfig"
> source "drivers/platform/x86/intel/wmi/Kconfig"
> +source "drivers/platform/x86/intel/tdx/Kconfig"
>
> config INTEL_HID_EVENT
> tristate "Intel HID Event"
> diff --git a/drivers/platform/x86/intel/Makefile b/drivers/platform/x86/intel/Makefile
> index 35f2066578b2..27a6c6c5a83f 100644
> --- a/drivers/platform/x86/intel/Makefile
> +++ b/drivers/platform/x86/intel/Makefile
> @@ -11,6 +11,7 @@ obj-$(CONFIG_INTEL_SKL_INT3472) += int3472/
> obj-$(CONFIG_INTEL_PMC_CORE) += pmc/
> obj-$(CONFIG_INTEL_PMT_CLASS) += pmt/
> obj-$(CONFIG_INTEL_SPEED_SELECT_INTERFACE) += speed_select_if/
> +obj-$(CONFIG_INTEL_TDX_GUEST) += tdx/
> obj-$(CONFIG_INTEL_TELEMETRY) += telemetry/
> obj-$(CONFIG_INTEL_WMI) += wmi/
>
> diff --git a/drivers/platform/x86/intel/tdx/Kconfig b/drivers/platform/x86/intel/tdx/Kconfig
> new file mode 100644
> index 000000000000..853e3a34c889
> --- /dev/null
> +++ b/drivers/platform/x86/intel/tdx/Kconfig
> @@ -0,0 +1,13 @@
> +# SPDX-License-Identifier: GPL-2.0-only
> +#
> +# X86 TDX Platform Specific Drivers
> +#
> +
> +config INTEL_TDX_ATTESTATION
> + tristate "Intel TDX attestation driver"
> + depends on INTEL_TDX_GUEST
> + help
> + The TDX attestation driver provides IOCTL interfaces to the user to
> + request TDREPORT from the TDX module or request quote from the VMM
> + or to get quote buffer size. It is mainly used to get secure disk
> + decryption keys from the key server.
> diff --git a/drivers/platform/x86/intel/tdx/Makefile b/drivers/platform/x86/intel/tdx/Makefile
> new file mode 100644
> index 000000000000..124d6b7b20a0
> --- /dev/null
> +++ b/drivers/platform/x86/intel/tdx/Makefile
> @@ -0,0 +1,3 @@
> +# SPDX-License-Identifier: GPL-2.0-only
> +
> +obj-$(CONFIG_INTEL_TDX_ATTESTATION) += intel_tdx_attest.o
> diff --git a/drivers/platform/x86/intel/tdx/intel_tdx_attest.c b/drivers/platform/x86/intel/tdx/intel_tdx_attest.c
> new file mode 100644
> index 000000000000..1db6c4f22692
> --- /dev/null
> +++ b/drivers/platform/x86/intel/tdx/intel_tdx_attest.c
> @@ -0,0 +1,241 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * intel_tdx_attest.c - TDX guest attestation interface driver.
> + *
> + * Implements user interface to trigger attestation process and
> + * read the TD Quote result.
> + *
> + * Copyright (C) 2021-2022 Intel Corporation
> + *
> + * Author:
> + * Kuppuswamy Sathyanarayanan <[email protected]>
> + */
> +
> +#define pr_fmt(fmt) "x86/tdx: attest: " fmt
> +
> +#include <linux/module.h>
> +#include <linux/miscdevice.h>
> +#include <linux/uaccess.h>
> +#include <linux/fs.h>
> +#include <linux/mm.h>
> +#include <linux/slab.h>
> +#include <linux/set_memory.h>
> +#include <linux/dma-mapping.h>
> +#include <linux/jiffies.h>
> +#include <linux/io.h>
> +#include <asm/apic.h>
> +#include <asm/tdx.h>
> +#include <asm/irq_vectors.h>
> +#include <uapi/misc/tdx.h>
> +
> +/* Used in Quote memory allocation */
> +#define QUOTE_SIZE (2 * PAGE_SIZE)
> +/* Used in Get Quote request memory allocation */
> +#define GET_QUOTE_MAX_SIZE (4 * PAGE_SIZE)
> +/* Get Quote timeout in msec */
> +#define GET_QUOTE_TIMEOUT (5000)
> +
> +/* Mutex to synchronize attestation requests */
> +static DEFINE_MUTEX(attestation_lock);
> +/* Completion object to track attestation status */
> +static DECLARE_COMPLETION(attestation_done);
> +/* Buffer used to copy report data in attestation handler */
> +static u8 report_data[TDX_REPORT_DATA_LEN] __aligned(64);
> +/* Data pointer used to get TD Quote data in attestation handler */
> +static void *tdquote_data;
> +/* Data pointer used to get TDREPORT data in attestation handler */
> +static void *tdreport_data;
> +/* DMA handle used to allocate and free tdquote DMA buffer */
> +dma_addr_t tdquote_dma_handle;
> +
> +struct tdx_gen_quote {
> + void *buf __user;
> + size_t len;
> +};
> +
> +static void attestation_callback_handler(void)
> +{
> + complete(&attestation_done);
> +}
> +
> +static long tdx_attest_ioctl(struct file *file, unsigned int cmd,
> + unsigned long arg)
> +{
> + void __user *argp = (void __user *)arg;
> + struct tdx_gen_quote tdquote_req;
> + long ret = 0;
> +
> + mutex_lock(&attestation_lock);
> +
> + switch (cmd) {
> + case TDX_CMD_GET_TDREPORT:
> + if (copy_from_user(report_data, argp, TDX_REPORT_DATA_LEN)) {
> + ret = -EFAULT;
> + break;
> + }
> +
> + /* Generate TDREPORT_STRUCT */
> + if (tdx_mcall_tdreport(tdreport_data, report_data)) {
> + ret = -EIO;
> + break;
> + }
> +
> + if (copy_to_user(argp, tdreport_data, TDX_TDREPORT_LEN))
> + ret = -EFAULT;
> + break;
> + case TDX_CMD_GEN_QUOTE:
> + reinit_completion(&attestation_done);
> +
> + /* Copy TDREPORT data from user buffer */
> + if (copy_from_user(&tdquote_req, argp, sizeof(struct tdx_gen_quote))) {
> + ret = -EFAULT;
> + break;
> + }
> +
> + if (tdquote_req.len <= 0 || tdquote_req.len > GET_QUOTE_MAX_SIZE) {
> + ret = -EINVAL;
> + break;
> + }
> +
> + if (copy_from_user(tdquote_data, tdquote_req.buf, tdquote_req.len)) {
> + ret = -EFAULT;
> + break;
> + }

There seems to be a mismatch with
https://github.com/intel/qemu-tdx/blob/tdx/target/i386/kvm/tdx.c#L1262

It looks like qemu expects a tdx_get_quote_header before the raw TDREPORT data?

Thanks,
-Aubrey

2022-03-11 21:27:04

by Li, Aubrey

[permalink] [raw]
Subject: Re: [PATCH v1 0/6] Add TDX Guest Attestation support

On 2022/2/23 上午7:17, Kuppuswamy Sathyanarayanan wrote:
> Hi All,
>
> Intel's Trust Domain Extensions (TDX) protect guest VMs from malicious
> hosts and some physical attacks. VM guest with TDX support is called
> as TD Guest.
>
> In TD Guest, the attestation process is used to verify the
> trustworthiness of TD guest to the 3rd party servers. Such attestation
> process is required by 3rd party servers before sending sensitive
> information to TD guests. One usage example is to get encryption keys
> from the key server for mounting the encrypted rootfs or secondary drive.
>
> Following patches add the attestation support to TDX guest which
> includes attestation user interface driver, user agent example, and
> related hypercall support.
>
> In this series, only following patches are in arch/x86 and are
> intended for x86 maintainers review.
>
> * x86/tdx: Add TDREPORT TDX Module call support
> * x86/tdx: Add GetQuote TDX hypercall support
> * x86/tdx: Add SetupEventNotifyInterrupt TDX hypercall support
> * x86/tdx: Add TDX Guest event notify interrupt vector support
>
> Patch titled "platform/x86: intel_tdx_attest: Add TDX Guest attestation
> interface driver" adds the attestation driver support. This is supposed
> to be reviewed by platform-x86 maintainers.
>
> Also, patch titled "tools/tdx: Add a sample attestation user app" adds
> a testing app for attestation feature which needs review from
> [email protected].
>
> Dependencies:
> --------------
>
> This feature has dependency on TDX guest core patch set series.
>
> https://lore.kernel.org/all/[email protected]/T/

Does this feature also have dependency on QEMU tdx support?

>
> History:
> ----------
>
> Previously this patch set was sent under title "Add TDX Guest
> Support (Attestation support)". In the previous version, only the
> attestation driver patch was reviewed and got acked. Rest of the
> patches need to be reviewed freshly.
>
> https://lore.kernel.org/bpf/20210806000946.2951441-1-sathyanarayanan.kuppuswamy@linux.intel.com/
>
> Changes since previous submission:
> * Updated commit log and error handling in TDREPORT, GetQuote and
> SetupEventNotifyInterrupt support patches.
> * Added locking support in attestation driver.
>
> Kuppuswamy Sathyanarayanan (6):
> x86/tdx: Add tdx_mcall_tdreport() API support
> x86/tdx: Add tdx_hcall_get_quote() API support
> x86/tdx: Add SetupEventNotifyInterrupt TDX hypercall support
> platform/x86: intel_tdx_attest: Add TDX Guest attestation interface
> driver
> x86/tdx: Add TDX Guest event notify interrupt vector support
> tools/tdx: Add a sample attestation user app
>
> arch/x86/coco/tdx.c | 170 ++++++++++++
> arch/x86/include/asm/hardirq.h | 4 +
> arch/x86/include/asm/idtentry.h | 4 +
> arch/x86/include/asm/irq_vectors.h | 7 +-
> arch/x86/include/asm/tdx.h | 5 +
> arch/x86/kernel/irq.c | 7 +
> drivers/platform/x86/intel/Kconfig | 1 +
> drivers/platform/x86/intel/Makefile | 1 +
> drivers/platform/x86/intel/tdx/Kconfig | 13 +
> drivers/platform/x86/intel/tdx/Makefile | 3 +
> .../platform/x86/intel/tdx/intel_tdx_attest.c | 241 ++++++++++++++++++
> include/uapi/misc/tdx.h | 37 +++
> tools/Makefile | 13 +-
> tools/tdx/Makefile | 19 ++
> tools/tdx/attest/.gitignore | 2 +
> tools/tdx/attest/Makefile | 24 ++
> tools/tdx/attest/tdx-attest-test.c | 240 +++++++++++++++++
> 17 files changed, 784 insertions(+), 7 deletions(-)
> create mode 100644 drivers/platform/x86/intel/tdx/Kconfig
> create mode 100644 drivers/platform/x86/intel/tdx/Makefile
> create mode 100644 drivers/platform/x86/intel/tdx/intel_tdx_attest.c
> create mode 100644 include/uapi/misc/tdx.h
> create mode 100644 tools/tdx/Makefile
> create mode 100644 tools/tdx/attest/.gitignore
> create mode 100644 tools/tdx/attest/Makefile
> create mode 100644 tools/tdx/attest/tdx-attest-test.c
>