aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kvm/svm.c
diff options
context:
space:
mode:
authorJan Kiszka <jan.kiszka@siemens.com>2010-04-14 09:51:09 -0400
committerAvi Kivity <avi@redhat.com>2010-05-17 05:17:46 -0400
commite269fb2189fb86d79d64c0ca74c6c1a549ad4aa3 (patch)
tree627c658efaec155d1f295d1fc7b8abded9d4f861 /arch/x86/kvm/svm.c
parent0760d44868f351ba30fc9a08cf1830e46aa72466 (diff)
KVM: x86: Push potential exception error code on task switches
When a fault triggers a task switch, the error code, if existent, has to be pushed on the new task's stack. Implement the missing bits. Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com> Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>
Diffstat (limited to 'arch/x86/kvm/svm.c')
-rw-r--r--arch/x86/kvm/svm.c11
1 files changed, 10 insertions, 1 deletions
diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c
index 87b36fbbfec8..78af52222fd2 100644
--- a/arch/x86/kvm/svm.c
+++ b/arch/x86/kvm/svm.c
@@ -2222,6 +2222,8 @@ static int task_switch_interception(struct vcpu_svm *svm)
2222 svm->vmcb->control.exit_int_info & SVM_EXITINTINFO_TYPE_MASK; 2222 svm->vmcb->control.exit_int_info & SVM_EXITINTINFO_TYPE_MASK;
2223 uint32_t idt_v = 2223 uint32_t idt_v =
2224 svm->vmcb->control.exit_int_info & SVM_EXITINTINFO_VALID; 2224 svm->vmcb->control.exit_int_info & SVM_EXITINTINFO_VALID;
2225 bool has_error_code = false;
2226 u32 error_code = 0;
2225 2227
2226 tss_selector = (u16)svm->vmcb->control.exit_info_1; 2228 tss_selector = (u16)svm->vmcb->control.exit_info_1;
2227 2229
@@ -2242,6 +2244,12 @@ static int task_switch_interception(struct vcpu_svm *svm)
2242 svm->vcpu.arch.nmi_injected = false; 2244 svm->vcpu.arch.nmi_injected = false;
2243 break; 2245 break;
2244 case SVM_EXITINTINFO_TYPE_EXEPT: 2246 case SVM_EXITINTINFO_TYPE_EXEPT:
2247 if (svm->vmcb->control.exit_info_2 &
2248 (1ULL << SVM_EXITINFOSHIFT_TS_HAS_ERROR_CODE)) {
2249 has_error_code = true;
2250 error_code =
2251 (u32)svm->vmcb->control.exit_info_2;
2252 }
2245 kvm_clear_exception_queue(&svm->vcpu); 2253 kvm_clear_exception_queue(&svm->vcpu);
2246 break; 2254 break;
2247 case SVM_EXITINTINFO_TYPE_INTR: 2255 case SVM_EXITINTINFO_TYPE_INTR:
@@ -2258,7 +2266,8 @@ static int task_switch_interception(struct vcpu_svm *svm)
2258 (int_vec == OF_VECTOR || int_vec == BP_VECTOR))) 2266 (int_vec == OF_VECTOR || int_vec == BP_VECTOR)))
2259 skip_emulated_instruction(&svm->vcpu); 2267 skip_emulated_instruction(&svm->vcpu);
2260 2268
2261 return kvm_task_switch(&svm->vcpu, tss_selector, reason); 2269 return kvm_task_switch(&svm->vcpu, tss_selector, reason,
2270 has_error_code, error_code);
2262} 2271}
2263 2272
2264static int cpuid_interception(struct vcpu_svm *svm) 2273static int cpuid_interception(struct vcpu_svm *svm)