[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [RFC PATCH] xen/gnttab: Store frame GFN in struct page_info on Arm


  • To: Oleksandr <olekstysh@xxxxxxxxx>
  • From: Jan Beulich <jbeulich@xxxxxxxx>
  • Date: Tue, 14 Sep 2021 10:31:43 +0200
  • Arc-authentication-results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=suse.com; dmarc=pass action=none header.from=suse.com; dkim=pass header.d=suse.com; arc=none
  • Arc-message-signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector9901; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version; bh=c1PgFZ/1KSPVZt+CxDUU17pwkTnnxg+QY9W8NaCFS90=; b=DYiRDSmCvbae79ugt8nzpWmvy9SoM/urrGSWbm2BX7bEf3ciiEMSSDnHHJ5Nm2bg+Bzdys2iToOkDjgHNZHTqNoEmgbPp61KRjuL/rBuMnODb5xs0NZbKKntyPnCeJPZSzS2wyHvQbm9SjpIGKPWhFjiOOpcP5+MgxWvXfCqDRY1pOq/jEg2plsRDkRX5+W0p/rk2UoqjsoRIPNk29HTkBS/pQAu3+g/+zxGOzF9WqH2mkUFa8osLSWiXyzp7m+soxOcHZtNWsY4EctSB2fFNN9CxHqX2/W29t3TCKiFiE4ATLgntVInIn39v2JXlQb9oiKBRqZY8/9c+4trLMxCOw==
  • Arc-seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=a9Tg3SO0ALScl1ojgXIVd4nbp8CY8B6Pj5owYYLMg/lsUK6YUdpn0q+cU5S6/eoiuLF0gpUVHa/l6M1ogW/MIdvy36tKTghfM3e6M8ar+ATF6//1G1DGj74Pc1cE8MeFfVW4Ok2GkTgcNIUuDqXVm5nNbImknaLNdGs9xdu9CSmwh4voGid1gzBkbdcP2aFzHYaPvgcueJtfpMXyHjjD7GMtW/h7bjxf1Kz5TvIdOss6Uap5MwjcPzGJMvQKwS26PJu1uWRXZz2zJIHd8Ciauobygnyb03rcT3uPNvwKNLb9J490f/8q5Pns89Eo6Xa/7732kkkiGiAFMPGJFaqkWw==
  • Authentication-results: lists.xenproject.org; dkim=none (message not signed) header.d=none;lists.xenproject.org; dmarc=none action=none header.from=suse.com;
  • Cc: Oleksandr Tyshchenko <oleksandr_tyshchenko@xxxxxxxx>, Stefano Stabellini <sstabellini@xxxxxxxxxx>, Julien Grall <julien@xxxxxxx>, Volodymyr Babchuk <Volodymyr_Babchuk@xxxxxxxx>, Andrew Cooper <andrew.cooper3@xxxxxxxxxx>, George Dunlap <george.dunlap@xxxxxxxxxx>, Ian Jackson <iwj@xxxxxxxxxxxxxx>, Wei Liu <wl@xxxxxxx>, Roger Pau Monné <roger.pau@xxxxxxxxxx>, xen-devel@xxxxxxxxxxxxxxxxxxxx
  • Delivery-date: Tue, 14 Sep 2021 08:31:52 +0000
  • List-id: Xen developer discussion <xen-devel.lists.xenproject.org>

On 13.09.2021 19:09, Oleksandr wrote:
> On 10.09.21 10:52, Jan Beulich wrote:
>> On 10.09.2021 01:04, Oleksandr Tyshchenko wrote:
>>> @@ -731,11 +733,19 @@ static void p2m_put_l3_page(const lpae_t pte)
>>>        */
>>>       if ( p2m_is_foreign(pte.p2m.type) )
>>>       {
>>> -        mfn_t mfn = lpae_get_mfn(pte);
>>> -
>>>           ASSERT(mfn_valid(mfn));
>>>           put_page(mfn_to_page(mfn));
>>>       }
>>> +
>>> +#ifdef CONFIG_GRANT_TABLE
>>> +    /*
>>> +     * Check whether we deal with grant table page. As the grant table page
>>> +     * is xen_heap page and its entry has known p2m type, detect it and 
>>> mark
>>> +     * the stored GFN as invalid.
>>> +     */
>>> +    if ( p2m_is_ram(pte.p2m.type) && is_xen_heap_mfn(mfn) )
>>> +        page_set_frame_gfn(mfn_to_page(mfn), INVALID_GFN);
>>> +#endif
>> I take it the write done is benign for other Xen heap pages? I suppose
>> this would want making very explicit, as such an assumption is easy to
>> go stale by entirely unrelated changes.
> 
> Yes, I don't see what bad could happen if we would clear this field for 
> non grant table pages. Except grant table pages I could detect only one 
> page passed this check here which is, I assume, shared_info page. All 
> pages have this field initialized with INVALID_GFN. But *only* grant 
> table pages have this field in use. So, I think, no one will suffer. I 
> will add a comment. Or you meant something more than just a comment?

The answer here goes hand in hand with the pending question of whether
you wouldn't better generally introduce recording of the GFN (and hence
effectively an M2P): The less special casing here, the better imo. The
more special casing here, the more justification / explanation is imo
needed in the comment.

>>> --- a/xen/include/asm-arm/mm.h
>>> +++ b/xen/include/asm-arm/mm.h
>>> @@ -39,7 +39,15 @@ struct page_info
>>>           /* Page is in use: ((count_info & PGC_count_mask) != 0). */
>>>           struct {
>>>               /* Type reference count and various PGT_xxx flags and fields. 
>>> */
>>> -            unsigned long type_info;
>>> +            unsigned long type_info:4;
>>> +
>>> +            /*
>>> +             * Stored GFN if page is used for grant table frame
>>> +             * (bits 59(27)-0).
>> Are these bit numbers correct? I thought Arm, like x86, counted bits
>> from low to high (unlike PPC, for example)?
> 
> I think, these are correct.  Yes, Little Endian is used.

Well, the low 4 bits are used by type_info here. Therefore I'm having
trouble seeing what the 0 refers to.

>>> @@ -94,12 +102,12 @@ struct page_info
>>>   #define PG_shift(idx)   (BITS_PER_LONG - (idx))
>>>   #define PG_mask(x, idx) (x ## UL << PG_shift(idx))
>>>   
>>> -#define PGT_none          PG_mask(0, 1)  /* no special uses of this page   
>>> */
>>> -#define PGT_writable_page PG_mask(1, 1)  /* has writable mappings?         
>>> */
>>> -#define PGT_type_mask     PG_mask(1, 1)  /* Bits 31 or 63.                 
>>> */
>>> +#define PGT_none          (0UL << 3)  /* no special uses of this page   */
>>> +#define PGT_writable_page (1UL << 3)  /* has writable mappings?         */
>>> +#define PGT_type_mask     (1UL << 3)
>>>   
>>>    /* Count of uses of this frame as its current type. */
>>> -#define PGT_count_width   PG_shift(2)
>>> +#define PGT_count_width   1
>>>   #define PGT_count_mask    ((1UL<<PGT_count_width)-1)
>> Leaving just a single bit seems pretty risky to me, and I can't see
>> why you do so. You need 52 bits on Arm64. Which means you have 12
>> bits left. Why not use them in full? Even on Arm32 you have 3 bits
>> available for the count afaict.
> 
> Only 1 bit in the type_info field is really used on Arm, but anyway ...
> 
> 
>>
>> Also there's a disconnect here: If anyone wanted to change the number
>> of bits used for the various fields, each such change should require
>> an adjustment in as few independent places as possible. That is, there
>> shouldn't be multiple uses of literal 4 further up, and there also
>> shouldn't be a hidden connection between that 4 and the PGT_* values
>> here. I think you'd better express the GFN as such a PGT_* construct
>> as well. And you better would keep using PG_mask() and PG_shift().
> 
> ... I think, this indeed makes sense. If got your request correctly, we 
> can avoid disconnect here
> and reserve 3-bit field for count for both Arm32 and Arm64. The struct 
> page_info's type_info field remains untouched.
> 
> 
> diff --git a/xen/include/asm-arm/mm.h b/xen/include/asm-arm/mm.h
> index ded74d2..8b73e1c 100644
> --- a/xen/include/asm-arm/mm.h
> +++ b/xen/include/asm-arm/mm.h
> @@ -99,8 +99,14 @@ struct page_info
>   #define PGT_type_mask     PG_mask(1, 1)  /* Bits 31 or 
> 63.                 */
> 
>    /* Count of uses of this frame as its current type. */
> -#define PGT_count_width   PG_shift(2)
> -#define PGT_count_mask    ((1UL<<PGT_count_width)-1)
> +#define PGT_count_base    PG_shift(4)
> +#define PGT_count_mask    PG_mask(7, 4)
> +
> +/* Stored in bits [27:0] or [59:0] GFN if page is used for grant table 
> frame */
> +#define PGT_gfn_width     PG_shift(4)
> +#define PGT_gfn_mask      ((1UL<<PGT_gfn_width)-1)
> +
> +#define PGT_INVALID_FRAME_GFN   _gfn(PGT_gfn_mask)
> 
>    /* Cleared when the owning guest 'frees' this page. */
>   #define _PGC_allocated    PG_shift(1)
> @@ -163,6 +169,22 @@ extern unsigned long xenheap_base_pdx;
> 
>   #define maddr_get_owner(ma) (page_get_owner(maddr_to_page((ma))))
> 
> +#define page_get_frame_gfn(_p) ({                               \
> +    gfn_t gfn_ = _gfn((_p)->u.inuse.type_info & PGT_gfn_mask);  \
> +    gfn_eq(gfn_, PGT_INVALID_FRAME_GFN) ? INVALID_GFN : gfn_;   \
> +})
> +
> +#define page_set_frame_gfn(_p, _gfn) ({                         \
> +    gfn_t gfn_ = gfn_eq(_gfn, INVALID_GFN) ?                    \
> +                 PGT_INVALID_FRAME_GFN : _gfn;                  \
> +    (_p)->u.inuse.type_info &= ~PGT_gfn_mask;                   \
> +    (_p)->u.inuse.type_info |= gfn_x(gfn_);                     \
> +})
> 
> [snip]
> 
> Is it close to what you keep in mind?

Yes. Just to be sure - did you check that moving the count up
from starting at bit 0 is compatible with all present uses? At
least on x86 I think we have uses where it is assumed to occupy
the bottom so many bits (and the same also for PGC_count_mask).

Jan




 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.