linux-pci.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Ben Widawsky <ben.widawsky@intel.com>
To: linux-cxl@vger.kernel.org
Cc: Ben Widawsky <ben.widawsky@intel.com>,
	linux-acpi@vger.kernel.org, linux-kernel@vger.kernel.org,
	linux-nvdimm@lists.01.org, linux-pci@vger.kernel.org,
	Bjorn Helgaas <helgaas@kernel.org>,
	Chris Browy <cbrowy@avery-design.com>,
	Christoph Hellwig <hch@infradead.org>,
	Dan Williams <dan.j.williams@intel.com>,
	Ira Weiny <ira.weiny@intel.com>, Jon Masters <jcm@jonmasters.org>,
	Jonathan Cameron <Jonathan.Cameron@Huawei.com>,
	Rafael Wysocki <rafael.j.wysocki@intel.com>,
	Randy Dunlap <rdunlap@infradead.org>,
	Vishal Verma <vishal.l.verma@intel.com>,
	daniel.lll@alibaba-inc.com,
	"John Groves (jgroves)" <jgroves@micron.com>,
	"Kelley, Sean V" <sean.v.kelley@intel.com>
Subject: [PATCH 11/14] cxl/mem: Use CEL for enabling commands
Date: Fri, 29 Jan 2021 16:24:35 -0800	[thread overview]
Message-ID: <20210130002438.1872527-12-ben.widawsky@intel.com> (raw)
In-Reply-To: <20210130002438.1872527-1-ben.widawsky@intel.com>

The Command Effects Log (CEL) is specified in the CXL 2.0 specification.
The CEL is one of two types of logs, the other being vendor specific.
They are distinguished in hardware/spec via UUID. The CEL is immediately
useful for 2 things:
1. Determine which optional commands are supported by the CXL device.
2. Enumerate any vendor specific commands

The CEL can be used by the driver to determine which commands are
available in the hardware (though it isn't, yet). That set of commands
might itself be a subset of commands which are available to be used via
CXL_MEM_SEND_COMMAND IOCTL.

Prior to this, all commands that the driver exposed were explicitly
enabled. After this, only those commands that are found in the CEL are
enabled.

Signed-off-by: Ben Widawsky <ben.widawsky@intel.com>
---
 drivers/cxl/mem.c            | 186 ++++++++++++++++++++++++++++++++++-
 include/uapi/linux/cxl_mem.h |   1 +
 2 files changed, 182 insertions(+), 5 deletions(-)

diff --git a/drivers/cxl/mem.c b/drivers/cxl/mem.c
index d01c6ee32a6b..787417c4d5dc 100644
--- a/drivers/cxl/mem.c
+++ b/drivers/cxl/mem.c
@@ -43,6 +43,8 @@ enum opcode {
 	CXL_MBOX_OP_INVALID		= 0x0000,
 #define CXL_MBOX_OP_RAW		CXL_MBOX_OP_INVALID
 	CXL_MBOX_OP_ACTIVATE_FW		= 0x0202,
+	CXL_MBOX_OP_GET_SUPPORTED_LOGS	= 0x0400,
+	CXL_MBOX_OP_GET_LOG		= 0x0401,
 	CXL_MBOX_OP_IDENTIFY		= 0x4000,
 	CXL_MBOX_OP_SET_PARTITION_INFO	= 0x4101,
 	CXL_MBOX_OP_SET_LSA		= 0x4103,
@@ -101,6 +103,18 @@ static DEFINE_IDA(cxl_memdev_ida);
 static struct dentry *cxl_debugfs;
 static bool raw_allow_all;
 
+enum {
+	CEL_UUID,
+	DEBUG_UUID
+};
+
+static const uuid_t log_uuid[] = {
+	[CEL_UUID] = UUID_INIT(0xda9c0b5, 0xbf41, 0x4b78, 0x8f, 0x79, 0x96,
+			       0xb1, 0x62, 0x3b, 0x3f, 0x17),
+	[DEBUG_UUID] = UUID_INIT(0xe1819d9, 0x11a9, 0x400c, 0x81, 0x1f, 0xd6,
+				 0x07, 0x19, 0x40, 0x3d, 0x86)
+};
+
 /**
  * struct cxl_mem_command - Driver representation of a memory device command
  * @info: Command information as it exists for the UAPI
@@ -153,6 +167,7 @@ static struct cxl_mem_command mem_commands[] = {
 	CXL_CMD(INVALID, KERNEL, 0, 0, HIDDEN),
 	CXL_CMD(IDENTIFY, NONE, 0, 0x43, MANDATORY),
 	CXL_CMD(RAW, NONE, ~0, ~0, PSEUDO),
+	CXL_CMD(GET_SUPPORTED_LOGS, NONE, 0, ~0, MANDATORY),
 };
 
 /*
@@ -1168,6 +1183,101 @@ static int cxl_mem_add_memdev(struct cxl_mem *cxlm)
 	return rc;
 }
 
+struct cxl_mbox_get_supported_logs {
+	__le16 entries;
+	u8 rsvd[6];
+	struct gsl_entry {
+		uuid_t uuid;
+		__le32 size;
+	} __packed entry[2];
+} __packed;
+struct cxl_mbox_get_log {
+	uuid_t uuid;
+	__le32 offset;
+	__le32 length;
+} __packed;
+
+static int cxl_xfer_log(struct cxl_mem *cxlm, uuid_t *uuid, u32 size, u8 *out)
+{
+	u32 remaining = size;
+	u32 offset = 0;
+
+	while (remaining) {
+		u32 xfer_size = min_t(u32, remaining, cxlm->mbox.payload_size);
+		struct mbox_cmd mbox_cmd;
+		int rc;
+		struct cxl_mbox_get_log log = {
+			.uuid = *uuid,
+			.offset = cpu_to_le32(offset),
+			.length = cpu_to_le32(xfer_size)
+		};
+
+		mbox_cmd = (struct mbox_cmd) {
+			.opcode = CXL_MBOX_OP_GET_LOG,
+			.payload_in = &log,
+			.payload_out = out,
+			.size_in = sizeof(log),
+		};
+
+		rc = cxl_mem_mbox_send_cmd(cxlm, &mbox_cmd);
+		if (rc)
+			return rc;
+
+		WARN_ON(mbox_cmd.size_out != xfer_size);
+
+		out += xfer_size;
+		remaining -= xfer_size;
+		offset += xfer_size;
+	}
+
+	return 0;
+}
+
+static void cxl_enable_cmd(struct cxl_mem *cxlm,
+			   const struct cxl_mem_command *cmd)
+{
+	if (test_and_set_bit(cmd->info.id, cxlm->enabled_cmds))
+		dev_warn(&cxlm->pdev->dev, "Command enabled twice\n");
+
+	dev_info(&cxlm->pdev->dev, "%s enabled",
+		 cxl_command_names[cmd->info.id].name);
+}
+
+/**
+ * cxl_walk_cel() - Walk through the Command Effects Log.
+ * @cxlm: Device.
+ * @size: Length of the Command Effects Log.
+ * @cel: CEL
+ *
+ * Iterate over each entry in the CEL and determine if the driver supports the
+ * command. If so, the command is enabled for the device and can be used later.
+ */
+static void cxl_walk_cel(struct cxl_mem *cxlm, size_t size, u8 *cel)
+{
+	struct cel_entry {
+		__le16 opcode;
+		__le16 effect;
+	} *cel_entry;
+	const int cel_entries = size / sizeof(*cel_entry);
+	int i;
+
+	cel_entry = (struct cel_entry *)cel;
+
+	for (i = 0; i < cel_entries; i++) {
+		const struct cel_entry *ce = &cel_entry[i];
+		const struct cxl_mem_command *cmd =
+			cxl_mem_find_command(le16_to_cpu(ce->opcode));
+
+		if (!cmd) {
+			dev_dbg(&cxlm->pdev->dev, "Unsupported opcode 0x%04x",
+				le16_to_cpu(ce->opcode));
+			continue;
+		}
+
+		cxl_enable_cmd(cxlm, cmd);
+	}
+}
+
 /**
  * cxl_mem_enumerate_cmds() - Enumerate commands for a device.
  * @cxlm: The device.
@@ -1180,19 +1290,85 @@ static int cxl_mem_add_memdev(struct cxl_mem *cxlm)
  */
 static int cxl_mem_enumerate_cmds(struct cxl_mem *cxlm)
 {
-	struct cxl_mem_command *c;
+	struct cxl_mbox_get_supported_logs gsl;
+	const struct cxl_mem_command *c;
+	struct mbox_cmd mbox_cmd;
+	int i, rc;
 
 	BUILD_BUG_ON(ARRAY_SIZE(mem_commands) >= CXL_MAX_COMMANDS);
 
-	/* All commands are considered enabled for now (except INVALID). */
+	/* Pseudo commands are always enabled */
 	cxl_for_each_cmd(c) {
-		if (c->flags & CXL_CMD_INTERNAL_FLAG_HIDDEN)
+		if (c->flags & CXL_CMD_INTERNAL_FLAG_PSEUDO)
+			cxl_enable_cmd(cxlm, c);
+	}
+
+	mbox_cmd = (struct mbox_cmd){
+		.opcode = CXL_MBOX_OP_GET_SUPPORTED_LOGS,
+		.payload_out = &gsl,
+		.size_in = 0,
+	};
+
+	rc = cxl_mem_mbox_get(cxlm);
+	if (rc)
+		return rc;
+
+	rc = cxl_mem_mbox_send_cmd(cxlm, &mbox_cmd);
+	if (rc)
+		goto out;
+
+	if (mbox_cmd.return_code != CXL_MBOX_SUCCESS) {
+		rc = -ENXIO;
+		goto out;
+	}
+
+	if (mbox_cmd.size_out > sizeof(gsl)) {
+		dev_warn(&cxlm->pdev->dev, "%zu excess logs\n",
+			 (mbox_cmd.size_out - sizeof(gsl)) /
+				 sizeof(struct gsl_entry));
+	}
+
+	for (i = 0; i < le16_to_cpu(gsl.entries); i++) {
+		u32 size = le32_to_cpu(gsl.entry[i].size);
+		uuid_t uuid = gsl.entry[i].uuid;
+		u8 *log;
+
+		dev_dbg(&cxlm->pdev->dev, "Found LOG type %pU of size %d",
+			&uuid, size);
+
+		if (!uuid_equal(&uuid, &log_uuid[CEL_UUID]))
 			continue;
 
-		set_bit(c->info.id, cxlm->enabled_cmds);
+		/*
+		 * It's a hardware bug if the log size is less than the input
+		 * payload size because there are many mandatory commands.
+		 */
+		if (sizeof(struct cxl_mbox_get_log) > size) {
+			dev_err(&cxlm->pdev->dev,
+				"CEL log size reported was too small (%d)",
+				size);
+			rc = -ENOMEM;
+			goto out;
+		}
+
+		log = kvmalloc(size, GFP_KERNEL);
+		if (!log) {
+			rc = -ENOMEM;
+			goto out;
+		}
+
+		rc = cxl_xfer_log(cxlm, &uuid, size, log);
+		if (rc)
+			goto out;
+
+		cxl_walk_cel(cxlm, size, log);
+
+		kvfree(log);
 	}
 
-	return 0;
+out:
+	cxl_mem_mbox_put(cxlm);
+	return rc;
 }
 
 /**
diff --git a/include/uapi/linux/cxl_mem.h b/include/uapi/linux/cxl_mem.h
index 25bfcb071c1f..64cb9753a077 100644
--- a/include/uapi/linux/cxl_mem.h
+++ b/include/uapi/linux/cxl_mem.h
@@ -34,6 +34,7 @@ extern "C" {
 	___C(INVALID, "Invalid Command"),                                 \
 	___C(IDENTIFY, "Identify Command"),                               \
 	___C(RAW, "Raw device command"),                                  \
+	___C(GET_SUPPORTED_LOGS, "Get Supported Logs"),                   \
 	___C(MAX, "Last command")
 
 #define ___C(a, b) CXL_MEM_COMMAND_ID_##a
-- 
2.30.0


  parent reply	other threads:[~2021-01-30  0:37 UTC|newest]

Thread overview: 96+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-01-30  0:24 [PATCH 00/14] CXL 2.0 Support Ben Widawsky
2021-01-30  0:24 ` [PATCH 01/14] cxl/mem: Introduce a driver for CXL-2.0-Type-3 endpoints Ben Widawsky
2021-01-30 23:51   ` David Rientjes
2021-02-01 17:21   ` Jonathan Cameron
2021-02-01 17:34   ` Konrad Rzeszutek Wilk
2021-02-02 17:58     ` Christoph Hellwig
2021-02-02 18:00   ` Christoph Hellwig
2021-01-30  0:24 ` [PATCH 02/14] cxl/mem: Map memory device registers Ben Widawsky
2021-01-30 23:51   ` David Rientjes
2021-02-01 16:46     ` Ben Widawsky
2021-02-01 18:19       ` Jonathan Cameron
2021-02-01 17:36   ` Konrad Rzeszutek Wilk
2021-02-02 18:04   ` Christoph Hellwig
2021-02-02 18:31     ` Ben Widawsky
2021-02-03 17:12       ` Christoph Hellwig
2021-01-30  0:24 ` [PATCH 03/14] cxl/mem: Find device capabilities Ben Widawsky
2021-01-30 23:51   ` David Rientjes
2021-02-01 16:53     ` Ben Widawsky
2021-02-01 21:51       ` David Rientjes
2021-02-01 21:58         ` Ben Widawsky
2021-02-01 22:23           ` David Rientjes
2021-02-01 22:28             ` Ben Widawsky
2021-02-01 22:33               ` Ben Widawsky
2021-02-01 22:45                 ` David Rientjes
2021-02-01 22:50                   ` Ben Widawsky
2021-02-01 23:09                     ` David Rientjes
2021-02-01 23:17                       ` Ben Widawsky
2021-02-01 23:58                         ` David Rientjes
2021-02-02  0:11                           ` Ben Widawsky
2021-02-02  0:14                             ` Dan Williams
2021-02-02  1:09                               ` David Rientjes
2021-02-01 22:02         ` Dan Williams
2021-02-01 17:41   ` Konrad Rzeszutek Wilk
2021-02-01 17:50     ` Ben Widawsky
2021-02-01 18:08       ` Konrad Rzeszutek Wilk
2021-02-02 18:10   ` Christoph Hellwig
2021-02-02 18:24     ` Ben Widawsky
2021-02-03 17:15       ` Christoph Hellwig
2021-02-03 17:23         ` Ben Widawsky
2021-02-03 21:23           ` Dan Williams
2021-02-04  7:16             ` Christoph Hellwig
2021-02-04 15:29               ` Ben Widawsky
2021-01-30  0:24 ` [PATCH 04/14] cxl/mem: Implement polled mode mailbox Ben Widawsky
2021-01-30 23:51   ` David Rientjes
2021-02-01 20:00     ` Dan Williams
2021-02-02 22:57       ` Ben Widawsky
2021-02-02 23:54         ` Dan Williams
2021-02-03  0:54           ` Ben Widawsky
2021-02-02 22:50     ` Ben Widawsky
2021-02-01 17:54   ` Konrad Rzeszutek Wilk
2021-02-01 19:13     ` Ben Widawsky
2021-02-01 19:28       ` Dan Williams
     [not found]         ` <SN6PR08MB46052FE9BC20A747CACD8F50D1B39@SN6PR08MB4605.namprd08.prod.outlook.com>
2021-02-04 22:24           ` [EXT] " Ben Widawsky
2021-01-30  0:24 ` [PATCH 05/14] cxl/mem: Register CXL memX devices Ben Widawsky
2021-01-30  0:31   ` Dan Williams
2021-01-30 23:52   ` David Rientjes
2021-02-01 17:10     ` Ben Widawsky
2021-02-01 21:53       ` David Rientjes
2021-02-01 21:55         ` Dan Williams
2021-02-02 18:13   ` Christoph Hellwig
2021-01-30  0:24 ` [PATCH 06/14] cxl/mem: Add basic IOCTL interface Ben Widawsky
2021-02-02 18:15   ` Christoph Hellwig
2021-02-02 18:33     ` Ben Widawsky
2021-01-30  0:24 ` [PATCH 07/14] cxl/mem: Add send command Ben Widawsky
2021-02-01 18:15   ` Konrad Rzeszutek Wilk
2021-02-02 23:08     ` Ben Widawsky
2021-01-30  0:24 ` [PATCH 08/14] taint: add taint for direct hardware access Ben Widawsky
2021-02-01 18:18   ` Konrad Rzeszutek Wilk
2021-02-01 18:34     ` Ben Widawsky
2021-02-01 19:01       ` Dan Williams
2021-02-02  2:49         ` Konrad Rzeszutek Wilk
2021-02-02 17:46           ` Dan Williams
2021-02-08 22:00   ` Dan Williams
2021-02-08 22:09     ` Kees Cook
2021-02-08 23:05       ` Ben Widawsky
2021-02-08 23:36       ` Dan Williams
2021-02-09  1:03         ` Dan Williams
2021-02-09  3:36           ` Ben Widawsky
2021-01-30  0:24 ` [PATCH 09/14] cxl/mem: Add a "RAW" send command Ben Widawsky
2021-02-01 18:24   ` Konrad Rzeszutek Wilk
2021-02-01 19:27     ` Ben Widawsky
2021-02-01 19:34       ` Konrad Rzeszutek Wilk
2021-02-01 21:20         ` Dan Williams
2021-01-30  0:24 ` [PATCH 10/14] cxl/mem: Create concept of enabled commands Ben Widawsky
2021-01-30  0:24 ` Ben Widawsky [this message]
2021-01-30  0:24 ` [PATCH 12/14] cxl/mem: Add set of informational commands Ben Widawsky
2021-01-30  0:24 ` [PATCH 13/14] cxl/mem: Add limited Get Log command (0401h) Ben Widawsky
2021-02-01 18:28   ` Konrad Rzeszutek Wilk
2021-02-02 23:51     ` Ben Widawsky
2021-02-02 23:57       ` Dan Williams
2021-02-03 17:16         ` Ben Widawsky
2021-02-03 18:14           ` Konrad Rzeszutek Wilk
2021-02-03 20:31             ` Dan Williams
2021-02-04 18:55               ` Ben Widawsky
2021-02-04 21:01                 ` Dan Williams
2021-01-30  0:24 ` [PATCH 14/14] MAINTAINERS: Add maintainers of the CXL driver Ben Widawsky

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=20210130002438.1872527-12-ben.widawsky@intel.com \
    --to=ben.widawsky@intel.com \
    --cc=Jonathan.Cameron@Huawei.com \
    --cc=cbrowy@avery-design.com \
    --cc=dan.j.williams@intel.com \
    --cc=daniel.lll@alibaba-inc.com \
    --cc=hch@infradead.org \
    --cc=helgaas@kernel.org \
    --cc=ira.weiny@intel.com \
    --cc=jcm@jonmasters.org \
    --cc=jgroves@micron.com \
    --cc=linux-acpi@vger.kernel.org \
    --cc=linux-cxl@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-nvdimm@lists.01.org \
    --cc=linux-pci@vger.kernel.org \
    --cc=rafael.j.wysocki@intel.com \
    --cc=rdunlap@infradead.org \
    --cc=sean.v.kelley@intel.com \
    --cc=vishal.l.verma@intel.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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).