Skip to content

Commit 74b0fe8

Browse files
jic23djbw
authored andcommitted
cxl/regs: Fix size of CXL Capability Header Register
In CXL 2.0, 8.2.5.1 CXL Capability Header Register: this register is given as 32 bits. 8.2.3 which covers the CXL 2.0 Component registers, including the CXL Capability Header Register states that access restrictions specified in Section 8.2.2 apply. 8.2.2 includes: * A 32 bit register shall be accessed as a 4 Byte quantity. ... If these rules are not followed, the behavior is undefined. Discovered during review of CXL QEMU emulation. Alex Bennée pointed out there was a comment saying that 4 byte registers must be read with a 4 byte read, but 8 byte reads were being emulated. https://lore.kernel.org/qemu-devel/87bkzyd3c7.fsf@linaro.org/ Fixing that, led to this code failing. Whilst a given hardware implementation 'might' work with an 8 byte read, it should not be relied upon. The QEMU emulation v5 will return 0 and log the wrong access width. The code moved, so one fixes tag for where this will directly apply and also a reference to the earlier introduction of the code for backports. Fixes: 0f06157 ("cxl/core: Move register mapping infrastructure") Fixes: 0842237 ("cxl/pci: Add HDM decoder capabilities") Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com> Cc: Alex Bennée <alex.bennee@linaro.org> Reviewed-by: Ben Widawsky <ben.widawsky@intel.com> Link: https://lore.kernel.org/r/20220201153437.2873-1-Jonathan.Cameron@huawei.com Signed-off-by: Dan Williams <dan.j.williams@intel.com>
1 parent 7004cc9 commit 74b0fe8

1 file changed

Lines changed: 2 additions & 2 deletions

File tree

drivers/cxl/core/regs.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ void cxl_probe_component_regs(struct device *dev, void __iomem *base,
3636
struct cxl_component_reg_map *map)
3737
{
3838
int cap, cap_count;
39-
u64 cap_array;
39+
u32 cap_array;
4040

4141
*map = (struct cxl_component_reg_map) { 0 };
4242

@@ -46,7 +46,7 @@ void cxl_probe_component_regs(struct device *dev, void __iomem *base,
4646
*/
4747
base += CXL_CM_OFFSET;
4848

49-
cap_array = readq(base + CXL_CM_CAP_HDR_OFFSET);
49+
cap_array = readl(base + CXL_CM_CAP_HDR_OFFSET);
5050

5151
if (FIELD_GET(CXL_CM_CAP_HDR_ID_MASK, cap_array) != CM_CAP_HDR_CAP_ID) {
5252
dev_err(dev,

0 commit comments

Comments
 (0)