Skip to content

Commit

Permalink
x86/tdx: Extend the confidential computing API to support TDX guests
Browse files Browse the repository at this point in the history
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 <kirill.shutemov@linux.intel.com>
Reviewed-by: Dave Hansen <dave.hansen@linux.intel.com>
Reviewed-by: Borislav Petkov <bp@suse.de>
  • Loading branch information
kiryl committed Mar 16, 2022
1 parent 3878b00 commit 4148522
Show file tree
Hide file tree
Showing 3 changed files with 60 additions and 0 deletions.
1 change: 1 addition & 0 deletions arch/x86/Kconfig
Expand Up @@ -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.
Expand Down
12 changes: 12 additions & 0 deletions arch/x86/coco/core.c
Expand Up @@ -87,19 +87,31 @@ EXPORT_SYMBOL_GPL(cc_platform_has);

u64 cc_mkenc(u64 val)
{
/*
* Both AMD and Intel use a bit in the page table to indicate
* encryption status of the page.
*
* - for AMD, bit *set* means the page is encrypted
* - for Intel *clear* means encrypted.
*/
switch (vendor) {
case CC_VENDOR_AMD:
return val | cc_mask;
case CC_VENDOR_INTEL:
return val & ~cc_mask;
default:
return val;
}
}

u64 cc_mkdec(u64 val)
{
/* See comment in cc_mkenc() */
switch (vendor) {
case CC_VENDOR_AMD:
return val & ~cc_mask;
case CC_VENDOR_INTEL:
return val | cc_mask;
default:
return val;
}
Expand Down
47 changes: 47 additions & 0 deletions arch/x86/coco/tdx/tdx.c
Expand Up @@ -5,8 +5,12 @@
#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

/*
* Wrapper for standard use of __tdx_hypercall with no output aside from
* return code.
Expand All @@ -30,8 +34,41 @@ void __tdx_hypercall_failed(void)
{
panic("TDVMCALL failed. TDX module bug?");
}

/*
* Used for TDX guests to make calls directly to the TD module. This
* should only be used for calls that have no legitimate reason to fail
* or where the kernel can not survive the call failing.
*/
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(unsigned int *gpa_width)
{
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].
*
* The GPA width that comes out of this call is critical. TDX guests
* can not meaningfully run without it.
*/
tdx_module_call(TDX_GET_INFO, 0, 0, 0, 0, &out);

*gpa_width = out.rcx & GENMASK(5, 0);
}

void __init tdx_early_init(void)
{
unsigned int gpa_width;
u32 eax, sig[3];

cpuid_count(TDX_CPUID_LEAF_ID, 0, &eax, &sig[0], &sig[2], &sig[1]);
Expand All @@ -41,5 +78,15 @@ void __init tdx_early_init(void)

setup_force_cpu_cap(X86_FEATURE_TDX_GUEST);

get_info(&gpa_width);

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(gpa_width - 1));

pr_info("Guest detected\n");
}

0 comments on commit 4148522

Please sign in to comment.