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

Re: [PATCH v3] vPCI: account for hidden devices


  • To: Jan Beulich <jbeulich@xxxxxxxx>
  • From: Roger Pau Monné <roger.pau@xxxxxxxxxx>
  • Date: Tue, 30 May 2023 15:36:35 +0200
  • 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-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=96weyViAV/4YcbOJcV3izndEXIx065gHdjHm5RRyJYM=; b=HJ60lqOmnT2dZN+4JtihZ8yP8FdGYmQQQ3jWr/NH1bV0o73ghk1zKRTOV0KpAc3wdtpUH14EteczAQcGPCwfbEt6fqld4d8y3brWIBlgkpQBLfzP+5mUFBCpF8wkt4SurxD4x9t6fQgtuyoIkdyPuCDhHCKUhtK8z2Qj/uIcQ/DNav7UzWukgAIX5oR9HlJadKgXuRjZdAywVgDWkfja6yu7iRPHVudylS0D30SjZT9rw3NsqTwCf94QPkS/XBy1seEQzICTQhRMehYpefpK5IeJONA5ovy4wUnxHK8Q+S6xprp+W/MajKtqYeiDuAy4UthoWrX3n3k9NVDTvQVjiw==
  • Arc-seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=illSC23pHVn2leBo7sZZYWDDo+aVVes5tUWJXEzbDrJsZt32zrdbANo5hiwOthesV8iaQCvfJgHH3XmsLM/u8J9ZjT2CUfXaRoMwoTsOUwC1T4pYdVKoHB5WLdXYOT6xHwFmVFhlye4c6F+dRXM8oJjOTCZghGWzYKoLHoMtpKmpdQ3iKrKCYInBEfBT3Fuhsmj7AZNXrXiJpNldbqJd6XHIeSVZ1EbrtBa8hMR3PNmO9FLj7AmO7MjNbNVV1ymKxQlbgKehyPKrXODkWVwam6GwV5LBy6cyTLldnmQ/s7Cu/8uy5e3b0V7xVOp3iwdcei7lJNBnB9lpBoIHo/+hWg==
  • Authentication-results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=citrix.com;
  • Cc: "xen-devel@xxxxxxxxxxxxxxxxxxxx" <xen-devel@xxxxxxxxxxxxxxxxxxxx>, Stefano Stabellini <sstabellini@xxxxxxxxxx>
  • Delivery-date: Tue, 30 May 2023 13:37:06 +0000
  • Ironport-data: A9a23:Mc5/pa0CDwvQoCSVO/bD5fhwkn2cJEfYwER7XKvMYLTBsI5bp2BVn GZJDWyGOauMYGfzcox3Yduw9k8P7ZPcnYRgTgBopC1hF35El5HIVI+TRqvS04F+DeWYFR46s J9OAjXkBJppJpMJjk71atANlVEliefTAOK6ULWeUsxIbVcMYD87jh5+kPIOjIdtgNyoayuAo tq3qMDEULOf82cc3lk8teTb8HuDgNyo4GlD5gFlPagR1LPjvyJ94Kw3dPnZw0TQGuG4LsbiL 87fwbew+H/u/htFIrtJRZ6iLyXm6paLVeS/oiI+t5qK23CulQRrukoPD9IOaF8/ttm8t4sZJ OOhF3CHYVxB0qXkwIzxWvTDes10FfUuFLTveRBTvSEPpqFvnrSFL/hGVSkL0YMkFulfGE5Br MFEBhc2P1OuieC9ya2KELVXr5F2RCXrFNt3VnBI6xj8VKxjZK+ZBqLA6JlfwSs6gd1IEbDGf c0FZDFzbRPGJRpSJlMQD5F4l+Ct7pX9W2QA9BTJ+uxpvS6PkmSd05C0WDbRUsaNSshP2F6Ru 0rN/njjAwFcP9uaodaA2iv13r+WxHulAer+EpW52eE0w3mrxlcLKxMLelyJn/2k00OxDoc3x 0s8v3BGQbIJ3E6hQ8T5Xha4iGWZpRNaUN1Ve8Uq5QfIxqfK7gKxAmkfUiUHeNEgrNUxRzEhy hmOhdyBLSd0rLSfRHaZ97GVhTC/Iy4YKSkFfyBscOcey9zqoYV2iw2VSN9mSfSxloetRW+2x C2Wpi8jgblVldQMy6iw4VHAhXSru4TNSQk2oA7QWwpJ8z9EWWJsXKTwgXCz0BqKBN/xooWp1 JTcp/Wj0Q==
  • Ironport-hdrordr: A9a23:KS8ZvKpIhqwZ2uYjRfBAxaYaV5v5L9V00zEX/kB9WHVpmszxrb HXoB17726QtN91Yh4dcL+7Sc+9qE3nhNpICOUqTNSftUzdyRKVxG8L1/qj/9XPcxeOtNK1/5 0QPZSXMbXLfBtHZSyT2nj8Lz9Y+qjHzEnKv5a7854Od3AJV0g61XY3Nu/zKCQfL2MqafRZdK Zw/vA30wZIO05nFPhTKUN1GNQrzOe7864ODyR2fCLOKWG1/H6VAOmQKWnm4v5naUIz/Z4StU zMkwn87qLmm+ij0RnC22KWx4k+oqqq9jPNbPb8xvT9fQ+c9jqAVcBZQLuFsykyoOazrHgXsP SkmWZSA+1Dr0rLeGe7uB3s3BSl9g0PxTvN9X+06EGT0fAQYloBer98bEZiA2qpmXYIjZVF+o JNwm6DsJJTZCmw4hjV1pzzThlvoEK/vHolloco/jdieLpbUqZYqboV9Fg9KuZIIAvKrLo/GO 1ZF83E4u1KGGnqJ0zxjy1U2dSpaG44GAyLK3JyzPC94nxthXh8+VETwtcSqHcG6fsGOu5529 g=
  • List-id: Xen developer discussion <xen-devel.lists.xenproject.org>

On Tue, May 30, 2023 at 02:38:56PM +0200, Jan Beulich wrote:
> Hidden devices (e.g. an add-in PCI serial card used for Xen's serial
> console) are associated with DomXEN, not Dom0. This means that while
> looking for overlapping BARs such devices cannot be found on Dom0's list
> of devices; DomXEN's list also needs to be scanned.
> 
> Suppress vPCI init altogether for r/o devices (which constitute a subset
> of hidden ones).
> 
> Signed-off-by: Jan Beulich <jbeulich@xxxxxxxx>

Reviewed-by: Roger Pau Monné <roger.pau@xxxxxxxxxx>

Just one nit below.

> ---
> v3: Also consider pdev being DomXEN's in modify_bars(). Also consult
>     DomXEN in vpci_{read,write}(). Move vpci_write()'s check of the r/o
>     map out of mainline code. Re-base over the standalone addition of
>     the loop continuation in modify_bars(), and finally make the code
>     change there well-formed.
> v2: Extend existing comment. Relax assertion. Don't initialize vPCI for
>     r/o devices.
> 
> --- a/xen/drivers/vpci/header.c
> +++ b/xen/drivers/vpci/header.c
> @@ -218,6 +218,7 @@ static int modify_bars(const struct pci_
>      struct vpci_header *header = &pdev->vpci->header;
>      struct rangeset *mem = rangeset_new(NULL, NULL, 0);
>      struct pci_dev *tmp, *dev = NULL;
> +    const struct domain *d;
>      const struct vpci_msix *msix = pdev->vpci->msix;
>      unsigned int i;
>      int rc;
> @@ -285,58 +286,69 @@ static int modify_bars(const struct pci_
>  
>      /*
>       * Check for overlaps with other BARs. Note that only BARs that are
> -     * currently mapped (enabled) are checked for overlaps.
> +     * currently mapped (enabled) are checked for overlaps. Note also that
> +     * for hwdom we also need to include hidden, i.e. DomXEN's, devices.
>       */
> -    for_each_pdev ( pdev->domain, tmp )
> +    for ( d = pdev->domain != dom_xen ? pdev->domain : hardware_domain; ; )
>      {
> -        if ( !tmp->vpci )
> -            /*
> -             * For the hardware domain it's possible to have devices assigned
> -             * to it that are not handled by vPCI, either because those are
> -             * read-only devices, or because vPCI setup has failed.
> -             */
> -            continue;
> -
> -        if ( tmp == pdev )
> +        for_each_pdev ( d, tmp )
>          {
> -            /*
> -             * Need to store the device so it's not constified and defer_map
> -             * can modify it in case of error.
> -             */
> -            dev = tmp;
> -            if ( !rom_only )
> +            if ( !tmp->vpci )
>                  /*
> -                 * If memory decoding is toggled avoid checking against the
> -                 * same device, or else all regions will be removed from the
> -                 * memory map in the unmap case.
> +                 * For the hardware domain it's possible to have devices
> +                 * assigned to it that are not handled by vPCI, either 
> because
> +                 * those are read-only devices, or because vPCI setup has
> +                 * failed.
>                   */
>                  continue;
> -        }
>  
> -        for ( i = 0; i < ARRAY_SIZE(tmp->vpci->header.bars); i++ )
> -        {
> -            const struct vpci_bar *bar = &tmp->vpci->header.bars[i];
> -            unsigned long start = PFN_DOWN(bar->addr);
> -            unsigned long end = PFN_DOWN(bar->addr + bar->size - 1);
> -
> -            if ( !bar->enabled || !rangeset_overlaps_range(mem, start, end) 
> ||
> -                 /*
> -                  * If only the ROM enable bit is toggled check against other
> -                  * BARs in the same device for overlaps, but not against the
> -                  * same ROM BAR.
> -                  */
> -                 (rom_only && tmp == pdev && bar->type == VPCI_BAR_ROM) )
> -                continue;
> +            if ( tmp == pdev )
> +            {
> +                /*
> +                 * Need to store the device so it's not constified and 
> defer_map
> +                 * can modify it in case of error.
> +                 */
> +                dev = tmp;
> +                if ( !rom_only )
> +                    /*
> +                     * If memory decoding is toggled avoid checking against 
> the
> +                     * same device, or else all regions will be removed from 
> the
> +                     * memory map in the unmap case.
> +                     */
> +                    continue;
> +            }
>  
> -            rc = rangeset_remove_range(mem, start, end);
> -            if ( rc )
> +            for ( i = 0; i < ARRAY_SIZE(tmp->vpci->header.bars); i++ )
>              {
> -                printk(XENLOG_G_WARNING "Failed to remove [%lx, %lx]: %d\n",
> -                       start, end, rc);
> -                rangeset_destroy(mem);
> -                return rc;
> +                const struct vpci_bar *bar = &tmp->vpci->header.bars[i];
> +                unsigned long start = PFN_DOWN(bar->addr);
> +                unsigned long end = PFN_DOWN(bar->addr + bar->size - 1);
> +
> +                if ( !bar->enabled ||
> +                     !rangeset_overlaps_range(mem, start, end) ||
> +                     /*
> +                      * If only the ROM enable bit is toggled check against
> +                      * other BARs in the same device for overlaps, but not
> +                      * against the same ROM BAR.
> +                      */
> +                     (rom_only && tmp == pdev && bar->type == VPCI_BAR_ROM) )
> +                    continue;
> +
> +                rc = rangeset_remove_range(mem, start, end);
> +                if ( rc )
> +                {
> +                    printk(XENLOG_G_WARNING "Failed to remove [%lx, %lx]: 
> %d\n",
> +                           start, end, rc);
> +                    rangeset_destroy(mem);
> +                    return rc;
> +                }
>              }
>          }
> +
> +        if ( !is_hardware_domain(d) )
> +            break;
> +
> +        d = dom_xen;

Nit: don't you want to do this in the advancement to the next
iteration?

Thanks, Roger.



 


Rackspace

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