From: Dave Jiang <dave.jiang@intel.com>
To: Vishal Verma <vishal.l.verma@intel.com>,
Alison Schofield <alison.schofield@intel.com>,
Ira Weiny <ira.weiny@intel.com>,
Ben Widawsky <bwidawsk@kernel.org>,
Dan Williams <dan.j.williams@intel.com>
Cc: <linux-cxl@vger.kernel.org>, <linux-kernel@vger.kernel.org>,
"Davidlohr Bueso" <dave@stgolabs.net>,
Jonathan Cameron <Jonathan.Cameron@Huawei.com>,
Russ Weight <russell.h.weight@intel.com>
Subject: Re: [PATCH v3 4/4] tools/testing/cxl: add firmware update emulation to CXL memdevs
Date: Tue, 13 Jun 2023 11:41:13 -0700 [thread overview]
Message-ID: <3093d78c-6edc-4b87-f5f4-cddb84999f2e@intel.com> (raw)
In-Reply-To: <20230602-vv-fw_update-v3-4-869f82069c95@intel.com>
On 6/11/23 23:55, Vishal Verma wrote:
> Add emulation for the 'Get FW Info', 'Transfer FW', and 'Activate FW'
> CXL mailbox commands to the cxl_test emulated memdevs to enable
> end-to-end unit testing of a firmware update flow. For now, only
> advertise an 'offline activation' capability as that is all the CXL
> memdev driver currently implements.
>
> Add some canned values for the serial number fields, and create a
> platform device sysfs knob to calculate the sha256sum of the firmware
> image that was received, so a unit test can compare it with the original
> file that was uploaded.
>
> Cc: Davidlohr Bueso <dave@stgolabs.net>
> Cc: Jonathan Cameron <Jonathan.Cameron@Huawei.com>
> Cc: Russ Weight <russell.h.weight@intel.com>
> Cc: Alison Schofield <alison.schofield@intel.com>
> Cc: Ira Weiny <ira.weiny@intel.com>
> Cc: Dave Jiang <dave.jiang@intel.com>
> Cc: Ben Widawsky <bwidawsk@kernel.org>
> Cc: Dan Williams <dan.j.williams@intel.com>
> Reviewed-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
> Signed-off-by: Vishal Verma <vishal.l.verma@intel.com>
Reviewed-by: Dave Jiang <dave.jiang@intel.com>
> ---
> tools/testing/cxl/test/mem.c | 160 +++++++++++++++++++++++++++++++++++++++++++
> 1 file changed, 160 insertions(+)
>
> diff --git a/tools/testing/cxl/test/mem.c b/tools/testing/cxl/test/mem.c
> index 68668d8df1cd..1166f470e0c7 100644
> --- a/tools/testing/cxl/test/mem.c
> +++ b/tools/testing/cxl/test/mem.c
> @@ -8,11 +8,14 @@
> #include <linux/sizes.h>
> #include <linux/bits.h>
> #include <asm/unaligned.h>
> +#include <crypto/sha2.h>
> #include <cxlmem.h>
>
> #include "trace.h"
>
> #define LSA_SIZE SZ_128K
> +#define FW_SIZE SZ_64M
> +#define FW_SLOTS 3
> #define DEV_SIZE SZ_2G
> #define EFFECT(x) (1U << x)
>
> @@ -72,6 +75,20 @@ static struct cxl_cel_entry mock_cel[] = {
> .opcode = cpu_to_le16(CXL_MBOX_OP_CLEAR_POISON),
> .effect = cpu_to_le16(EFFECT(DATA_CHANGE_IMMEDIATE)),
> },
> + {
> + .opcode = cpu_to_le16(CXL_MBOX_OP_GET_FW_INFO),
> + .effect = CXL_CMD_EFFECT_NONE,
> + },
> + {
> + .opcode = cpu_to_le16(CXL_MBOX_OP_TRANSFER_FW),
> + .effect = cpu_to_le16(EFFECT(CONF_CHANGE_COLD_RESET) |
> + EFFECT(BACKGROUND_OP)),
> + },
> + {
> + .opcode = cpu_to_le16(CXL_MBOX_OP_ACTIVATE_FW),
> + .effect = cpu_to_le16(EFFECT(CONF_CHANGE_COLD_RESET) |
> + EFFECT(CONF_CHANGE_IMMEDIATE)),
> + },
> };
>
> /* See CXL 2.0 Table 181 Get Health Info Output Payload */
> @@ -123,6 +140,10 @@ struct mock_event_store {
>
> struct cxl_mockmem_data {
> void *lsa;
> + void *fw;
> + int fw_slot;
> + int fw_staged;
> + size_t fw_size;
> u32 security_state;
> u8 user_pass[NVDIMM_PASSPHRASE_LEN];
> u8 master_pass[NVDIMM_PASSPHRASE_LEN];
> @@ -1128,6 +1149,87 @@ static struct attribute *cxl_mock_mem_core_attrs[] = {
> };
> ATTRIBUTE_GROUPS(cxl_mock_mem_core);
>
> +static int mock_fw_info(struct cxl_dev_state *cxlds,
> + struct cxl_mbox_cmd *cmd)
> +{
> + struct cxl_mockmem_data *mdata = dev_get_drvdata(cxlds->dev);
> + struct cxl_mbox_get_fw_info fw_info = {
> + .num_slots = FW_SLOTS,
> + .slot_info = (mdata->fw_slot & 0x7) |
> + ((mdata->fw_staged & 0x7) << 3),
> + .activation_cap = 0,
> + };
> +
> + strcpy(fw_info.slot_1_revision, "cxl_test_fw_001");
> + strcpy(fw_info.slot_2_revision, "cxl_test_fw_002");
> + strcpy(fw_info.slot_3_revision, "cxl_test_fw_003");
> + strcpy(fw_info.slot_4_revision, "");
> +
> + if (cmd->size_out < sizeof(fw_info))
> + return -EINVAL;
> +
> + memcpy(cmd->payload_out, &fw_info, sizeof(fw_info));
> + return 0;
> +}
> +
> +static int mock_transfer_fw(struct cxl_dev_state *cxlds,
> + struct cxl_mbox_cmd *cmd)
> +{
> + struct cxl_mbox_transfer_fw *transfer = cmd->payload_in;
> + struct cxl_mockmem_data *mdata = dev_get_drvdata(cxlds->dev);
> + void *fw = mdata->fw;
> + size_t offset, length;
> +
> + offset = le32_to_cpu(transfer->offset) * CXL_FW_TRANSFER_ALIGNMENT;
> + length = cmd->size_in - sizeof(*transfer);
> + if (offset + length > FW_SIZE)
> + return -EINVAL;
> +
> + switch (transfer->action) {
> + case CXL_FW_TRANSFER_ACTION_FULL:
> + if (offset != 0)
> + return -EINVAL;
> + fallthrough;
> + case CXL_FW_TRANSFER_ACTION_END:
> + if (transfer->slot == 0 || transfer->slot > FW_SLOTS)
> + return -EINVAL;
> + mdata->fw_size = offset + length;
> + break;
> + case CXL_FW_TRANSFER_ACTION_INITIATE:
> + case CXL_FW_TRANSFER_ACTION_CONTINUE:
> + break;
> + case CXL_FW_TRANSFER_ACTION_ABORT:
> + return 0;
> + default:
> + return -EINVAL;
> + }
> +
> + memcpy(fw + offset, transfer->data, length);
> + return 0;
> +}
> +
> +static int mock_activate_fw(struct cxl_dev_state *cxlds,
> + struct cxl_mbox_cmd *cmd)
> +{
> + struct cxl_mbox_activate_fw *activate = cmd->payload_in;
> + struct cxl_mockmem_data *mdata = dev_get_drvdata(cxlds->dev);
> +
> + if (activate->slot == 0 || activate->slot > FW_SLOTS)
> + return -EINVAL;
> +
> + switch (activate->action) {
> + case CXL_FW_ACTIVATE_ONLINE:
> + mdata->fw_slot = activate->slot;
> + mdata->fw_staged = 0;
> + return 0;
> + case CXL_FW_ACTIVATE_OFFLINE:
> + mdata->fw_staged = activate->slot;
> + return 0;
> + }
> +
> + return -EINVAL;
> +}
> +
> static int cxl_mock_mbox_send(struct cxl_dev_state *cxlds, struct cxl_mbox_cmd *cmd)
> {
> struct device *dev = cxlds->dev;
> @@ -1194,6 +1296,15 @@ static int cxl_mock_mbox_send(struct cxl_dev_state *cxlds, struct cxl_mbox_cmd *
> case CXL_MBOX_OP_CLEAR_POISON:
> rc = mock_clear_poison(cxlds, cmd);
> break;
> + case CXL_MBOX_OP_GET_FW_INFO:
> + rc = mock_fw_info(cxlds, cmd);
> + break;
> + case CXL_MBOX_OP_TRANSFER_FW:
> + rc = mock_transfer_fw(cxlds, cmd);
> + break;
> + case CXL_MBOX_OP_ACTIVATE_FW:
> + rc = mock_activate_fw(cxlds, cmd);
> + break;
> default:
> break;
> }
> @@ -1209,6 +1320,11 @@ static void label_area_release(void *lsa)
> vfree(lsa);
> }
>
> +static void fw_buf_release(void *buf)
> +{
> + vfree(buf);
> +}
> +
> static bool is_rcd(struct platform_device *pdev)
> {
> const struct platform_device_id *id = platform_get_device_id(pdev);
> @@ -1241,10 +1357,19 @@ static int cxl_mock_mem_probe(struct platform_device *pdev)
> mdata->lsa = vmalloc(LSA_SIZE);
> if (!mdata->lsa)
> return -ENOMEM;
> + mdata->fw = vmalloc(FW_SIZE);
> + if (!mdata->fw)
> + return -ENOMEM;
> + mdata->fw_slot = 2;
> +
> rc = devm_add_action_or_reset(dev, label_area_release, mdata->lsa);
> if (rc)
> return rc;
>
> + rc = devm_add_action_or_reset(dev, fw_buf_release, mdata->fw);
> + if (rc)
> + return rc;
> +
> cxlds = cxl_dev_state_create(dev);
> if (IS_ERR(cxlds))
> return PTR_ERR(cxlds);
> @@ -1286,6 +1411,10 @@ static int cxl_mock_mem_probe(struct platform_device *pdev)
> if (IS_ERR(cxlmd))
> return PTR_ERR(cxlmd);
>
> + rc = cxl_memdev_setup_fw_upload(cxlds);
> + if (rc)
> + return rc;
> +
> cxl_mem_get_event_records(cxlds, CXLDEV_EVENT_STATUS_ALL);
>
> return 0;
> @@ -1324,9 +1453,40 @@ static ssize_t security_lock_store(struct device *dev, struct device_attribute *
>
> static DEVICE_ATTR_RW(security_lock);
>
> +static ssize_t fw_buf_checksum_show(struct device *dev,
> + struct device_attribute *attr, char *buf)
> +{
> + struct cxl_mockmem_data *mdata = dev_get_drvdata(dev);
> + u8 hash[SHA256_DIGEST_SIZE];
> + unsigned char *hstr, *hptr;
> + struct sha256_state sctx;
> + ssize_t written = 0;
> + int i;
> +
> + sha256_init(&sctx);
> + sha256_update(&sctx, mdata->fw, mdata->fw_size);
> + sha256_final(&sctx, hash);
> +
> + hstr = kzalloc((SHA256_DIGEST_SIZE * 2) + 1, GFP_KERNEL);
> + if (!hstr)
> + return -ENOMEM;
> +
> + hptr = hstr;
> + for (i = 0; i < SHA256_DIGEST_SIZE; i++)
> + hptr += sprintf(hptr, "%02x", hash[i]);
> +
> + written = sysfs_emit(buf, "%s\n", hstr);
> +
> + kfree(hstr);
> + return written;
> +}
> +
> +static DEVICE_ATTR_RO(fw_buf_checksum);
> +
> static struct attribute *cxl_mock_mem_attrs[] = {
> &dev_attr_security_lock.attr,
> &dev_attr_event_trigger.attr,
> + &dev_attr_fw_buf_checksum.attr,
> NULL
> };
> ATTRIBUTE_GROUPS(cxl_mock_mem);
>
prev parent reply other threads:[~2023-06-13 18:41 UTC|newest]
Thread overview: 11+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-06-12 6:55 [PATCH v3 0/4] cxl: Add a firmware update mechanism and cxl_test emulation Vishal Verma
2023-06-12 6:55 ` [PATCH v3 1/4] cxl: add a firmware update mechanism using the sysfs firmware loader Vishal Verma
2023-06-13 18:34 ` Dave Jiang
2023-06-14 14:14 ` Jonathan Cameron
2023-06-14 17:15 ` Verma, Vishal L
2023-06-12 6:55 ` [PATCH v3 2/4] tools/testing/cxl: Fix command effects for inject/clear poison Vishal Verma
2023-06-13 18:37 ` Dave Jiang
2023-06-12 6:55 ` [PATCH v3 3/4] tools/testing/cxl: Use named effects for the Command Effect Log Vishal Verma
2023-06-13 18:38 ` Dave Jiang
2023-06-12 6:55 ` [PATCH v3 4/4] tools/testing/cxl: add firmware update emulation to CXL memdevs Vishal Verma
2023-06-13 18:41 ` Dave Jiang [this message]
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=3093d78c-6edc-4b87-f5f4-cddb84999f2e@intel.com \
--to=dave.jiang@intel.com \
--cc=Jonathan.Cameron@Huawei.com \
--cc=alison.schofield@intel.com \
--cc=bwidawsk@kernel.org \
--cc=dan.j.williams@intel.com \
--cc=dave@stgolabs.net \
--cc=ira.weiny@intel.com \
--cc=linux-cxl@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=russell.h.weight@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