[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [PATCH v6 6/7] xen/arm: introduce acquire_staticmem_pages and acquire_domstatic_pages
On Wed, 8 Sep 2021, Penny Zheng wrote: > New function acquire_staticmem_pages aims to acquire nr_mfns contiguous pages > of static memory, starting at #smfn. And it is the equivalent of > alloc_heap_pages for static memory. > > For each page, it shall check if the page is reserved(PGC_reserved) > and free. It shall also do a set of necessary initialization, which are > mostly the same ones in alloc_heap_pages, like, following the same > cache-coherency policy and turning page status into PGC_state_inuse, etc. > > New function acquire_domstatic_pages is the equivalent of alloc_domheap_pages > for static memory, and it is to acquire nr_mfns contiguous pages of > static memory and assign them to one specific domain. > > It uses acquire_staticmem_pages to acquire nr_mfns pages of static memory. > Then on success, it will use assign_pages to assign those pages to one > specific domain. > > In order to differentiate pages of static memory from those allocated from > heap, this patch introduces a new page flag PGC_reserved, then mark pages of > static memory PGC_reserved when initializing them. > > Signed-off-by: Penny Zheng <penny.zheng@xxxxxxx> Reviewed-by: Stefano Stabellini <sstabellini@xxxxxxxxxx> > --- > xen/common/page_alloc.c | 118 ++++++++++++++++++++++++++++++++++++++- > xen/include/asm-arm/mm.h | 3 + > xen/include/xen/mm.h | 2 + > 3 files changed, 121 insertions(+), 2 deletions(-) > > diff --git a/xen/common/page_alloc.c b/xen/common/page_alloc.c > index bb19bb10ff..59dffcfa1d 100644 > --- a/xen/common/page_alloc.c > +++ b/xen/common/page_alloc.c > @@ -151,6 +151,10 @@ > #define p2m_pod_offline_or_broken_replace(pg) BUG_ON(pg != NULL) > #endif > > +#ifndef PGC_reserved > +#define PGC_reserved 0 > +#endif > + > /* > * Comma-separated list of hexadecimal page numbers containing bad bytes. > * e.g. 'badpage=0x3f45,0x8a321'. > @@ -2283,7 +2287,7 @@ int assign_pages( > > for ( i = 0; i < nr; i++ ) > { > - ASSERT(!(pg[i].count_info & ~PGC_extra)); > + ASSERT(!(pg[i].count_info & ~(PGC_extra | PGC_reserved))); > if ( pg[i].count_info & PGC_extra ) > extra_pages++; > } > @@ -2322,7 +2326,8 @@ int assign_pages( > page_set_owner(&pg[i], d); > smp_wmb(); /* Domain pointer must be visible before updating refcnt. > */ > pg[i].count_info = > - (pg[i].count_info & PGC_extra) | PGC_allocated | 1; > + (pg[i].count_info & (PGC_extra | PGC_reserved)) | PGC_allocated > | 1; > + > page_list_add_tail(&pg[i], page_to_list(d, &pg[i])); > } > > @@ -2626,8 +2631,117 @@ void __init free_staticmem_pages(struct page_info > *pg, unsigned long nr_mfns, > /* TODO: asynchronous scrubbing for pages of static memory. */ > scrub_one_page(pg); > } > + > + /* In case initializing page of static memory, mark it PGC_reserved. > */ > + pg[i].count_info |= PGC_reserved; > } > } > + > +/* > + * Acquire nr_mfns contiguous reserved pages, starting at #smfn, of > + * static memory. > + * This function needs to be reworked if used outside of boot. > + */ > +static struct page_info * __init acquire_staticmem_pages(mfn_t smfn, > + unsigned long > nr_mfns, > + unsigned int > memflags) > +{ > + bool need_tlbflush = false; > + uint32_t tlbflush_timestamp = 0; > + unsigned long i; > + struct page_info *pg; > + > + ASSERT(nr_mfns); > + for ( i = 0; i < nr_mfns; i++ ) > + if ( !mfn_valid(mfn_add(smfn, i)) ) > + return NULL; > + > + pg = mfn_to_page(smfn); > + > + spin_lock(&heap_lock); > + > + for ( i = 0; i < nr_mfns; i++ ) > + { > + /* The page should be reserved and not yet allocated. */ > + if ( pg[i].count_info != (PGC_state_free | PGC_reserved) ) > + { > + printk(XENLOG_ERR > + "pg[%lu] Static MFN %"PRI_mfn" c=%#lx t=%#x\n", > + i, mfn_x(smfn) + i, > + pg[i].count_info, pg[i].tlbflush_timestamp); > + goto out_err; > + } > + > + if ( !(memflags & MEMF_no_tlbflush) ) > + accumulate_tlbflush(&need_tlbflush, &pg[i], > + &tlbflush_timestamp); > + > + /* > + * Preserve flag PGC_reserved and change page state > + * to PGC_state_inuse. > + */ > + pg[i].count_info = PGC_reserved | PGC_state_inuse; > + /* Initialise fields which have other uses for free pages. */ > + pg[i].u.inuse.type_info = 0; > + page_set_owner(&pg[i], NULL); > + } > + > + spin_unlock(&heap_lock); > + > + if ( need_tlbflush ) > + filtered_flush_tlb_mask(tlbflush_timestamp); > + > + /* > + * Ensure cache and RAM are consistent for platforms where the guest > + * can control its own visibility of/through the cache. > + */ > + for ( i = 0; i < nr_mfns; i++ ) > + flush_page_to_ram(mfn_x(smfn) + i, !(memflags & > MEMF_no_icache_flush)); > + > + return pg; > + > + out_err: > + while ( i-- ) > + pg[i].count_info = PGC_reserved | PGC_state_free; > + > + spin_unlock(&heap_lock); > + > + return NULL; > +} > + > +/* > + * Acquire nr_mfns contiguous pages, starting at #smfn, of static memory, > + * then assign them to one specific domain #d. > + */ > +int __init acquire_domstatic_pages(struct domain *d, mfn_t smfn, > + unsigned long nr_mfns, unsigned int > memflags) > +{ > + struct page_info *pg; > + > + ASSERT(!in_irq()); > + > + pg = acquire_staticmem_pages(smfn, nr_mfns, memflags); > + if ( !pg ) > + return -ENOENT; > + > + if ( !d || (memflags & (MEMF_no_owner | MEMF_no_refcount)) ) > + { > + /* > + * Respective handling omitted here because right now > + * acquired static memory is only for guest RAM. > + */ > + ASSERT_UNREACHABLE(); > + return -EINVAL; > + } > + > + if ( assign_pages(d, pg, nr_mfns, memflags) ) > + { > + free_staticmem_pages(pg, nr_mfns, memflags & MEMF_no_scrub); > + return -EINVAL; > + } > + > + return 0; > +} > #endif > > /* > diff --git a/xen/include/asm-arm/mm.h b/xen/include/asm-arm/mm.h > index ded74d29da..7b5e7b7f69 100644 > --- a/xen/include/asm-arm/mm.h > +++ b/xen/include/asm-arm/mm.h > @@ -108,6 +108,9 @@ struct page_info > /* Page is Xen heap? */ > #define _PGC_xen_heap PG_shift(2) > #define PGC_xen_heap PG_mask(1, 2) > + /* Page is reserved */ > +#define _PGC_reserved PG_shift(3) > +#define PGC_reserved PG_mask(1, 3) > /* ... */ > /* Page is broken? */ > #define _PGC_broken PG_shift(7) > diff --git a/xen/include/xen/mm.h b/xen/include/xen/mm.h > index a74e93eba8..da1b158693 100644 > --- a/xen/include/xen/mm.h > +++ b/xen/include/xen/mm.h > @@ -89,6 +89,8 @@ bool scrub_free_pages(void); > /* These functions are for static memory */ > void free_staticmem_pages(struct page_info *pg, unsigned long nr_mfns, > bool need_scrub); > +int acquire_domstatic_pages(struct domain *d, mfn_t smfn, unsigned long > nr_mfns, > + unsigned int memflags); > #endif > > /* Map machine page range in Xen virtual address space. */ > -- > 2.25.1 >
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |