Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S932767AbdHWUoL (ORCPT ); Wed, 23 Aug 2017 16:44:11 -0400 Received: from mail-wr0-f195.google.com ([209.85.128.195]:37443 "EHLO mail-wr0-f195.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S932699AbdHWUoH (ORCPT ); Wed, 23 Aug 2017 16:44:07 -0400 From: Paolo Bonzini To: linux-kernel@vger.kernel.org, kvm@vger.kernel.org Cc: wanpeng.li@hotmail.com, david@redhat.com, rkrcmar@redhat.com, jmattson@google.com Subject: [PATCH 3/4] KVM: x86: pass struct kvm_queued_exception to kvm_multiple_exception Date: Wed, 23 Aug 2017 22:43:57 +0200 Message-Id: <1503521038-21073-4-git-send-email-pbonzini@redhat.com> X-Mailer: git-send-email 1.8.3.1 In-Reply-To: <1503521038-21073-1-git-send-email-pbonzini@redhat.com> References: <1503521038-21073-1-git-send-email-pbonzini@redhat.com> Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 4402 Lines: 148 Avoid early overwriting of vcpu->arch.exception.nested_apf, and make it easier to add CR2 or DR6 in the future. Signed-off-by: Paolo Bonzini --- arch/x86/kvm/x86.c | 79 ++++++++++++++++++++++++++++++++---------------------- 1 file changed, 47 insertions(+), 32 deletions(-) diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index 4e699238a113..88b91114c5a8 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -381,25 +381,14 @@ static int exception_type(int vector) } static void kvm_multiple_exception(struct kvm_vcpu *vcpu, - unsigned nr, bool has_error, u32 error_code, - bool reinject) + struct kvm_queued_exception ex) { u32 prev_nr; int class1, class2; kvm_make_request(KVM_REQ_EVENT, vcpu); - - if (!vcpu->arch.exception.pending) { - queue: - if (has_error && !is_protmode(vcpu)) - has_error = false; - vcpu->arch.exception.pending = true; - vcpu->arch.exception.has_error_code = has_error; - vcpu->arch.exception.nr = nr; - vcpu->arch.exception.error_code = error_code; - vcpu->arch.exception.reinject = reinject; - return; - } + if (!vcpu->arch.exception.pending) + goto queue; /* to check exception */ prev_nr = vcpu->arch.exception.nr; @@ -409,30 +398,43 @@ static void kvm_multiple_exception(struct kvm_vcpu *vcpu, return; } class1 = exception_class(prev_nr); - class2 = exception_class(nr); + class2 = exception_class(ex.nr); if ((class1 == EXCPT_CONTRIBUTORY && class2 == EXCPT_CONTRIBUTORY) || (class1 == EXCPT_PF && class2 != EXCPT_BENIGN)) { /* generate double fault per SDM Table 5-5 */ - vcpu->arch.exception.pending = true; - vcpu->arch.exception.has_error_code = true; - vcpu->arch.exception.nr = DF_VECTOR; - vcpu->arch.exception.error_code = 0; - } else - /* replace previous exception with a new one in a hope - that instruction re-execution will regenerate lost - exception */ - goto queue; + ex.pending = true; + ex.has_error_code = true; + ex.nr = DF_VECTOR; + ex.error_code = 0; + } + + /* + * Else replace previous exception with a new one in a hope + * that instruction re-execution will regenerate lost + * exception. + */ + +queue: + ex.pending = true; + ex.has_error_code = ex.has_error_code && is_protmode(vcpu); + vcpu->arch.exception = ex; + return; } void kvm_queue_exception(struct kvm_vcpu *vcpu, unsigned nr) { - kvm_multiple_exception(vcpu, nr, false, 0, false); + kvm_multiple_exception(vcpu, ((struct kvm_queued_exception) { + .nr = nr + })); } EXPORT_SYMBOL_GPL(kvm_queue_exception); void kvm_requeue_exception(struct kvm_vcpu *vcpu, unsigned nr) { - kvm_multiple_exception(vcpu, nr, false, 0, true); + kvm_multiple_exception(vcpu, ((struct kvm_queued_exception) { + .nr = nr, + .reinject = true + })); } EXPORT_SYMBOL_GPL(kvm_requeue_exception); @@ -449,14 +451,18 @@ int kvm_complete_insn_gp(struct kvm_vcpu *vcpu, int err) void kvm_inject_page_fault(struct kvm_vcpu *vcpu, struct x86_exception *fault) { + bool nested_apf = is_guest_mode(vcpu) && fault->async_page_fault; ++vcpu->stat.pf_guest; - vcpu->arch.exception.nested_apf = - is_guest_mode(vcpu) && fault->async_page_fault; - if (vcpu->arch.exception.nested_apf) + if (nested_apf) vcpu->arch.apf.nested_apf_token = fault->address; else vcpu->arch.cr2 = fault->address; - kvm_queue_exception_e(vcpu, PF_VECTOR, fault->error_code); + kvm_multiple_exception(vcpu, ((struct kvm_queued_exception) { + .nr = PF_VECTOR, + .nested_apf = nested_apf, + .has_error_code = true, + .error_code = fault->error_code + })); } EXPORT_SYMBOL_GPL(kvm_inject_page_fault); @@ -479,13 +485,22 @@ void kvm_inject_nmi(struct kvm_vcpu *vcpu) void kvm_queue_exception_e(struct kvm_vcpu *vcpu, unsigned nr, u32 error_code) { - kvm_multiple_exception(vcpu, nr, true, error_code, false); + kvm_multiple_exception(vcpu, ((struct kvm_queued_exception) { + .nr = nr, + .has_error_code = true, + .error_code = error_code + })); } EXPORT_SYMBOL_GPL(kvm_queue_exception_e); void kvm_requeue_exception_e(struct kvm_vcpu *vcpu, unsigned nr, u32 error_code) { - kvm_multiple_exception(vcpu, nr, true, error_code, true); + kvm_multiple_exception(vcpu, ((struct kvm_queued_exception) { + .nr = nr, + .has_error_code = true, + .error_code = error_code, + .reinject = true + })); } EXPORT_SYMBOL_GPL(kvm_requeue_exception_e); -- 1.8.3.1