Skip to contentSkip to conversation

Clean up page fault injection

PATCH Applied Avi Kivity 4 participants 6 messages Nov 29, 2010 – Dec 2, 2010

Subsystems (3)
lore
Share & tools
lore

Avi Kivity

author
#0 lore raw

cover Clean up page fault injection

Currently fault injection is somewhat confused with important information carried in the vcpu area where it has no place. This patch cleans it up.

Gleb, Joerg, I'd appreciate review and testing of the apf and nnpt related changes.

Goes on top of the previous 7-part emulator series. Also available in 'emulator' branch of kvm.git.

Avi Kivity (1):
KVM: Pull extra page fault information into struct x86_exception

 arch/x86/include/asm/kvm_emulate.h |    2 +
 arch/x86/include/asm/kvm_host.h    |   17 +++----------
 arch/x86/kvm/mmu.c                 |    5 ++-
 arch/x86/kvm/paging_tmpl.h         |    6 ++--
 arch/x86/kvm/svm.c                 |    7 +++--
 arch/x86/kvm/x86.c                 |   44 +++++++++++++++++++----------------
 6 files changed, 40 insertions(+), 41 deletions(-)
author
#1 lore raw

PATCH 1/1 KVM: Pull extra page fault information into struct x86_exception

Currently page fault cr2 and nesting infomation are carried outside the fault data structure. Instead they are placed in the vcpu struct, which results in confusion as global variables are manipulated instead of passing parameters.

Fix this issue by adding address and nested fields to struct x86_exception, so this struct can carry all information associated with a fault.

---
 arch/x86/include/asm/kvm_emulate.h |    2 +
 arch/x86/include/asm/kvm_host.h    |   17 +++----------
 arch/x86/kvm/mmu.c                 |    5 ++-
 arch/x86/kvm/paging_tmpl.h         |    6 ++--
 arch/x86/kvm/svm.c                 |    7 +++--
 arch/x86/kvm/x86.c                 |   44 +++++++++++++++++++----------------
 6 files changed, 40 insertions(+), 41 deletions(-)
arch/x86/include/asm/kvm_emulate.h +2 -0
index 87d017e..bf70ece 100644
@@ -19,6 +19,8 @@ struct x86_exception {
 	u8 vector;
 	bool error_code_valid;
 	u16 error_code;
+	bool nested_page_fault;
+	u64 address; /* cr2 or nested page fault gpa */
 };
 
 /*
arch/x86/include/asm/kvm_host.h +4 -13
index 24bad0a..2621c4d 100644
@@ -242,7 +242,8 @@ struct kvm_mmu {
 	void (*set_cr3)(struct kvm_vcpu *vcpu, unsigned long root);
 	unsigned long (*get_cr3)(struct kvm_vcpu *vcpu);
 	int (*page_fault)(struct kvm_vcpu *vcpu, gva_t gva, u32 err, bool no_apf);
-	void (*inject_page_fault)(struct kvm_vcpu *vcpu);
+	void (*inject_page_fault)(struct kvm_vcpu *vcpu,
+				  struct x86_exception *fault);
 	void (*free)(struct kvm_vcpu *vcpu);
 	gpa_t (*gva_to_gpa)(struct kvm_vcpu *vcpu, gva_t gva, u32 access,
 			    struct x86_exception *exception);
@@ -318,16 +319,6 @@ struct kvm_vcpu_arch {
 	 */
 	struct kvm_mmu *walk_mmu;
 
-	/*
-	 * This struct is filled with the necessary information to propagate a
-	 * page fault into the guest
-	 */
-	struct {
-		u64      address;
-		unsigned error_code;
-		bool     nested;
-	} fault;
-
 	/* only needed in kvm_pv_mmu_op() path, but it's hot so
 	 * put it here to avoid allocation */
 	struct kvm_pv_mmu_op_buffer mmu_op_buffer;
@@ -685,11 +676,11 @@ void kvm_queue_exception(struct kvm_vcpu *vcpu, unsigned nr);
 void kvm_queue_exception_e(struct kvm_vcpu *vcpu, unsigned nr, u32 error_code);
 void kvm_requeue_exception(struct kvm_vcpu *vcpu, unsigned nr);
 void kvm_requeue_exception_e(struct kvm_vcpu *vcpu, unsigned nr, u32 error_code);
-void kvm_inject_page_fault(struct kvm_vcpu *vcpu);
+void kvm_inject_page_fault(struct kvm_vcpu *vcpu, struct x86_exception *fault);
 int kvm_read_guest_page_mmu(struct kvm_vcpu *vcpu, struct kvm_mmu *mmu,
 			    gfn_t gfn, void *data, int offset, int len,
 			    u32 access);
-void kvm_propagate_fault(struct kvm_vcpu *vcpu);
+void kvm_propagate_fault(struct kvm_vcpu *vcpu, struct x86_exception *fault);
 bool kvm_require_cpl(struct kvm_vcpu *vcpu, int required_cpl);
 
 int kvm_pic_set_irq(void *opaque, int irq, int level);
arch/x86/kvm/mmu.c +3 -2
index 28ddc13..e99afef 100644
@@ -2737,9 +2737,10 @@ static unsigned long get_cr3(struct kvm_vcpu *vcpu)
 	return vcpu->arch.cr3;
 }
 
-static void inject_page_fault(struct kvm_vcpu *vcpu)
+static void inject_page_fault(struct kvm_vcpu *vcpu,
+			      struct x86_exception *fault)
 {
-	vcpu->arch.mmu.inject_page_fault(vcpu);
+	vcpu->arch.mmu.inject_page_fault(vcpu, fault);
 }
 
 static void paging_free(struct kvm_vcpu *vcpu)
arch/x86/kvm/paging_tmpl.h +3 -3
index aaed914..9a1990b 100644
@@ -279,8 +279,8 @@ error:
 	if (rsvd_fault)
 		walker->fault.error_code |= PFERR_RSVD_MASK;
 
-	vcpu->arch.fault.address    = addr;
-	vcpu->arch.fault.error_code = walker->fault.error_code;
+	walker->fault.address = addr;
+	walker->fault.nested_page_fault = mmu != vcpu->arch.walk_mmu;
 
 	trace_kvm_mmu_walker_error(walker->fault.error_code);
 	return 0;
@@ -561,7 +561,7 @@ static int FNAME(page_fault)(struct kvm_vcpu *vcpu, gva_t addr, u32 error_code,
 	 */
 	if (!r) {
 		pgprintk("%s: guest page fault\n", __func__);
-		inject_page_fault(vcpu);
+		inject_page_fault(vcpu, &walker.fault);
 		vcpu->arch.last_pt_write_count = 0; /* reset fork detector */
 		return 0;
 	}
arch/x86/kvm/svm.c +4 -3
index c6a7798..59669c2 100644
@@ -1647,14 +1647,15 @@ static void nested_svm_set_tdp_cr3(struct kvm_vcpu *vcpu,
 	force_new_asid(vcpu);
 }
 
-static void nested_svm_inject_npf_exit(struct kvm_vcpu *vcpu)
+static void nested_svm_inject_npf_exit(struct kvm_vcpu *vcpu,
+				       struct x86_exception *fault)
 {
 	struct vcpu_svm *svm = to_svm(vcpu);
 
 	svm->vmcb->control.exit_code = SVM_EXIT_NPF;
 	svm->vmcb->control.exit_code_hi = 0;
-	svm->vmcb->control.exit_info_1 = vcpu->arch.fault.error_code;
-	svm->vmcb->control.exit_info_2 = vcpu->arch.fault.address;
+	svm->vmcb->control.exit_info_1 = fault->error_code;
+	svm->vmcb->control.exit_info_2 = fault->address;
 
 	nested_svm_vmexit(svm);
 }
arch/x86/kvm/x86.c +24 -20

92 lines not on this page · raw message

Signature · 1 line
1.7.1
Tested-by on v1 1/1
#2 lore raw

Re: [PATCH 1/1] KVM: Pull extra page fault information into struct x86_exception

Quoted 7 lines · Avi Kivity

Currently page fault cr2 and nesting infomation are carried outside the fault data structure. Instead they are placed in the vcpu struct, which results in confusion as global variables are manipulated instead of passing parameters.

Fix this issue by adding address and nested fields to struct x86_exception, so this struct can carry all information associated with a fault.

Tested with nnpt and found no regressions.

Quoted 1 line
Signature · 5 lines
AMD Operating System Research Center

Advanced Micro Devices GmbH Einsteinring 24 85609 Dornach
General Managers: Alberto Bozzo, Andrew Bowd
Registration: Dornach, Landkr. Muenchen; Registerger. Muenchen, HRB Nr. 43632
Tested-by on v1 1/1
#3 lore raw

Re: [PATCH 1/1] KVM: Pull extra page fault information into struct x86_exception

In reply to Avi Kivity
Quoted 9 lines · Avi Kivity

Currently page fault cr2 and nesting infomation are carried outside the fault data structure. Instead they are placed in the vcpu struct, which results in confusion as global variables are manipulated instead of passing parameters.

Fix this issue by adding address and nested fields to struct x86_exception, so this struct can carry all information associated with a fault.

--
Gleb.

#4 lore raw
In reply to Avi Kivity
Quoted 2 lines · Avi Kivity

Gleb, Joerg, I'd appreciate review and testing of the apf and nnpt related changes.

I'll give it a test as soon as possible.

Joerg

Signature · 5 lines
AMD Operating System Research Center

Advanced Micro Devices GmbH Einsteinring 24 85609 Dornach
General Managers: Alberto Bozzo, Andrew Bowd
Registration: Dornach, Landkr. Muenchen; Registerger. Muenchen, HRB Nr. 43632
#5 lore raw
In reply to Avi Kivity
Quoted 12 lines · Avi Kivity

Currently fault injection is somewhat confused with important information carried in the vcpu area where it has no place. This patch cleans it up.

Gleb, Joerg, I'd appreciate review and testing of the apf and nnpt related changes.

Goes on top of the previous 7-part emulator series. Also available in 'emulator' branch of kvm.git.

Avi Kivity (1):
KVM: Pull extra page fault information into struct x86_exception

Quoted 7 lines
 arch/x86/include/asm/kvm_emulate.h |    2 +
 arch/x86/include/asm/kvm_host.h    |   17 +++----------
 arch/x86/kvm/mmu.c                 |    5 ++-
 arch/x86/kvm/paging_tmpl.h         |    6 ++--
 arch/x86/kvm/svm.c                 |    7 +++--
 arch/x86/kvm/x86.c                 |   44 +++++++++++++++++++----------------
 6 files changed, 40 insertions(+), 41 deletions(-)

Applied, thanks.