[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [Xen-devel] [PATCH] xen: arm: avoid truncation in mfn to paddr conversions
On Mon, 2 Dec 2013, Ian Campbell wrote: > Although MFNs are 64-bit in the hypercall ABI they are most often unsigned > long internally, and therefore be 32-bit on arm32. Physical addresses are > always 64-bit via paddr_t. > > This means that the common "mfn << PAGE_SHIFT" pattern risks losing some of > the top bits of the address is high enough. This need not imply a high amount > of RAM, just a sparse physical address map. > > The correct form is ((paddr_t)mfn)<<PAGE_SHIFT and we have the pfn_to_paddr > macro which implements this. Grep for PAGE_SHIFT and << and switch to the > macro everywhere we can in the arch specific code. Note that page.h is > included by mm.h which defines the macro and so remains with the open coded > cast. I have inspected the common code matching this pattern and it uses the > correct casts where necessary (x86 also has pfn_to_paddr, so as a further > cleanup we could fix the common code too, but I haven't done that here). > > I observed this as failure to boot a guest on midway, due to trying to map a > foreign page which belonged to no guest. I think this likely explains the > crashes which Julien has seen too. > > Signed-off-by: Ian Campbell <ian.campbell@xxxxxxxxxx> Acked-by: Stefano Stabellini <stefano.stabellini@xxxxxxxxxxxxx> > xen/arch/arm/domain_build.c | 4 ++-- > xen/arch/arm/mm.c | 4 ++-- > xen/arch/arm/p2m.c | 16 +++++++++------- > xen/arch/arm/setup.c | 8 ++++---- > xen/include/asm-arm/mm.h | 4 ++-- > 5 files changed, 19 insertions(+), 17 deletions(-) > > diff --git a/xen/arch/arm/domain_build.c b/xen/arch/arm/domain_build.c > index 90fe88e..6c2fd3c 100644 > --- a/xen/arch/arm/domain_build.c > +++ b/xen/arch/arm/domain_build.c > @@ -84,8 +84,8 @@ static void allocate_memory_11(struct domain *d, struct > kernel_info *kinfo) > panic("Failed to allocate contiguous memory for dom0\n"); > > spfn = page_to_mfn(pg); > - start = spfn << PAGE_SHIFT; > - size = (1 << order) << PAGE_SHIFT; > + start = pfn_to_paddr(spfn); > + size = pfn_to_paddr((1 << order)); > > // 1:1 mapping > printk("Populate P2M %#"PRIx64"->%#"PRIx64" (1:1 mapping for dom0)\n", > diff --git a/xen/arch/arm/mm.c b/xen/arch/arm/mm.c > index 2de7dc7..8189915 100644 > --- a/xen/arch/arm/mm.c > +++ b/xen/arch/arm/mm.c > @@ -1032,10 +1032,10 @@ static int xenmem_add_to_physmap_one( > return rc; > } > > - maddr = p2m_lookup(od, idx << PAGE_SHIFT); > + maddr = p2m_lookup(od, pfn_to_paddr(idx)); > if ( maddr == INVALID_PADDR ) > { > - dump_p2m_lookup(od, idx << PAGE_SHIFT); > + dump_p2m_lookup(od, pfn_to_paddr(idx)); > rcu_unlock_domain(od); > return -EINVAL; > } > diff --git a/xen/arch/arm/p2m.c b/xen/arch/arm/p2m.c > index af32511..1d5c841 100644 > --- a/xen/arch/arm/p2m.c > +++ b/xen/arch/arm/p2m.c > @@ -296,18 +296,20 @@ int guest_physmap_add_page(struct domain *d, > unsigned long mfn, > unsigned int page_order) > { > - return create_p2m_entries(d, INSERT, gpfn << PAGE_SHIFT, > - (gpfn + (1<<page_order)) << PAGE_SHIFT, > - mfn << PAGE_SHIFT, MATTR_MEM); > + return create_p2m_entries(d, INSERT, > + pfn_to_paddr(gpfn), > + pfn_to_paddr(gpfn + (1<<page_order)), > + pfn_to_paddr(mfn), MATTR_MEM); > } > > void guest_physmap_remove_page(struct domain *d, > unsigned long gpfn, > unsigned long mfn, unsigned int page_order) > { > - create_p2m_entries(d, REMOVE, gpfn << PAGE_SHIFT, > - (gpfn + (1<<page_order)) << PAGE_SHIFT, > - mfn << PAGE_SHIFT, MATTR_MEM); > + create_p2m_entries(d, REMOVE, > + pfn_to_paddr(gpfn), > + pfn_to_paddr(gpfn + (1<<page_order)), > + pfn_to_paddr(mfn), MATTR_MEM); > } > > int p2m_alloc_table(struct domain *d) > @@ -450,7 +452,7 @@ err: > > unsigned long gmfn_to_mfn(struct domain *d, unsigned long gpfn) > { > - paddr_t p = p2m_lookup(d, gpfn << PAGE_SHIFT); > + paddr_t p = p2m_lookup(d, pfn_to_paddr(gpfn)); > return p >> PAGE_SHIFT; > } > > diff --git a/xen/arch/arm/setup.c b/xen/arch/arm/setup.c > index 6834813..e640d81 100644 > --- a/xen/arch/arm/setup.c > +++ b/xen/arch/arm/setup.c > @@ -456,7 +456,7 @@ static void __init setup_mm(unsigned long dtb_paddr, > size_t dtb_size) > { > /* xenheap is always in the initial contiguous region */ > e = consider_modules(contig_start, contig_end, > - xenheap_pages<<PAGE_SHIFT, > + pfn_to_paddr(xenheap_pages), > 32<<20, 0); > if ( e ) > break; > @@ -470,7 +470,7 @@ static void __init setup_mm(unsigned long dtb_paddr, > size_t dtb_size) > domheap_pages = heap_pages - xenheap_pages; > > early_printk("Xen heap: %"PRIpaddr"-%"PRIpaddr" (%lu pages)\n", > - e - (xenheap_pages << PAGE_SHIFT), e, > + e - (pfn_to_paddr(xenheap_pages)), e, > xenheap_pages); > early_printk("Dom heap: %lu pages\n", domheap_pages); > > @@ -517,8 +517,8 @@ static void __init setup_mm(unsigned long dtb_paddr, > size_t dtb_size) > e = bank_end; > > /* Avoid the xenheap */ > - if ( s < ((xenheap_mfn_start+xenheap_pages) << PAGE_SHIFT) > - && (xenheap_mfn_start << PAGE_SHIFT) < e ) > + if ( s < pfn_to_paddr(xenheap_mfn_start+xenheap_pages) > + && pfn_to_paddr(xenheap_mfn_start) < e ) > { > e = pfn_to_paddr(xenheap_mfn_start); > n = pfn_to_paddr(xenheap_mfn_start+xenheap_pages); > diff --git a/xen/include/asm-arm/mm.h b/xen/include/asm-arm/mm.h > index ce66099..b8d4e7d 100644 > --- a/xen/include/asm-arm/mm.h > +++ b/xen/include/asm-arm/mm.h > @@ -123,8 +123,8 @@ extern unsigned long xenheap_virt_end; > #endif > > #define is_xen_fixed_mfn(mfn) \ > - ((((mfn) << PAGE_SHIFT) >= virt_to_maddr(&_start)) && \ > - (((mfn) << PAGE_SHIFT) <= virt_to_maddr(&_end))) > + ((pfn_to_paddr(mfn) >= virt_to_maddr(&_start)) && \ > + (pfn_to_paddr(mfn) <= virt_to_maddr(&_end))) > > #define page_get_owner(_p) (_p)->v.inuse.domain > #define page_set_owner(_p,_d) ((_p)->v.inuse.domain = (_d)) > -- > 1.7.10.4 > _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxx http://lists.xen.org/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |