Skip to content

Commit 7367539

Browse files
committed
Merge tag 'cxl-fixes-6.9-rc7' of git://git.kernel.org/pub/scm/linux/kernel/git/cxl/cxl
Pull cxl fix from Dave Jiang: "Add missing RCH support for endpoint access_coordinate calculation. A late bug was reported by Robert Richter that the Restricted CXL Host (RCH) support was missing in the CXL endpoint access_coordinate calculation. The missing support causes the topology iterator to stumble over a NULL pointer and triggers a kernel OOPS on a platform with CXL 1.1 support. The fix bypasses RCH topology as the access_coordinate calculation is not necessary since RCH does not support hotplug and the memory region exported should be covered by the HMAT table already. A unit test is also added to cxl_test to check against future regressions on the topology iterator" * tag 'cxl-fixes-6.9-rc7' of git://git.kernel.org/pub/scm/linux/kernel/git/cxl/cxl: cxl: Fix cxl_endpoint_get_perf_coordinate() support for RCH
2 parents ddb4c3f + 5d211c7 commit 7367539

File tree

2 files changed

+21
-1
lines changed

2 files changed

+21
-1
lines changed

drivers/cxl/core/port.c

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2184,6 +2184,7 @@ static bool parent_port_is_cxl_root(struct cxl_port *port)
21842184
int cxl_endpoint_get_perf_coordinates(struct cxl_port *port,
21852185
struct access_coordinate *coord)
21862186
{
2187+
struct cxl_memdev *cxlmd = to_cxl_memdev(port->uport_dev);
21872188
struct access_coordinate c[] = {
21882189
{
21892190
.read_bandwidth = UINT_MAX,
@@ -2197,12 +2198,20 @@ int cxl_endpoint_get_perf_coordinates(struct cxl_port *port,
21972198
struct cxl_port *iter = port;
21982199
struct cxl_dport *dport;
21992200
struct pci_dev *pdev;
2201+
struct device *dev;
22002202
unsigned int bw;
22012203
bool is_cxl_root;
22022204

22032205
if (!is_cxl_endpoint(port))
22042206
return -EINVAL;
22052207

2208+
/*
2209+
* Skip calculation for RCD. Expectation is HMAT already covers RCD case
2210+
* since RCH does not support hotplug.
2211+
*/
2212+
if (cxlmd->cxlds->rcd)
2213+
return 0;
2214+
22062215
/*
22072216
* Exit the loop when the parent port of the current iter port is cxl
22082217
* root. The iterative loop starts at the endpoint and gathers the
@@ -2232,8 +2241,12 @@ int cxl_endpoint_get_perf_coordinates(struct cxl_port *port,
22322241
return -EINVAL;
22332242
cxl_coordinates_combine(c, c, dport->coord);
22342243

2244+
dev = port->uport_dev->parent;
2245+
if (!dev_is_pci(dev))
2246+
return -ENODEV;
2247+
22352248
/* Get the calculated PCI paths bandwidth */
2236-
pdev = to_pci_dev(port->uport_dev->parent);
2249+
pdev = to_pci_dev(dev);
22372250
bw = pcie_bandwidth_available(pdev, NULL, NULL, NULL);
22382251
if (bw == 0)
22392252
return -ENXIO;

tools/testing/cxl/test/cxl.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1001,6 +1001,7 @@ static void mock_cxl_endpoint_parse_cdat(struct cxl_port *port)
10011001
struct cxl_memdev *cxlmd = to_cxl_memdev(port->uport_dev);
10021002
struct cxl_dev_state *cxlds = cxlmd->cxlds;
10031003
struct cxl_memdev_state *mds = to_cxl_memdev_state(cxlds);
1004+
struct access_coordinate ep_c[ACCESS_COORDINATE_MAX];
10041005
struct range pmem_range = {
10051006
.start = cxlds->pmem_res.start,
10061007
.end = cxlds->pmem_res.end,
@@ -1020,6 +1021,12 @@ static void mock_cxl_endpoint_parse_cdat(struct cxl_port *port)
10201021
dpa_perf_setup(port, &pmem_range, &mds->pmem_perf);
10211022

10221023
cxl_memdev_update_perf(cxlmd);
1024+
1025+
/*
1026+
* This function is here to only test the topology iterator. It serves
1027+
* no other purpose.
1028+
*/
1029+
cxl_endpoint_get_perf_coordinates(port, ep_c);
10231030
}
10241031

10251032
static struct cxl_mock_ops cxl_mock_ops = {

0 commit comments

Comments
 (0)