Commit 80936d68 authored by Vignesh Raghavendra's avatar Vignesh Raghavendra Committed by Vinod Koul

dmaengine: ti: k3-udma: Fix smatch warnings

Smatch reports below warnings [1] wrt dereferencing rm_res when it can
potentially be ERR_PTR(). This is possible when entire range is
allocated to Linux
Fix this case by making sure, there is no deference of rm_res when its
ERR_PTR().

[1]:
 drivers/dma/ti/k3-udma.c:4524 udma_setup_resources() error: 'rm_res' dereferencing possible ERR_PTR()
 drivers/dma/ti/k3-udma.c:4537 udma_setup_resources() error: 'rm_res' dereferencing possible ERR_PTR()
 drivers/dma/ti/k3-udma.c:4681 bcdma_setup_resources() error: 'rm_res' dereferencing possible ERR_PTR()
 drivers/dma/ti/k3-udma.c:4696 bcdma_setup_resources() error: 'rm_res' dereferencing possible ERR_PTR()
 drivers/dma/ti/k3-udma.c:4711 bcdma_setup_resources() error: 'rm_res' dereferencing possible ERR_PTR()
 drivers/dma/ti/k3-udma.c:4848 pktdma_setup_resources() error: 'rm_res' dereferencing possible ERR_PTR()
 drivers/dma/ti/k3-udma.c:4861 pktdma_setup_resources() error: 'rm_res' dereferencing possible ERR_PTR()
Reported-by: default avatarNishanth Menon <nm@ti.com>
Signed-off-by: default avatarVignesh Raghavendra <vigneshr@ti.com>
Acked-by: default avatarPeter Ujfalusi <peter.ujfalusi@gmail.com>
Link: https://lore.kernel.org/r/20211209180957.29036-1-vigneshr@ti.comSigned-off-by: default avatarVinod Koul <vkoul@kernel.org>
parent fa51b16d
...@@ -4534,35 +4534,49 @@ static int udma_setup_resources(struct udma_dev *ud) ...@@ -4534,35 +4534,49 @@ static int udma_setup_resources(struct udma_dev *ud)
rm_res = tisci_rm->rm_ranges[RM_RANGE_TCHAN]; rm_res = tisci_rm->rm_ranges[RM_RANGE_TCHAN];
if (IS_ERR(rm_res)) { if (IS_ERR(rm_res)) {
bitmap_zero(ud->tchan_map, ud->tchan_cnt); bitmap_zero(ud->tchan_map, ud->tchan_cnt);
irq_res.sets = 1;
} else { } else {
bitmap_fill(ud->tchan_map, ud->tchan_cnt); bitmap_fill(ud->tchan_map, ud->tchan_cnt);
for (i = 0; i < rm_res->sets; i++) for (i = 0; i < rm_res->sets; i++)
udma_mark_resource_ranges(ud, ud->tchan_map, udma_mark_resource_ranges(ud, ud->tchan_map,
&rm_res->desc[i], "tchan"); &rm_res->desc[i], "tchan");
}
irq_res.sets = rm_res->sets; irq_res.sets = rm_res->sets;
}
/* rchan and matching default flow ranges */ /* rchan and matching default flow ranges */
rm_res = tisci_rm->rm_ranges[RM_RANGE_RCHAN]; rm_res = tisci_rm->rm_ranges[RM_RANGE_RCHAN];
if (IS_ERR(rm_res)) { if (IS_ERR(rm_res)) {
bitmap_zero(ud->rchan_map, ud->rchan_cnt); bitmap_zero(ud->rchan_map, ud->rchan_cnt);
irq_res.sets++;
} else { } else {
bitmap_fill(ud->rchan_map, ud->rchan_cnt); bitmap_fill(ud->rchan_map, ud->rchan_cnt);
for (i = 0; i < rm_res->sets; i++) for (i = 0; i < rm_res->sets; i++)
udma_mark_resource_ranges(ud, ud->rchan_map, udma_mark_resource_ranges(ud, ud->rchan_map,
&rm_res->desc[i], "rchan"); &rm_res->desc[i], "rchan");
irq_res.sets += rm_res->sets;
} }
irq_res.sets += rm_res->sets;
irq_res.desc = kcalloc(irq_res.sets, sizeof(*irq_res.desc), GFP_KERNEL); irq_res.desc = kcalloc(irq_res.sets, sizeof(*irq_res.desc), GFP_KERNEL);
if (!irq_res.desc)
return -ENOMEM;
rm_res = tisci_rm->rm_ranges[RM_RANGE_TCHAN]; rm_res = tisci_rm->rm_ranges[RM_RANGE_TCHAN];
if (IS_ERR(rm_res)) {
irq_res.desc[0].start = 0;
irq_res.desc[0].num = ud->tchan_cnt;
i = 1;
} else {
for (i = 0; i < rm_res->sets; i++) { for (i = 0; i < rm_res->sets; i++) {
irq_res.desc[i].start = rm_res->desc[i].start; irq_res.desc[i].start = rm_res->desc[i].start;
irq_res.desc[i].num = rm_res->desc[i].num; irq_res.desc[i].num = rm_res->desc[i].num;
irq_res.desc[i].start_sec = rm_res->desc[i].start_sec; irq_res.desc[i].start_sec = rm_res->desc[i].start_sec;
irq_res.desc[i].num_sec = rm_res->desc[i].num_sec; irq_res.desc[i].num_sec = rm_res->desc[i].num_sec;
} }
}
rm_res = tisci_rm->rm_ranges[RM_RANGE_RCHAN]; rm_res = tisci_rm->rm_ranges[RM_RANGE_RCHAN];
if (IS_ERR(rm_res)) {
irq_res.desc[i].start = 0;
irq_res.desc[i].num = ud->rchan_cnt;
} else {
for (j = 0; j < rm_res->sets; j++, i++) { for (j = 0; j < rm_res->sets; j++, i++) {
if (rm_res->desc[j].num) { if (rm_res->desc[j].num) {
irq_res.desc[i].start = rm_res->desc[j].start + irq_res.desc[i].start = rm_res->desc[j].start +
...@@ -4575,6 +4589,7 @@ static int udma_setup_resources(struct udma_dev *ud) ...@@ -4575,6 +4589,7 @@ static int udma_setup_resources(struct udma_dev *ud)
irq_res.desc[i].num_sec = rm_res->desc[j].num_sec; irq_res.desc[i].num_sec = rm_res->desc[j].num_sec;
} }
} }
}
ret = ti_sci_inta_msi_domain_alloc_irqs(ud->dev, &irq_res); ret = ti_sci_inta_msi_domain_alloc_irqs(ud->dev, &irq_res);
kfree(irq_res.desc); kfree(irq_res.desc);
if (ret) { if (ret) {
...@@ -4690,57 +4705,75 @@ static int bcdma_setup_resources(struct udma_dev *ud) ...@@ -4690,57 +4705,75 @@ static int bcdma_setup_resources(struct udma_dev *ud)
rm_res = tisci_rm->rm_ranges[RM_RANGE_BCHAN]; rm_res = tisci_rm->rm_ranges[RM_RANGE_BCHAN];
if (IS_ERR(rm_res)) { if (IS_ERR(rm_res)) {
bitmap_zero(ud->bchan_map, ud->bchan_cnt); bitmap_zero(ud->bchan_map, ud->bchan_cnt);
irq_res.sets++;
} else { } else {
bitmap_fill(ud->bchan_map, ud->bchan_cnt); bitmap_fill(ud->bchan_map, ud->bchan_cnt);
for (i = 0; i < rm_res->sets; i++) for (i = 0; i < rm_res->sets; i++)
udma_mark_resource_ranges(ud, ud->bchan_map, udma_mark_resource_ranges(ud, ud->bchan_map,
&rm_res->desc[i], &rm_res->desc[i],
"bchan"); "bchan");
}
irq_res.sets += rm_res->sets; irq_res.sets += rm_res->sets;
} }
}
/* tchan ranges */ /* tchan ranges */
if (ud->tchan_cnt) { if (ud->tchan_cnt) {
rm_res = tisci_rm->rm_ranges[RM_RANGE_TCHAN]; rm_res = tisci_rm->rm_ranges[RM_RANGE_TCHAN];
if (IS_ERR(rm_res)) { if (IS_ERR(rm_res)) {
bitmap_zero(ud->tchan_map, ud->tchan_cnt); bitmap_zero(ud->tchan_map, ud->tchan_cnt);
irq_res.sets += 2;
} else { } else {
bitmap_fill(ud->tchan_map, ud->tchan_cnt); bitmap_fill(ud->tchan_map, ud->tchan_cnt);
for (i = 0; i < rm_res->sets; i++) for (i = 0; i < rm_res->sets; i++)
udma_mark_resource_ranges(ud, ud->tchan_map, udma_mark_resource_ranges(ud, ud->tchan_map,
&rm_res->desc[i], &rm_res->desc[i],
"tchan"); "tchan");
}
irq_res.sets += rm_res->sets * 2; irq_res.sets += rm_res->sets * 2;
} }
}
/* rchan ranges */ /* rchan ranges */
if (ud->rchan_cnt) { if (ud->rchan_cnt) {
rm_res = tisci_rm->rm_ranges[RM_RANGE_RCHAN]; rm_res = tisci_rm->rm_ranges[RM_RANGE_RCHAN];
if (IS_ERR(rm_res)) { if (IS_ERR(rm_res)) {
bitmap_zero(ud->rchan_map, ud->rchan_cnt); bitmap_zero(ud->rchan_map, ud->rchan_cnt);
irq_res.sets += 2;
} else { } else {
bitmap_fill(ud->rchan_map, ud->rchan_cnt); bitmap_fill(ud->rchan_map, ud->rchan_cnt);
for (i = 0; i < rm_res->sets; i++) for (i = 0; i < rm_res->sets; i++)
udma_mark_resource_ranges(ud, ud->rchan_map, udma_mark_resource_ranges(ud, ud->rchan_map,
&rm_res->desc[i], &rm_res->desc[i],
"rchan"); "rchan");
}
irq_res.sets += rm_res->sets * 2; irq_res.sets += rm_res->sets * 2;
} }
}
irq_res.desc = kcalloc(irq_res.sets, sizeof(*irq_res.desc), GFP_KERNEL); irq_res.desc = kcalloc(irq_res.sets, sizeof(*irq_res.desc), GFP_KERNEL);
if (!irq_res.desc)
return -ENOMEM;
if (ud->bchan_cnt) { if (ud->bchan_cnt) {
rm_res = tisci_rm->rm_ranges[RM_RANGE_BCHAN]; rm_res = tisci_rm->rm_ranges[RM_RANGE_BCHAN];
if (IS_ERR(rm_res)) {
irq_res.desc[0].start = oes->bcdma_bchan_ring;
irq_res.desc[0].num = ud->bchan_cnt;
i = 1;
} else {
for (i = 0; i < rm_res->sets; i++) { for (i = 0; i < rm_res->sets; i++) {
irq_res.desc[i].start = rm_res->desc[i].start + irq_res.desc[i].start = rm_res->desc[i].start +
oes->bcdma_bchan_ring; oes->bcdma_bchan_ring;
irq_res.desc[i].num = rm_res->desc[i].num; irq_res.desc[i].num = rm_res->desc[i].num;
} }
} }
}
if (ud->tchan_cnt) { if (ud->tchan_cnt) {
rm_res = tisci_rm->rm_ranges[RM_RANGE_TCHAN]; rm_res = tisci_rm->rm_ranges[RM_RANGE_TCHAN];
if (IS_ERR(rm_res)) {
irq_res.desc[i].start = oes->bcdma_tchan_data;
irq_res.desc[i].num = ud->tchan_cnt;
irq_res.desc[i + 1].start = oes->bcdma_tchan_ring;
irq_res.desc[i + 1].num = ud->tchan_cnt;
i += 2;
} else {
for (j = 0; j < rm_res->sets; j++, i += 2) { for (j = 0; j < rm_res->sets; j++, i += 2) {
irq_res.desc[i].start = rm_res->desc[j].start + irq_res.desc[i].start = rm_res->desc[j].start +
oes->bcdma_tchan_data; oes->bcdma_tchan_data;
...@@ -4751,8 +4784,16 @@ static int bcdma_setup_resources(struct udma_dev *ud) ...@@ -4751,8 +4784,16 @@ static int bcdma_setup_resources(struct udma_dev *ud)
irq_res.desc[i + 1].num = rm_res->desc[j].num; irq_res.desc[i + 1].num = rm_res->desc[j].num;
} }
} }
}
if (ud->rchan_cnt) { if (ud->rchan_cnt) {
rm_res = tisci_rm->rm_ranges[RM_RANGE_RCHAN]; rm_res = tisci_rm->rm_ranges[RM_RANGE_RCHAN];
if (IS_ERR(rm_res)) {
irq_res.desc[i].start = oes->bcdma_rchan_data;
irq_res.desc[i].num = ud->rchan_cnt;
irq_res.desc[i + 1].start = oes->bcdma_rchan_ring;
irq_res.desc[i + 1].num = ud->rchan_cnt;
i += 2;
} else {
for (j = 0; j < rm_res->sets; j++, i += 2) { for (j = 0; j < rm_res->sets; j++, i += 2) {
irq_res.desc[i].start = rm_res->desc[j].start + irq_res.desc[i].start = rm_res->desc[j].start +
oes->bcdma_rchan_data; oes->bcdma_rchan_data;
...@@ -4763,6 +4804,7 @@ static int bcdma_setup_resources(struct udma_dev *ud) ...@@ -4763,6 +4804,7 @@ static int bcdma_setup_resources(struct udma_dev *ud)
irq_res.desc[i + 1].num = rm_res->desc[j].num; irq_res.desc[i + 1].num = rm_res->desc[j].num;
} }
} }
}
ret = ti_sci_inta_msi_domain_alloc_irqs(ud->dev, &irq_res); ret = ti_sci_inta_msi_domain_alloc_irqs(ud->dev, &irq_res);
kfree(irq_res.desc); kfree(irq_res.desc);
...@@ -4858,40 +4900,55 @@ static int pktdma_setup_resources(struct udma_dev *ud) ...@@ -4858,40 +4900,55 @@ static int pktdma_setup_resources(struct udma_dev *ud)
if (IS_ERR(rm_res)) { if (IS_ERR(rm_res)) {
/* all rflows are assigned exclusively to Linux */ /* all rflows are assigned exclusively to Linux */
bitmap_zero(ud->rflow_in_use, ud->rflow_cnt); bitmap_zero(ud->rflow_in_use, ud->rflow_cnt);
irq_res.sets = 1;
} else { } else {
bitmap_fill(ud->rflow_in_use, ud->rflow_cnt); bitmap_fill(ud->rflow_in_use, ud->rflow_cnt);
for (i = 0; i < rm_res->sets; i++) for (i = 0; i < rm_res->sets; i++)
udma_mark_resource_ranges(ud, ud->rflow_in_use, udma_mark_resource_ranges(ud, ud->rflow_in_use,
&rm_res->desc[i], "rflow"); &rm_res->desc[i], "rflow");
}
irq_res.sets = rm_res->sets; irq_res.sets = rm_res->sets;
}
/* tflow ranges */ /* tflow ranges */
rm_res = tisci_rm->rm_ranges[RM_RANGE_TFLOW]; rm_res = tisci_rm->rm_ranges[RM_RANGE_TFLOW];
if (IS_ERR(rm_res)) { if (IS_ERR(rm_res)) {
/* all tflows are assigned exclusively to Linux */ /* all tflows are assigned exclusively to Linux */
bitmap_zero(ud->tflow_map, ud->tflow_cnt); bitmap_zero(ud->tflow_map, ud->tflow_cnt);
irq_res.sets++;
} else { } else {
bitmap_fill(ud->tflow_map, ud->tflow_cnt); bitmap_fill(ud->tflow_map, ud->tflow_cnt);
for (i = 0; i < rm_res->sets; i++) for (i = 0; i < rm_res->sets; i++)
udma_mark_resource_ranges(ud, ud->tflow_map, udma_mark_resource_ranges(ud, ud->tflow_map,
&rm_res->desc[i], "tflow"); &rm_res->desc[i], "tflow");
}
irq_res.sets += rm_res->sets; irq_res.sets += rm_res->sets;
}
irq_res.desc = kcalloc(irq_res.sets, sizeof(*irq_res.desc), GFP_KERNEL); irq_res.desc = kcalloc(irq_res.sets, sizeof(*irq_res.desc), GFP_KERNEL);
if (!irq_res.desc)
return -ENOMEM;
rm_res = tisci_rm->rm_ranges[RM_RANGE_TFLOW]; rm_res = tisci_rm->rm_ranges[RM_RANGE_TFLOW];
if (IS_ERR(rm_res)) {
irq_res.desc[0].start = oes->pktdma_tchan_flow;
irq_res.desc[0].num = ud->tflow_cnt;
i = 1;
} else {
for (i = 0; i < rm_res->sets; i++) { for (i = 0; i < rm_res->sets; i++) {
irq_res.desc[i].start = rm_res->desc[i].start + irq_res.desc[i].start = rm_res->desc[i].start +
oes->pktdma_tchan_flow; oes->pktdma_tchan_flow;
irq_res.desc[i].num = rm_res->desc[i].num; irq_res.desc[i].num = rm_res->desc[i].num;
} }
}
rm_res = tisci_rm->rm_ranges[RM_RANGE_RFLOW]; rm_res = tisci_rm->rm_ranges[RM_RANGE_RFLOW];
if (IS_ERR(rm_res)) {
irq_res.desc[i].start = oes->pktdma_rchan_flow;
irq_res.desc[i].num = ud->rflow_cnt;
} else {
for (j = 0; j < rm_res->sets; j++, i++) { for (j = 0; j < rm_res->sets; j++, i++) {
irq_res.desc[i].start = rm_res->desc[j].start + irq_res.desc[i].start = rm_res->desc[j].start +
oes->pktdma_rchan_flow; oes->pktdma_rchan_flow;
irq_res.desc[i].num = rm_res->desc[j].num; irq_res.desc[i].num = rm_res->desc[j].num;
} }
}
ret = ti_sci_inta_msi_domain_alloc_irqs(ud->dev, &irq_res); ret = ti_sci_inta_msi_domain_alloc_irqs(ud->dev, &irq_res);
kfree(irq_res.desc); kfree(irq_res.desc);
if (ret) { if (ret) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment