Skip to content

Commit bebfbba

Browse files
fdefrancdavejiang
authored andcommitted
cxl/acpi: Warn on mixed CXL VH and RCH/RCD Hierarchy
Each Host Bridge instance has a corresponding CXL Host Bridge Structure (CHBS) ACPI table that identifies its capabilities. CHBS tables can be two types (CXL 3.1 Table 9-21): The PCIe Root Complex Register Block (RCRB) and CXL Host Bridge Component Registers (CHBCR). If a Host Bridge is attached to a device that is operating in Restricted CXL Device Mode (RCD), BIOS publishes an RCRB with the base address of registers that describe its capabilities (CXL 3.1 sec. 9.11). Instead, the new (CXL 2.0+) Component registers can only be accessed by means of a base address published with a CHBCR (CXL 3.1 sec. 9.12). If an eRCD (a device that forces the host-bridge into CXL 1.1 Restricted CXL Host mode) is attached to a CXL 2.0+ Host-Bridge, the current CXL specification does not define a mechanism for finding CXL-2.0-only root-port component registers like HDM decoders and Extended Security capability. An algorithm to locate a CHBCR associated with an RCRB, would be too invasive to land without some concrete motivation. Therefore, just print a message to inform of unsupported config. Count how many different CHBS "Version" types are detected by cxl_get_chbs_iter(). Then make cxl_get_chbs() print a warning if that sum is greater than 1. Tested-by: Alison Schofield <alison.schofield@intel.com> Signed-off-by: Fabio M. De Francesco <fabio.m.de.francesco@linux.intel.com> Reviewed-by: Davidlohr Bueso <dave@stgolabs.net> Reviewed-by: Alison Schofield <alison.schofield@intel.com> Link: https://patch.msgid.link/20240628175535.272472-1-fabio.m.de.francesco@linux.intel.com Signed-off-by: Dave Jiang <dave.jiang@intel.com>
1 parent 8ecef8e commit bebfbba

File tree

1 file changed

+27
-7
lines changed

1 file changed

+27
-7
lines changed

drivers/cxl/acpi.c

Lines changed: 27 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -482,6 +482,8 @@ struct cxl_chbs_context {
482482
unsigned long long uid;
483483
resource_size_t base;
484484
u32 cxl_version;
485+
int nr_versions;
486+
u32 saved_version;
485487
};
486488

487489
static int cxl_get_chbs_iter(union acpi_subtable_headers *header, void *arg,
@@ -490,22 +492,31 @@ static int cxl_get_chbs_iter(union acpi_subtable_headers *header, void *arg,
490492
struct cxl_chbs_context *ctx = arg;
491493
struct acpi_cedt_chbs *chbs;
492494

493-
if (ctx->base != CXL_RESOURCE_NONE)
494-
return 0;
495-
496495
chbs = (struct acpi_cedt_chbs *) header;
497496

498-
if (ctx->uid != chbs->uid)
497+
if (chbs->cxl_version == ACPI_CEDT_CHBS_VERSION_CXL11 &&
498+
chbs->length != CXL_RCRB_SIZE)
499499
return 0;
500500

501-
ctx->cxl_version = chbs->cxl_version;
502501
if (!chbs->base)
503502
return 0;
504503

505-
if (chbs->cxl_version == ACPI_CEDT_CHBS_VERSION_CXL11 &&
506-
chbs->length != CXL_RCRB_SIZE)
504+
if (ctx->saved_version != chbs->cxl_version) {
505+
/*
506+
* cxl_version cannot be overwritten before the next two
507+
* checks, then use saved_version
508+
*/
509+
ctx->saved_version = chbs->cxl_version;
510+
ctx->nr_versions++;
511+
}
512+
513+
if (ctx->base != CXL_RESOURCE_NONE)
514+
return 0;
515+
516+
if (ctx->uid != chbs->uid)
507517
return 0;
508518

519+
ctx->cxl_version = chbs->cxl_version;
509520
ctx->base = chbs->base;
510521

511522
return 0;
@@ -529,10 +540,19 @@ static int cxl_get_chbs(struct device *dev, struct acpi_device *hb,
529540
.uid = uid,
530541
.base = CXL_RESOURCE_NONE,
531542
.cxl_version = UINT_MAX,
543+
.saved_version = UINT_MAX,
532544
};
533545

534546
acpi_table_parse_cedt(ACPI_CEDT_TYPE_CHBS, cxl_get_chbs_iter, ctx);
535547

548+
if (ctx->nr_versions > 1) {
549+
/*
550+
* Disclaim eRCD support given some component register may
551+
* only be found via CHBCR
552+
*/
553+
dev_info(dev, "Unsupported platform config, mixed Virtual Host and Restricted CXL Host hierarchy.");
554+
}
555+
536556
return 0;
537557
}
538558

0 commit comments

Comments
 (0)