aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/cxl
diff options
context:
space:
mode:
authorBen Widawsky <ben.widawsky@intel.com>2021-04-15 16:26:08 -0700
committerDan Williams <dan.j.williams@intel.com>2021-04-15 19:27:54 -0700
commitb21bb4cd1102dd9e24a169d09cf4e6f3c8a46bcf (patch)
tree05602b8c26ae0fd91964dbb1ddc55f39cbe9f89f /drivers/cxl
parentcxl/mem: Force array size of mem_commands[] to CXL_MEM_COMMAND_ID_MAX (diff)
downloadlinux-dev-b21bb4cd1102dd9e24a169d09cf4e6f3c8a46bcf.tar.xz
linux-dev-b21bb4cd1102dd9e24a169d09cf4e6f3c8a46bcf.zip
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: 8adaf747c9f0 ("cxl/mem: Find device capabilities") Reported-by: Vishal Verma <vishal.l.verma@intel.com> Signed-off-by: Ben Widawsky <ben.widawsky@intel.com> Link: https://lore.kernel.org/r/20210415232610.603273-1-ben.widawsky@intel.com Signed-off-by: Dan Williams <dan.j.williams@intel.com>
Diffstat (limited to 'drivers/cxl')
-rw-r--r--drivers/cxl/mem.c2
1 files changed, 1 insertions, 1 deletions
diff --git a/drivers/cxl/mem.c b/drivers/cxl/mem.c
index e3003f49b329..1b5078311f7d 100644
--- a/drivers/cxl/mem.c
+++ b/drivers/cxl/mem.c
@@ -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 */