| 
    
 [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  |