Commit b21bb4cd authored by Ben Widawsky's avatar Ben Widawsky Committed by Dan Williams

cxl/mem: Fix register block offset calculation

The "Register Offset Low" register of a "DVSEC Register Locator"
contains the 64K aligned offset for the registers along with the BAR
indicator and an id. The implementation was treating the "Register Block
Offset Low" field a value rather than as a pre-aligned component of the
64-bit offset. So, just mask, don't mask and shift (FIELD_GET).

The user visible result of this bug is that the driver fails to bind to
the device after none of the required blocks are found.

This was missed earlier because the primary development done in the QEMU
environment only uses 0 offsets, i.e. 0 shifted is still 0.

Fixes: 8adaf747 ("cxl/mem: Find device capabilities")
Reported-by: default avatarVishal Verma <vishal.l.verma@intel.com>
Signed-off-by: default avatarBen Widawsky <ben.widawsky@intel.com>
Link: https://lore.kernel.org/r/20210415232610.603273-1-ben.widawsky@intel.comSigned-off-by: default avatarDan Williams <dan.j.williams@intel.com>
parent 392be0bd
......@@ -998,7 +998,7 @@ static struct cxl_mem *cxl_mem_create(struct pci_dev *pdev, u32 reg_lo,
return NULL;
}
offset = ((u64)reg_hi << 32) | FIELD_GET(CXL_REGLOC_ADDR_MASK, reg_lo);
offset = ((u64)reg_hi << 32) | (reg_lo & CXL_REGLOC_ADDR_MASK);
bar = FIELD_GET(CXL_REGLOC_BIR_MASK, reg_lo);
/* Basic sanity check that BAR is big enough */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment