From: Tim Deegan Date: Thu, 5 May 2011 16:40:34 +0000 (+0100) Subject: x86/mm: don't treat entirely empty p2m entries as RAM. X-Git-Tag: 4.2.0-rc1~2283 X-Git-Url: http://xenbits.xensource.com/gitweb?a=commitdiff_plain;h=31915b333f5413d3be1f9f90aace5bf8b3cedab0;p=xen.git x86/mm: don't treat entirely empty p2m entries as RAM. The AMD IOMMU pagetable-sharing code switched p2m type 0 to be r/w RAM rather than invalid. Be more careful when translating from PTEs to p2m types that we don't treat all-zeros as a RAM mapping of frame zero. Signed-off-by: Tim Deegan --- diff --git a/xen/arch/x86/mm/hap/p2m-ept.c b/xen/arch/x86/mm/hap/p2m-ept.c index f1c2b0ee4d..0fa0182fbd 100644 --- a/xen/arch/x86/mm/hap/p2m-ept.c +++ b/xen/arch/x86/mm/hap/p2m-ept.c @@ -579,8 +579,9 @@ static mfn_t ept_get_entry(struct p2m_domain *p2m, goto out; } - - if ( ept_entry->sa_p2mt != p2m_invalid ) + /* Need to check for all-zeroes because typecode 0 is p2m_ram and an + * entirely empty entry shouldn't have RAM type. */ + if ( ept_entry->epte != 0 && ept_entry->sa_p2mt != p2m_invalid ) { *t = ept_entry->sa_p2mt; *a = ept_entry->access; diff --git a/xen/arch/x86/mm/p2m.c b/xen/arch/x86/mm/p2m.c index 001883d256..a57464549f 100644 --- a/xen/arch/x86/mm/p2m.c +++ b/xen/arch/x86/mm/p2m.c @@ -1883,9 +1883,6 @@ static mfn_t p2m_gfn_to_mfn_current(struct p2m_domain *p2m, p2mt = p2m_flags_to_type(l1e_get_flags(l1e)); ASSERT(l1e_get_pfn(l1e) != INVALID_MFN || !p2m_is_ram(p2mt)); - if ( l1e.l1 == 0 ) - p2mt = p2m_invalid; - if ( p2m_flags_to_type(l1e_get_flags(l1e)) == p2m_populate_on_demand ) { diff --git a/xen/include/asm-x86/p2m.h b/xen/include/asm-x86/p2m.h index 91b7ce6994..97c830a550 100644 --- a/xen/include/asm-x86/p2m.h +++ b/xen/include/asm-x86/p2m.h @@ -381,12 +381,12 @@ static inline p2m_type_t p2m_flags_to_type(unsigned long flags) { /* Type is stored in the "available" bits */ #ifdef __x86_64__ - /* - * AMD IOMMU: When we share p2m table with iommu, bit 9 - bit 11 will be - * used for iommu hardware to encode next io page level. Bit 59 - bit 62 - * are used for iommu flags, We could not use these bits to store p2m types. - */ - + /* For AMD IOMMUs we need to use type 0 for plain RAM, but we need + * to make sure that an entirely empty PTE doesn't have RAM type */ + if ( flags == 0 ) + return p2m_invalid; + /* AMD IOMMUs use bits 9-11 to encode next io page level and bits + * 59-62 for iommu flags so we can't use them to store p2m type info. */ return (flags >> 12) & 0x7f; #else return (flags >> 9) & 0x7;