diff options
Diffstat (limited to 'arch/x86/kvm/svm.c')
-rw-r--r-- | arch/x86/kvm/svm.c | 15 |
1 files changed, 12 insertions, 3 deletions
diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c index c1c1b973e80a..ad273468c08a 100644 --- a/arch/x86/kvm/svm.c +++ b/arch/x86/kvm/svm.c | |||
@@ -1112,9 +1112,18 @@ static int invalid_op_interception(struct vcpu_svm *svm, | |||
1112 | static int task_switch_interception(struct vcpu_svm *svm, | 1112 | static int task_switch_interception(struct vcpu_svm *svm, |
1113 | struct kvm_run *kvm_run) | 1113 | struct kvm_run *kvm_run) |
1114 | { | 1114 | { |
1115 | pr_unimpl(&svm->vcpu, "%s: task switch is unsupported\n", __func__); | 1115 | u16 tss_selector; |
1116 | kvm_run->exit_reason = KVM_EXIT_UNKNOWN; | 1116 | |
1117 | return 0; | 1117 | tss_selector = (u16)svm->vmcb->control.exit_info_1; |
1118 | if (svm->vmcb->control.exit_info_2 & | ||
1119 | (1ULL << SVM_EXITINFOSHIFT_TS_REASON_IRET)) | ||
1120 | return kvm_task_switch(&svm->vcpu, tss_selector, | ||
1121 | TASK_SWITCH_IRET); | ||
1122 | if (svm->vmcb->control.exit_info_2 & | ||
1123 | (1ULL << SVM_EXITINFOSHIFT_TS_REASON_JMP)) | ||
1124 | return kvm_task_switch(&svm->vcpu, tss_selector, | ||
1125 | TASK_SWITCH_JMP); | ||
1126 | return kvm_task_switch(&svm->vcpu, tss_selector, TASK_SWITCH_CALL); | ||
1118 | } | 1127 | } |
1119 | 1128 | ||
1120 | static int cpuid_interception(struct vcpu_svm *svm, struct kvm_run *kvm_run) | 1129 | static int cpuid_interception(struct vcpu_svm *svm, struct kvm_run *kvm_run) |