Skip to content

Commit 030f880

Browse files
committed
cxl/region: Fix region setup/teardown for RCDs
RCDs (CXL memory devices that link train without VH capability and show up as root complex integrated endpoints), hide the presence of the link between the endpoint and the host-bridge. The CXL region setup/teardown paths assume that a link hop is present and go looking for at least one 'struct cxl_port' instance between the CXL root port-object and an endpoint port-object leading to crashes of the form: BUG: kernel NULL pointer dereference, address: 0000000000000008 [..] RIP: 0010:cxl_region_setup_targets+0x3e9/0xae0 [cxl_core] [..] Call Trace: <TASK> cxl_region_attach+0x46c/0x7a0 [cxl_core] cxl_create_region+0x20b/0x270 [cxl_core] cxl_mock_mem_probe+0x641/0x800 [cxl_mock_mem] platform_probe+0x5b/0xb0 Detect RCDs explicitly and skip walking the non-existent port hierarchy between root and endpoint in that case. While this has been a problem since: commit 0a19bfc ("cxl/port: Add RCD endpoint port enumeration") ...it becomes a more reliable crash scenario with the new autodiscovery implementation. Fixes: a32320b ("cxl/region: Add region autodiscovery") Reviewed-by: Ira Weiny <ira.weiny@intel.com> Reviewed-by: Dave Jiang <dave.jiang@intel.com> Link: https://lore.kernel.org/r/168002858268.50647.728091521032131326.stgit@dwillia2-xfh.jf.intel.com Signed-off-by: Dan Williams <dan.j.williams@intel.com>
1 parent d35b495 commit 030f880

File tree

1 file changed

+27
-1
lines changed

1 file changed

+27
-1
lines changed

drivers/cxl/core/region.c

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -134,9 +134,13 @@ static int cxl_region_decode_reset(struct cxl_region *cxlr, int count)
134134
struct cxl_endpoint_decoder *cxled = p->targets[i];
135135
struct cxl_memdev *cxlmd = cxled_to_memdev(cxled);
136136
struct cxl_port *iter = cxled_to_port(cxled);
137+
struct cxl_dev_state *cxlds = cxlmd->cxlds;
137138
struct cxl_ep *ep;
138139
int rc = 0;
139140

141+
if (cxlds->rcd)
142+
goto endpoint_reset;
143+
140144
while (!is_cxl_root(to_cxl_port(iter->dev.parent)))
141145
iter = to_cxl_port(iter->dev.parent);
142146

@@ -153,6 +157,7 @@ static int cxl_region_decode_reset(struct cxl_region *cxlr, int count)
153157
return rc;
154158
}
155159

160+
endpoint_reset:
156161
rc = cxled->cxld.reset(&cxled->cxld);
157162
if (rc)
158163
return rc;
@@ -1199,6 +1204,7 @@ static void cxl_region_teardown_targets(struct cxl_region *cxlr)
11991204
{
12001205
struct cxl_region_params *p = &cxlr->params;
12011206
struct cxl_endpoint_decoder *cxled;
1207+
struct cxl_dev_state *cxlds;
12021208
struct cxl_memdev *cxlmd;
12031209
struct cxl_port *iter;
12041210
struct cxl_ep *ep;
@@ -1214,6 +1220,10 @@ static void cxl_region_teardown_targets(struct cxl_region *cxlr)
12141220
for (i = 0; i < p->nr_targets; i++) {
12151221
cxled = p->targets[i];
12161222
cxlmd = cxled_to_memdev(cxled);
1223+
cxlds = cxlmd->cxlds;
1224+
1225+
if (cxlds->rcd)
1226+
continue;
12171227

12181228
iter = cxled_to_port(cxled);
12191229
while (!is_cxl_root(to_cxl_port(iter->dev.parent)))
@@ -1229,14 +1239,24 @@ static int cxl_region_setup_targets(struct cxl_region *cxlr)
12291239
{
12301240
struct cxl_region_params *p = &cxlr->params;
12311241
struct cxl_endpoint_decoder *cxled;
1242+
struct cxl_dev_state *cxlds;
1243+
int i, rc, rch = 0, vh = 0;
12321244
struct cxl_memdev *cxlmd;
12331245
struct cxl_port *iter;
12341246
struct cxl_ep *ep;
1235-
int i, rc;
12361247

12371248
for (i = 0; i < p->nr_targets; i++) {
12381249
cxled = p->targets[i];
12391250
cxlmd = cxled_to_memdev(cxled);
1251+
cxlds = cxlmd->cxlds;
1252+
1253+
/* validate that all targets agree on topology */
1254+
if (!cxlds->rcd) {
1255+
vh++;
1256+
} else {
1257+
rch++;
1258+
continue;
1259+
}
12401260

12411261
iter = cxled_to_port(cxled);
12421262
while (!is_cxl_root(to_cxl_port(iter->dev.parent)))
@@ -1256,6 +1276,12 @@ static int cxl_region_setup_targets(struct cxl_region *cxlr)
12561276
}
12571277
}
12581278

1279+
if (rch && vh) {
1280+
dev_err(&cxlr->dev, "mismatched CXL topologies detected\n");
1281+
cxl_region_teardown_targets(cxlr);
1282+
return -ENXIO;
1283+
}
1284+
12591285
return 0;
12601286
}
12611287

0 commit comments

Comments
 (0)