Skip to content
Permalink
Browse files
KVM: TDX: silently discard SMI request
TDX doesn't support SMM and SMI.  There are choices to handle SMI requests
from the TDX guest or the device model(e.g. qemu).  Silently ignore the
request or return the error somehow.  This patch implements silently
ignoring SMI request.

If the TDX guest requests SMI, it's troublesome for KVM to tell it to the
guest from deep KVM logic except killing the VM.  Although it's easy to
return an error to device model (e.g. qemu) on SMI request via
ioctl(KVM_SMI), it may be a result for the TDX guest to program the virtual
IOAPIC or other virtual devices.  The error should be reported to the TDX
guest.  Also the device model needs to be enhanced to handle an error when
requesting SMI.  For simplicity, the choice is to silently ignore SMI
requests for the TDX guest.

Signed-off-by: Isaku Yamahata <isaku.yamahata@intel.com>
  • Loading branch information
yamahata committed Dec 16, 2021
1 parent e5add37 commit 11f826bfb08f30839cadce9dd9ee8bddaaf97e9f
Show file tree
Hide file tree
Showing 4 changed files with 72 additions and 4 deletions.
@@ -195,6 +195,41 @@ static int vt_get_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
return vmx_get_msr(vcpu, msr_info);
}

static int vt_smi_allowed(struct kvm_vcpu *vcpu, bool for_injection)
{
if (is_td_vcpu(vcpu))
return tdx_smi_allowed(vcpu, for_injection);

return vmx_smi_allowed(vcpu, for_injection);
}

static int vt_enter_smm(struct kvm_vcpu *vcpu, char *smstate)
{
if (unlikely(is_td_vcpu(vcpu)))
return tdx_enter_smm(vcpu, smstate);

return vmx_enter_smm(vcpu, smstate);
}

static int vt_leave_smm(struct kvm_vcpu *vcpu, const char *smstate)
{
if (unlikely(is_td_vcpu(vcpu)))
return tdx_leave_smm(vcpu, smstate);

return vmx_leave_smm(vcpu, smstate);
}

static void vt_enable_smi_window(struct kvm_vcpu *vcpu)
{
if (is_td_vcpu(vcpu)) {
tdx_enable_smi_window(vcpu);
return;
}

/* RSM will cause a vmexit anyway. */
vmx_enable_smi_window(vcpu);
}

static void vt_apicv_post_state_restore(struct kvm_vcpu *vcpu)
{
if (is_td_vcpu(vcpu))
@@ -556,10 +591,10 @@ struct kvm_x86_ops vt_x86_ops __initdata = {

.setup_mce = vmx_setup_mce,

.smi_allowed = vmx_smi_allowed,
.enter_smm = vmx_enter_smm,
.leave_smm = vmx_leave_smm,
.enable_smi_window = vmx_enable_smi_window,
.smi_allowed = vt_smi_allowed,
.enter_smm = vt_enter_smm,
.leave_smm = vt_leave_smm,
.enable_smi_window = vt_enable_smi_window,

.can_emulate_instruction = vmx_can_emulate_instruction,
.apic_init_signal_blocked = vmx_apic_init_signal_blocked,
@@ -1584,6 +1584,31 @@ int tdx_set_msr(struct kvm_vcpu *vcpu, struct msr_data *msr)
return 1;
}

int tdx_smi_allowed(struct kvm_vcpu *vcpu, bool for_injection)
{
/* SMI isn't supported for TDX. */
return false;
}

int tdx_enter_smm(struct kvm_vcpu *vcpu, char *smstate)
{
/* smi_allowed() is always false for TDX as above. */
WARN_ON_ONCE(1);
return 0;
}

int tdx_leave_smm(struct kvm_vcpu *vcpu, const char *smstate)
{
WARN_ON_ONCE(1);
return 0;
}

void tdx_enable_smi_window(struct kvm_vcpu *vcpu)
{
/* SMI isn't supported for TDX. Silently discard SMI request. */
vcpu->arch.smi_pending = false;
}

int tdx_dev_ioctl(void __user *argp)
{
struct kvm_tdx_capabilities __user *user_caps;
@@ -26,6 +26,10 @@ void tdx_apicv_post_state_restore(struct kvm_vcpu *vcpu) {}
int tdx_deliver_posted_interrupt(struct kvm_vcpu *vcpu, int vector) { return 0; }
void tdx_get_exit_info(struct kvm_vcpu *vcpu, u32 *reason,
u64 *info1, u64 *info2, u32 *intr_info, u32 *error_code) {}
int tdx_smi_allowed(struct kvm_vcpu *vcpu, bool for_injection) { return false; }
int tdx_enter_smm(struct kvm_vcpu *vcpu, char *smstate) { return 0; }
int tdx_leave_smm(struct kvm_vcpu *vcpu, const char *smstate) { return 0; }
void tdx_enable_smi_window(struct kvm_vcpu *vcpu) {}

int tdx_dev_ioctl(void __user *argp) { return -EOPNOTSUPP; }
int tdx_vm_ioctl(struct kvm *kvm, void __user *argp) { return -EOPNOTSUPP; }
@@ -150,6 +150,10 @@ void tdx_get_exit_info(struct kvm_vcpu *vcpu, u32 *reason,
bool tdx_is_emulated_msr(u32 index, bool write);
int tdx_get_msr(struct kvm_vcpu *vcpu, struct msr_data *msr);
int tdx_set_msr(struct kvm_vcpu *vcpu, struct msr_data *msr);
int tdx_smi_allowed(struct kvm_vcpu *vcpu, bool for_injection);
int tdx_enter_smm(struct kvm_vcpu *vcpu, char *smstate);
int tdx_leave_smm(struct kvm_vcpu *vcpu, const char *smstate);
void tdx_enable_smi_window(struct kvm_vcpu *vcpu);

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

0 comments on commit 11f826b

Please sign in to comment.