Skip to content
Permalink
Browse files
KVM: TDX: Add helper function to initialize TDX module
Add two helper function to initialize TDX module and get system-wide
parameters.  When TDX module is needed, dynamically initialize the TDX
module.

Signed-off-by: Isaku Yamahata <isaku.yamahata@intel.com>
  • Loading branch information
yamahata committed Feb 8, 2022
1 parent 6dbac45 commit c3655d888b8950b33970012d3359b9e3921e36c6
Show file tree
Hide file tree
Showing 5 changed files with 152 additions and 0 deletions.
@@ -5,6 +5,7 @@
#include "vmx.h"
#include "nested.h"
#include "pmu.h"
#include "tdx.h"

#ifdef CONFIG_INTEL_TDX_HOST
static bool __read_mostly enable_tdx = true;
@@ -32,6 +33,31 @@ static __init int vt_hardware_setup(void)
return 0;
}

int tdx_enable(void)
{
static DEFINE_MUTEX(tdx_init_lock);
static bool __read_mostly tdx_module_initialized;
int ret = 0;

mutex_lock(&tdx_init_lock);
if (!enable_tdx) {
ret = -EOPNOTSUPP;
goto out;
}

if (!tdx_module_initialized) {
ret = tdx_module_setup();
if (!ret)
tdx_module_initialized = true;
else
disable_tdx();
}

out:
mutex_unlock(&tdx_init_lock);
return ret;
}

struct kvm_x86_ops vt_x86_ops __initdata = {
.name = "kvm_intel",

@@ -34,9 +34,56 @@ static void __init tdx_keyids_init(void)
tdx_seam_keyid = tdx_keyids_start;
}

/* Capabilities of KVM + the TDX module. */
struct tdx_capabilities tdx_caps;

static u64 hkid_mask __ro_after_init;
static u8 hkid_start_pos __ro_after_init;

int tdx_module_setup(void)
{
struct tdsysinfo_struct *tdsysinfo;
int ret = 0;

BUILD_BUG_ON(sizeof(*tdsysinfo) != 1024);
BUILD_BUG_ON(TDX_MAX_NR_CPUID_CONFIGS != 37);

tdsysinfo = kmalloc(sizeof(*tdsysinfo), GFP_KERNEL);
if (!tdsysinfo)
return -ENOMEM;

ret = init_tdx(tdsysinfo);
if (ret) {
pr_info("Failed to initialize TDX module.\n");
goto out;
}

tdx_caps.tdcs_nr_pages = tdsysinfo->tdcs_base_size / PAGE_SIZE;
tdx_caps.tdvpx_nr_pages = tdsysinfo->tdvps_base_size / PAGE_SIZE - 1;

tdx_caps.attrs_fixed0 = tdsysinfo->attributes_fixed0;
tdx_caps.attrs_fixed1 = tdsysinfo->attributes_fixed1;
tdx_caps.xfam_fixed0 = tdsysinfo->xfam_fixed0;
tdx_caps.xfam_fixed1 = tdsysinfo->xfam_fixed1;

tdx_caps.nr_cpuid_configs = tdsysinfo->num_cpuid_config;
if (tdx_caps.nr_cpuid_configs > TDX_MAX_NR_CPUID_CONFIGS) {
ret = -EIO;
goto out;
}

if (!memcpy(tdx_caps.cpuid_configs, tdsysinfo->cpuid_configs,
tdsysinfo->num_cpuid_config *
sizeof(struct tdx_cpuid_config))) {
ret = -EIO;
goto out;
}

out:
kfree(tdsysinfo);
return ret;
}

int __init tdx_hardware_setup(struct kvm_x86_ops *x86_ops)
{
u32 max_pa;
@@ -10,6 +10,8 @@
#include "tdx_ops.h"

#ifdef CONFIG_INTEL_TDX_HOST
int tdx_module_setup(void);
int tdx_enable(void);

struct tdx_td_page {
unsigned long va;
@@ -31,6 +33,24 @@ struct vcpu_tdx {
struct tdx_td_page *tdvpx;
};

#define TDX_MAX_NR_CPUID_CONFIGS \
((sizeof(struct tdsysinfo_struct) - \
offsetof(struct tdsysinfo_struct, cpuid_configs)) \
/ sizeof(struct tdx_cpuid_config))

struct tdx_capabilities {
u8 tdcs_nr_pages;
u8 tdvpx_nr_pages;

u64 attrs_fixed0;
u64 attrs_fixed1;
u64 xfam_fixed0;
u64 xfam_fixed1;

u32 nr_cpuid_configs;
struct tdx_cpuid_config cpuid_configs[TDX_MAX_NR_CPUID_CONFIGS];
};

static inline bool is_td(struct kvm *kvm)
{
return kvm->arch.vm_type == KVM_X86_TDX_VM;
@@ -137,6 +157,8 @@ TDX_BUILD_TDVPS_ACCESSORS(64, STATE_NON_ARCH, state_non_arch);
TDX_BUILD_TDVPS_ACCESSORS(8, MANAGEMENT, management);

#else
static inline int tdx_module_setup(void) { return -EOPNOTSUPP; };

struct kvm_tdx;
struct vcpu_tdx;

@@ -6,6 +6,62 @@

#include <linux/types.h>

/*
* workaround to compile.
* TODO: once the TDX module initiation code in x86 host is merged, remove this.
* The function returns struct tdsysinfo_struct from TDX module provides which
* is the system wide information about the TDX module.
* Return NULL if the TDX module is not ready for KVM to use for TDX VM guest
* life cycle.
*/
#if __has_include(<asm/tdx_host.h>)
#include <asm/tdx_host.h>
#else
struct tdx_cpuid_config {
u32 leaf;
u32 sub_leaf;
u32 eax;
u32 ebx;
u32 ecx;
u32 edx;
} __packed;

struct tdsysinfo_struct {
/* The TDX Module Info */
u32 attributes;
u32 vendor_id;
u32 build_date;
u16 build_num;
u16 minor_version;
u16 major_version;
u8 reserved0[14];
/* Memory Info */
u16 max_tdmrs;
u16 max_reserved_per_tdmr;
u16 pamt_entry_size;
u8 reserved1[10];
/* Control Struct Info */
u16 tdcs_base_size;
u8 reserved2[2];
u16 tdvps_base_size;
u8 tdvps_xfam_dependent_size;
u8 reserved3[9];
/* TD Capabilities */
u64 attributes_fixed0;
u64 attributes_fixed1;
u64 xfam_fixed0;
u64 xfam_fixed1;
u8 reserved4[32];
u32 num_cpuid_config;
union {
struct tdx_cpuid_config cpuid_configs[0];
u8 reserved5[892];
};
} __packed __aligned(1024);

static inline int init_tdx(struct tdsysinfo_struct *tdsysinfo) { return -ENODEV; }
#endif

/*
* TDX SEAMCALL API function leaves
*/
@@ -6,4 +6,5 @@
void __init tdx_pre_kvm_init(unsigned int *vcpu_size,
unsigned int *vcpu_align, unsigned int *vm_size) {}

int tdx_module_setup(void) { return -EOPNOTSUPP; };
int __init tdx_hardware_setup(struct kvm_x86_ops *x86_ops) { return -EOPNOTSUPP; }

0 comments on commit c3655d8

Please sign in to comment.