diff options
author | Jan Kiszka <jan.kiszka@siemens.com> | 2010-04-14 09:51:09 -0400 |
---|---|---|
committer | Avi Kivity <avi@redhat.com> | 2010-05-17 05:17:46 -0400 |
commit | e269fb2189fb86d79d64c0ca74c6c1a549ad4aa3 (patch) | |
tree | 627c658efaec155d1f295d1fc7b8abded9d4f861 /arch/x86/kvm/svm.c | |
parent | 0760d44868f351ba30fc9a08cf1830e46aa72466 (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.c | 11 |
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 | ||
2264 | static int cpuid_interception(struct vcpu_svm *svm) | 2273 | static int cpuid_interception(struct vcpu_svm *svm) |