Skip to content
Permalink
Browse files
KVM: TDX: Do TDX specific vcpu initialization
One 64bit value is passed to vcpu as an initial parameter in guest vcpu RCX
initial value.

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 to pass vcpu parameter.  Which requires vCPU-scoped
operations in addition to the existing VM-scoped operations.

Add callback for kvm vCPU-scoped operations of KVM_MEMORY_ENCRYPT_OP and
add a new subcommand, KVM_TDX_INIT_VCPU, to pass a parameter for TDX vcpu.

Signed-off-by: Sean Christopherson <sean.j.christopherson@intel.com>
Signed-off-by: Isaku Yamahata <isaku.yamahata@intel.com>
  • Loading branch information
Sean Christopherson authored and yamahata committed Dec 15, 2021
1 parent bd5ba6a commit 2a1d7e9bae19b842ad5ac81f5e0b549066b58ff7
Show file tree
Hide file tree
Showing 9 changed files with 68 additions and 0 deletions.
@@ -1483,6 +1483,7 @@ struct kvm_x86_ops {

int (*mem_enc_op_dev)(void __user *argp);
int (*mem_enc_op)(struct kvm *kvm, void __user *argp);
int (*mem_enc_op_vcpu)(struct kvm_vcpu *vcpu, 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);
int (*vm_copy_enc_context_from)(struct kvm *kvm, unsigned int source_fd);
@@ -515,6 +515,7 @@ struct kvm_pmu_event_filter {
enum kvm_tdx_cmd_id {
KVM_TDX_CAPABILITIES = 0,
KVM_TDX_INIT_VM,
KVM_TDX_INIT_VCPU,

KVM_TDX_CMD_NR_MAX,
};
@@ -117,6 +117,14 @@ static int vt_mem_enc_op(struct kvm *kvm, void __user *argp)
return tdx_vm_ioctl(kvm, argp);
}

static int vt_mem_enc_op_vcpu(struct kvm_vcpu *vcpu, void __user *argp)
{
if (!is_td_vcpu(vcpu))
return -EINVAL;

return tdx_vcpu_ioctl(vcpu, argp);
}

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

@@ -259,6 +267,7 @@ struct kvm_x86_ops vt_x86_ops __initdata = {

.mem_enc_op_dev = vt_mem_enc_op_dev,
.mem_enc_op = vt_mem_enc_op,
.mem_enc_op_vcpu = vt_mem_enc_op_vcpu,
};

static struct kvm_x86_init_ops vt_init_ops __initdata = {
@@ -106,6 +106,11 @@ static inline bool is_hkid_assigned(struct kvm_tdx *kvm_tdx)
return kvm_tdx->hkid >= 0;
}

static inline bool is_td_finalized(struct kvm_tdx *kvm_tdx)
{
return kvm_tdx->finalized;
}

void tdx_hardware_enable(void)
{
}
@@ -794,6 +799,45 @@ int tdx_vm_ioctl(struct kvm *kvm, void __user *argp)
return r;
}

int tdx_vcpu_ioctl(struct kvm_vcpu *vcpu, void __user *argp)
{
struct kvm_tdx *kvm_tdx = to_kvm_tdx(vcpu->kvm);
struct vcpu_tdx *tdx = to_tdx(vcpu);
struct kvm_tdx_cmd cmd;
u64 err;

if (tdx->initialized)
return -EINVAL;

if (!is_td_initialized(vcpu->kvm) || is_td_finalized(kvm_tdx))
return -EINVAL;

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

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

err = tdh_vp_init(tdx->tdvpr.pa, cmd.data);
if (WARN_ON_ONCE(err)) {
pr_tdx_error(TDH_VP_INIT, err, NULL);
return -EIO;
}

tdx->initialized = true;

td_vmcs_write16(tdx, POSTED_INTR_NV, POSTED_INTR_VECTOR);
td_vmcs_write64(tdx, POSTED_INTR_DESC_ADDR, __pa(&tdx->pi_desc));
td_vmcs_setbit32(tdx, PIN_BASED_VM_EXEC_CONTROL, PIN_BASED_POSTED_INTR);

if (vcpu->kvm->arch.bus_lock_detection_enabled)
td_vmcs_setbit32(tdx,
SECONDARY_VM_EXEC_CONTROL,
SECONDARY_EXEC_BUS_LOCK_DETECTION);

return 0;
}

int __init tdx_hardware_setup(struct kvm_x86_ops *x86_ops)
{
int i, max_pkgs;
@@ -31,6 +31,8 @@ struct kvm_tdx {
int cpuid_nent;
struct kvm_cpuid_entry2 cpuid_entries[KVM_MAX_CPUID_ENTRIES];

bool finalized;

u64 tsc_offset;
};

@@ -42,6 +44,8 @@ struct vcpu_tdx {

/* Posted interrupt descriptor */
struct pi_desc pi_desc;

bool initialized;
};

#define TDX_MAX_NR_CPUID_CONFIGS \
@@ -13,3 +13,4 @@ void tdx_vcpu_reset(struct kvm_vcpu *vcpu, bool init_event) {}

int tdx_dev_ioctl(void __user *argp) { return -EOPNOTSUPP; }
int tdx_vm_ioctl(struct kvm *kvm, void __user *argp) { return -EOPNOTSUPP; }
int tdx_vcpu_ioctl(struct kvm_vcpu *vcpu, void __user *argp) { return -ENOPNOTSUPP; }
@@ -138,5 +138,6 @@ void tdx_vcpu_reset(struct kvm_vcpu *vcpu, bool init_event);

int tdx_dev_ioctl(void __user *argp);
int tdx_vm_ioctl(struct kvm *kvm, void __user *argp);
int tdx_vcpu_ioctl(struct kvm_vcpu *vcpu, void __user *argp);

#endif /* __KVM_X86_VMX_X86_OPS_H */
@@ -5524,6 +5524,12 @@ long kvm_arch_vcpu_ioctl(struct file *filp,
case KVM_SET_DEVICE_ATTR:
r = kvm_vcpu_ioctl_device_attr(vcpu, ioctl, argp);
break;
case KVM_MEMORY_ENCRYPT_OP:
r = -EINVAL;
if (!kvm_x86_ops.mem_enc_op_vcpu)
goto out;
r = kvm_x86_ops.mem_enc_op_vcpu(vcpu, argp);
break;
default:
r = -EINVAL;
}
@@ -515,6 +515,7 @@ struct kvm_pmu_event_filter {
enum kvm_tdx_cmd_id {
KVM_TDX_CAPABILITIES = 0,
KVM_TDX_INIT_VM,
KVM_TDX_INIT_VCPU,

KVM_TDX_CMD_NR_MAX,
};

0 comments on commit 2a1d7e9

Please sign in to comment.