KVM: x86: Handle emulation failure directly in kvm_task_switch()
Consolidate the reporting of emulation failure into kvm_task_switch() so that it can return EMULATE_USER_EXIT. This helps pave the way for removing EMULATE_FAIL altogether. This also fixes a theoretical bug where task switch interception could suppress an EMULATE_USER_EXIT return. Signed-off-by: Sean Christopherson <sean.j.christopherson@intel.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
This commit is contained in:
		
							parent
							
								
									738fece46d
								
							
						
					
					
						commit
						1051778f6e
					
				| @ -3892,17 +3892,10 @@ static int task_switch_interception(struct vcpu_svm *svm) | ||||
| 	if (int_type != SVM_EXITINTINFO_TYPE_SOFT) | ||||
| 		int_vec = -1; | ||||
| 
 | ||||
| 	if (kvm_task_switch(&svm->vcpu, tss_selector, int_vec, reason, | ||||
| 				has_error_code, error_code) == EMULATE_FAIL) | ||||
| 		goto fail; | ||||
| 
 | ||||
| 	return 1; | ||||
| 
 | ||||
| fail: | ||||
| 	svm->vcpu.run->exit_reason = KVM_EXIT_INTERNAL_ERROR; | ||||
| 	svm->vcpu.run->internal.suberror = KVM_INTERNAL_ERROR_EMULATION; | ||||
| 	svm->vcpu.run->internal.ndata = 0; | ||||
| 	return 0; | ||||
| 	return kvm_task_switch(&svm->vcpu, tss_selector, int_vec, reason, | ||||
| 			       has_error_code, error_code) != EMULATE_USER_EXIT; | ||||
| } | ||||
| 
 | ||||
| static int cpuid_interception(struct vcpu_svm *svm) | ||||
|  | ||||
| @ -5074,21 +5074,13 @@ static int handle_task_switch(struct kvm_vcpu *vcpu) | ||||
| 		       type != INTR_TYPE_NMI_INTR)) | ||||
| 		skip_emulated_instruction(vcpu); | ||||
| 
 | ||||
| 	if (kvm_task_switch(vcpu, tss_selector, | ||||
| 			    type == INTR_TYPE_SOFT_INTR ? idt_index : -1, reason, | ||||
| 			    has_error_code, error_code) == EMULATE_FAIL) { | ||||
| 		vcpu->run->exit_reason = KVM_EXIT_INTERNAL_ERROR; | ||||
| 		vcpu->run->internal.suberror = KVM_INTERNAL_ERROR_EMULATION; | ||||
| 		vcpu->run->internal.ndata = 0; | ||||
| 		return 0; | ||||
| 	} | ||||
| 
 | ||||
| 	/*
 | ||||
| 	 * TODO: What about debug traps on tss switch? | ||||
| 	 *       Are we supposed to inject them and update dr6? | ||||
| 	 */ | ||||
| 
 | ||||
| 	return 1; | ||||
| 	return kvm_task_switch(vcpu, tss_selector, | ||||
| 			       type == INTR_TYPE_SOFT_INTR ? idt_index : -1, | ||||
| 			       reason, has_error_code, error_code) != EMULATE_USER_EXIT; | ||||
| } | ||||
| 
 | ||||
| static int handle_ept_violation(struct kvm_vcpu *vcpu) | ||||
|  | ||||
| @ -8693,9 +8693,12 @@ int kvm_task_switch(struct kvm_vcpu *vcpu, u16 tss_selector, int idt_index, | ||||
| 
 | ||||
| 	ret = emulator_task_switch(ctxt, tss_selector, idt_index, reason, | ||||
| 				   has_error_code, error_code); | ||||
| 
 | ||||
| 	if (ret) | ||||
| 		return EMULATE_FAIL; | ||||
| 	if (ret) { | ||||
| 		vcpu->run->exit_reason = KVM_EXIT_INTERNAL_ERROR; | ||||
| 		vcpu->run->internal.suberror = KVM_INTERNAL_ERROR_EMULATION; | ||||
| 		vcpu->run->internal.ndata = 0; | ||||
| 		return EMULATE_USER_EXIT; | ||||
| 	} | ||||
| 
 | ||||
| 	kvm_rip_write(vcpu, ctxt->eip); | ||||
| 	kvm_set_rflags(vcpu, ctxt->eflags); | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user