Skip to content
Permalink
Browse files
KVM: TDX: Add KVM TDX system-wide initialization and teardown
Add TDX system-wide initialization for KVM to get the TDX parameters. Add a
place holder to enable/disable KVM TDX feature.

It is assumed that the TDX module is already initialized and it's ready
for KVM to use the TDX module APIs for TDX VM life cycle management.

tdx_get_sysinfo() returns system-wide TDX module parameters.  NULL when
the TDX module isn't initialized.

Signed-off-by: Isaku Yamahata <isaku.yamahata@intel.com>
  • Loading branch information
yamahata committed Dec 15, 2021
1 parent bf8636a commit 3545bcde2d72e4b5b5f16571788aac0ddb5f49a5
Show file tree
Hide file tree
Showing 5 changed files with 168 additions and 3 deletions.
@@ -6,6 +6,48 @@
#include "nested.h"
#include "pmu.h"

#ifdef CONFIG_INTEL_TDX_HOST
static bool __read_mostly enable_tdx = true;
module_param_named(tdx, enable_tdx, bool, 0444);
#else
#define enable_tdx false
#endif

static __init int vt_hardware_setup(void)
{
int ret;

ret = vmx_hardware_setup();
if (ret)
return ret;

if (enable_tdx && tdx_hardware_setup(&vt_x86_ops))
enable_tdx = false;
return 0;
}

static int vt_hardware_enable(void)
{
int ret;

ret = vmx_hardware_enable();
if (ret)
return ret;

if (enable_tdx)
tdx_hardware_enable();
return 0;
}

static void vt_hardware_disable(void)
{
/* Note, TDX *and* VMX need to be disabled if TDX is enabled. */
if (enable_tdx)
tdx_hardware_disable();

vmx_hardware_disable();
}

static bool vt_is_vm_type_supported(unsigned long type)
{
return type == KVM_X86_DEFAULT_VM;
@@ -16,8 +58,8 @@ struct kvm_x86_ops vt_x86_ops __initdata = {

.hardware_unsetup = vmx_hardware_unsetup,

.hardware_enable = vmx_hardware_enable,
.hardware_disable = vmx_hardware_disable,
.hardware_enable = vt_hardware_enable,
.hardware_disable = vt_hardware_disable,
.cpu_has_accelerated_tpr = report_flexpriority,
.has_emulated_msr = vmx_has_emulated_msr,

@@ -154,7 +196,7 @@ static struct kvm_x86_init_ops vt_init_ops __initdata = {
.cpu_has_kvm_support = vmx_cpu_has_kvm_support,
.disabled_by_bios = vmx_disabled_by_bios,
.check_processor_compatibility = vmx_check_processor_compat,
.hardware_setup = vmx_hardware_setup,
.hardware_setup = vt_hardware_setup,

.runtime_ops = &vt_x86_ops,
};
@@ -2,14 +2,113 @@
#include <linux/cpu.h>
#include <linux/kvm_host.h>

#include "capabilities.h"
#include "tdx_errno.h"
#include "tdx_ops.h"
#include "x86_ops.h"
#include "cpuid.h"
#include "lapic.h"
#include "tdx.h"

#include <trace/events/kvm.h>
#include "trace.h"

#undef pr_fmt
#define pr_fmt(fmt) "tdx: " fmt

/*
* 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
static inline const struct tdsysinfo_struct *tdx_get_sysinfo(void)
{
return NULL;
}
#endif

/* KeyID range reserved to TDX by BIOS */
static u32 tdx_keyids_start __read_mostly;
static u32 tdx_nr_keyids __read_mostly;
static u32 tdx_seam_keyid __read_mostly;

static void __init tdx_keyids_init(void)
{
u32 nr_mktme_ids;

rdmsr(MSR_IA32_MKTME_KEYID_PART, nr_mktme_ids, tdx_nr_keyids);

/* KeyID 0 is reserved, i.e. KeyIDs are 1-based. */
tdx_keyids_start = nr_mktme_ids + 1;
tdx_seam_keyid = tdx_keyids_start;
}

/* Capabilities of KVM + TDX-SEAM. */
struct tdx_capabilities tdx_caps;

static u64 hkid_mask __ro_after_init;
static u8 hkid_start_pos __ro_after_init;

void tdx_hardware_enable(void)
{
}

void tdx_hardware_disable(void)
{
}

int __init tdx_hardware_setup(struct kvm_x86_ops *x86_ops)
{
u32 max_pa;
const struct tdsysinfo_struct *tdsysinfo = tdx_get_sysinfo();

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

if (!enable_ept) {
pr_warn("Cannot enable TDX with EPT disabled\n");
return -EINVAL;
}

if (tdsysinfo == NULL) {
WARN_ON_ONCE(cpu_feature_enabled(X86_FEATURE_TDX));
return -ENODEV;
}

if (WARN_ON_ONCE(x86_ops->tlb_remote_flush))
return -EIO;

tdx_keyids_init();

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)
return -EIO;

if (!memcpy(tdx_caps.cpuid_configs, tdsysinfo->cpuid_configs,
tdsysinfo->num_cpuid_config * sizeof(struct tdx_cpuid_config)))
return -EIO;

max_pa = cpuid_eax(0x80000008) & 0xff;
hkid_start_pos = boot_cpu_data.x86_phys_bits;
hkid_mask = GENMASK_ULL(max_pa - 1, hkid_start_pos);

return 0;
}

void __init tdx_pre_kvm_init(unsigned int *vcpu_size,
unsigned int *vcpu_align, unsigned int *vm_size)
{
@@ -31,6 +31,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;
@@ -3,3 +3,6 @@

void __init tdx_pre_kvm_init(unsigned int *vcpu_size,
unsigned int *vcpu_align, unsigned int *vm_size) {}
int __init tdx_hardware_setup(struct kvm_x86_ops *x86_ops) { return -EOPNOTSUPP; }
void tdx_hardware_enable(void) {}
void tdx_hardware_disable(void) {}
@@ -125,5 +125,8 @@ void vmx_setup_mce(struct kvm_vcpu *vcpu);

void __init tdx_pre_kvm_init(unsigned int *vcpu_size,
unsigned int *vcpu_align, unsigned int *vm_size);
int __init tdx_hardware_setup(struct kvm_x86_ops *x86_ops);
void tdx_hardware_enable(void);
void tdx_hardware_disable(void);

#endif /* __KVM_X86_VMX_X86_OPS_H */

0 comments on commit 3545bcd

Please sign in to comment.