Skip to content

Commit 75cea07

Browse files
skoralahdavejiang
authored andcommitted
cxl/hdm: Avoid incorrect DVSEC fallback when HDM decoders are enabled
Check the global CXL_HDM_DECODER_ENABLE bit instead of looping over per-decoder COMMITTED bits to determine whether to fall back to DVSEC range emulation. When the HDM decoder capability is globally enabled, ignore DVSEC range registers regardless of individual decoder commit state. should_emulate_decoders() currently loops over per-decoder COMMITTED bits, which leads to an incorrect DVSEC fallback when those bits are zero. One way to trigger this is to destroy a region and bounce the memdev: cxl disable-region region0 cxl destroy-region region0 cxl disable-memdev mem0 cxl enable-memdev mem0 Region teardown zeroes the HDM decoder registers including the committed bits. The subsequent memdev re-probe finds uncommitted decoders and falls back to DVSEC emulation, even though HDM remains globally enabled. Observed failures: should_emulate_decoders: cxl_port endpoint6: decoder6.0: committed: 0 base: 0x0_00000000 size: 0x0_00000000 devm_cxl_setup_hdm: cxl_port endpoint6: Fallback map 1 range register .. devm_cxl_add_region: cxl_acpi ACPI0017:00: decoder0.0: created region0 __construct_region: cxl_pci 0000:e1:00.0: mem1:decoder6.0: __construct_region region0 res: [mem 0x850000000-0x284fffffff flags 0x200] iw: 1 ig: 4096 cxl region0: pci0000:e0:port1 cxl_port_setup_targets expected iw: 1 ig: 4096 .. cxl region0: pci0000:e0:port1 cxl_port_setup_targets got iw: 1 ig: 256 state: disabled .. cxl_port endpoint6: failed to attach decoder6.0 to region0: -6 .. devm_cxl_add_region: cxl_acpi ACPI0017:00: decoder0.0: created region4 alloc_hpa: cxl region4: HPA allocation error (-34) .. Fixes: 52cc48a ("cxl/hdm: Limit emulation to the number of range registers") Signed-off-by: Smita Koralahalli <[email protected]> Reviewed-by: Dan Williams <[email protected]> Link: https://patch.msgid.link/[email protected] Signed-off-by: Dave Jiang <[email protected]>
1 parent 93d0fcd commit 75cea07

1 file changed

Lines changed: 9 additions & 16 deletions

File tree

drivers/cxl/core/hdm.c

Lines changed: 9 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,6 @@ static bool should_emulate_decoders(struct cxl_endpoint_dvsec_info *info)
9494
struct cxl_hdm *cxlhdm;
9595
void __iomem *hdm;
9696
u32 ctrl;
97-
int i;
9897

9998
if (!info)
10099
return false;
@@ -113,22 +112,16 @@ static bool should_emulate_decoders(struct cxl_endpoint_dvsec_info *info)
113112
return false;
114113

115114
/*
116-
* If any decoders are committed already, there should not be any
117-
* emulated DVSEC decoders.
115+
* If HDM decoders are globally enabled, do not fall back to DVSEC
116+
* range emulation. Zeroed decoder registers after region teardown
117+
* do not imply absence of HDM capability.
118+
*
119+
* Falling back to DVSEC here would treat the decoder as AUTO and
120+
* may incorrectly latch default interleave settings.
118121
*/
119-
for (i = 0; i < cxlhdm->decoder_count; i++) {
120-
ctrl = readl(hdm + CXL_HDM_DECODER0_CTRL_OFFSET(i));
121-
dev_dbg(&info->port->dev,
122-
"decoder%d.%d: committed: %ld base: %#x_%.8x size: %#x_%.8x\n",
123-
info->port->id, i,
124-
FIELD_GET(CXL_HDM_DECODER0_CTRL_COMMITTED, ctrl),
125-
readl(hdm + CXL_HDM_DECODER0_BASE_HIGH_OFFSET(i)),
126-
readl(hdm + CXL_HDM_DECODER0_BASE_LOW_OFFSET(i)),
127-
readl(hdm + CXL_HDM_DECODER0_SIZE_HIGH_OFFSET(i)),
128-
readl(hdm + CXL_HDM_DECODER0_SIZE_LOW_OFFSET(i)));
129-
if (FIELD_GET(CXL_HDM_DECODER0_CTRL_COMMITTED, ctrl))
130-
return false;
131-
}
122+
ctrl = readl(hdm + CXL_HDM_DECODER_CTRL_OFFSET);
123+
if (ctrl & CXL_HDM_DECODER_ENABLE)
124+
return false;
132125

133126
return true;
134127
}

0 commit comments

Comments
 (0)