[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