Skip to content

Commit 5d09c63

Browse files
committed
cxl/hdm: Remove broken error path
Dan reports that cxl_decoder_commit() potentially leaks a hold of cxl_dpa_rwsem. The potential error case is a "should not" happen scenario, turn it into a "can not" happen scenario by adding the error check to cxl_port_setup_targets() where other setting validation occurs. Reported-by: Dan Carpenter <[email protected]> Closes: http://lore.kernel.org/r/[email protected] Reviewed-by: Dave Jiang <[email protected]> Reviewed-by: Ira Weiny <[email protected]> Fixes: 176baef ("cxl/hdm: Commit decoder state to hardware") Signed-off-by: Dan Williams <[email protected]>
1 parent 69d56b1 commit 5d09c63

File tree

2 files changed

+10
-17
lines changed

2 files changed

+10
-17
lines changed

drivers/cxl/core/hdm.c

Lines changed: 2 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -565,17 +565,11 @@ static void cxld_set_type(struct cxl_decoder *cxld, u32 *ctrl)
565565
CXL_HDM_DECODER0_CTRL_HOSTONLY);
566566
}
567567

568-
static int cxlsd_set_targets(struct cxl_switch_decoder *cxlsd, u64 *tgt)
568+
static void cxlsd_set_targets(struct cxl_switch_decoder *cxlsd, u64 *tgt)
569569
{
570570
struct cxl_dport **t = &cxlsd->target[0];
571571
int ways = cxlsd->cxld.interleave_ways;
572572

573-
if (dev_WARN_ONCE(&cxlsd->cxld.dev,
574-
ways > 8 || ways > cxlsd->nr_targets,
575-
"ways: %d overflows targets: %d\n", ways,
576-
cxlsd->nr_targets))
577-
return -ENXIO;
578-
579573
*tgt = FIELD_PREP(GENMASK(7, 0), t[0]->port_id);
580574
if (ways > 1)
581575
*tgt |= FIELD_PREP(GENMASK(15, 8), t[1]->port_id);
@@ -591,8 +585,6 @@ static int cxlsd_set_targets(struct cxl_switch_decoder *cxlsd, u64 *tgt)
591585
*tgt |= FIELD_PREP(GENMASK_ULL(55, 48), t[6]->port_id);
592586
if (ways > 7)
593587
*tgt |= FIELD_PREP(GENMASK_ULL(63, 56), t[7]->port_id);
594-
595-
return 0;
596588
}
597589

598590
/*
@@ -680,13 +672,7 @@ static int cxl_decoder_commit(struct cxl_decoder *cxld)
680672
void __iomem *tl_lo = hdm + CXL_HDM_DECODER0_TL_LOW(id);
681673
u64 targets;
682674

683-
rc = cxlsd_set_targets(cxlsd, &targets);
684-
if (rc) {
685-
dev_dbg(&port->dev, "%s: target configuration error\n",
686-
dev_name(&cxld->dev));
687-
goto err;
688-
}
689-
675+
cxlsd_set_targets(cxlsd, &targets);
690676
writel(upper_32_bits(targets), tl_hi);
691677
writel(lower_32_bits(targets), tl_lo);
692678
} else {
@@ -704,7 +690,6 @@ static int cxl_decoder_commit(struct cxl_decoder *cxld)
704690

705691
port->commit_end++;
706692
rc = cxld_await_commit(hdm, cxld->id);
707-
err:
708693
if (rc) {
709694
dev_dbg(&port->dev, "%s: error %d committing decoder\n",
710695
dev_name(&cxld->dev), rc);

drivers/cxl/core/region.c

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1196,6 +1196,14 @@ static int cxl_port_setup_targets(struct cxl_port *port,
11961196
return rc;
11971197
}
11981198

1199+
if (iw > 8 || iw > cxlsd->nr_targets) {
1200+
dev_dbg(&cxlr->dev,
1201+
"%s:%s:%s: ways: %d overflows targets: %d\n",
1202+
dev_name(port->uport_dev), dev_name(&port->dev),
1203+
dev_name(&cxld->dev), iw, cxlsd->nr_targets);
1204+
return -ENXIO;
1205+
}
1206+
11991207
if (test_bit(CXL_REGION_F_AUTO, &cxlr->flags)) {
12001208
if (cxld->interleave_ways != iw ||
12011209
cxld->interleave_granularity != ig ||

0 commit comments

Comments
 (0)