|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [PATCH v3] vpci: Add resizable bar support
On 13.12.2024 06:42, Jiqian Chen wrote:
> --- /dev/null
> +++ b/xen/drivers/vpci/rebar.c
> @@ -0,0 +1,130 @@
> +/* SPDX-License-Identifier: 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>
> +
> +static void cf_check rebar_ctrl_write(const struct pci_dev *pdev,
> + unsigned int reg,
> + uint32_t val,
> + void *data)
> +{
> + uint64_t size;
> + struct vpci_bar *bar = data;
> +
> + size = PCI_REBAR_CTRL_SIZE(val);
> + if ( bar->enabled )
> + {
> + if ( size == bar->size )
> + return;
> +
> + /*
> + * Refuse to resize a BAR while memory decoding is enabled, as
> + * otherwise the size of the mapped region in the p2m would become
> + * stale with the newly set BAR size, and the position of the BAR
> + * would be reset to undefined. Note the PCIe specification also
> + * forbids resizing a BAR with memory decoding enabled.
> + */
> + gprintk(XENLOG_ERR,
> + "%pp: refuse to resize BAR with memory decoding enabled\n",
> + &pdev->sbdf);
> + return;
> + }
> +
> + if ( !((size >> PCI_REBAR_SIZE_BIAS) &
> + MASK_EXTR(pci_conf_read32(pdev->sbdf,
> + reg - PCI_REBAR_CTRL + PCI_REBAR_CAP),
> + PCI_REBAR_CAP_SIZES)) )
> + gprintk(XENLOG_WARNING,
> + "%pp: new size %#lx is not supported by hardware\n",
> + &pdev->sbdf, size);
This only covers the 1Mb ... 128Tb range. What about the 256Tb ... 8Eb one?
> +static int cf_check init_rebar(struct pci_dev *pdev)
> +{
> + uint32_t ctrl;
> + unsigned int rebar_offset, nbars;
> +
> + rebar_offset = pci_find_ext_capability(pdev->sbdf, PCI_EXT_CAP_ID_REBAR);
> +
> + if ( !rebar_offset )
> + return 0;
> +
> + if ( !is_hardware_domain(pdev->domain) )
> + {
> + printk("ReBar is not supported for domUs\n");
> + return -EOPNOTSUPP;
> + }
> +
> + ctrl = pci_conf_read32(pdev->sbdf, rebar_offset + PCI_REBAR_CTRL);
> + nbars = MASK_EXTR(ctrl, PCI_REBAR_CTRL_NBAR_MASK);
> +
> + for ( unsigned int i = 0; i < nbars; i++, rebar_offset += PCI_REBAR_CTRL
> )
PCI_REBAR_CTRL is an offset; it can't be used to bump rebar_offset here.
That'll need a separate constant, even if both evaluate to 8.
Jan
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |