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: Paolo Bonzini <pbonzini@redhat.com>
This commit is contained in:
parent
a0c0feb579
commit
5e35251951
|
@ -322,8 +322,20 @@ retry_walk:
|
|||
|
||||
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,
|
||||
|
|
|
@ -1974,10 +1974,26 @@ static void nested_svm_inject_npf_exit(struct kvm_vcpu *vcpu,
|
|||
{
|
||||
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 = fault->error_code;
|
||||
svm->vmcb->control.exit_info_2 = fault->address;
|
||||
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 = (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);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue