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