PCI: keystone: Fix NULL pointer dereference in case of DT error in ks_pcie_setup_rc_app_regs()

If IORESOURCE_MEM is not provided in Device Tree due to
any error, resource_list_first_type() will return NULL and
pci_parse_request_of_pci_ranges() will just emit a warning.

This will cause a NULL pointer dereference. Fix this bug by adding NULL
return check.

Found by Linux Verification Center (linuxtesting.org) with SVACE.

Fixes: 0f71c60ffd ("PCI: dwc: Remove storing of PCI resources")
Link: https://lore.kernel.org/linux-pci/20240505061517.11527-1-amishin@t-argos.ru
Suggested-by: Bjorn Helgaas <helgaas@kernel.org>
Suggested-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
Signed-off-by: Aleksandr Mishin <amishin@t-argos.ru>
Signed-off-by: Krzysztof Wilczyński <kwilczynski@kernel.org>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Reviewed-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
This commit is contained in:
Aleksandr Mishin 2024-05-05 09:15:17 +03:00 committed by Bjorn Helgaas
parent 9ffa0e70b2
commit a231707a91

View File

@ -400,17 +400,22 @@ static const struct irq_domain_ops ks_pcie_intx_irq_domain_ops = {
.xlate = irq_domain_xlate_onetwocell,
};
static void ks_pcie_setup_rc_app_regs(struct keystone_pcie *ks_pcie)
static int ks_pcie_setup_rc_app_regs(struct keystone_pcie *ks_pcie)
{
u32 val;
u32 num_viewport = ks_pcie->num_viewport;
struct dw_pcie *pci = ks_pcie->pci;
struct dw_pcie_rp *pp = &pci->pp;
u64 start, end;
struct resource_entry *entry;
struct resource *mem;
u64 start, end;
int i;
mem = resource_list_first_type(&pp->bridge->windows, IORESOURCE_MEM)->res;
entry = resource_list_first_type(&pp->bridge->windows, IORESOURCE_MEM);
if (!entry)
return -ENODEV;
mem = entry->res;
start = mem->start;
end = mem->end;
@ -421,7 +426,7 @@ static void ks_pcie_setup_rc_app_regs(struct keystone_pcie *ks_pcie)
ks_pcie_clear_dbi_mode(ks_pcie);
if (ks_pcie->is_am6)
return;
return 0;
val = ilog2(OB_WIN_SIZE);
ks_pcie_app_writel(ks_pcie, OB_SIZE, val);
@ -438,6 +443,8 @@ static void ks_pcie_setup_rc_app_regs(struct keystone_pcie *ks_pcie)
val = ks_pcie_app_readl(ks_pcie, CMD_STATUS);
val |= OB_XLAT_EN_VAL;
ks_pcie_app_writel(ks_pcie, CMD_STATUS, val);
return 0;
}
static void __iomem *ks_pcie_other_map_bus(struct pci_bus *bus,
@ -798,7 +805,10 @@ static int __init ks_pcie_host_init(struct dw_pcie_rp *pp)
return ret;
ks_pcie_stop_link(pci);
ks_pcie_setup_rc_app_regs(ks_pcie);
ret = ks_pcie_setup_rc_app_regs(ks_pcie);
if (ret)
return ret;
writew(PCI_IO_RANGE_TYPE_32 | (PCI_IO_RANGE_TYPE_32 << 8),
pci->dbi_base + PCI_IO_BASE);