Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 5e352519 authored by Paolo Bonzini's avatar Paolo Bonzini
Browse files

KVM: nSVM: propagate the NPF EXITINFO to the guest



This is similar to what the EPT code does with the exit qualification.
This allows the guest to see a valid value for bits 33:32.

Signed-off-by: default avatarPaolo Bonzini <pbonzini@redhat.com>
parent a0c0feb5
Loading
Loading
Loading
Loading
+12 −0
Original line number Diff line number Diff line
@@ -322,8 +322,20 @@ static int FNAME(walk_addr_generic)(struct guest_walker *walker,

		real_gfn = mmu->translate_gpa(vcpu, gfn_to_gpa(table_gfn),
					      PFERR_USER_MASK|PFERR_WRITE_MASK);

		/*
		 * FIXME: This can happen if emulation (for of an INS/OUTS
		 * instruction) triggers a nested page fault.  The exit
		 * qualification / exit info field will incorrectly have
		 * "guest page access" as the nested page fault's cause,
		 * instead of "guest page structure access".  To fix this,
		 * the x86_exception struct should be augmented with enough
		 * information to fix the exit_qualification or exit_info_1
		 * fields.
		 */
		if (unlikely(real_gfn == UNMAPPED_GVA))
			goto error;

		real_gfn = gpa_to_gfn(real_gfn);

		host_addr = gfn_to_hva_prot(vcpu->kvm, real_gfn,
+20 −4
Original line number Diff line number Diff line
@@ -1974,10 +1974,26 @@ static void nested_svm_inject_npf_exit(struct kvm_vcpu *vcpu,
{
	struct vcpu_svm *svm = to_svm(vcpu);

	if (svm->vmcb->control.exit_code != SVM_EXIT_NPF) {
		/*
		 * TODO: track the cause of the nested page fault, and
		 * correctly fill in the high bits of exit_info_1.
		 */
		svm->vmcb->control.exit_code = SVM_EXIT_NPF;
		svm->vmcb->control.exit_code_hi = 0;
	svm->vmcb->control.exit_info_1 = fault->error_code;
		svm->vmcb->control.exit_info_1 = (1ULL << 32);
		svm->vmcb->control.exit_info_2 = fault->address;
	}

	svm->vmcb->control.exit_info_1 &= ~0xffffffffULL;
	svm->vmcb->control.exit_info_1 |= fault->error_code;

	/*
	 * The present bit is always zero for page structure faults on real
	 * hardware.
	 */
	if (svm->vmcb->control.exit_info_1 & (2ULL << 32))
		svm->vmcb->control.exit_info_1 &= ~1;

	nested_svm_vmexit(svm);
}