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

Re: [PATCH] vpci: Add resizable bar support


  • To: Roger Pau Monné <roger.pau@xxxxxxxxxx>
  • From: "Chen, Jiqian" <Jiqian.Chen@xxxxxxx>
  • Date: Tue, 19 Nov 2024 07:31:42 +0000
  • Accept-language: en-US
  • Arc-authentication-results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=amd.com; dmarc=pass action=none header.from=amd.com; dkim=pass header.d=amd.com; arc=none
  • Arc-message-signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector10001; 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=pEITLgkfwnkF28SbCxEhpAYu6aXOOcz5jQESveJqI+s=; b=eFwGSpUJYgv4AcVOuMFJz5sdb9te4M5zPs8JhyG9k2EyTPpqXx1YziJsnmP9ehBIqPUDsxunQI9YVbSjwshuXZ3/9Fhul+ioZ7dKiOlrGUTkzqY27n12bFOPMT+O08sIxM//SOaUGJc4Jrcl3bYHCveema22z6za0WCG930kvMUDO1BazrFQYyOuISKQ+6JX5vqxS4jOxu1zRc1IdO9tORZSDuzJqbb4+HKjyMzhxNpoB18Vmwx4EcuPMymUd9g5ioSc4mP1NoHmfAo+CR1KejrjnXs7M2AzHClJZhU2J7xdq1wncQeni/IT/FfWWeF9zqzLp6rTj/djT41VYwMZVQ==
  • Arc-seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=FA6MuFHE2YU7ziAd7OjoY91K0yNQ7s7BLrn65IEhtUecOyD7Jngsjio2JtgG22tjjid+Aa06bgrW9VFuaX4f0lHQW0O1QWwXl49sWbLVoYYrXTGRbg6yWJx6nwad+cEB/69TwY1a6fQjohUvvFjbT4k7+gYPM9PUCwI5XmlfLYfkxOH7Ri0XqjtVZ5UxGNtM00Y+gK0nhmValbbQjCBBL3pxEy0rZchSO3OHWgp+s2XrvKOGkz5+6/oOd41BiUMdrAIvVWJI6kli0if2iUTp4V7iT/MlC3SUmDMJHCw3Y8d8JVEW0Zuul65w5Pj79XY0S8ruVwKwru799gAUoQ8bCw==
  • Authentication-results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=amd.com;
  • Cc: "xen-devel@xxxxxxxxxxxxxxxxxxxx" <xen-devel@xxxxxxxxxxxxxxxxxxxx>, Andrew Cooper <andrew.cooper3@xxxxxxxxxx>, Jan Beulich <jbeulich@xxxxxxxx>, Julien Grall <julien@xxxxxxx>, Stefano Stabellini <sstabellini@xxxxxxxxxx>, "Chen, Jiqian" <Jiqian.Chen@xxxxxxx>
  • Delivery-date: Tue, 19 Nov 2024 07:32:06 +0000
  • List-id: Xen developer discussion <xen-devel.lists.xenproject.org>
  • Thread-index: AQHbNaIlMxf8mJcywkeNRFmHEai1qbK82tSAgAHkIwA=
  • Thread-topic: [PATCH] vpci: Add resizable bar support

On 2024/11/18 18:17, Roger Pau Monné wrote:
> On Wed, Nov 13, 2024 at 04:00:27PM +0800, Jiqian Chen wrote:
>> Some devices, like discrete GPU of amd, support resizable bar capability,
>> but vpci of Xen doesn't support this feature, so they fail to resize bars
>> and then cause probing failure.
>>
>> According to PCIe spec, each bar that support resizing has two registers,
>> PCI_REBAR_CAP and PCI_REBAR_CTRL, so add these two registers and their
>> corresponding handler into vpci.
>>
>> PCI_REBAR_CAP is RO, only provide reading.
>>
>> PCI_REBAR_CTRL only has bar size is RW, so add write function to support
>> setting the new size.
>>
>> Signed-off-by: Jiqian Chen <Jiqian.Chen@xxxxxxx>
>> ---
>>  xen/drivers/vpci/Makefile  |  2 +-
>>  xen/drivers/vpci/rebar.c   | 89 ++++++++++++++++++++++++++++++++++++++
>>  xen/include/xen/pci_regs.h | 11 +++++
>>  3 files changed, 101 insertions(+), 1 deletion(-)
>>  create mode 100644 xen/drivers/vpci/rebar.c
>>
>> diff --git a/xen/drivers/vpci/Makefile b/xen/drivers/vpci/Makefile
>> index 1a1413b93e76..a7c8a30a8956 100644
>> --- a/xen/drivers/vpci/Makefile
>> +++ b/xen/drivers/vpci/Makefile
>> @@ -1,2 +1,2 @@
>> -obj-y += vpci.o header.o
>> +obj-y += vpci.o header.o rebar.o
>>  obj-$(CONFIG_HAS_PCI_MSI) += msi.o msix.o
>> diff --git a/xen/drivers/vpci/rebar.c b/xen/drivers/vpci/rebar.c
>> new file mode 100644
>> index 000000000000..84dbd84b0745
>> --- /dev/null
>> +++ b/xen/drivers/vpci/rebar.c
>> @@ -0,0 +1,89 @@
>> +/* SPDX-License-Identifier: GPL-2.0 */
> 
> The GPL-2.0 identifier is deprecated, either use GPL-2.0-or-later or
> GPL-2.0-only.
> 
>> +/*
>> + * Copyright (C) 2024 Advanced Micro Devices, Inc. All Rights Reserved.
>> + *
>> + * Author: Jiqian Chen <Jiqian.Chen@xxxxxxx>
>> + */
>> +
>> +#include <xen/hypercall.h>
>> +#include <xen/vpci.h>
>> +
>> +/*
>> + * The number value of the BAR Size in PCI_REBAR_CTRL register reprent:
>> + * 0    1 MB (2^20 bytes)
>> + * 1    2 MB (2^21 bytes)
>> + * 2    4 MB (2^22 bytes)
>> + *  ...
>> + * 43   8 EB (2^63 bytes)
>> + */
>> +#define PCI_REBAR_CTRL_BAR_UNIT (1ULL << 20)
>> +
>> +static void cf_check rebar_ctrl_write(const struct pci_dev *pdev,
>> +                                      unsigned int reg,
>> +                                      uint32_t val,
>> +                                      void *data)
>> +{
>> +    uint32_t ctrl, index;
> 
> index should better be unsigned int, as it's the BAR index [0, 5], and
> so fits perfectly in an unsigned int.
> 
>> +    struct vpci_bar *bars = pdev->vpci->header.bars;
> 
> You could pass bars as the data parameter.
> 
> Additionally you need to check that memory decoding is not enabled for
> the device, otherwise attempting to change the BAR size will lead to
> the active p2m mappings getting out of sync w.r.t. the new BAR size.
> 
>> +
>> +    ctrl = pci_conf_read32(pdev->sbdf, reg);
>> +    if ( ctrl == val )
>> +        return;
> 
> I would still carry out the write in this case, as that's what the
> owner of the device requested.
> 
>> +
>> +    ctrl &= ~PCI_REBAR_CTRL_BAR_SIZE;
>> +    if ( ctrl != ( val & ~PCI_REBAR_CTRL_BAR_SIZE ) )
>                      ^ extra space here and         ^ here
>> +        return;
> 
> The feature only being exposed to dom0 ATM, I would suggest we allow
> it to write any bits it wants in the control register, as that would
> be what the OS would do when not running as a guest.
But only PCI_REBAR_CTRL_BAR_SIZE bits of REBAR_CTRL register are RW, others are 
RO.
Is removing the check here fine?

> 
>> +
>> +    index = ctrl & PCI_REBAR_CTRL_BAR_IDX;
> 
> Some sanity checking of the BAR index might be good.  At least a check
> that the BAR is of type VPCI_BAR_MEM64_LO or VPCI_BAR_MEM32.
But the information of the BAR that support resizing is from hardware(when 
init_rebar), that shouldn't have any problems and doesn't need to check the 
BAR's info.

> 
>> +    bars[index].size = (1 << ((val & PCI_REBAR_CTRL_BAR_SIZE) >>
>> +                              PCI_REBAR_CTRL_BAR_SHIFT)) *
>> +                       PCI_REBAR_CTRL_BAR_UNIT;
> 
> This would better be a macro in pci_regs.h I think, and you need to
> use 1UL, plus using MASK_EXTR() simplifies it:
> 
> PCI_REBAR_CTRL_SIZE(v) (1UL << (MASK_EXTR(v, PCI_REBAR_CTRL_BAR_SIZE) + 20))
OK, another question: Should I need to check the size is allowed by 
hardware(the PCI_REBAR_CAP_SIZES bits in PCI_REBAR_CAP)?

> 
>> +
>> +    pci_conf_write32(pdev->sbdf, reg, val);
>> +}
>> +
>> +static int cf_check init_rebar(struct pci_dev *pdev)
>> +{
>> +    unsigned int rebar_offset;
>> +    uint32_t ctrl, nbars;
> 
> nbars can be unsigned int.
> 
>> +    int rc = 0;
>> +
>> +    rebar_offset = pci_find_ext_capability(pdev->sbdf, 
>> PCI_EXT_CAP_ID_REBAR);
>> +
>> +    if ( !rebar_offset )
>> +        return rc;
> 
> Just return 0, it's clearer than having to figure out what rc is set
> to.
> 
>> +
>> +    ctrl = pci_conf_read32(pdev->sbdf, rebar_offset + PCI_REBAR_CTRL);
>> +    nbars = (ctrl & PCI_REBAR_CTRL_NBAR_MASK) >> PCI_REBAR_CTRL_NBAR_SHIFT;
> 
> MASK_EXTR(ctrl, PCI_REBAR_CTRL_NBAR_MASK).
> 
>> +
>> +    for ( int i = 0; i < nbars; i++, rebar_offset += 8 ) {
> 
> unsigned int, and defined outside of the loop.  Also coding style:
> braces need to be on a newline.
> 
> You could even reduce the scope of rc by defining it inside the
> loop.
> 
>> +        rc = vpci_add_register(pdev->vpci, vpci_hw_read32, NULL,
>> +                               rebar_offset + PCI_REBAR_CAP, 4, NULL);
> 
> I'm not sure we want to limit dom0 writes to the capabilities
> registers, as said above dom0 gets unfiltered access to almost all
> registers, so it can do what it would otherwise do when running on
> native hardware.
You mean, this register(PCI_REBAR_CAP) is not needed to be added?

> 
>> +        if ( rc ) {
>> +            printk("%s: %pp: add register for PCI_REBAR_CAP failed 
>> (rc=%d)\n",
>> +                   __func__, &pdev->sbdf, rc);
>> +            break;
>> +        }
>> +
>> +        rc = vpci_add_register(pdev->vpci, vpci_hw_read32, rebar_ctrl_write,
>> +                               rebar_offset + PCI_REBAR_CTRL, 4, NULL);
>> +        if ( rc ) {
>> +            printk("%s: %pp: add register for PCI_REBAR_CTRL failed 
>> (rc=%d)\n",
>> +                   __func__, &pdev->sbdf, rc);
> 
> IMO I think you can forego printing __func__, and just use:
> 
> "%pp: add register for PCI_REBAR_CTRL failed: %d\n"
> 
>> +            break;
>> +        }
>> +    }
>> +
>> +    return rc;
>> +}
>> +REGISTER_VPCI_INIT(init_rebar, VPCI_PRIORITY_LOW);
>> +
>> +/*
>> + * Local variables:
>> + * mode: C
>> + * c-file-style: "BSD"
>> + * c-basic-offset: 4
>> + * tab-width: 4
>> + * indent-tabs-mode: nil
>> + * End:
>> + */
>> diff --git a/xen/include/xen/pci_regs.h b/xen/include/xen/pci_regs.h
>> index 250ba106dbd3..5d2aa130916e 100644
>> --- a/xen/include/xen/pci_regs.h
>> +++ b/xen/include/xen/pci_regs.h
>> @@ -459,6 +459,7 @@
>>  #define PCI_EXT_CAP_ID_ARI  14
>>  #define PCI_EXT_CAP_ID_ATS  15
>>  #define PCI_EXT_CAP_ID_SRIOV        16
>> +#define PCI_EXT_CAP_ID_REBAR        21      /* Resizable BAR */
>>  
>>  /* Advanced Error Reporting */
>>  #define PCI_ERR_UNCOR_STATUS        4       /* Uncorrectable Error Status */
>> @@ -541,6 +542,16 @@
>>  #define  PCI_VNDR_HEADER_REV(x)     (((x) >> 16) & 0xf)
>>  #define  PCI_VNDR_HEADER_LEN(x)     (((x) >> 20) & 0xfff)
>>  
>> +/* Resizable BARs */
>> +#define PCI_REBAR_CAP               4       /* capability register */
>> +#define  PCI_REBAR_CAP_SIZES                0x00FFFFF0  /* supported BAR 
>> sizes */
>> +#define PCI_REBAR_CTRL              8       /* control register */
>> +#define  PCI_REBAR_CTRL_BAR_IDX             0x00000007  /* BAR index */
>> +#define  PCI_REBAR_CTRL_NBAR_MASK   0x000000E0  /* # of resizable BARs */
>> +#define  PCI_REBAR_CTRL_NBAR_SHIFT  5           /* shift for # of BARs */
>> +#define  PCI_REBAR_CTRL_BAR_SIZE    0x00001F00  /* BAR size */
>> +#define  PCI_REBAR_CTRL_BAR_SHIFT   8           /* shift for BAR size */
> 
> If you use MASK_EXTR() there's no need for the _SHIFT macros I think?
Yes, and will change patch according to your all comments in next version.
Thanks!

> 
> Thanks, Roger.

-- 
Best regards,
Jiqian Chen.

 


Rackspace

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