[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [Xen-devel] [PATCH v2 15/15] xen: arm: handle 40-bit addresses in the p2m
On Fri, 22 Nov 2013, Ian Campbell wrote: > On the X-gene platform there are resources up this high which must be mapped > to dom0. > > Remove the first level page from the p2m->pages list since it is actually two > pages and must be freed as such. Do so in p2m_teardown. > > I've also punted on the implementation of dump_p2m_lookup for high > addresses... > > Signed-off-by: Ian Campbell <ian.campbell@xxxxxxxxxx> > --- > v2: > Remove irrelevant commentary from commit message > No longer RFC > --- > xen/arch/arm/p2m.c | 60 > +++++++++++++++++++++++++++++++++++++++++----------- > 1 file changed, 48 insertions(+), 12 deletions(-) > > diff --git a/xen/arch/arm/p2m.c b/xen/arch/arm/p2m.c > index 82dda65..af32511 100644 > --- a/xen/arch/arm/p2m.c > +++ b/xen/arch/arm/p2m.c > @@ -7,6 +7,10 @@ > #include <asm/flushtlb.h> > #include <asm/gic.h> > > +/* First level P2M is 2 consecutive pages */ > +#define P2M_FIRST_ORDER 1 > +#define P2M_FIRST_ENTRIES (LPAE_ENTRIES<<P2M_FIRST_ORDER) > + > void dump_p2m_lookup(struct domain *d, paddr_t addr) > { > struct p2m_domain *p2m = &d->arch.p2m; > @@ -14,6 +18,12 @@ void dump_p2m_lookup(struct domain *d, paddr_t addr) > > printk("dom%d IPA 0x%"PRIpaddr"\n", d->domain_id, addr); > > + if ( first_linear_offset(addr) > LPAE_ENTRIES ) > + { > + printk("Cannot dump addresses in second of first level pages...\n"); > + return; > + } > + > printk("P2M @ %p mfn:0x%lx\n", > p2m->first_level, page_to_mfn(p2m->first_level)); > > @@ -31,6 +41,30 @@ void p2m_load_VTTBR(struct domain *d) > isb(); /* Ensure update is visible */ > } > > +static int p2m_first_level_index(paddr_t addr) Would it make sense to make this an inline function? Regardless you have my acked-by. > +{ > + /* > + * 1st pages are concatenated so zeroeth offset gives us the > + * index of the 1st page > + */ > + return zeroeth_table_offset(addr); > +} > + > +/* > + * Map whichever of the first pages contain addr. The caller should > + * then use first_table_offset as an index. > + */ > +static lpae_t *p2m_map_first(struct p2m_domain *p2m, paddr_t addr) > +{ > + struct page_info *page; > + > + BUG_ON(first_linear_offset(addr) > P2M_FIRST_ENTRIES); > + > + page = p2m->first_level + p2m_first_level_index(addr); > + > + return __map_domain_page(page); > +} > + > /* > * Lookup the MFN corresponding to a domain's PFN. > * > @@ -45,7 +79,7 @@ paddr_t p2m_lookup(struct domain *d, paddr_t paddr) > > spin_lock(&p2m->lock); > > - first = __map_domain_page(p2m->first_level); > + first = p2m_map_first(p2m, paddr); > > pte = first[first_table_offset(paddr)]; > if ( !pte.p2m.valid || !pte.p2m.table ) > @@ -135,18 +169,21 @@ static int create_p2m_entries(struct domain *d, > struct p2m_domain *p2m = &d->arch.p2m; > lpae_t *first = NULL, *second = NULL, *third = NULL; > paddr_t addr; > - unsigned long cur_first_offset = ~0, cur_second_offset = ~0; > + unsigned long cur_first_page = ~0, > + cur_first_offset = ~0, > + cur_second_offset = ~0; > > spin_lock(&p2m->lock); > > - /* XXX Don't actually handle 40 bit guest physical addresses */ > - BUG_ON(start_gpaddr & 0x8000000000ULL); > - BUG_ON(end_gpaddr & 0x8000000000ULL); > - > - first = __map_domain_page(p2m->first_level); > - > for(addr = start_gpaddr; addr < end_gpaddr; addr += PAGE_SIZE) > { > + if ( cur_first_page != p2m_first_level_index(addr) ) > + { > + if ( first ) unmap_domain_page(first); > + first = p2m_map_first(p2m, addr); > + cur_first_page = p2m_first_level_index(addr); > + } > + > if ( !first[first_table_offset(addr)].p2m.valid ) > { > rc = p2m_create_table(d, &first[first_table_offset(addr)]); > @@ -279,15 +316,12 @@ int p2m_alloc_table(struct domain *d) > struct page_info *page; > void *p; > > - /* First level P2M is 2 consecutive pages */ > - page = alloc_domheap_pages(NULL, 1, 0); > + page = alloc_domheap_pages(NULL, P2M_FIRST_ORDER, 0); > if ( page == NULL ) > return -ENOMEM; > > spin_lock(&p2m->lock); > > - page_list_add(page, &p2m->pages); > - > /* Clear both first level pages */ > p = __map_domain_page(page); > clear_page(p); > @@ -380,6 +414,8 @@ void p2m_teardown(struct domain *d) > while ( (pg = page_list_remove_head(&p2m->pages)) ) > free_domheap_page(pg); > > + free_domheap_pages(p2m->first_level, P2M_FIRST_ORDER); > + > p2m->first_level = NULL; > > p2m_free_vmid(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 |