Skip to content

Commit 5c6224b

Browse files
committed
cxl/acpi: Fix load failures due to single window creation failure
The expectation is that cxl_parse_cfwms() continues in the face the of failure as evidenced by code like: cxlrd = cxl_root_decoder_alloc(root_port, ways, cxl_calc_hb); if (IS_ERR(cxlrd)) return 0; There are other error paths in that function which mistakenly follow idiomatic expectations and return an error when they should not. Most of those mistakes are innocuous checks that hardly ever fail in practice. However, a recent change succeed in making the implementation more fragile by applying an idiomatic, but still wrong "fix" [1]. In this failure case the kernel reports: cxl root0: Failed to populate active decoder targets cxl_acpi ACPI0017:00: Failed to add decode range: [mem 0x00000000-0x7fffffff flags 0x200] ...which is a real issue with that one window (to be fixed separately), but ends up failing the entirety of cxl_acpi_probe(). Undo that recent breakage while also removing the confusion about ignoring errors. Update all exits paths to return an error per typical expectations and let an outer wrapper function handle dropping the error. Fixes: 91019b5 ("cxl/acpi: Return 'rc' instead of '0' in cxl_parse_cfmws()") [1] Cc: <stable@vger.kernel.org> Cc: Breno Leitao <leitao@debian.org> Cc: Alison Schofield <alison.schofield@intel.com> Cc: Vishal Verma <vishal.l.verma@intel.com> Signed-off-by: Dan Williams <dan.j.williams@intel.com>
1 parent 40de53f commit 5c6224b

File tree

1 file changed

+28
-18
lines changed

1 file changed

+28
-18
lines changed

drivers/cxl/acpi.c

Lines changed: 28 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -316,31 +316,27 @@ static const struct cxl_root_ops acpi_root_ops = {
316316
.qos_class = cxl_acpi_qos_class,
317317
};
318318

319-
static int cxl_parse_cfmws(union acpi_subtable_headers *header, void *arg,
320-
const unsigned long end)
319+
static int __cxl_parse_cfmws(struct acpi_cedt_cfmws *cfmws,
320+
struct cxl_cfmws_context *ctx)
321321
{
322322
int target_map[CXL_DECODER_MAX_INTERLEAVE];
323-
struct cxl_cfmws_context *ctx = arg;
324323
struct cxl_port *root_port = ctx->root_port;
325324
struct resource *cxl_res = ctx->cxl_res;
326325
struct cxl_cxims_context cxims_ctx;
327326
struct cxl_root_decoder *cxlrd;
328327
struct device *dev = ctx->dev;
329-
struct acpi_cedt_cfmws *cfmws;
330328
cxl_calc_hb_fn cxl_calc_hb;
331329
struct cxl_decoder *cxld;
332330
unsigned int ways, i, ig;
333331
struct resource *res;
334332
int rc;
335333

336-
cfmws = (struct acpi_cedt_cfmws *) header;
337-
338334
rc = cxl_acpi_cfmws_verify(dev, cfmws);
339335
if (rc) {
340336
dev_err(dev, "CFMWS range %#llx-%#llx not registered\n",
341337
cfmws->base_hpa,
342338
cfmws->base_hpa + cfmws->window_size - 1);
343-
return 0;
339+
return rc;
344340
}
345341

346342
rc = eiw_to_ways(cfmws->interleave_ways, &ways);
@@ -376,7 +372,7 @@ static int cxl_parse_cfmws(union acpi_subtable_headers *header, void *arg,
376372

377373
cxlrd = cxl_root_decoder_alloc(root_port, ways, cxl_calc_hb);
378374
if (IS_ERR(cxlrd))
379-
return 0;
375+
return PTR_ERR(cxlrd);
380376

381377
cxld = &cxlrd->cxlsd.cxld;
382378
cxld->flags = cfmws_to_decoder_flags(cfmws->restrictions);
@@ -420,16 +416,7 @@ static int cxl_parse_cfmws(union acpi_subtable_headers *header, void *arg,
420416
put_device(&cxld->dev);
421417
else
422418
rc = cxl_decoder_autoremove(dev, cxld);
423-
if (rc) {
424-
dev_err(dev, "Failed to add decode range: %pr", res);
425-
return rc;
426-
}
427-
dev_dbg(dev, "add: %s node: %d range [%#llx - %#llx]\n",
428-
dev_name(&cxld->dev),
429-
phys_to_target_node(cxld->hpa_range.start),
430-
cxld->hpa_range.start, cxld->hpa_range.end);
431-
432-
return 0;
419+
return rc;
433420

434421
err_insert:
435422
kfree(res->name);
@@ -438,6 +425,29 @@ static int cxl_parse_cfmws(union acpi_subtable_headers *header, void *arg,
438425
return -ENOMEM;
439426
}
440427

428+
static int cxl_parse_cfmws(union acpi_subtable_headers *header, void *arg,
429+
const unsigned long end)
430+
{
431+
struct acpi_cedt_cfmws *cfmws = (struct acpi_cedt_cfmws *)header;
432+
struct cxl_cfmws_context *ctx = arg;
433+
struct device *dev = ctx->dev;
434+
int rc;
435+
436+
rc = __cxl_parse_cfmws(cfmws, ctx);
437+
if (rc)
438+
dev_err(dev,
439+
"Failed to add decode range: [%#llx - %#llx] (%d)\n",
440+
cfmws->base_hpa,
441+
cfmws->base_hpa + cfmws->window_size - 1, rc);
442+
else
443+
dev_dbg(dev, "decode range: node: %d range [%#llx - %#llx]\n",
444+
phys_to_target_node(cfmws->base_hpa), cfmws->base_hpa,
445+
cfmws->base_hpa + cfmws->window_size - 1);
446+
447+
/* never fail cxl_acpi load for a single window failure */
448+
return 0;
449+
}
450+
441451
__mock struct acpi_device *to_cxl_host_bridge(struct device *host,
442452
struct device *dev)
443453
{

0 commit comments

Comments
 (0)