Jesse Keating 2f82dd
From: Xiao Guangrong <xiaoguangrong@cn.fujitsu.com>
Jesse Keating 2f82dd
Date: Wed, 30 Jun 2010 08:02:45 +0000 (+0800)
Jesse Keating 2f82dd
Subject: KVM: MMU: fix conflict access permissions in direct sp
Jesse Keating 2f82dd
X-Git-Url: http://git.kernel.org/?p=linux%2Fkernel%2Fgit%2Ftorvalds%2Flinux-2.6.git;a=commitdiff_plain;h=6aa0b9dec5d6dde26ea17b0b5be8fccfe19df3c9
Jesse Keating 2f82dd
Jesse Keating 2f82dd
KVM: MMU: fix conflict access permissions in direct sp
Jesse Keating 2f82dd
Jesse Keating 2f82dd
In no-direct mapping, we mark sp is 'direct' when we mapping the
Jesse Keating 2f82dd
guest's larger page, but its access is encoded form upper page-struct
Jesse Keating 2f82dd
entire not include the last mapping, it will cause access conflict.
Jesse Keating 2f82dd
Jesse Keating 2f82dd
For example, have this mapping:
Jesse Keating 2f82dd
        [W]
Jesse Keating 2f82dd
      / PDE1 -> |---|
Jesse Keating 2f82dd
  P[W]          |   | LPA
Jesse Keating 2f82dd
      \ PDE2 -> |---|
Jesse Keating 2f82dd
        [R]
Jesse Keating 2f82dd
Jesse Keating 2f82dd
P have two children, PDE1 and PDE2, both PDE1 and PDE2 mapping the
Jesse Keating 2f82dd
same lage page(LPA). The P's access is WR, PDE1's access is WR,
Jesse Keating 2f82dd
PDE2's access is RO(just consider read-write permissions here)
Jesse Keating 2f82dd
Jesse Keating 2f82dd
When guest access PDE1, we will create a direct sp for LPA, the sp's
Jesse Keating 2f82dd
access is from P, is W, then we will mark the ptes is W in this sp.
Jesse Keating 2f82dd
Jesse Keating 2f82dd
Then, guest access PDE2, we will find LPA's shadow page, is the same as
Jesse Keating 2f82dd
PDE's, and mark the ptes is RO.
Jesse Keating 2f82dd
Jesse Keating 2f82dd
So, if guest access PDE1, the incorrect #PF is occured.
Jesse Keating 2f82dd
Jesse Keating 2f82dd
Fixed by encode the last mapping access into direct shadow page
Jesse Keating 2f82dd
Jesse Keating 2f82dd
Signed-off-by: Xiao Guangrong <xiaoguangrong@cn.fujitsu.com>
Jesse Keating 2f82dd
Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>
Jesse Keating 2f82dd
Signed-off-by: Avi Kivity <avi@redhat.com>
Jesse Keating 2f82dd
---
Jesse Keating 2f82dd
Jesse Keating 2f82dd
diff --git a/arch/x86/kvm/paging_tmpl.h b/arch/x86/kvm/paging_tmpl.h
Jesse Keating 2f82dd
index 89d66ca..2331bdc 100644
Jesse Keating 2f82dd
--- a/arch/x86/kvm/paging_tmpl.h
Jesse Keating 2f82dd
+++ b/arch/x86/kvm/paging_tmpl.h
Jesse Keating 2f82dd
@@ -342,6 +342,7 @@ static u64 *FNAME(fetch)(struct kvm_vcpu *vcpu, gva_t addr,
Jesse Keating 2f82dd
 			/* advance table_gfn when emulating 1gb pages with 4k */
Jesse Keating 2f82dd
 			if (delta == 0)
Jesse Keating 2f82dd
 				table_gfn += PT_INDEX(addr, level);
Jesse Keating 2f82dd
+			access &= gw->pte_access;
Jesse Keating 2f82dd
 		} else {
Jesse Keating 2f82dd
 			direct = 0;
Jesse Keating 2f82dd
 			table_gfn = gw->table_gfn[level - 2];