From: <shiju.jose@huawei.com>
To: <linux-edac@vger.kernel.org>, <linux-cxl@vger.kernel.org>,
<linux-acpi@vger.kernel.org>, <linux-mm@kvack.org>,
<linux-kernel@vger.kernel.org>
Cc: <bp@alien8.de>, <tony.luck@intel.com>, <rafael@kernel.org>,
<lenb@kernel.org>, <mchehab@kernel.org>,
<dan.j.williams@intel.com>, <dave@stgolabs.net>,
<jonathan.cameron@huawei.com>, <dave.jiang@intel.com>,
<alison.schofield@intel.com>, <vishal.l.verma@intel.com>,
<ira.weiny@intel.com>, <david@redhat.com>,
<Vilas.Sridharan@amd.com>, <leo.duran@amd.com>,
<Yazen.Ghannam@amd.com>, <rientjes@google.com>,
<jiaqiyan@google.com>, <Jon.Grimm@amd.com>,
<dave.hansen@linux.intel.com>, <naoya.horiguchi@nec.com>,
<james.morse@arm.com>, <jthoughton@google.com>,
<somasundaram.a@hpe.com>, <erdemaktas@google.com>,
<pgonda@google.com>, <duenwen@google.com>, <gthelen@google.com>,
<wschwartz@amperecomputing.com>, <dferguson@amperecomputing.com>,
<wbs@os.amperecomputing.com>, <nifan.cxl@gmail.com>,
<yazen.ghannam@amd.com>, <tanxiaofei@huawei.com>,
<prime.zeng@hisilicon.com>, <roberto.sassu@huawei.com>,
<kangkang.shen@futurewei.com>, <wanghuiqiang@huawei.com>,
<linuxarm@huawei.com>, <shiju.jose@huawei.com>
Subject: [PATCH v18 10/19] cxl: Add Get Supported Features command for kernel usage
Date: Mon, 6 Jan 2025 12:10:06 +0000 [thread overview]
Message-ID: <20250106121017.1620-11-shiju.jose@huawei.com> (raw)
In-Reply-To: <20250106121017.1620-1-shiju.jose@huawei.com>
From: Dave Jiang <dave.jiang@intel.com>
CXL spec r3.1 8.2.9.6.1 Get Supported Features (Opcode 0500h)
The command retrieve the list of supported device-specific features
(identified by UUID) and general information about each Feature.
The driver will retrieve the feature entries in order to make checks and
provide information for the Get Feature and Set Feature command. One of
the main piece of information retrieved are the effects a Set Feature
command would have for a particular feature.
Co-developed-by: Shiju Jose <shiju.jose@huawei.com>
Signed-off-by: Shiju Jose <shiju.jose@huawei.com>
Signed-off-by: Dave Jiang <dave.jiang@intel.com>
---
drivers/cxl/core/features.c | 28 +++++++
drivers/cxl/core/mbox.c | 3 +-
drivers/cxl/cxl.h | 2 +
drivers/cxl/features.c | 146 +++++++++++++++++++++++++++++++++++-
include/cxl/features.h | 32 ++++++++
5 files changed, 209 insertions(+), 2 deletions(-)
diff --git a/drivers/cxl/core/features.c b/drivers/cxl/core/features.c
index eb6eb191a32e..66a4b82910e6 100644
--- a/drivers/cxl/core/features.c
+++ b/drivers/cxl/core/features.c
@@ -1,6 +1,7 @@
// SPDX-License-Identifier: GPL-2.0-only
/* Copyright(c) 2024-2025 Intel Corporation. All rights reserved. */
#include <linux/device.h>
+#include <cxl/mailbox.h>
#include "cxl.h"
#include "core.h"
@@ -69,3 +70,30 @@ struct cxl_features *cxl_features_alloc(struct cxl_mailbox *cxl_mbox,
return ERR_PTR(rc);
}
EXPORT_SYMBOL_NS_GPL(cxl_features_alloc, "CXL");
+
+struct cxl_feat_entry *
+cxl_get_supported_feature_entry(struct cxl_features *features,
+ const uuid_t *feat_uuid)
+{
+ struct cxl_feat_entry *feat_entry;
+ struct cxl_features_state *cfs;
+ int count;
+
+ cfs = dev_get_drvdata(&features->dev);
+ if (!cfs)
+ return ERR_PTR(-EOPNOTSUPP);
+
+ if (!cfs->num_features)
+ return ERR_PTR(-ENOENT);
+
+ /* Check CXL dev supports the feature */
+ feat_entry = cfs->entries;
+ for (count = 0; count < cfs->num_features;
+ count++, feat_entry++) {
+ if (uuid_equal(&feat_entry->uuid, feat_uuid))
+ return feat_entry;
+ }
+
+ return ERR_PTR(-ENOENT);
+}
+EXPORT_SYMBOL_NS_GPL(cxl_get_supported_feature_entry, "CXL");
diff --git a/drivers/cxl/core/mbox.c b/drivers/cxl/core/mbox.c
index 5e21ff99d70f..0b4946205910 100644
--- a/drivers/cxl/core/mbox.c
+++ b/drivers/cxl/core/mbox.c
@@ -234,7 +234,7 @@ static struct cxl_mem_command *cxl_mem_find_command(u16 opcode)
return NULL;
}
-static struct cxl_mem_command *cxl_find_feature_command(u16 opcode)
+struct cxl_mem_command *cxl_find_feature_command(u16 opcode)
{
struct cxl_mem_command *c;
@@ -244,6 +244,7 @@ static struct cxl_mem_command *cxl_find_feature_command(u16 opcode)
return NULL;
}
+EXPORT_SYMBOL_NS_GPL(cxl_find_feature_command, "CXL");
static const char *cxl_mem_opcode_to_name(u16 opcode)
{
diff --git a/drivers/cxl/cxl.h b/drivers/cxl/cxl.h
index ee29d1a1c8df..1284614d71d0 100644
--- a/drivers/cxl/cxl.h
+++ b/drivers/cxl/cxl.h
@@ -912,6 +912,8 @@ void cxl_coordinates_combine(struct access_coordinate *out,
bool cxl_endpoint_decoder_reset_detected(struct cxl_port *port);
+struct cxl_mem_command *cxl_find_feature_command(u16 opcode);
+
/*
* Unit test builds overrides this to __weak, find the 'strong' version
* of these symbols in tools/testing/cxl/.
diff --git a/drivers/cxl/features.c b/drivers/cxl/features.c
index 93b16b5e2b68..2cdf5ed0a771 100644
--- a/drivers/cxl/features.c
+++ b/drivers/cxl/features.c
@@ -3,20 +3,164 @@
#include <linux/device.h>
#include <linux/module.h>
#include <linux/pci.h>
+#include <cxl/mailbox.h>
#include <cxl/features.h>
#include "cxl.h"
+#include "cxlmem.h"
+
+static void cxl_free_feature_entries(void *entries)
+{
+ kvfree(entries);
+}
+
+static int cxl_get_supported_features_count(struct cxl_mailbox *cxl_mbox)
+{
+ struct cxl_mbox_get_sup_feats_out mbox_out;
+ struct cxl_mbox_get_sup_feats_in mbox_in;
+ struct cxl_mbox_cmd mbox_cmd;
+ int rc;
+
+ memset(&mbox_in, 0, sizeof(mbox_in));
+ mbox_in.count = cpu_to_le32(sizeof(mbox_out));
+ memset(&mbox_out, 0, sizeof(mbox_out));
+ mbox_cmd = (struct cxl_mbox_cmd) {
+ .opcode = CXL_MBOX_OP_GET_SUPPORTED_FEATURES,
+ .size_in = sizeof(mbox_in),
+ .payload_in = &mbox_in,
+ .size_out = sizeof(mbox_out),
+ .payload_out = &mbox_out,
+ .min_out = sizeof(mbox_out),
+ };
+ rc = cxl_internal_send_cmd(cxl_mbox, &mbox_cmd);
+ if (rc < 0)
+ return rc;
+
+ return le16_to_cpu(mbox_out.supported_feats);
+}
+
+static int cxl_get_supported_features(struct cxl_features_state *cfs)
+{
+ int remain_feats, max_size, max_feats, start, rc, hdr_size;
+ struct cxl_mailbox *cxl_mbox = cfs->features->cxl_mbox;
+ int feat_size = sizeof(struct cxl_feat_entry);
+ struct cxl_mbox_get_sup_feats_in mbox_in;
+ struct cxl_feat_entry *entry;
+ struct cxl_mbox_cmd mbox_cmd;
+ struct cxl_mem_command *cmd;
+ int count;
+
+ /* Get supported features is optional, need to check */
+ cmd = cxl_find_feature_command(CXL_MBOX_OP_GET_SUPPORTED_FEATURES);
+ if (!cmd)
+ return -EOPNOTSUPP;
+ if (!test_bit(cmd->info.id, cxl_mbox->feature_cmds))
+ return -EOPNOTSUPP;
+
+ count = cxl_get_supported_features_count(cxl_mbox);
+ if (count == 0)
+ return 0;
+ if (count < 0)
+ return -ENXIO;
+
+ struct cxl_feat_entry *entries __free(kvfree) =
+ kvmalloc(count * sizeof(*entries), GFP_KERNEL);
+ if (!entries)
+ return -ENOMEM;
+
+ struct cxl_mbox_get_sup_feats_out *mbox_out __free(kvfree) =
+ kvmalloc(cxl_mbox->payload_size, GFP_KERNEL);
+ if (!mbox_out)
+ return -ENOMEM;
+
+ hdr_size = sizeof(*mbox_out);
+ max_size = cxl_mbox->payload_size - hdr_size;
+ /* max feat entries that can fit in mailbox max payload size */
+ max_feats = max_size / feat_size;
+ entry = entries;
+
+ start = 0;
+ remain_feats = count;
+ do {
+ int retrieved, alloc_size, copy_feats;
+ int num_entries;
+
+ if (remain_feats > max_feats) {
+ alloc_size = sizeof(*mbox_out) + max_feats * feat_size;
+ remain_feats = remain_feats - max_feats;
+ copy_feats = max_feats;
+ } else {
+ alloc_size = sizeof(*mbox_out) + remain_feats * feat_size;
+ copy_feats = remain_feats;
+ remain_feats = 0;
+ }
+
+ memset(&mbox_in, 0, sizeof(mbox_in));
+ mbox_in.count = cpu_to_le32(alloc_size);
+ mbox_in.start_idx = cpu_to_le16(start);
+ memset(mbox_out, 0, alloc_size);
+ mbox_cmd = (struct cxl_mbox_cmd) {
+ .opcode = CXL_MBOX_OP_GET_SUPPORTED_FEATURES,
+ .size_in = sizeof(mbox_in),
+ .payload_in = &mbox_in,
+ .size_out = alloc_size,
+ .payload_out = mbox_out,
+ .min_out = hdr_size,
+ };
+ rc = cxl_internal_send_cmd(cxl_mbox, &mbox_cmd);
+ if (rc < 0)
+ return rc;
+
+ if (mbox_cmd.size_out <= hdr_size)
+ return -ENXIO;
+
+ /*
+ * Make sure retrieved out buffer is multiple of feature
+ * entries.
+ */
+ retrieved = mbox_cmd.size_out - hdr_size;
+ if (retrieved % feat_size)
+ return -ENXIO;
+
+ num_entries = le16_to_cpu(mbox_out->num_entries);
+ /*
+ * If the reported output entries * defined entry size !=
+ * retrieved output bytes, then the output package is incorrect.
+ */
+ if (num_entries * feat_size != retrieved)
+ return -ENXIO;
+
+ memcpy(entry, mbox_out->ents, retrieved);
+ entry++;
+ /*
+ * If the number of output entries is less than expected, add the
+ * remaining entries to the next batch.
+ */
+ remain_feats += copy_feats - num_entries;
+ start += num_entries;
+ } while (remain_feats);
+
+ cfs->num_features = count;
+ cfs->entries = no_free_ptr(entries);
+ return devm_add_action_or_reset(&cfs->features->dev,
+ cxl_free_feature_entries, cfs->entries);
+}
static int cxl_features_probe(struct device *dev)
{
struct cxl_features *features = to_cxl_features(dev);
+ int rc;
+
struct cxl_features_state *cfs __free(kfree) =
kzalloc(sizeof(*cfs), GFP_KERNEL);
-
if (!cfs)
return -ENOMEM;
cfs->features = features;
+ rc = cxl_get_supported_features(cfs);
+ if (rc)
+ return rc;
+
dev_set_drvdata(dev, no_free_ptr(cfs));
return 0;
diff --git a/include/cxl/features.h b/include/cxl/features.h
index 7a8be3c621a1..429b9782667c 100644
--- a/include/cxl/features.h
+++ b/include/cxl/features.h
@@ -3,6 +3,8 @@
#ifndef __CXL_FEATURES_H__
#define __CXL_FEATURES_H__
+#include <linux/uuid.h>
+
struct cxl_mailbox;
enum feature_cmds {
@@ -19,12 +21,42 @@ struct cxl_features {
};
#define to_cxl_features(dev) container_of(dev, struct cxl_features, dev)
+/* Get Supported Features (0x500h) CXL r3.1 8.2.9.6.1 */
+struct cxl_mbox_get_sup_feats_in {
+ __le32 count;
+ __le16 start_idx;
+ u8 reserved[2];
+} __packed;
+
+struct cxl_feat_entry {
+ uuid_t uuid;
+ __le16 id;
+ __le16 get_feat_size;
+ __le16 set_feat_size;
+ __le32 flags;
+ u8 get_feat_ver;
+ u8 set_feat_ver;
+ __le16 effects;
+ u8 reserved[18];
+} __packed;
+
+struct cxl_mbox_get_sup_feats_out {
+ __le16 num_entries;
+ __le16 supported_feats;
+ u8 reserved[4];
+ struct cxl_feat_entry ents[] __counted_by_le(num_entries);
+} __packed;
+
struct cxl_features_state {
struct cxl_features *features;
int num_features;
+ struct cxl_feat_entry *entries;
};
struct cxl_features *cxl_features_alloc(struct cxl_mailbox *cxl_mbox,
struct device *parent);
+struct cxl_feat_entry *
+cxl_get_supported_feature_entry(struct cxl_features *features,
+ const uuid_t *feat_uuid);
#endif
--
2.43.0
next prev parent reply other threads:[~2025-01-06 12:11 UTC|newest]
Thread overview: 87+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-01-06 12:09 [PATCH v18 00/19] EDAC: Scrub: introduce generic EDAC RAS control feature driver + CXL/ACPI-RAS2 drivers shiju.jose
2025-01-06 12:09 ` [PATCH v18 01/19] EDAC: Add support for EDAC device features control shiju.jose
2025-01-06 13:37 ` Borislav Petkov
2025-01-06 14:48 ` Shiju Jose
2025-01-13 15:06 ` Mauro Carvalho Chehab
2025-01-14 9:55 ` Jonathan Cameron
2025-01-14 10:08 ` Shiju Jose
2025-01-14 11:33 ` Mauro Carvalho Chehab
2025-01-30 19:18 ` Daniel Ferguson
2025-01-06 12:09 ` [PATCH v18 02/19] EDAC: Add scrub control feature shiju.jose
2025-01-06 15:57 ` Borislav Petkov
2025-01-06 19:34 ` Shiju Jose
2025-01-07 7:32 ` Borislav Petkov
2025-01-07 9:23 ` Shiju Jose
2025-01-08 15:47 ` Shiju Jose
2025-01-13 15:50 ` Mauro Carvalho Chehab
2025-01-30 19:18 ` Daniel Ferguson
2025-01-06 12:09 ` [PATCH v18 03/19] EDAC: Add ECS " shiju.jose
2025-01-13 16:09 ` Mauro Carvalho Chehab
2025-01-06 12:10 ` [PATCH v18 04/19] EDAC: Add memory repair " shiju.jose
2025-01-09 9:19 ` Borislav Petkov
2025-01-09 11:00 ` Shiju Jose
2025-01-09 12:32 ` Borislav Petkov
2025-01-09 14:24 ` Jonathan Cameron
2025-01-09 15:18 ` Borislav Petkov
2025-01-09 16:01 ` Jonathan Cameron
2025-01-09 16:19 ` Borislav Petkov
2025-01-09 18:34 ` Jonathan Cameron
2025-01-09 23:51 ` Dan Williams
2025-01-10 11:01 ` Jonathan Cameron
2025-01-10 22:49 ` Dan Williams
2025-01-13 11:40 ` Jonathan Cameron
2025-01-14 19:35 ` Dan Williams
2025-01-15 10:07 ` Jonathan Cameron
2025-01-15 11:35 ` Mauro Carvalho Chehab
2025-01-11 17:12 ` Borislav Petkov
2025-01-13 11:07 ` Jonathan Cameron
2025-01-21 16:16 ` Borislav Petkov
2025-01-21 18:16 ` Jonathan Cameron
2025-01-22 19:09 ` Borislav Petkov
2025-02-06 13:39 ` Jonathan Cameron
2025-02-17 13:23 ` Borislav Petkov
2025-02-18 16:51 ` Jonathan Cameron
2025-02-19 18:45 ` Borislav Petkov
2025-02-20 12:19 ` Jonathan Cameron
2025-01-14 13:10 ` Mauro Carvalho Chehab
2025-01-14 12:57 ` Mauro Carvalho Chehab
2025-01-14 12:38 ` Mauro Carvalho Chehab
2025-01-14 13:05 ` Jonathan Cameron
2025-01-14 14:39 ` Mauro Carvalho Chehab
2025-01-14 11:47 ` Mauro Carvalho Chehab
2025-01-14 12:31 ` Shiju Jose
2025-01-14 14:26 ` Mauro Carvalho Chehab
2025-01-14 13:47 ` Mauro Carvalho Chehab
2025-01-14 14:30 ` Shiju Jose
2025-01-15 12:03 ` Mauro Carvalho Chehab
2025-01-06 12:10 ` [PATCH v18 05/19] ACPI:RAS2: Add ACPI RAS2 driver shiju.jose
2025-01-21 23:01 ` Daniel Ferguson
2025-01-22 15:38 ` Shiju Jose
2025-01-30 19:19 ` Daniel Ferguson
2025-01-06 12:10 ` [PATCH v18 06/19] ras: mem: Add memory " shiju.jose
2025-01-21 23:01 ` Daniel Ferguson
2025-01-30 19:19 ` Daniel Ferguson
2025-01-06 12:10 ` [PATCH v18 07/19] cxl: Refactor user ioctl command path from mds to mailbox shiju.jose
2025-01-06 12:10 ` [PATCH v18 08/19] cxl: Add skeletal features driver shiju.jose
2025-01-06 12:10 ` [PATCH v18 09/19] cxl: Enumerate feature commands shiju.jose
2025-01-06 12:10 ` shiju.jose [this message]
2025-01-06 12:10 ` [PATCH v18 11/19] cxl: Add features driver attribute to emit number of features supported shiju.jose
2025-01-06 12:10 ` [PATCH v18 12/19] cxl/mbox: Add GET_FEATURE mailbox command shiju.jose
2025-01-06 12:10 ` [PATCH v18 13/19] cxl/mbox: Add SET_FEATURE " shiju.jose
2025-01-06 12:10 ` [PATCH v18 14/19] cxl: Setup exclusive CXL features that are reserved for the kernel shiju.jose
2025-01-06 12:10 ` [PATCH v18 15/19] cxl/memfeature: Add CXL memory device patrol scrub control feature shiju.jose
2025-01-24 20:38 ` Dan Williams
2025-01-27 10:06 ` Jonathan Cameron
2025-01-27 12:53 ` Shiju Jose
2025-01-27 23:17 ` Dan Williams
2025-01-29 12:28 ` Shiju Jose
2025-01-06 12:10 ` [PATCH v18 16/19] cxl/memfeature: Add CXL memory device ECS " shiju.jose
2025-01-06 12:10 ` [PATCH v18 17/19] cxl/mbox: Add support for PERFORM_MAINTENANCE mailbox command shiju.jose
2025-01-06 12:10 ` [PATCH v18 18/19] cxl/memfeature: Add CXL memory device soft PPR control feature shiju.jose
2025-01-06 12:10 ` [PATCH v18 19/19] cxl/memfeature: Add CXL memory device memory sparing " shiju.jose
2025-01-13 14:46 ` [PATCH v18 00/19] EDAC: Scrub: introduce generic EDAC RAS control feature driver + CXL/ACPI-RAS2 drivers Mauro Carvalho Chehab
2025-01-13 15:36 ` Jonathan Cameron
2025-01-14 14:06 ` Mauro Carvalho Chehab
2025-01-13 18:15 ` Shiju Jose
2025-01-30 19:18 ` Daniel Ferguson
2025-02-03 9:25 ` Shiju Jose
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=20250106121017.1620-11-shiju.jose@huawei.com \
--to=shiju.jose@huawei.com \
--cc=Jon.Grimm@amd.com \
--cc=Vilas.Sridharan@amd.com \
--cc=Yazen.Ghannam@amd.com \
--cc=alison.schofield@intel.com \
--cc=bp@alien8.de \
--cc=dan.j.williams@intel.com \
--cc=dave.hansen@linux.intel.com \
--cc=dave.jiang@intel.com \
--cc=dave@stgolabs.net \
--cc=david@redhat.com \
--cc=dferguson@amperecomputing.com \
--cc=duenwen@google.com \
--cc=erdemaktas@google.com \
--cc=gthelen@google.com \
--cc=ira.weiny@intel.com \
--cc=james.morse@arm.com \
--cc=jiaqiyan@google.com \
--cc=jonathan.cameron@huawei.com \
--cc=jthoughton@google.com \
--cc=kangkang.shen@futurewei.com \
--cc=lenb@kernel.org \
--cc=leo.duran@amd.com \
--cc=linux-acpi@vger.kernel.org \
--cc=linux-cxl@vger.kernel.org \
--cc=linux-edac@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-mm@kvack.org \
--cc=linuxarm@huawei.com \
--cc=mchehab@kernel.org \
--cc=naoya.horiguchi@nec.com \
--cc=nifan.cxl@gmail.com \
--cc=pgonda@google.com \
--cc=prime.zeng@hisilicon.com \
--cc=rafael@kernel.org \
--cc=rientjes@google.com \
--cc=roberto.sassu@huawei.com \
--cc=somasundaram.a@hpe.com \
--cc=tanxiaofei@huawei.com \
--cc=tony.luck@intel.com \
--cc=vishal.l.verma@intel.com \
--cc=wanghuiqiang@huawei.com \
--cc=wbs@os.amperecomputing.com \
--cc=wschwartz@amperecomputing.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