[bug report] PCI: rockchip: Fix window mapping and address translation for endpoint

Dan Carpenter dan.carpenter at linaro.org
Tue Jun 27 00:19:07 PDT 2023


Hello Rick Wertenbroek,

The patch dc73ed0f1b8b: "PCI: rockchip: Fix window mapping and
address translation for endpoint" from Apr 18, 2023, leads to the
following Smatch static checker warning:

	drivers/pci/controller/pcie-rockchip-ep.c:405 rockchip_pcie_ep_send_msi_irq()
	warn: was expecting a 64 bit value instead of '~4294967040'

drivers/pci/controller/pcie-rockchip-ep.c
    351 static int rockchip_pcie_ep_send_msi_irq(struct rockchip_pcie_ep *ep, u8 fn,
    352                                          u8 interrupt_num)
    353 {
    354         struct rockchip_pcie *rockchip = &ep->rockchip;
    355         u32 flags, mme, data, data_mask;
    356         u8 msi_count;
    357         u64 pci_addr;
                ^^^^^^^^^^^^^

    358         u32 r;
    359 
    360         /* Check MSI enable bit */
    361         flags = rockchip_pcie_read(&ep->rockchip,
    362                                    ROCKCHIP_PCIE_EP_FUNC_BASE(fn) +
    363                                    ROCKCHIP_PCIE_EP_MSI_CTRL_REG);
    364         if (!(flags & ROCKCHIP_PCIE_EP_MSI_CTRL_ME))
    365                 return -EINVAL;
    366 
    367         /* Get MSI numbers from MME */
    368         mme = ((flags & ROCKCHIP_PCIE_EP_MSI_CTRL_MME_MASK) >>
    369                         ROCKCHIP_PCIE_EP_MSI_CTRL_MME_OFFSET);
    370         msi_count = 1 << mme;
    371         if (!interrupt_num || interrupt_num > msi_count)
    372                 return -EINVAL;
    373 
    374         /* Set MSI private data */
    375         data_mask = msi_count - 1;
    376         data = rockchip_pcie_read(rockchip,
    377                                   ROCKCHIP_PCIE_EP_FUNC_BASE(fn) +
    378                                   ROCKCHIP_PCIE_EP_MSI_CTRL_REG +
    379                                   PCI_MSI_DATA_64);
    380         data = (data & ~data_mask) | ((interrupt_num - 1) & data_mask);
    381 
    382         /* Get MSI PCI address */
    383         pci_addr = rockchip_pcie_read(rockchip,
    384                                       ROCKCHIP_PCIE_EP_FUNC_BASE(fn) +
    385                                       ROCKCHIP_PCIE_EP_MSI_CTRL_REG +
    386                                       PCI_MSI_ADDRESS_HI);
    387         pci_addr <<= 32;

The high 32 bits are definitely set.

    388         pci_addr |= rockchip_pcie_read(rockchip,
    389                                        ROCKCHIP_PCIE_EP_FUNC_BASE(fn) +
    390                                        ROCKCHIP_PCIE_EP_MSI_CTRL_REG +
    391                                        PCI_MSI_ADDRESS_LO);
    392 
    393         /* Set the outbound region if needed. */
    394         if (unlikely(ep->irq_pci_addr != (pci_addr & PCIE_ADDR_MASK) ||
    395                      ep->irq_pci_fn != fn)) {
    396                 r = rockchip_ob_region(ep->irq_phys_addr);
    397                 rockchip_pcie_prog_ep_ob_atu(rockchip, fn, r,
    398                                              ep->irq_phys_addr,
    399                                              pci_addr & PCIE_ADDR_MASK,
    400                                              ~PCIE_ADDR_MASK + 1);
    401                 ep->irq_pci_addr = (pci_addr & PCIE_ADDR_MASK);
    402                 ep->irq_pci_fn = fn;
    403         }
    404 
--> 405         writew(data, ep->irq_cpu_addr + (pci_addr & ~PCIE_ADDR_MASK));

PCIE_ADDR_MASK is 0xffffff00 (which is unsigned int).  What Smatch is
saying here is that pci_addr is a u64 it looks like the intention was to
zero out the last byte, but instead we are zeroing the high 32 bits as
well as the last 8 bits.

    406         return 0;
    407 }

regards,
dan carpenter



More information about the Linux-rockchip mailing list