mirror of
				https://github.com/torvalds/linux.git
				synced 2025-11-04 10:40:15 +02:00 
			
		
		
		
	KVM: x86: Return to userspace with internal error on unexpected exit reason
Receiving an unexpected exit reason from hardware should be considered as a severe bug in KVM. Therefore, instead of just injecting #UD to guest and ignore it, exit to userspace on internal error so that it could handle it properly (probably by terminating guest). In addition, prefer to use vcpu_unimpl() instead of WARN_ONCE() as handling unexpected exit reason should be a rare unexpected event (that was expected to never happen) and we prefer to print a message on it every time it occurs to guest. Furthermore, dump VMCS/VMCB to dmesg to assist diagnosing such cases. Reviewed-by: Mihai Carabas <mihai.carabas@oracle.com> Reviewed-by: Nikita Leshenko <nikita.leshchenko@oracle.com> Reviewed-by: Joao Martins <joao.m.martins@oracle.com> Signed-off-by: Liran Alon <liran.alon@oracle.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
This commit is contained in:
		
							parent
							
								
									1edce0a9eb
								
							
						
					
					
						commit
						7396d337cf
					
				
					 3 changed files with 17 additions and 5 deletions
				
			
		| 
						 | 
				
			
			@ -4981,9 +4981,14 @@ static int handle_exit(struct kvm_vcpu *vcpu)
 | 
			
		|||
 | 
			
		||||
	if (exit_code >= ARRAY_SIZE(svm_exit_handlers)
 | 
			
		||||
	    || !svm_exit_handlers[exit_code]) {
 | 
			
		||||
		WARN_ONCE(1, "svm: unexpected exit reason 0x%x\n", exit_code);
 | 
			
		||||
		kvm_queue_exception(vcpu, UD_VECTOR);
 | 
			
		||||
		return 1;
 | 
			
		||||
		vcpu_unimpl(vcpu, "svm: unexpected exit reason 0x%x\n", exit_code);
 | 
			
		||||
		dump_vmcb(vcpu);
 | 
			
		||||
		vcpu->run->exit_reason = KVM_EXIT_INTERNAL_ERROR;
 | 
			
		||||
		vcpu->run->internal.suberror =
 | 
			
		||||
			KVM_INTERNAL_ERROR_UNEXPECTED_EXIT_REASON;
 | 
			
		||||
		vcpu->run->internal.ndata = 1;
 | 
			
		||||
		vcpu->run->internal.data[0] = exit_code;
 | 
			
		||||
		return 0;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return svm_exit_handlers[exit_code](svm);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -5870,8 +5870,13 @@ static int vmx_handle_exit(struct kvm_vcpu *vcpu)
 | 
			
		|||
	else {
 | 
			
		||||
		vcpu_unimpl(vcpu, "vmx: unexpected exit reason 0x%x\n",
 | 
			
		||||
				exit_reason);
 | 
			
		||||
		kvm_queue_exception(vcpu, UD_VECTOR);
 | 
			
		||||
		return 1;
 | 
			
		||||
		dump_vmcs();
 | 
			
		||||
		vcpu->run->exit_reason = KVM_EXIT_INTERNAL_ERROR;
 | 
			
		||||
		vcpu->run->internal.suberror =
 | 
			
		||||
			KVM_INTERNAL_ERROR_UNEXPECTED_EXIT_REASON;
 | 
			
		||||
		vcpu->run->internal.ndata = 1;
 | 
			
		||||
		vcpu->run->internal.data[0] = exit_reason;
 | 
			
		||||
		return 0;
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -243,6 +243,8 @@ struct kvm_hyperv_exit {
 | 
			
		|||
#define KVM_INTERNAL_ERROR_SIMUL_EX	2
 | 
			
		||||
/* Encounter unexpected vm-exit due to delivery event. */
 | 
			
		||||
#define KVM_INTERNAL_ERROR_DELIVERY_EV	3
 | 
			
		||||
/* Encounter unexpected vm-exit reason */
 | 
			
		||||
#define KVM_INTERNAL_ERROR_UNEXPECTED_EXIT_REASON	4
 | 
			
		||||
 | 
			
		||||
/* for KVM_RUN, returned by mmap(vcpu_fd, offset=0) */
 | 
			
		||||
struct kvm_run {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in a new issue