mirror of
https://git.proxmox.com/git/mirror_ubuntu-kernels.git
synced 2026-01-08 18:24:39 +00:00
In TDX guest, the attestation process is used to verify the TDX guest trustworthiness to other entities before provisioning secrets to the guest. The first step in the attestation process is TDREPORT generation, which involves getting the guest measurement data in the format of TDREPORT, which is further used to validate the authenticity of the TDX guest. TDREPORT by design is integrity-protected and can only be verified on the local machine. To support remote verification of the TDREPORT in a SGX-based attestation, the TDREPORT needs to be sent to the SGX Quoting Enclave (QE) to convert it to a remotely verifiable Quote. SGX QE by design can only run outside of the TDX guest (i.e. in a host process or in a normal VM) and guest can use communication channels like vsock or TCP/IP to send the TDREPORT to the QE. But for security concerns, the TDX guest may not support these communication channels. To handle such cases, TDX defines a GetQuote hypercall which can be used by the guest to request the host VMM to communicate with the SGX QE. More details about GetQuote hypercall can be found in TDX Guest-Host Communication Interface (GHCI) for Intel TDX 1.0, section titled "TDG.VP.VMCALL<GetQuote>". Trusted Security Module (TSM) [1] exposes a common ABI for Confidential Computing Guest platforms to get the measurement data via ConfigFS. Extend the TSM framework and add support to allow an attestation agent to get the TDX Quote data (included usage example below). report=/sys/kernel/config/tsm/report/report0 mkdir $report dd if=/dev/urandom bs=64 count=1 > $report/inblob hexdump -C $report/outblob rmdir $report GetQuote TDVMCALL requires TD guest pass a 4K aligned shared buffer with TDREPORT data as input, which is further used by the VMM to copy the TD Quote result after successful Quote generation. To create the shared buffer, allocate a large enough memory and mark it shared using set_memory_decrypted() in tdx_guest_init(). This buffer will be re-used for GetQuote requests in the TDX TSM handler. Although this method reserves a fixed chunk of memory for GetQuote requests, such one time allocation can help avoid memory fragmentation related allocation failures later in the uptime of the guest. Since the Quote generation process is not time-critical or frequently used, the current version uses a polling model for Quote requests and it also does not support parallel GetQuote requests. Link: https://lore.kernel.org/lkml/169342399185.3934343.3035845348326944519.stgit@dwillia2-xfh.jf.intel.com/ [1] Signed-off-by: Kuppuswamy Sathyanarayanan <sathyanarayanan.kuppuswamy@linux.intel.com> Reviewed-by: Erdem Aktas <erdemaktas@google.com> Tested-by: Kuppuswamy Sathyanarayanan <sathyanarayanan.kuppuswamy@linux.intel.com> Tested-by: Peter Gonda <pgonda@google.com> Reviewed-by: Tom Lendacky <thomas.lendacky@amd.com> Signed-off-by: Dan Williams <dan.j.williams@intel.com>
79 lines
1.9 KiB
C
79 lines
1.9 KiB
C
/* SPDX-License-Identifier: GPL-2.0 */
|
|
/* Copyright (C) 2021-2022 Intel Corporation */
|
|
#ifndef _ASM_X86_TDX_H
|
|
#define _ASM_X86_TDX_H
|
|
|
|
#include <linux/init.h>
|
|
#include <linux/bits.h>
|
|
|
|
#include <asm/errno.h>
|
|
#include <asm/ptrace.h>
|
|
#include <asm/shared/tdx.h>
|
|
|
|
/*
|
|
* SW-defined error codes.
|
|
*
|
|
* Bits 47:40 == 0xFF indicate Reserved status code class that never used by
|
|
* TDX module.
|
|
*/
|
|
#define TDX_ERROR _BITUL(63)
|
|
#define TDX_SW_ERROR (TDX_ERROR | GENMASK_ULL(47, 40))
|
|
#define TDX_SEAMCALL_VMFAILINVALID (TDX_SW_ERROR | _UL(0xFFFF0000))
|
|
|
|
#ifndef __ASSEMBLY__
|
|
|
|
/*
|
|
* Used by the #VE exception handler to gather the #VE exception
|
|
* info from the TDX module. This is a software only structure
|
|
* and not part of the TDX module/VMM ABI.
|
|
*/
|
|
struct ve_info {
|
|
u64 exit_reason;
|
|
u64 exit_qual;
|
|
/* Guest Linear (virtual) Address */
|
|
u64 gla;
|
|
/* Guest Physical Address */
|
|
u64 gpa;
|
|
u32 instr_len;
|
|
u32 instr_info;
|
|
};
|
|
|
|
#ifdef CONFIG_INTEL_TDX_GUEST
|
|
|
|
void __init tdx_early_init(void);
|
|
|
|
void tdx_get_ve_info(struct ve_info *ve);
|
|
|
|
bool tdx_handle_virt_exception(struct pt_regs *regs, struct ve_info *ve);
|
|
|
|
void tdx_safe_halt(void);
|
|
|
|
bool tdx_early_handle_ve(struct pt_regs *regs);
|
|
|
|
int tdx_mcall_get_report0(u8 *reportdata, u8 *tdreport);
|
|
|
|
u64 tdx_hcall_get_quote(u8 *buf, size_t size);
|
|
|
|
#else
|
|
|
|
static inline void tdx_early_init(void) { };
|
|
static inline void tdx_safe_halt(void) { };
|
|
|
|
static inline bool tdx_early_handle_ve(struct pt_regs *regs) { return false; }
|
|
|
|
#endif /* CONFIG_INTEL_TDX_GUEST */
|
|
|
|
#if defined(CONFIG_KVM_GUEST) && defined(CONFIG_INTEL_TDX_GUEST)
|
|
long tdx_kvm_hypercall(unsigned int nr, unsigned long p1, unsigned long p2,
|
|
unsigned long p3, unsigned long p4);
|
|
#else
|
|
static inline long tdx_kvm_hypercall(unsigned int nr, unsigned long p1,
|
|
unsigned long p2, unsigned long p3,
|
|
unsigned long p4)
|
|
{
|
|
return -ENODEV;
|
|
}
|
|
#endif /* CONFIG_INTEL_TDX_GUEST && CONFIG_KVM_GUEST */
|
|
#endif /* !__ASSEMBLY__ */
|
|
#endif /* _ASM_X86_TDX_H */
|