aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kvm/svm.c
diff options
context:
space:
mode:
authorIzik Eidus <izike@qumranet.com>2008-03-24 17:14:53 -0400
committerAvi Kivity <avi@qumranet.com>2008-04-27 05:00:39 -0400
commit37817f2982d0f559f90cecc66e150dd9d2c2df05 (patch)
tree45114b5720d7a13bdbe48cc6a75dc6de03d6fcd2 /arch/x86/kvm/svm.c
parent2e4d2653497856b102c90153f970c9e344ba96c6 (diff)
KVM: x86: hardware task switching support
This emulates the x86 hardware task switch mechanism in software, as it is unsupported by either vmx or svm. It allows operating systems which use it, like freedos, to run as kvm guests. Signed-off-by: Izik Eidus <izike@qumranet.com> Signed-off-by: Avi Kivity <avi@qumranet.com>
Diffstat (limited to 'arch/x86/kvm/svm.c')
-rw-r--r--arch/x86/kvm/svm.c15
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,
1112static int task_switch_interception(struct vcpu_svm *svm, 1112static 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
1120static int cpuid_interception(struct vcpu_svm *svm, struct kvm_run *kvm_run) 1129static int cpuid_interception(struct vcpu_svm *svm, struct kvm_run *kvm_run)