diff options
author | Paolo Bonzini <pbonzini@redhat.com> | 2014-09-02 15:23:06 +0400 |
---|---|---|
committer | Paolo Bonzini <pbonzini@redhat.com> | 2014-09-05 14:01:13 +0400 |
commit | 54987b7afa902e886b3a751c056c2a4d4701020e (patch) | |
tree | 1a7d4ca35f40849dcfee8a5e6b4bbe6a1785cfdb /arch/x86/kvm/paging_tmpl.h | |
parent | ef54bcfeea6c8b04e2a4f9396e16d88558aa2eee (diff) | |
download | linux-54987b7afa902e886b3a751c056c2a4d4701020e.tar.xz |
KVM: x86: propagate exception from permission checks on the nested page fault
Currently, if a permission error happens during the translation of
the final GPA to HPA, walk_addr_generic returns 0 but does not fill
in walker->fault. To avoid this, add an x86_exception* argument
to the translate_gpa function, and let it fill in walker->fault.
The nested_page_fault field will be true, since the walk_mmu is the
nested_mmu and translate_gpu instead operates on the "outer" (NPT)
instance.
Reported-by: Valentine Sinitsyn <valentine.sinitsyn@gmail.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Diffstat (limited to 'arch/x86/kvm/paging_tmpl.h')
-rw-r--r-- | arch/x86/kvm/paging_tmpl.h | 7 |
1 files changed, 4 insertions, 3 deletions
diff --git a/arch/x86/kvm/paging_tmpl.h b/arch/x86/kvm/paging_tmpl.h index df1a044d92de..0ab6c65a2821 100644 --- a/arch/x86/kvm/paging_tmpl.h +++ b/arch/x86/kvm/paging_tmpl.h @@ -321,7 +321,8 @@ retry_walk: walker->pte_gpa[walker->level - 1] = pte_gpa; real_gfn = mmu->translate_gpa(vcpu, gfn_to_gpa(table_gfn), - PFERR_USER_MASK|PFERR_WRITE_MASK); + PFERR_USER_MASK|PFERR_WRITE_MASK, + &walker->fault); /* * FIXME: This can happen if emulation (for of an INS/OUTS @@ -334,7 +335,7 @@ retry_walk: * fields. */ if (unlikely(real_gfn == UNMAPPED_GVA)) - goto error; + return 0; real_gfn = gpa_to_gfn(real_gfn); @@ -376,7 +377,7 @@ retry_walk: if (PTTYPE == 32 && walker->level == PT_DIRECTORY_LEVEL && is_cpuid_PSE36()) gfn += pse36_gfn_delta(pte); - real_gpa = mmu->translate_gpa(vcpu, gfn_to_gpa(gfn), access); + real_gpa = mmu->translate_gpa(vcpu, gfn_to_gpa(gfn), access, &walker->fault); if (real_gpa == UNMAPPED_GVA) return 0; |