From mboxrd@z Thu Jan 1 00:00:00 1970 From: Gianluca Guida Subject: Fix PSE PAT handling in guest walk. Date: Mon, 24 Nov 2008 17:12:08 +0100 Message-ID: <492AD258.3070509@eu.citrix.com> Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="------------090702060109020602030308" Return-path: List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Sender: xen-devel-bounces@lists.xensource.com Errors-To: xen-devel-bounces@lists.xensource.com To: xen-devel@lists.xensource.com Cc: Tim Deegan List-Id: xen-devel@lists.xenproject.org This is a multi-part message in MIME format. --------------090702060109020602030308 Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit Hello, Guest walk was currently checking for _PAGE_PSE_PAT flag in guest_l2e_get_flags(). The problem is that this function only checks for the first 12 bits of the PDE, while _PAGE_PSE_PAT is actually on bit 12 (that is the 13th bit). This caused _PAGE_PAT bit to never been set on splintered L1s. Fix attached. Signed-off-by: Gianluca Guida --------------090702060109020602030308 Content-Type: text/x-diff; name="fix-pse-pat.patch" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="fix-pse-pat.patch" diff -r 24cc31a6b867 xen/arch/x86/mm/guest_walk.c --- a/xen/arch/x86/mm/guest_walk.c Sat Nov 22 09:34:55 2008 +0000 +++ b/xen/arch/x86/mm/guest_walk.c Mon Nov 24 14:48:33 2008 +0000 @@ -193,15 +193,15 @@ guest_walk_tables(struct vcpu *v, unsign * access controls are enforced in the shadow l2e. */ int flags = (_PAGE_PRESENT|_PAGE_USER|_PAGE_RW| _PAGE_ACCESSED|_PAGE_DIRTY); - /* PSE level 2 entries use bit 12 for PAT; propagate it to bit 7 - * of the level 1. */ - if ( (guest_l2e_get_flags(gw->l2e) & _PAGE_PSE_PAT) ) - flags |= _PAGE_PAT; - /* Copy the cache-control bits to the l1 as well, because we - * can't represent PAT in the (non-PSE) shadow l2e. :( - * This could cause problems if a guest ever maps an area of - * memory with superpages using more than one caching mode. */ - flags |= guest_l2e_get_flags(gw->l2e) & (_PAGE_PWT|_PAGE_PCD); + /* Import cache-control bits. Note that _PAGE_PAT is actually + * _PAGE_PSE, and it is always set. We will clear it in case + * _PAGE_PSE_PAT (bit 12, i.e. first bit of gfn) is clear. */ + flags |= (guest_l2e_get_flags(gw->l2e) + & (_PAGE_PAT|_PAGE_PWT|_PAGE_PCD)); + if ( !(gfn_x(start) & 1) ) + /* _PAGE_PSE_PAT not set: remove _PAGE_PAT from flags. */ + flags &= ~_PAGE_PAT; + /* Increment the pfn by the right number of 4k pages. * The ~0x1 is to mask out the PAT bit mentioned above. */ start = _gfn((gfn_x(start) & ~0x1) + guest_l1_table_offset(va)); --------------090702060109020602030308 Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Content-Disposition: inline _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel --------------090702060109020602030308--