Skip to content
Permalink
Browse files
KVM: TDX: x86: Add support for device-scoped KVM_MEMORY_ENCRYPT_OP
KVM_MEMORY_ENCRYPT_OP KVM API was introduced for VM-scoped operations of
protected guest VM.  It has sub-commands under the API.

Repurpose KVM_MEMORY_ENCRYPT_OP for TDX specific operations.  Getting
system-wide parameters, TDX-specific VM initialization, and TDX-specific
vCPU initialization.  Which requires KVM device-scoped operation and
vCPU-scoped operations in addition to the existing VM-scoped operations.

Add callback for KVM device-scoped operations of KVM_MEMORY_ENCRYPT_OP and
implement subcommand to return system-wide parameters of the TDX module.

Signed-off-by: Sean Christopherson <sean.j.christopherson@intel.com>
Signed-off-by: Isaku Yamahata <isaku.yamahata@intel.com>
  • Loading branch information
yamahata committed Dec 15, 2021
1 parent 3545bcd commit a7aca922f6abdf63d234853308401894d6c4106d
Show file tree
Hide file tree
Showing 8 changed files with 125 additions and 0 deletions.
@@ -1477,6 +1477,7 @@ struct kvm_x86_ops {
int (*leave_smm)(struct kvm_vcpu *vcpu, const char *smstate);
void (*enable_smi_window)(struct kvm_vcpu *vcpu);

int (*mem_enc_op_dev)(void __user *argp);
int (*mem_enc_op)(struct kvm *kvm, void __user *argp);
int (*mem_enc_reg_region)(struct kvm *kvm, struct kvm_enc_region *argp);
int (*mem_enc_unreg_region)(struct kvm *kvm, struct kvm_enc_region *argp);
@@ -511,4 +511,37 @@ struct kvm_pmu_event_filter {
#define KVM_X86_DEFAULT_VM 0
#define KVM_X86_TDX_VM 1

/* Trust Domain eXtension sub-ioctl() commands. */
enum kvm_tdx_cmd_id {
KVM_TDX_CAPABILITIES = 0,

KVM_TDX_CMD_NR_MAX,
};

struct kvm_tdx_cmd {
__u32 id;
__u32 metadata;
__u64 data;
};

struct kvm_tdx_cpuid_config {
__u32 leaf;
__u32 sub_leaf;
__u32 eax;
__u32 ebx;
__u32 ecx;
__u32 edx;
};

struct kvm_tdx_capabilities {
__u64 attrs_fixed0;
__u64 attrs_fixed1;
__u64 xfam_fixed0;
__u64 xfam_fixed1;

__u32 nr_cpuid_configs;
__u32 padding;
struct kvm_tdx_cpuid_config cpuid_configs[0];
};

#endif /* _ASM_X86_KVM_H */
@@ -53,6 +53,14 @@ static bool vt_is_vm_type_supported(unsigned long type)
return type == KVM_X86_DEFAULT_VM;
}

static int vt_mem_enc_op_dev(void __user *argp)
{
if (!enable_tdx)
return -EOPNOTSUPP;

return tdx_dev_ioctl(argp);
}

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

@@ -190,6 +198,8 @@ struct kvm_x86_ops vt_x86_ops __initdata = {
.complete_emulated_msr = kvm_complete_insn_gp,

.vcpu_deliver_sipi_vector = kvm_vcpu_deliver_sipi_vector,

.mem_enc_op_dev = vt_mem_enc_op_dev,
};

static struct kvm_x86_init_ops vt_init_ops __initdata = {
@@ -63,6 +63,44 @@ void tdx_hardware_disable(void)
{
}

int tdx_dev_ioctl(void __user *argp)
{
struct kvm_tdx_capabilities __user *user_caps;
struct kvm_tdx_capabilities caps;
struct kvm_tdx_cmd cmd;

BUILD_BUG_ON(sizeof(struct kvm_tdx_cpuid_config) !=
sizeof(struct tdx_cpuid_config));

if (copy_from_user(&cmd, argp, sizeof(cmd)))
return -EFAULT;

if (cmd.metadata || cmd.id != KVM_TDX_CAPABILITIES)
return -EINVAL;

user_caps = (void __user *)cmd.data;
if (copy_from_user(&caps, user_caps, sizeof(caps)))
return -EFAULT;

if (caps.nr_cpuid_configs < tdx_caps.nr_cpuid_configs)
return -E2BIG;
caps.nr_cpuid_configs = tdx_caps.nr_cpuid_configs;

if (copy_to_user(user_caps->cpuid_configs, &tdx_caps.cpuid_configs,
tdx_caps.nr_cpuid_configs * sizeof(struct tdx_cpuid_config)))
return -EFAULT;

caps.attrs_fixed0 = tdx_caps.attrs_fixed0;
caps.attrs_fixed1 = tdx_caps.attrs_fixed1;
caps.xfam_fixed0 = tdx_caps.xfam_fixed0;
caps.xfam_fixed1 = tdx_caps.xfam_fixed1;

if (copy_to_user((void __user *)cmd.data, &caps, sizeof(caps)))
return -EFAULT;

return 0;
}

int __init tdx_hardware_setup(struct kvm_x86_ops *x86_ops)
{
u32 max_pa;
@@ -6,3 +6,5 @@ void __init tdx_pre_kvm_init(unsigned int *vcpu_size,
int __init tdx_hardware_setup(struct kvm_x86_ops *x86_ops) { return -EOPNOTSUPP; }
void tdx_hardware_enable(void) {}
void tdx_hardware_disable(void) {}

int tdx_dev_ioctl(void __user *argp) { return -EOPNOTSUPP; }
@@ -129,4 +129,6 @@ int __init tdx_hardware_setup(struct kvm_x86_ops *x86_ops);
void tdx_hardware_enable(void);
void tdx_hardware_disable(void);

int tdx_dev_ioctl(void __user *argp);

#endif /* __KVM_X86_VMX_X86_OPS_H */
@@ -4358,6 +4358,12 @@ long kvm_arch_dev_ioctl(struct file *filp,
case KVM_GET_SUPPORTED_HV_CPUID:
r = kvm_ioctl_get_supported_hv_cpuid(NULL, argp);
break;
case KVM_MEMORY_ENCRYPT_OP:
r = -EINVAL;
if (!kvm_x86_ops.mem_enc_op_dev)
goto out;
r = kvm_x86_ops.mem_enc_op_dev(argp);
break;
default:
r = -EINVAL;
break;
@@ -511,4 +511,37 @@ struct kvm_pmu_event_filter {
#define KVM_X86_DEFAULT_VM 0
#define KVM_X86_TDX_VM 1

/* Trust Domain eXtension sub-ioctl() commands. */
enum kvm_tdx_cmd_id {
KVM_TDX_CAPABILITIES = 0,

KVM_TDX_CMD_NR_MAX,
};

struct kvm_tdx_cmd {
__u32 id;
__u32 metadata;
__u64 data;
};

struct kvm_tdx_cpuid_config {
__u32 leaf;
__u32 sub_leaf;
__u32 eax;
__u32 ebx;
__u32 ecx;
__u32 edx;
};

struct kvm_tdx_capabilities {
__u64 attrs_fixed0;
__u64 attrs_fixed1;
__u64 xfam_fixed0;
__u64 xfam_fixed1;

__u32 nr_cpuid_configs;
__u32 padding;
struct kvm_tdx_cpuid_config cpuid_configs[0];
};

#endif /* _ASM_X86_KVM_H */

0 comments on commit a7aca92

Please sign in to comment.