lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [day] [month] [year] [list]
Message-ID: <CABe3_aFQo0c+RUP8FsAGucU7Abovv0HzmDNz6w9FXiFPt4RPyA@mail.gmail.com>
Date: Wed, 21 Jan 2026 14:29:16 -0500
From: Charles Mirabile <cmirabil@...hat.com>
To: Randolph <randolph@...estech.com>
Cc: linux-kernel@...r.kernel.org, linux-pci@...r.kernel.org, 
	bhelgaas@...gle.com, robh@...nel.org, kwilczynski@...nel.org, 
	lpieralisi@...nel.org, mani@...nel.org, jingoohan1@...il.com, 
	samuel.holland@...ive.com, Frank.Li@....com, randolph.sklin@...il.com, 
	tim609@...estech.com
Subject: Re: [PATCH v2] PCI: dwc: Use multiple ATU regions for large bridge windows

Hi Randolph—

Thanks for sending this again!

On Fri, Jan 9, 2026 at 6:43 AM Randolph <randolph@...estech.com> wrote:
>
> From: Samuel Holland <samuel.holland@...ive.com>
>
> Some SoCs may allocate more address space for a bridge window than can
> be covered by a single ATU region. Allow using a larger bridge window
> by allocating multiple adjacent ATU regions.
>
> Signed-off-by: Samuel Holland <samuel.holland@...ive.com>
> Reviewed-by: Frank Li <Frank.Li@....com>
> Acked-by: Charles Mirabile <cmirabil@...hat.com>
> Signed-off-by: Charles Mirabile <cmirabil@...hat.com>
> Co-developed-by: Randolph Lin <randolph@...estech.com>
> Signed-off-by: Randolph Lin <randolph@...estech.com>
> ---
> Since our changes depend on the original patch and no updated revision
> has been posted by the original author, we reached out to Samuel Holland
> directly and received his approval.I have consolidated the required
> changes and am resending them as v2.
> ---
>  .../pci/controller/dwc/pcie-designware-host.c | 72 ++++++++++++++-----
>  1 file changed, 55 insertions(+), 17 deletions(-)
>
> diff --git a/drivers/pci/controller/dwc/pcie-designware-host.c b/drivers/pci/controller/dwc/pcie-designware-host.c
> index 372207c33a85..771e71b40f76 100644
> --- a/drivers/pci/controller/dwc/pcie-designware-host.c
> +++ b/drivers/pci/controller/dwc/pcie-designware-host.c
> @@ -903,29 +903,49 @@ static int dw_pcie_iatu_setup(struct dw_pcie_rp *pp)
>
>         i = 0;
>         resource_list_for_each_entry(entry, &pp->bridge->windows) {
> +               resource_size_t res_size;
> +
>                 if (resource_type(entry->res) != IORESOURCE_MEM)
>                         continue;
>
> -               if (pci->num_ob_windows <= ++i)
> +               if (pci->num_ob_windows <= i + 1)
>                         break;
>
> -               atu.index = i;
>                 atu.type = PCIE_ATU_TYPE_MEM;
>                 atu.parent_bus_addr = entry->res->start - pci->parent_bus_offset;
>                 atu.pci_addr = entry->res->start - entry->offset;
>
>                 /* Adjust iATU size if MSG TLP region was allocated before */
>                 if (pp->msg_res && pp->msg_res->parent == entry->res)
> -                       atu.size = resource_size(entry->res) -
> +                       res_size = resource_size(entry->res) -
>                                         resource_size(pp->msg_res);
>                 else
> -                       atu.size = resource_size(entry->res);
> +                       res_size = resource_size(entry->res);
> +
> +               while (res_size > 0) {
> +                       /*
> +                        * Make sure to fail probe if we run out of windows
> +                        * in the middle and we would end up only partially
> +                        * mapping a single resource
> +                        */
> +                       if (pci->num_ob_windows <= ++i) {
> +                               dev_err(pci->dev, "Exhausted outbound windows mapping %pr\n",
> +                                       entry->res);
> +                               return -ENOMEM;
> +                       }
> +                       atu.index = i;
> +                       atu.size = MIN(pci->region_limit + 1, res_size);
>
> -               ret = dw_pcie_prog_outbound_atu(pci, &atu);
> -               if (ret) {
> -                       dev_err(pci->dev, "Failed to set MEM range %pr\n",
> -                               entry->res);
> -                       return ret;
> +                       ret = dw_pcie_prog_outbound_atu(pci, &atu);
> +                       if (ret) {
> +                               dev_err(pci->dev, "Failed to set MEM range %pr\n",
> +                                       entry->res);
> +                               return ret;
> +                       }
> +
> +                       atu.parent_bus_addr += atu.size;
> +                       atu.pci_addr += atu.size;
> +                       res_size -= atu.size;
>                 }
>         }
>
> @@ -956,20 +976,38 @@ static int dw_pcie_iatu_setup(struct dw_pcie_rp *pp)
>
>         i = 0;
>         resource_list_for_each_entry(entry, &pp->bridge->dma_ranges) {
> +               resource_size_t res_start, res_size, window_size;
> +
>                 if (resource_type(entry->res) != IORESOURCE_MEM)
>                         continue;
>
>                 if (pci->num_ib_windows <= i)
>                         break;
>
> -               ret = dw_pcie_prog_inbound_atu(pci, i++, PCIE_ATU_TYPE_MEM,
> -                                              entry->res->start,
> -                                              entry->res->start - entry->offset,
> -                                              resource_size(entry->res));
> -               if (ret) {
> -                       dev_err(pci->dev, "Failed to set DMA range %pr\n",
> -                               entry->res);
> -                       return ret;
> +               res_size = resource_size(entry->res);
> +               res_start = entry->res->start;
> +               while (res_size >= 0) {

I think this should be `> 0` instead of `>= 0` like the loop from the
outbound window. Looking back it is actually my own mistake from the
reply I sent to v1 that you faithfully replicated. One of those times
you wish for git blame-someone-else :^)

Hopefully this can just get folded in as the patch is taken to avoid a v3.

> +                       /*
> +                        * Make sure to fail probe if we run out of windows
> +                        * in the middle and we would end up only partially
> +                        * mapping a single resource
> +                        */
> +                       if (pci->num_ib_windows <= i) {
> +                               dev_err(pci->dev, "Exhausted inbound windows mapping %pr\n",
> +                                       entry->res);
> +                               return -ENOMEM;
> +                       }
> +                       window_size = MIN(pci->region_limit + 1, res_size);
> +                       ret = dw_pcie_prog_inbound_atu(pci, i++, PCIE_ATU_TYPE_MEM, res_start,
> +                                                      res_start - entry->offset, window_size);
> +                       if (ret) {
> +                               dev_err(pci->dev, "Failed to set DMA range %pr\n",
> +                                       entry->res);
> +                               return ret;
> +                       }
> +
> +                       res_start += window_size;
> +                       res_size -= window_size;
>                 }
>         }
>
> --
> 2.34.1
>

Best—Charlie


Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ