drivers/dma/ti/k3-udma.c:2635 pktdma_alloc_chan_resources() warn: variable dereferenced before check 'uc->rchan' (see line 2556)

From: Dan Carpenter
Date: Fri Mar 26 2021 - 04:31:56 EST


tree: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git master
head: db24726bfefa68c606947a86132591568a06bfb4
commit: d2abc982333c02f9e1ff1c6b3782174f5b7662d7 dmaengine: ti: k3-udma: Initial support for K3 PKTDMA
config: arm64-randconfig-m031-20210325 (attached as .config)
compiler: aarch64-linux-gcc (GCC) 9.3.0

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@xxxxxxxxx>
Reported-by: Dan Carpenter <dan.carpenter@xxxxxxxxxx>

New smatch warnings:
drivers/dma/ti/k3-udma.c:2635 pktdma_alloc_chan_resources() warn: variable dereferenced before check 'uc->rchan' (see line 2556)
drivers/dma/ti/k3-udma.c:4769 pktdma_setup_resources() error: 'rm_res' dereferencing possible ERR_PTR()

Old smatch warnings:
drivers/dma/ti/k3-udma.c:4445 udma_setup_resources() error: 'rm_res' dereferencing possible ERR_PTR()
drivers/dma/ti/k3-udma.c:4458 udma_setup_resources() error: 'rm_res' dereferencing possible ERR_PTR()
drivers/dma/ti/k3-udma.c:4602 bcdma_setup_resources() error: 'rm_res' dereferencing possible ERR_PTR()
drivers/dma/ti/k3-udma.c:4617 bcdma_setup_resources() error: 'rm_res' dereferencing possible ERR_PTR()
drivers/dma/ti/k3-udma.c:4632 bcdma_setup_resources() error: 'rm_res' dereferencing possible ERR_PTR()
drivers/dma/ti/k3-udma.c:4782 pktdma_setup_resources() error: 'rm_res' dereferencing possible ERR_PTR()

vim +2635 drivers/dma/ti/k3-udma.c

d2abc982333c02 Peter Ujfalusi 2020-12-08 2508 static int pktdma_alloc_chan_resources(struct dma_chan *chan)
d2abc982333c02 Peter Ujfalusi 2020-12-08 2509 {
d2abc982333c02 Peter Ujfalusi 2020-12-08 2510 struct udma_chan *uc = to_udma_chan(chan);
d2abc982333c02 Peter Ujfalusi 2020-12-08 2511 struct udma_dev *ud = to_udma_dev(chan->device);
d2abc982333c02 Peter Ujfalusi 2020-12-08 2512 const struct udma_oes_offsets *oes = &ud->soc_data->oes;
d2abc982333c02 Peter Ujfalusi 2020-12-08 2513 u32 irq_ring_idx;
d2abc982333c02 Peter Ujfalusi 2020-12-08 2514 int ret;
d2abc982333c02 Peter Ujfalusi 2020-12-08 2515
d2abc982333c02 Peter Ujfalusi 2020-12-08 2516 /*
d2abc982333c02 Peter Ujfalusi 2020-12-08 2517 * Make sure that the completion is in a known state:
d2abc982333c02 Peter Ujfalusi 2020-12-08 2518 * No teardown, the channel is idle
d2abc982333c02 Peter Ujfalusi 2020-12-08 2519 */
d2abc982333c02 Peter Ujfalusi 2020-12-08 2520 reinit_completion(&uc->teardown_completed);
d2abc982333c02 Peter Ujfalusi 2020-12-08 2521 complete_all(&uc->teardown_completed);
d2abc982333c02 Peter Ujfalusi 2020-12-08 2522 uc->state = UDMA_CHAN_IS_IDLE;
d2abc982333c02 Peter Ujfalusi 2020-12-08 2523
d2abc982333c02 Peter Ujfalusi 2020-12-08 2524 switch (uc->config.dir) {
d2abc982333c02 Peter Ujfalusi 2020-12-08 2525 case DMA_MEM_TO_DEV:
d2abc982333c02 Peter Ujfalusi 2020-12-08 2526 /* Slave transfer synchronized - mem to dev (TX) trasnfer */
d2abc982333c02 Peter Ujfalusi 2020-12-08 2527 dev_dbg(uc->ud->dev, "%s: chan%d as MEM-to-DEV\n", __func__,
d2abc982333c02 Peter Ujfalusi 2020-12-08 2528 uc->id);
d2abc982333c02 Peter Ujfalusi 2020-12-08 2529
d2abc982333c02 Peter Ujfalusi 2020-12-08 2530 ret = udma_alloc_tx_resources(uc);
d2abc982333c02 Peter Ujfalusi 2020-12-08 2531 if (ret) {
d2abc982333c02 Peter Ujfalusi 2020-12-08 2532 uc->config.remote_thread_id = -1;
d2abc982333c02 Peter Ujfalusi 2020-12-08 2533 return ret;
d2abc982333c02 Peter Ujfalusi 2020-12-08 2534 }
d2abc982333c02 Peter Ujfalusi 2020-12-08 2535
d2abc982333c02 Peter Ujfalusi 2020-12-08 2536 uc->config.src_thread = ud->psil_base + uc->tchan->id;
d2abc982333c02 Peter Ujfalusi 2020-12-08 2537 uc->config.dst_thread = uc->config.remote_thread_id;
d2abc982333c02 Peter Ujfalusi 2020-12-08 2538 uc->config.dst_thread |= K3_PSIL_DST_THREAD_ID_OFFSET;
d2abc982333c02 Peter Ujfalusi 2020-12-08 2539
d2abc982333c02 Peter Ujfalusi 2020-12-08 2540 irq_ring_idx = uc->tchan->tflow_id + oes->pktdma_tchan_flow;
d2abc982333c02 Peter Ujfalusi 2020-12-08 2541
d2abc982333c02 Peter Ujfalusi 2020-12-08 2542 ret = pktdma_tisci_tx_channel_config(uc);
d2abc982333c02 Peter Ujfalusi 2020-12-08 2543 break;
d2abc982333c02 Peter Ujfalusi 2020-12-08 2544 case DMA_DEV_TO_MEM:
d2abc982333c02 Peter Ujfalusi 2020-12-08 2545 /* Slave transfer synchronized - dev to mem (RX) trasnfer */
d2abc982333c02 Peter Ujfalusi 2020-12-08 2546 dev_dbg(uc->ud->dev, "%s: chan%d as DEV-to-MEM\n", __func__,
d2abc982333c02 Peter Ujfalusi 2020-12-08 2547 uc->id);
d2abc982333c02 Peter Ujfalusi 2020-12-08 2548
d2abc982333c02 Peter Ujfalusi 2020-12-08 2549 ret = udma_alloc_rx_resources(uc);
d2abc982333c02 Peter Ujfalusi 2020-12-08 2550 if (ret) {
d2abc982333c02 Peter Ujfalusi 2020-12-08 2551 uc->config.remote_thread_id = -1;
d2abc982333c02 Peter Ujfalusi 2020-12-08 2552 return ret;
d2abc982333c02 Peter Ujfalusi 2020-12-08 2553 }
d2abc982333c02 Peter Ujfalusi 2020-12-08 2554
d2abc982333c02 Peter Ujfalusi 2020-12-08 2555 uc->config.src_thread = uc->config.remote_thread_id;
d2abc982333c02 Peter Ujfalusi 2020-12-08 @2556 uc->config.dst_thread = (ud->psil_base + uc->rchan->id) |
^^^^^^^^^^^^^
This code dereferences "uc->rchan" without checking for NULL.

d2abc982333c02 Peter Ujfalusi 2020-12-08 2557 K3_PSIL_DST_THREAD_ID_OFFSET;
d2abc982333c02 Peter Ujfalusi 2020-12-08 2558
d2abc982333c02 Peter Ujfalusi 2020-12-08 2559 irq_ring_idx = uc->rflow->id + oes->pktdma_rchan_flow;
d2abc982333c02 Peter Ujfalusi 2020-12-08 2560
d2abc982333c02 Peter Ujfalusi 2020-12-08 2561 ret = pktdma_tisci_rx_channel_config(uc);
d2abc982333c02 Peter Ujfalusi 2020-12-08 2562 break;
d2abc982333c02 Peter Ujfalusi 2020-12-08 2563 default:
d2abc982333c02 Peter Ujfalusi 2020-12-08 2564 /* Can not happen */
d2abc982333c02 Peter Ujfalusi 2020-12-08 2565 dev_err(uc->ud->dev, "%s: chan%d invalid direction (%u)\n",
d2abc982333c02 Peter Ujfalusi 2020-12-08 2566 __func__, uc->id, uc->config.dir);
d2abc982333c02 Peter Ujfalusi 2020-12-08 2567 return -EINVAL;
d2abc982333c02 Peter Ujfalusi 2020-12-08 2568 }
d2abc982333c02 Peter Ujfalusi 2020-12-08 2569
d2abc982333c02 Peter Ujfalusi 2020-12-08 2570 /* check if the channel configuration was successful */
d2abc982333c02 Peter Ujfalusi 2020-12-08 2571 if (ret)
d2abc982333c02 Peter Ujfalusi 2020-12-08 2572 goto err_res_free;
d2abc982333c02 Peter Ujfalusi 2020-12-08 2573
d2abc982333c02 Peter Ujfalusi 2020-12-08 2574 if (udma_is_chan_running(uc)) {
d2abc982333c02 Peter Ujfalusi 2020-12-08 2575 dev_warn(ud->dev, "chan%d: is running!\n", uc->id);
d2abc982333c02 Peter Ujfalusi 2020-12-08 2576 udma_reset_chan(uc, false);
d2abc982333c02 Peter Ujfalusi 2020-12-08 2577 if (udma_is_chan_running(uc)) {
d2abc982333c02 Peter Ujfalusi 2020-12-08 2578 dev_err(ud->dev, "chan%d: won't stop!\n", uc->id);
d2abc982333c02 Peter Ujfalusi 2020-12-08 2579 ret = -EBUSY;
d2abc982333c02 Peter Ujfalusi 2020-12-08 2580 goto err_res_free;
d2abc982333c02 Peter Ujfalusi 2020-12-08 2581 }
d2abc982333c02 Peter Ujfalusi 2020-12-08 2582 }
d2abc982333c02 Peter Ujfalusi 2020-12-08 2583
d2abc982333c02 Peter Ujfalusi 2020-12-08 2584 uc->dma_dev = dmaengine_get_dma_device(chan);
d2abc982333c02 Peter Ujfalusi 2020-12-08 2585 uc->hdesc_pool = dma_pool_create(uc->name, uc->dma_dev,
d2abc982333c02 Peter Ujfalusi 2020-12-08 2586 uc->config.hdesc_size, ud->desc_align,
d2abc982333c02 Peter Ujfalusi 2020-12-08 2587 0);
d2abc982333c02 Peter Ujfalusi 2020-12-08 2588 if (!uc->hdesc_pool) {
d2abc982333c02 Peter Ujfalusi 2020-12-08 2589 dev_err(ud->ddev.dev,
d2abc982333c02 Peter Ujfalusi 2020-12-08 2590 "Descriptor pool allocation failed\n");
d2abc982333c02 Peter Ujfalusi 2020-12-08 2591 uc->use_dma_pool = false;
d2abc982333c02 Peter Ujfalusi 2020-12-08 2592 ret = -ENOMEM;
d2abc982333c02 Peter Ujfalusi 2020-12-08 2593 goto err_res_free;
d2abc982333c02 Peter Ujfalusi 2020-12-08 2594 }
d2abc982333c02 Peter Ujfalusi 2020-12-08 2595
d2abc982333c02 Peter Ujfalusi 2020-12-08 2596 uc->use_dma_pool = true;
d2abc982333c02 Peter Ujfalusi 2020-12-08 2597
d2abc982333c02 Peter Ujfalusi 2020-12-08 2598 /* PSI-L pairing */
d2abc982333c02 Peter Ujfalusi 2020-12-08 2599 ret = navss_psil_pair(ud, uc->config.src_thread, uc->config.dst_thread);
d2abc982333c02 Peter Ujfalusi 2020-12-08 2600 if (ret) {
d2abc982333c02 Peter Ujfalusi 2020-12-08 2601 dev_err(ud->dev, "PSI-L pairing failed: 0x%04x -> 0x%04x\n",
d2abc982333c02 Peter Ujfalusi 2020-12-08 2602 uc->config.src_thread, uc->config.dst_thread);
d2abc982333c02 Peter Ujfalusi 2020-12-08 2603 goto err_res_free;
d2abc982333c02 Peter Ujfalusi 2020-12-08 2604 }
d2abc982333c02 Peter Ujfalusi 2020-12-08 2605
d2abc982333c02 Peter Ujfalusi 2020-12-08 2606 uc->psil_paired = true;
d2abc982333c02 Peter Ujfalusi 2020-12-08 2607
d2abc982333c02 Peter Ujfalusi 2020-12-08 2608 uc->irq_num_ring = ti_sci_inta_msi_get_virq(ud->dev, irq_ring_idx);
d2abc982333c02 Peter Ujfalusi 2020-12-08 2609 if (uc->irq_num_ring <= 0) {
d2abc982333c02 Peter Ujfalusi 2020-12-08 2610 dev_err(ud->dev, "Failed to get ring irq (index: %u)\n",
d2abc982333c02 Peter Ujfalusi 2020-12-08 2611 irq_ring_idx);
d2abc982333c02 Peter Ujfalusi 2020-12-08 2612 ret = -EINVAL;
d2abc982333c02 Peter Ujfalusi 2020-12-08 2613 goto err_psi_free;
d2abc982333c02 Peter Ujfalusi 2020-12-08 2614 }
d2abc982333c02 Peter Ujfalusi 2020-12-08 2615
d2abc982333c02 Peter Ujfalusi 2020-12-08 2616 ret = request_irq(uc->irq_num_ring, udma_ring_irq_handler,
d2abc982333c02 Peter Ujfalusi 2020-12-08 2617 IRQF_TRIGGER_HIGH, uc->name, uc);
d2abc982333c02 Peter Ujfalusi 2020-12-08 2618 if (ret) {
d2abc982333c02 Peter Ujfalusi 2020-12-08 2619 dev_err(ud->dev, "chan%d: ring irq request failed\n", uc->id);
d2abc982333c02 Peter Ujfalusi 2020-12-08 2620 goto err_irq_free;
d2abc982333c02 Peter Ujfalusi 2020-12-08 2621 }
d2abc982333c02 Peter Ujfalusi 2020-12-08 2622
d2abc982333c02 Peter Ujfalusi 2020-12-08 2623 uc->irq_num_udma = 0;
d2abc982333c02 Peter Ujfalusi 2020-12-08 2624
d2abc982333c02 Peter Ujfalusi 2020-12-08 2625 udma_reset_rings(uc);
d2abc982333c02 Peter Ujfalusi 2020-12-08 2626
d2abc982333c02 Peter Ujfalusi 2020-12-08 2627 INIT_DELAYED_WORK_ONSTACK(&uc->tx_drain.work,
d2abc982333c02 Peter Ujfalusi 2020-12-08 2628 udma_check_tx_completion);
d2abc982333c02 Peter Ujfalusi 2020-12-08 2629
d2abc982333c02 Peter Ujfalusi 2020-12-08 2630 if (uc->tchan)
d2abc982333c02 Peter Ujfalusi 2020-12-08 2631 dev_dbg(ud->dev,
d2abc982333c02 Peter Ujfalusi 2020-12-08 2632 "chan%d: tchan%d, tflow%d, Remote thread: 0x%04x\n",
d2abc982333c02 Peter Ujfalusi 2020-12-08 2633 uc->id, uc->tchan->id, uc->tchan->tflow_id,
d2abc982333c02 Peter Ujfalusi 2020-12-08 2634 uc->config.remote_thread_id);
d2abc982333c02 Peter Ujfalusi 2020-12-08 @2635 else if (uc->rchan)
^^^^^^^^^
This code assumes "uc->rchan" can be NULL. This is potentially a
false positive. Ignore it if it is.

d2abc982333c02 Peter Ujfalusi 2020-12-08 2636 dev_dbg(ud->dev,
d2abc982333c02 Peter Ujfalusi 2020-12-08 2637 "chan%d: rchan%d, rflow%d, Remote thread: 0x%04x\n",
d2abc982333c02 Peter Ujfalusi 2020-12-08 2638 uc->id, uc->rchan->id, uc->rflow->id,
d2abc982333c02 Peter Ujfalusi 2020-12-08 2639 uc->config.remote_thread_id);
d2abc982333c02 Peter Ujfalusi 2020-12-08 2640 return 0;
d2abc982333c02 Peter Ujfalusi 2020-12-08 2641
d2abc982333c02 Peter Ujfalusi 2020-12-08 2642 err_irq_free:
d2abc982333c02 Peter Ujfalusi 2020-12-08 2643 uc->irq_num_ring = 0;
d2abc982333c02 Peter Ujfalusi 2020-12-08 2644 err_psi_free:
d2abc982333c02 Peter Ujfalusi 2020-12-08 2645 navss_psil_unpair(ud, uc->config.src_thread, uc->config.dst_thread);
d2abc982333c02 Peter Ujfalusi 2020-12-08 2646 uc->psil_paired = false;
d2abc982333c02 Peter Ujfalusi 2020-12-08 2647 err_res_free:
d2abc982333c02 Peter Ujfalusi 2020-12-08 2648 udma_free_tx_resources(uc);
d2abc982333c02 Peter Ujfalusi 2020-12-08 2649 udma_free_rx_resources(uc);
d2abc982333c02 Peter Ujfalusi 2020-12-08 2650
d2abc982333c02 Peter Ujfalusi 2020-12-08 2651 udma_reset_uchan(uc);
d2abc982333c02 Peter Ujfalusi 2020-12-08 2652
d2abc982333c02 Peter Ujfalusi 2020-12-08 2653 dma_pool_destroy(uc->hdesc_pool);
d2abc982333c02 Peter Ujfalusi 2020-12-08 2654 uc->use_dma_pool = false;
d2abc982333c02 Peter Ujfalusi 2020-12-08 2655
d2abc982333c02 Peter Ujfalusi 2020-12-08 2656 return ret;
d2abc982333c02 Peter Ujfalusi 2020-12-08 2657 }

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all@xxxxxxxxxxxx

Attachment: .config.gz
Description: application/gzip