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

Re: [PATCH 1/3] gnttab: adjust pin count overflow checks


  • To: Jan Beulich <jbeulich@xxxxxxxx>, "xen-devel@xxxxxxxxxxxxxxxxxxxx" <xen-devel@xxxxxxxxxxxxxxxxxxxx>
  • From: Andrew Cooper <andrew.cooper3@xxxxxxxxxx>
  • Date: Fri, 15 Jan 2021 13:09:40 +0000
  • Arc-authentication-results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=citrix.com; dmarc=pass action=none header.from=citrix.com; dkim=pass header.d=citrix.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:X-MS-Exchange-SenderADCheck; bh=DHyVzc6HBrw4xdr7fHHZmugs8Aoti0rcyI17EDZztZY=; b=Z06Mh0j41cB1Otu7jZ6pq0B5DPkWOLjfGJiy4aF6vDnLg1PNwia25DEqDXKHEP77+6tdghDYQAht7BX/idpWq7S31hTuEiDtSrtKKkv9HFt7JSzX8CNajYa5EbS1jSU3Gl4J2IdqYjRONLzjktxQQaRbKiOxjke6bR+/X1t7dvHsJaL/J8GZuH0fnFEm8bz54nE40rriB+bB93vNMakcXjEFxGbhOtqSWd9ux8lKN8mvsxxujp9re/avAkPLJjgFu65PXmmItIniUaawADoxMT5Ucmjc9mGmteYHPF338r6kHmQpJTywjNiLQDtao2LPcShUyeJhvbG1R5h1l10a/Q==
  • Arc-seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=fbbpWefTMFH9m5GtDgP9ji67vHb+cTFBNrvLyiB/k6OmGhj4qUiU5y+7fH0ISmlJjiTohhDG/5pz6pl4mh4W6y8sICOKHLOTygFHw4ZTyzlK/aCzYeX+dhpkRuiINOYaloxPLaZXa2OTf1lBD4gOhW6UcHsgBLuy8DVqQ5PKTePEt2dc/SlTfvcrzeRQt2xVmJXpoSzQUa8NvAVX3NWzVwm7v2Vs8hzJrtym/4/QYH1jvmy75UuKt/PFUFb+iAyrfKcL2oFlsllugg47pVMdV2bBMw8lstqfXr0mb0i5l/FA6AYeVjNGzy0Gz3dtAvb3mWwj/n2zXo35sgCyld+yBg==
  • Authentication-results: esa3.hc3370-68.iphmx.com; dkim=pass (signature verified) header.i=@citrix.onmicrosoft.com
  • Cc: George Dunlap <george.dunlap@xxxxxxxxxx>, Ian Jackson <iwj@xxxxxxxxxxxxxx>, Julien Grall <julien@xxxxxxx>, Stefano Stabellini <sstabellini@xxxxxxxxxx>, Wei Liu <wl@xxxxxxx>
  • Delivery-date: Fri, 15 Jan 2021 13:09:59 +0000
  • Ironport-sdr: qpuYnRo3VFgTUbh+yr2t+HgxEC/aQekEnnoomejjilFPFpIStN9sUkg+0ycdWhrfVtOY/kBl3I WH2FblPfzfTEVfcFFdr5jh/vH/Z3wEDoHIdWoxufJ8hZpetqwyrcu5e1ao4NglVRX8WrQV4lQD JWZ7r2KhZwm5VDMY+BTFbiakmIxo2a7munIUcjDDeebX64xd07d92Gw+7i2v2YkgGO60dpoQla 1IL/dTbXFua1zYCGxqZh+F8LS9bwfysEwOdDU1k0mZewoZgSG3umvaOCtXvHBo9qe0q8VT7WzO 65o=
  • List-id: Xen developer discussion <xen-devel.lists.xenproject.org>

On 14/01/2021 15:23, Jan Beulich wrote:
> It's at least odd to check counters which aren't going to be
> incremented. And it's also not helpful to use open-coded literal numbers
> in these checks.
>
> Calculate the increment values first and derive from them the mask to
> use in the checks.
>
> Also move the pin count checks ahead of the calculation of the status
> (and for copy also sha2) pointers: They're not needed in the failure
> cases, and this way the compiler may also have an easier time keeping
> the variables at least transiently in registers for the subsequent uses.
>
> Signed-off-by: Jan Beulich <jbeulich@xxxxxxxx>
>
> --- a/xen/common/grant_table.c
> +++ b/xen/common/grant_table.c
> @@ -323,22 +323,25 @@ shared_entry_header(struct grant_table *
>  /* Active grant entry - used for shadowing GTF_permit_access grants. */
>  struct active_grant_entry {
>      uint32_t      pin;    /* Reference count information:             */
> +                          /* Width of the individual counter fields.  */
> +#define GNTPIN_cntr_width    8
> +#define GNTPIN_cntr_mask     ((1U << GNTPIN_cntr_width) - 1)
>                            /* Count of writable host-CPU mappings.     */
>  #define GNTPIN_hstw_shift    0
>  #define GNTPIN_hstw_inc      (1U << GNTPIN_hstw_shift)
> -#define GNTPIN_hstw_mask     (0xFFU << GNTPIN_hstw_shift)
> +#define GNTPIN_hstw_mask     (GNTPIN_cntr_mask << GNTPIN_hstw_shift)
>                            /* Count of read-only host-CPU mappings.    */
> -#define GNTPIN_hstr_shift    8
> +#define GNTPIN_hstr_shift    (GNTPIN_hstw_shift + GNTPIN_cntr_width)

While this patch is by-and-large an improvement, it unfortunately
further hides how the pin field works, which is already clear-as-mud.

I'd recommend replacing the "Reference count information:" comment with:

/*
 * 4x byte-wide reference counts, for {host,device}{read,write}
 * mappings, implemented as a single 32bit presumably to optimise
 * checking for any reference.
 */
uint32_t      pin;


I still can't make up my mind as to whether this is a sensible
optimisation.  It is borderline obfuscated code, due to having a totally
undocumented and weird data arrangement.

> @@ -1052,19 +1063,19 @@ map_grant_ref(
>      shah = shared_entry_header(rgt, ref);
>      act = active_entry_acquire(rgt, ref);
>  
> -    /* Make sure we do not access memory speculatively */
> -    status = evaluate_nospec(rgt->gt_version == 1) ? &shah->flags
> -                                                 : &status_entry(rgt, ref);
> -
>      /* If already pinned, check the active domid and avoid refcnt overflow. 
> */
>      if ( act->pin &&
>           ((act->domid != ld->domain_id) ||
> -          (act->pin & 0x80808080U) != 0 ||
> +          (act->pin & (pin_incr << (GNTPIN_cntr_width - 1))) ||

This, I'm afraid, is not an improvement.  What we want is:

#define GNTPIN_overflow_mask 0x80808080U

The reason for checking all at once is defence in depth (not strictly
necessary, but also not a problem), and in this specific example, using
a constant results in better code because pin_incr doesn't need
unspilling from stack and manipulated.

If you're happy with both of these suggestions, then Reviewed-by: Andrew
Cooper <andrew.cooper3@xxxxxxxxxx> to avoid a repost.

~Andrew



 


Rackspace

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