From: Ben Cheatham <Benjamin.Cheatham@amd.com>
To: <dave@stgolabs.net>, <jonathan.cameron@huawei.com>,
<dave.jiang@intel.com>, <alison.schofield@intel.com>,
<vishal.l.verma@intel.com>, <ira.weiny@intel.com>,
<dan.j.williams@intel.com>, <rafael@kernel.org>
Cc: <benjamin.cheatham@amd.com>, <yazen.ghannam@amd.com>,
<linux-cxl@vger.kernel.org>, <linux-acpi@vger.kernel.org>
Subject: [PATCH v7 4/5] cxl/port, EINJ: Add CXL EINJ callback functions
Date: Tue, 28 Nov 2023 10:06:55 -0600 [thread overview]
Message-ID: <20231128160656.166609-5-Benjamin.Cheatham@amd.com> (raw)
In-Reply-To: <20231128160656.166609-1-Benjamin.Cheatham@amd.com>
Add functions to the EINJ module to be used in the CXL module for CXL
protocol error injection. The callbacks implement the einj_types and
einj_inject files under /sys/kernel/debug/cxl/portX/dportY. These two
files work in the same way as the available_error_types and error_inject
files under /sys/kernel/debug/apei/einj, but only for CXL error types.
If the dport is enumerated in RCH (CXL 1.1) mode, a CXL 1.1 error is
injected into the dport; a CXL 2.0 error is injected otherwise.
Reviewed-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
Signed-off-by: Ben Cheatham <Benjamin.Cheatham@amd.com>
---
drivers/acpi/apei/Kconfig | 3 ++
drivers/acpi/apei/einj.c | 105 ++++++++++++++++++++++++++++++++++++++
2 files changed, 108 insertions(+)
diff --git a/drivers/acpi/apei/Kconfig b/drivers/acpi/apei/Kconfig
index 6b18f8bc7be3..100c27beb581 100644
--- a/drivers/acpi/apei/Kconfig
+++ b/drivers/acpi/apei/Kconfig
@@ -11,6 +11,9 @@ config ACPI_APEI
select PSTORE
select UEFI_CPER
depends on HAVE_ACPI_APEI
+ imply CXL_BUS
+ imply CXL_ACPI
+ imply CXL_PORT
help
APEI allows to report errors (for example from the chipset)
to the operating system. This improves NMI handling
diff --git a/drivers/acpi/apei/einj.c b/drivers/acpi/apei/einj.c
index 330329ac2f1f..98d5e6d60a02 100644
--- a/drivers/acpi/apei/einj.c
+++ b/drivers/acpi/apei/einj.c
@@ -21,9 +21,11 @@
#include <linux/nmi.h>
#include <linux/delay.h>
#include <linux/mm.h>
+#include <linux/pci.h>
#include <asm/unaligned.h>
#include "apei-internal.h"
+#include "../../cxl/cxl.h"
#undef pr_fmt
#define pr_fmt(fmt) "EINJ: " fmt
@@ -627,6 +629,25 @@ static int available_error_type_show(struct seq_file *m, void *v)
DEFINE_SHOW_ATTRIBUTE(available_error_type);
+static int cxl_einj_available_error_type(struct seq_file *m, void *v)
+{
+ int cxl_err, rc;
+ u32 available_error_type = 0;
+
+ rc = einj_get_available_error_type(&available_error_type);
+ if (rc)
+ return rc;
+
+ for (int pos = 0; pos < ARRAY_SIZE(einj_cxl_error_type_string); pos++) {
+ cxl_err = ACPI_EINJ_CXL_CACHE_CORRECTABLE << pos;
+
+ if (available_error_type & cxl_err)
+ seq_puts(m, einj_cxl_error_type_string[pos]);
+ }
+
+ return 0;
+}
+
static int validate_error_type(u64 type)
{
u32 tval, vendor, available_error_type = 0;
@@ -657,6 +678,68 @@ static int validate_error_type(u64 type)
return 0;
}
+static int cxl_dport_get_sbdf(struct cxl_dport *dport, u64 *sbdf)
+{
+ struct pci_dev *pdev;
+ struct pci_bus *pbus;
+ struct pci_host_bridge *bridge;
+ u64 seg = 0, bus;
+
+ if (!dev_is_pci(dport->dport_dev))
+ return -EINVAL;
+
+ pdev = to_pci_dev(dport->dport_dev);
+ pbus = pdev->bus;
+ bridge = pci_find_host_bridge(pbus);
+
+ if (!bridge)
+ return -ENODEV;
+
+ if (bridge->domain_nr != PCI_DOMAIN_NR_NOT_SET)
+ seg = bridge->domain_nr << 24;
+
+ bus = pbus->number << 16;
+ *sbdf = seg | bus | pdev->devfn;
+
+ return 0;
+}
+
+static int cxl_einj_inject_error(struct cxl_dport *dport, u64 type)
+{
+ u64 param1 = 0, param2 = 0, param4 = 0;
+ u32 flags;
+ int rc;
+
+ /* Only CXL error types can be specified */
+ if (type & ~CXL_ERROR_MASK || (type & ACPI5_VENDOR_BIT))
+ return -EINVAL;
+
+ rc = validate_error_type(type);
+ if (rc)
+ return rc;
+
+ /*
+ * If dport is in restricted mode, inject a CXL 1.1 error,
+ * otherwise inject a CXL 2.0 error
+ */
+ if (dport->rch) {
+ if (dport->rcrb.base == CXL_RESOURCE_NONE)
+ return -EINVAL;
+
+ param1 = (u64) dport->rcrb.base;
+ param2 = 0xfffffffffffff000;
+ flags = 0x2;
+ } else {
+ rc = cxl_dport_get_sbdf(dport, ¶m4);
+ if (rc)
+ return rc;
+
+ flags = 0x4;
+ }
+
+ return einj_error_inject(type, flags, param1, param2, 0, param4);
+}
+
static int error_type_get(void *data, u64 *val)
{
*val = error_type;
@@ -668,6 +751,7 @@ static int error_type_set(void *data, u64 val)
{
int rc;
+ /* CXL error types have to be injected from cxl debugfs */
if (val & CXL_ERROR_MASK && !(val & ACPI5_VENDOR_BIT))
return -EINVAL;
@@ -714,6 +798,7 @@ static int __init einj_init(void)
{
int rc;
acpi_status status;
+ struct cxl_einj_ops cxl_ops;
struct apei_exec_context ctx;
if (acpi_disabled) {
@@ -793,6 +878,15 @@ static int __init einj_init(void)
einj_debug_dir, &vendor_flags);
}
+ if (IS_REACHABLE(CONFIG_CXL_ACPI) || IS_REACHABLE(CONFIG_CXL_PORT)) {
+ cxl_ops = (struct cxl_einj_ops) {
+ .einj_type = cxl_einj_available_error_type,
+ .einj_inject = cxl_einj_inject_error,
+ };
+
+ cxl_einj_set_ops_cbs(&cxl_ops);
+ }
+
pr_info("Error INJection is initialized.\n");
return 0;
@@ -810,8 +904,18 @@ static int __init einj_init(void)
static void __exit einj_exit(void)
{
+ struct cxl_einj_ops cxl_ops;
struct apei_exec_context ctx;
+ if (IS_REACHABLE(CONFIG_CXL_ACPI) || IS_REACHABLE(CONFIG_CXL_PORT)) {
+ cxl_ops = (struct cxl_einj_ops) {
+ .einj_type = NULL,
+ .einj_inject = NULL,
+ };
+
+ cxl_einj_set_ops_cbs(&cxl_ops);
+ }
+
if (einj_param) {
acpi_size size = (acpi5) ?
sizeof(struct set_error_type_with_address) :
@@ -832,4 +936,5 @@ module_exit(einj_exit);
MODULE_AUTHOR("Huang Ying");
MODULE_DESCRIPTION("APEI Error INJection support");
+MODULE_IMPORT_NS(CXL);
MODULE_LICENSE("GPL");
--
2.34.1
next prev parent reply other threads:[~2023-11-28 16:08 UTC|newest]
Thread overview: 16+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-11-28 16:06 [PATCH v7 0/5] CXL, ACPI, APEI, EINJ: Update EINJ for CXL error types Ben Cheatham
2023-11-28 16:06 ` [PATCH v7 1/5] cxl/port: Add EINJ debugfs files and callback support Ben Cheatham
2023-12-07 23:13 ` Dan Williams
2023-12-08 16:22 ` Ben Cheatham
2023-12-08 18:01 ` Dan Williams
2023-12-08 20:35 ` Ben Cheatham
2023-12-08 22:27 ` Ben Cheatham
2023-12-09 0:07 ` Dan Williams
2023-11-28 16:06 ` [PATCH v7 2/5] ACPI: Add CXL protocol error defines Ben Cheatham
2023-12-07 23:28 ` Dan Williams
2023-11-28 16:06 ` [PATCH v7 3/5] EINJ: Separate CXL errors from other EINJ errors Ben Cheatham
2023-12-07 23:30 ` Dan Williams
2023-11-28 16:06 ` Ben Cheatham [this message]
2023-12-08 0:03 ` [PATCH v7 4/5] cxl/port, EINJ: Add CXL EINJ callback functions Dan Williams
2023-12-08 16:22 ` Ben Cheatham
2023-11-28 16:06 ` [PATCH v7 5/5] EINJ: Update EINJ documentation Ben Cheatham
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20231128160656.166609-5-Benjamin.Cheatham@amd.com \
--to=benjamin.cheatham@amd.com \
--cc=alison.schofield@intel.com \
--cc=dan.j.williams@intel.com \
--cc=dave.jiang@intel.com \
--cc=dave@stgolabs.net \
--cc=ira.weiny@intel.com \
--cc=jonathan.cameron@huawei.com \
--cc=linux-acpi@vger.kernel.org \
--cc=linux-cxl@vger.kernel.org \
--cc=rafael@kernel.org \
--cc=vishal.l.verma@intel.com \
--cc=yazen.ghannam@amd.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.