Skip to content

Commit 41394e3

Browse files
kirylhansendc
authored andcommitted
x86/tdx: Extend the confidential computing API to support TDX guests
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. CC API also provides an interface to deal with encryption mask. Extend it to cover TDX. Details about which bit in the page table entry to be used to indicate shared/private state is determined by using the TDINFO TDCALL. Signed-off-by: Kirill A. Shutemov <[email protected]> Signed-off-by: Dave Hansen <[email protected]> Reviewed-by: Dave Hansen <[email protected]> Reviewed-by: Borislav Petkov <[email protected]> Link: https://lkml.kernel.org/r/[email protected]
1 parent eb94f1b commit 41394e3

File tree

3 files changed

+60
-0
lines changed

3 files changed

+60
-0
lines changed

arch/x86/Kconfig

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -882,6 +882,7 @@ config INTEL_TDX_GUEST
882882
bool "Intel TDX (Trust Domain Extensions) - Guest Support"
883883
depends on X86_64 && CPU_SUP_INTEL
884884
depends on X86_X2APIC
885+
select ARCH_HAS_CC_PLATFORM
885886
help
886887
Support running as a guest under Intel TDX. Without this support,
887888
the guest kernel can not boot or run under TDX.

arch/x86/coco/core.c

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,19 +87,31 @@ EXPORT_SYMBOL_GPL(cc_platform_has);
8787

8888
u64 cc_mkenc(u64 val)
8989
{
90+
/*
91+
* Both AMD and Intel use a bit in the page table to indicate
92+
* encryption status of the page.
93+
*
94+
* - for AMD, bit *set* means the page is encrypted
95+
* - for Intel *clear* means encrypted.
96+
*/
9097
switch (vendor) {
9198
case CC_VENDOR_AMD:
9299
return val | cc_mask;
100+
case CC_VENDOR_INTEL:
101+
return val & ~cc_mask;
93102
default:
94103
return val;
95104
}
96105
}
97106

98107
u64 cc_mkdec(u64 val)
99108
{
109+
/* See comment in cc_mkenc() */
100110
switch (vendor) {
101111
case CC_VENDOR_AMD:
102112
return val & ~cc_mask;
113+
case CC_VENDOR_INTEL:
114+
return val | cc_mask;
103115
default:
104116
return val;
105117
}

arch/x86/coco/tdx/tdx.c

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,12 @@
55
#define pr_fmt(fmt) "tdx: " fmt
66

77
#include <linux/cpufeature.h>
8+
#include <asm/coco.h>
89
#include <asm/tdx.h>
910

11+
/* TDX module Call Leaf IDs */
12+
#define TDX_GET_INFO 1
13+
1014
/*
1115
* Wrapper for standard use of __tdx_hypercall with no output aside from
1216
* return code.
@@ -31,8 +35,47 @@ void __tdx_hypercall_failed(void)
3135
panic("TDVMCALL failed. TDX module bug?");
3236
}
3337

38+
/*
39+
* Used for TDX guests to make calls directly to the TD module. This
40+
* should only be used for calls that have no legitimate reason to fail
41+
* or where the kernel can not survive the call failing.
42+
*/
43+
static inline void tdx_module_call(u64 fn, u64 rcx, u64 rdx, u64 r8, u64 r9,
44+
struct tdx_module_output *out)
45+
{
46+
if (__tdx_module_call(fn, rcx, rdx, r8, r9, out))
47+
panic("TDCALL %lld failed (Buggy TDX module!)\n", fn);
48+
}
49+
50+
static u64 get_cc_mask(void)
51+
{
52+
struct tdx_module_output out;
53+
unsigned int gpa_width;
54+
55+
/*
56+
* TDINFO TDX module call is used to get the TD execution environment
57+
* information like GPA width, number of available vcpus, debug mode
58+
* information, etc. More details about the ABI can be found in TDX
59+
* Guest-Host-Communication Interface (GHCI), section 2.4.2 TDCALL
60+
* [TDG.VP.INFO].
61+
*
62+
* The GPA width that comes out of this call is critical. TDX guests
63+
* can not meaningfully run without it.
64+
*/
65+
tdx_module_call(TDX_GET_INFO, 0, 0, 0, 0, &out);
66+
67+
gpa_width = out.rcx & GENMASK(5, 0);
68+
69+
/*
70+
* The highest bit of a guest physical address is the "sharing" bit.
71+
* Set it for shared pages and clear it for private pages.
72+
*/
73+
return BIT_ULL(gpa_width - 1);
74+
}
75+
3476
void __init tdx_early_init(void)
3577
{
78+
u64 cc_mask;
3679
u32 eax, sig[3];
3780

3881
cpuid_count(TDX_CPUID_LEAF_ID, 0, &eax, &sig[0], &sig[2], &sig[1]);
@@ -42,5 +85,9 @@ void __init tdx_early_init(void)
4285

4386
setup_force_cpu_cap(X86_FEATURE_TDX_GUEST);
4487

88+
cc_set_vendor(CC_VENDOR_INTEL);
89+
cc_mask = get_cc_mask();
90+
cc_set_mask(cc_mask);
91+
4592
pr_info("Guest detected\n");
4693
}

0 commit comments

Comments
 (0)