Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > linux.kernel > #1718634

[PATCH 3/4] KVM: x86: pass struct kvm_queued_exception to kvm_multiple_exception

From Paolo Bonzini <pbonzini@redhat.com>
Newsgroups linux.kernel
Subject [PATCH 3/4] KVM: x86: pass struct kvm_queued_exception to kvm_multiple_exception
Date 2017-08-23 22:50 +0200
Message-ID <uhKL8-5jQ-25@gated-at.bofh.it> (permalink)
References <uhKL8-5jQ-13@gated-at.bofh.it>
Organization linux.* mail to news gateway

Show all headers | View raw


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 <pbonzini@redhat.com>
---
 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

Back to linux.kernel | Previous | Next — Previous in thread | Next in thread | Find similar | Unroll thread


Thread

[RFC PATCH 0/4] KVM: x86: allow overwriting L2 reinjected exception with L1 vmexit Paolo Bonzini <pbonzini@redhat.com> - 2017-08-23 22:50 +0200
  [PATCH 3/4] KVM: x86: pass struct kvm_queued_exception to kvm_multiple_exception Paolo Bonzini <pbonzini@redhat.com> - 2017-08-23 22:50 +0200
  [PATCH 2/4] KVM: nVMX: fill nested IDT-vectored event info on all L2->L0 exits Paolo Bonzini <pbonzini@redhat.com> - 2017-08-23 22:50 +0200
  [PATCH 4/4] KVM: x86: allow overwriting L2 reinjected exception with L1 vmexit Paolo Bonzini <pbonzini@redhat.com> - 2017-08-23 22:50 +0200

csiph-web