Commit 45f667eb authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull Compute Express Link (CXL) fixes from Dave Jiang:

 - Adjust the startup priority of cxl_pmem to be higher than that of
   cxl_acpi

 - Use proper endpoint validity check upon sanitize

 - Avoid incorrect DVSEC fallback when HDM decoders are enabled

 - Fix CXL_ACPI and CXL_PMEM Kconfig tristate mismatch

 - Fix leakage in __construct_region()

 - Fix use after free of parent_port in cxl_detach_ep()

* tag 'cxl-fixes-7.0-rc6' of git://git.kernel.org/pub/scm/linux/kernel/git/cxl/cxl:
  cxl: Adjust the startup priority of cxl_pmem to be higher than that of cxl_acpi
  cxl/mbox: Use proper endpoint validity check upon sanitize
  cxl/hdm: Avoid incorrect DVSEC fallback when HDM decoders are enabled
  cxl/acpi: Fix CXL_ACPI and CXL_PMEM Kconfig tristate mismatch
  cxl/region: Fix leakage in __construct_region()
  cxl/port: Fix use after free of parent_port in cxl_detach_ep()
parents e3c33bc7 be5c5280
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -59,6 +59,7 @@ config CXL_ACPI
	tristate "CXL ACPI: Platform Support"
	depends on ACPI
	depends on ACPI_NUMA
	depends on CXL_PMEM || !CXL_PMEM
	default CXL_BUS
	select ACPI_TABLE_LIB
	select ACPI_HMAT
+9 −16
Original line number Diff line number Diff line
@@ -94,7 +94,6 @@ static bool should_emulate_decoders(struct cxl_endpoint_dvsec_info *info)
	struct cxl_hdm *cxlhdm;
	void __iomem *hdm;
	u32 ctrl;
	int i;

	if (!info)
		return false;
@@ -113,22 +112,16 @@ static bool should_emulate_decoders(struct cxl_endpoint_dvsec_info *info)
		return false;

	/*
	 * If any decoders are committed already, there should not be any
	 * emulated DVSEC decoders.
	 * If HDM decoders are globally enabled, do not fall back to DVSEC
	 * range emulation. Zeroed decoder registers after region teardown
	 * do not imply absence of HDM capability.
	 *
	 * Falling back to DVSEC here would treat the decoder as AUTO and
	 * may incorrectly latch default interleave settings.
	 */
	for (i = 0; i < cxlhdm->decoder_count; i++) {
		ctrl = readl(hdm + CXL_HDM_DECODER0_CTRL_OFFSET(i));
		dev_dbg(&info->port->dev,
			"decoder%d.%d: committed: %ld base: %#x_%.8x size: %#x_%.8x\n",
			info->port->id, i,
			FIELD_GET(CXL_HDM_DECODER0_CTRL_COMMITTED, ctrl),
			readl(hdm + CXL_HDM_DECODER0_BASE_HIGH_OFFSET(i)),
			readl(hdm + CXL_HDM_DECODER0_BASE_LOW_OFFSET(i)),
			readl(hdm + CXL_HDM_DECODER0_SIZE_HIGH_OFFSET(i)),
			readl(hdm + CXL_HDM_DECODER0_SIZE_LOW_OFFSET(i)));
		if (FIELD_GET(CXL_HDM_DECODER0_CTRL_COMMITTED, ctrl))
	ctrl = readl(hdm + CXL_HDM_DECODER_CTRL_OFFSET);
	if (ctrl & CXL_HDM_DECODER_ENABLE)
		return false;
	}

	return true;
}
+1 −1
Original line number Diff line number Diff line
@@ -1301,7 +1301,7 @@ int cxl_mem_sanitize(struct cxl_memdev *cxlmd, u16 cmd)
	 * Require an endpoint to be safe otherwise the driver can not
	 * be sure that the device is unmapped.
	 */
	if (endpoint && cxl_num_decoders_committed(endpoint) == 0)
	if (cxlmd->dev.driver && cxl_num_decoders_committed(endpoint) == 0)
		return __cxl_mem_sanitize(mds, cmd);

	return -EBUSY;
+6 −2
Original line number Diff line number Diff line
@@ -552,11 +552,14 @@ static void cxl_port_release(struct device *dev)
	xa_destroy(&port->dports);
	xa_destroy(&port->regions);
	ida_free(&cxl_port_ida, port->id);
	if (is_cxl_root(port))

	if (is_cxl_root(port)) {
		kfree(to_cxl_root(port));
	else
	} else {
		put_device(dev->parent);
		kfree(port);
	}
}

static ssize_t decoders_committed_show(struct device *dev,
				       struct device_attribute *attr, char *buf)
@@ -707,6 +710,7 @@ static struct cxl_port *cxl_port_alloc(struct device *uport_dev,
		struct cxl_port *iter;

		dev->parent = &parent_port->dev;
		get_device(dev->parent);
		port->depth = parent_port->depth + 1;
		port->parent_dport = parent_dport;

+3 −1
Original line number Diff line number Diff line
@@ -3854,8 +3854,10 @@ static int __construct_region(struct cxl_region *cxlr,
	}

	rc = sysfs_update_group(&cxlr->dev.kobj, &cxl_region_group);
	if (rc)
	if (rc) {
		kfree(res);
		return rc;
	}

	rc = insert_resource(cxlrd->res, res);
	if (rc) {
Loading