Commit 8039804c authored by Ben Cheatham's avatar Ben Cheatham Committed by Dan Williams
Browse files

cxl/core: Add CXL EINJ debugfs files



Export CXL helper functions in einj-cxl.c for getting/injecting
available CXL protocol error types to sysfs under kernel/debug/cxl.

The kernel/debug/cxl/einj_types file will print the available CXL
protocol errors in the same format as the available_error_types
file provided by the einj module. The
kernel/debug/cxl/$dport_dev/einj_inject file is functionally the same
as the error_type and error_inject files provided by the EINJ module,
i.e.: writing an error type into $dport_dev/einj_inject will inject
said error type into the CXL dport represented by $dport_dev.

Reviewed-by: default avatarJonathan Cameron <Jonathan.Cameron@huawei.com>
Signed-off-by: default avatarBen Cheatham <Benjamin.Cheatham@amd.com>
Link: https://lore.kernel.org/r/20240311142508.31717-4-Benjamin.Cheatham@amd.com


Signed-off-by: default avatarDan Williams <dan.j.williams@intel.com>
parent 12fb28ea
Loading
Loading
Loading
Loading
+30 −0
Original line number Diff line number Diff line
@@ -33,3 +33,33 @@ Description:
		device cannot clear poison from the address, -ENXIO is returned.
		The clear_poison attribute is only visible for devices
		supporting the capability.

What:		/sys/kernel/debug/cxl/einj_types
Date:		January, 2024
KernelVersion:	v6.9
Contact:	linux-cxl@vger.kernel.org
Description:
		(RO) Prints the CXL protocol error types made available by
		the platform in the format "0x<error number>	<error type>".
		The possible error types are (as of ACPI v6.5):
			0x1000	CXL.cache Protocol Correctable
			0x2000	CXL.cache Protocol Uncorrectable non-fatal
			0x4000	CXL.cache Protocol Uncorrectable fatal
			0x8000	CXL.mem Protocol Correctable
			0x10000	CXL.mem Protocol Uncorrectable non-fatal
			0x20000	CXL.mem Protocol Uncorrectable fatal

		The <error number> can be written to einj_inject to inject
		<error type> into a chosen dport.

What:		/sys/kernel/debug/cxl/$dport_dev/einj_inject
Date:		January, 2024
KernelVersion:	v6.9
Contact:	linux-cxl@vger.kernel.org
Description:
		(WO) Writing an integer to this file injects the corresponding
		CXL protocol error into $dport_dev ($dport_dev will be a device
		name from /sys/bus/pci/devices). The integer to type mapping for
		injection can be found by reading from einj_types. If the dport
		was enumerated in RCH mode, a CXL 1.1 error is injected, otherwise
		a CXL 2.0 error is injected.
+41 −0
Original line number Diff line number Diff line
@@ -3,6 +3,7 @@
#include <linux/platform_device.h>
#include <linux/memregion.h>
#include <linux/workqueue.h>
#include <linux/einj-cxl.h>
#include <linux/debugfs.h>
#include <linux/device.h>
#include <linux/module.h>
@@ -793,6 +794,40 @@ static int cxl_dport_setup_regs(struct device *host, struct cxl_dport *dport,
	return rc;
}

DEFINE_SHOW_ATTRIBUTE(einj_cxl_available_error_type);

static int cxl_einj_inject(void *data, u64 type)
{
	struct cxl_dport *dport = data;

	if (dport->rch)
		return einj_cxl_inject_rch_error(dport->rcrb.base, type);

	return einj_cxl_inject_error(to_pci_dev(dport->dport_dev), type);
}
DEFINE_DEBUGFS_ATTRIBUTE(cxl_einj_inject_fops, NULL, cxl_einj_inject,
			 "0x%llx\n");

static void cxl_debugfs_create_dport_dir(struct cxl_dport *dport)
{
	struct dentry *dir;

	if (!einj_cxl_is_initialized())
		return;

	/*
	 * dport_dev needs to be a PCIe port for CXL 2.0+ ports because
	 * EINJ expects a dport SBDF to be specified for 2.0 error injection.
	 */
	if (!dport->rch && !dev_is_pci(dport->dport_dev))
		return;

	dir = cxl_debugfs_create_dir(dev_name(dport->dport_dev));

	debugfs_create_file("einj_inject", 0200, dir, dport,
			    &cxl_einj_inject_fops);
}

static struct cxl_port *__devm_cxl_add_port(struct device *host,
					    struct device *uport_dev,
					    resource_size_t component_reg_phys,
@@ -1149,6 +1184,8 @@ __devm_cxl_add_dport(struct cxl_port *port, struct device *dport_dev,
	if (dev_is_pci(dport_dev))
		dport->link_latency = cxl_pci_get_latency(to_pci_dev(dport_dev));

	cxl_debugfs_create_dport_dir(dport);

	return dport;
}

@@ -2221,6 +2258,10 @@ static __init int cxl_core_init(void)

	cxl_debugfs = debugfs_create_dir("cxl", NULL);

	if (einj_cxl_is_initialized())
		debugfs_create_file("einj_types", 0400, cxl_debugfs, NULL,
				    &einj_cxl_available_error_type_fops);

	cxl_mbox_init();

	rc = cxl_memdev_init();