|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] RE: [PATCH V3 08/10] xen/arm: introduce acquire_staticmem_pages and acquire_domstatic_pages
Hi Jan
> -----Original Message-----
> From: Jan Beulich <jbeulich@xxxxxxxx>
> Sent: Monday, July 19, 2021 5:26 PM
> To: Penny Zheng <Penny.Zheng@xxxxxxx>
> Cc: Bertrand Marquis <Bertrand.Marquis@xxxxxxx>; Wei Chen
> <Wei.Chen@xxxxxxx>; nd <nd@xxxxxxx>; xen-devel@xxxxxxxxxxxxxxxxxxxx;
> sstabellini@xxxxxxxxxx; julien@xxxxxxx
> Subject: Re: [PATCH V3 08/10] xen/arm: introduce acquire_staticmem_pages
> and acquire_domstatic_pages
>
> On 15.07.2021 07:18, Penny Zheng wrote:
> > @@ -1065,6 +1069,73 @@ static struct page_info *alloc_heap_pages(
> > return pg;
> > }
> >
> > +#ifdef CONFIG_STATIC_MEMORY
> > +/*
> > + * Acquire nr_mfns contiguous reserved pages, starting at #smfn, of
> > + * static memory.
> > + */
> > +static struct page_info *acquire_staticmem_pages(unsigned long nr_mfns,
> > + mfn_t smfn,
> > + unsigned int
> > +memflags)
>
> This and the other function not being __init, and there neither being any
> caller
> nor any freeing, a question is whether __init wants adding; patch 10 suggests
> so. The lack of freeing in particular means that domains created using static
> memory won't be restartable, requiring a host reboot instead.
>
Right now, all domain on static allocation get constructed through device tree,
in
boot-up time. "__init" is preferred.
> > +{
> > + bool need_tlbflush = false;
> > + uint32_t tlbflush_timestamp = 0;
> > + unsigned long i;
> > + struct page_info *pg;
> > +
> > + /* For now, it only supports pre-configured static memory. */
> > + if ( !mfn_valid(smfn) || !nr_mfns )
> > + return NULL;
> > +
> > + spin_lock(&heap_lock);
> > +
> > + pg = mfn_to_page(smfn);
> > +
> > + for ( i = 0; i < nr_mfns; i++ )
> > + {
> > + /*
> > + * Reference count must continuously be zero for free pages
> > + * of static memory(PGC_reserved).
> > + */
> > + 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(page_to_mfn(pg + i)),
> > + pg[i].count_info, pg[i].tlbflush_timestamp);
> > + BUG();
> > + }
> > +
> > + 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);
> > +
> > + /*
> > + * Ensure cache and RAM are consistent for platforms where the
> > + * guest can control its own visibility of/through the cache.
> > + */
> > + flush_page_to_ram(mfn_x(page_to_mfn(&pg[i])),
> > + !(memflags & MEMF_no_icache_flush));
>
> Indentation.
>
> > + }
> > +
> > + if ( need_tlbflush )
> > + filtered_flush_tlb_mask(tlbflush_timestamp);
> > +
> > + spin_unlock(&heap_lock);
>
> I'm pretty sure I did comment before on the flush_page_to_ram() being inside
> the locked region here. While XSA-364 doesn't apply here because you don't
> defer scrubbing (yet), the flushing may still take too long to happen inside
> the
> locked region. Of course there's a dependency here on when exactly the call(s)
> to this code will happen. In particular if other DomU-s can already be running
> at that point, this may not be tolerable by some of them. Yet if this is
> intentional and deemed not a problem, then I'd have kind of expected the
> description to mention this difference from alloc_heap_pages(), which you say
> this is an equivalent of.
>
Sorry for missing the comments on the flush_page_to_ram() being inside the
locked region.
Taking a while reading the XSA-364, you're right, especially with asynchronous
scrubbing in the to-do list, putting cleaning cache outside of the locked region
is necessary here.
> > @@ -2411,6 +2483,42 @@ struct page_info *alloc_domheap_pages(
> > return pg;
> > }
> >
> > +#ifdef CONFIG_STATIC_MEMORY
> > +/*
> > + * Acquire nr_mfns contiguous pages, starting at #smfn, of static
> > +memory,
> > + * then assign them to one specific domain #d.
> > + */
> > +struct page_info *acquire_domstatic_pages(
> > + struct domain *d, unsigned long nr_mfns, mfn_t smfn,
> > + unsigned int memflags)
> > +{
> > + struct page_info *pg = NULL;
> > +
> > + ASSERT(!in_irq());
> > +
> > + pg = acquire_staticmem_pages(nr_mfns, smfn, memflags);
> > + if ( !pg )
> > + return NULL;
> > +
> > + /* Right now, MEMF_no_owner case is meaningless here. */
> > + ASSERT(d);
> > + if ( memflags & MEMF_no_refcount )
> > + {
> > + unsigned long i;
> > +
> > + for ( i = 0; i < nr_mfns; i++ )
> > + pg[i].count_info |= PGC_extra;
> > + }
>
> With MEMF_no_owner now called out as meaningless here, what about
> MEMF_no_refcount?
>
I could not think of a case where "memflags & MEMF_no_refcount" is needed right
now.
All acquired pages are for guest RAM right now, extra pages like grant table,
etc, are not supported
on domain on static allocation, even more, any dom0-less domain.
I'll remove this part and put a few comments on it.
> Jan
Cheers
Penny
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |