summaryrefslogtreecommitdiff
path: root/arch/x86/kvm/paging_tmpl.h
diff options
context:
space:
mode:
authorPaolo Bonzini <pbonzini@redhat.com>2014-09-02 15:23:06 +0400
committerPaolo Bonzini <pbonzini@redhat.com>2014-09-05 14:01:13 +0400
commit54987b7afa902e886b3a751c056c2a4d4701020e (patch)
tree1a7d4ca35f40849dcfee8a5e6b4bbe6a1785cfdb /arch/x86/kvm/paging_tmpl.h
parentef54bcfeea6c8b04e2a4f9396e16d88558aa2eee (diff)
downloadlinux-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.h7
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;