Message ID | 20240403154844.3403859-6-dave.jiang@intel.com |
---|---|
State | Accepted |
Commit | 4ff2d4b81d7057bf0141aa14cbcf1780f063a477 |
Headers | show |
Series | cxl: access_coordinate validity fixes for 6.9 | expand |
Dave Jiang wrote: > Jonathan noted that when the coordinates for host bridge and switches > can be 0s if no actual data are retrieved and the calculation continues. > The resulting number would be inaccurate. Add checks to ensure that the > calculation would complete only if the numbers are valid. > > While not seen in the wild, issue may show up with a BIOS that reported > CXL root ports via Generic Ports (via a PCI handle in the SRAT entry). > > Fixes: 14a6960b3e92 ("cxl: Add helper function that calculate performance data for downstream ports") > Reported-by: Jonathan Cameron <Jonathan.Cameron@huawei.com> > Reviewed-by: Jonathan Cameron <Jonathan.Cameron@huawei.com> > Reviewed-by: Davidlohr Bueso <dave@stgolabs.net> > Signed-off-by: Dave Jiang <dave.jiang@intel.com> Looks good, Reviewed-by: Dan Williams <dan.j.williams@intel.com>
diff --git a/drivers/cxl/core/port.c b/drivers/cxl/core/port.c index 801c4018a1dd..762783bb091a 100644 --- a/drivers/cxl/core/port.c +++ b/drivers/cxl/core/port.c @@ -2141,6 +2141,18 @@ static void add_latency(struct access_coordinate *c, long latency) } } +static bool coordinates_valid(struct access_coordinate *c) +{ + for (int i = 0; i < ACCESS_COORDINATE_MAX; i++) { + if (c[i].read_bandwidth && c[i].write_bandwidth && + c[i].read_latency && c[i].write_latency) + continue; + return false; + } + + return true; +} + static void set_min_bandwidth(struct access_coordinate *c, unsigned int bw) { for (int i = 0; i < ACCESS_COORDINATE_MAX; i++) { @@ -2206,13 +2218,18 @@ int cxl_endpoint_get_perf_coordinates(struct cxl_port *port, * There's no valid access_coordinate for a root port since RPs do not * have CDAT and therefore needs to be skipped. */ - if (!is_cxl_root) + if (!is_cxl_root) { + if (!coordinates_valid(dport->coord)) + return -EINVAL; cxl_coordinates_combine(c, c, dport->coord); + } add_latency(c, dport->link_latency); } while (!is_cxl_root); dport = iter->parent_dport; /* Retrieve HB coords */ + if (!coordinates_valid(dport->coord)) + return -EINVAL; cxl_coordinates_combine(c, c, dport->coord); /* Get the calculated PCI paths bandwidth */