Messages in this thread Patch in this message | | | From | "Kirill A. Shutemov" <> | Subject | [PATCHv4 05/30] x86/tdx: Extend the confidential computing API to support TDX guests | Date | Thu, 24 Feb 2022 18:56:05 +0300 |
| |
Confidential Computing (CC) features (like string I/O unroll support, memory encryption/decryption support, etc) are conditionally enabled in the kernel using cc_platform_has() API. Since TDX guests also need to use these CC features, extend cc_platform_has() API and add TDX guest-specific CC attributes support.
Like AMD SME/SEV, TDX uses a bit in the page table entry to indicate encryption status of the page, but the polarity of the mask is opposite to AMD: if the bit is set the page is accessible to VMM.
Details about which bit in the page table entry to be used to indicate shared/private state can be determined by using the TDINFO TDCALL.
Signed-off-by: Kirill A. Shutemov <kirill.shutemov@linux.intel.com> --- arch/x86/Kconfig | 1 + arch/x86/coco/core.c | 4 ++++ arch/x86/coco/tdx.c | 43 +++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 48 insertions(+)
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index c346d66b51fc..93e67842e369 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig @@ -884,6 +884,7 @@ config INTEL_TDX_GUEST bool "Intel TDX (Trust Domain Extensions) - Guest Support" depends on X86_64 && CPU_SUP_INTEL depends on X86_X2APIC + select ARCH_HAS_CC_PLATFORM help Support running as a guest under Intel TDX. Without this support, the guest kernel can not boot or run under TDX. diff --git a/arch/x86/coco/core.c b/arch/x86/coco/core.c index fc1365dd927e..9113baebbfd2 100644 --- a/arch/x86/coco/core.c +++ b/arch/x86/coco/core.c @@ -90,6 +90,8 @@ u64 cc_mkenc(u64 val) switch (vendor) { case CC_VENDOR_AMD: return val | cc_mask; + case CC_VENDOR_INTEL: + return val & ~cc_mask; default: return val; } @@ -100,6 +102,8 @@ u64 cc_mkdec(u64 val) switch (vendor) { case CC_VENDOR_AMD: return val & ~cc_mask; + case CC_VENDOR_INTEL: + return val | cc_mask; default: return val; } diff --git a/arch/x86/coco/tdx.c b/arch/x86/coco/tdx.c index 17365fd40ba2..74c6e68dd1b3 100644 --- a/arch/x86/coco/tdx.c +++ b/arch/x86/coco/tdx.c @@ -5,8 +5,17 @@ #define pr_fmt(fmt) "tdx: " fmt #include <linux/cpufeature.h> +#include <asm/coco.h> #include <asm/tdx.h> +/* TDX module Call Leaf IDs */ +#define TDX_GET_INFO 1 + +static struct { + unsigned int gpa_width; + unsigned long attributes; +} td_info __ro_after_init; + /* * Wrapper for standard use of __tdx_hypercall with no output aside from * return code. @@ -25,6 +34,30 @@ static inline u64 _tdx_hypercall(u64 fn, u64 r12, u64 r13, u64 r14, u64 r15) return __tdx_hypercall(&args, 0); } +static inline void tdx_module_call(u64 fn, u64 rcx, u64 rdx, u64 r8, u64 r9, + struct tdx_module_output *out) +{ + if (__tdx_module_call(fn, rcx, rdx, r8, r9, out)) + panic("TDCALL %lld failed (Buggy TDX module!)\n", fn); +} + +static void get_info(void) +{ + struct tdx_module_output out; + + /* + * TDINFO TDX module call is used to get the TD execution environment + * information like GPA width, number of available vcpus, debug mode + * information, etc. More details about the ABI can be found in TDX + * Guest-Host-Communication Interface (GHCI), section 2.4.2 TDCALL + * [TDG.VP.INFO]. + */ + tdx_module_call(TDX_GET_INFO, 0, 0, 0, 0, &out); + + td_info.gpa_width = out.rcx & GENMASK(5, 0); + td_info.attributes = out.rdx; +} + void __init tdx_early_init(void) { u32 eax, sig[3]; @@ -37,5 +70,15 @@ void __init tdx_early_init(void) setup_force_cpu_cap(X86_FEATURE_TDX_GUEST); + get_info(); + + cc_set_vendor(CC_VENDOR_INTEL); + + /* + * The highest bit of a guest physical address is the "sharing" bit. + * Set it for shared pages and clear it for private pages. + */ + cc_set_mask(BIT_ULL(td_info.gpa_width - 1)); + pr_info("Guest detected\n"); } -- 2.34.1
| |