From patchwork Fri Mar 10 18:49:02 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alison Schofield X-Patchwork-Id: 13169957 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 1D92AC74A44 for ; Fri, 10 Mar 2023 18:49:28 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230229AbjCJSt1 (ORCPT ); Fri, 10 Mar 2023 13:49:27 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:37294 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229589AbjCJSt0 (ORCPT ); Fri, 10 Mar 2023 13:49:26 -0500 Received: from mga12.intel.com (mga12.intel.com [192.55.52.136]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 66E13E190D for ; Fri, 10 Mar 2023 10:49:25 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1678474165; x=1710010165; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=Io4XAc3eyT8VA8FYIWrI43jwi/ifWRXfGUE4mU8olQg=; b=j+I/m3inqzxCH6R6OGr0soRYK/Wcs6XFfGA/JtguTXZ/92w9oz4WGne6 RvbgV7S8dNJty6MHHMFJv+33AW4inNpseIxGDlJ7Edo/X5WGuRydgXKBH 8BOkX4T7xrpuiViP/wTOb3QMD8ltILrc2C4FJD3KEanuXIrfCCr9SCQ4M EIszqul9dZVIWwQtK6jCD9CZtHXKEUNol84wxkrZ6Nj/MYjip7FsMSPQP +HDeA7dzB6N2LxUdv2p5Vs6FMrOEvlFIXujjVoXtaGr4gTDdnWTcRzrbt PFp3nrDLR8vZOX/ZeXTdjj9aQnzKa5Pf7StkK5PedWXUzqtx87jwGsKDp w==; X-IronPort-AV: E=McAfee;i="6500,9779,10645"; a="316452278" X-IronPort-AV: E=Sophos;i="5.98,250,1673942400"; d="scan'208";a="316452278" Received: from fmsmga007.fm.intel.com ([10.253.24.52]) by fmsmga106.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 10 Mar 2023 10:49:24 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=McAfee;i="6500,9779,10645"; a="680292287" X-IronPort-AV: E=Sophos;i="5.98,250,1673942400"; d="scan'208";a="680292287" Received: from aschofie-mobl2.amr.corp.intel.com (HELO localhost) ([10.255.228.62]) by fmsmga007-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 10 Mar 2023 10:49:23 -0800 From: alison.schofield@intel.com To: Dan Williams , Ira Weiny , Vishal Verma , Ben Widawsky , Dave Jiang Cc: Alison Schofield , linux-cxl@vger.kernel.org, Jonathan Cameron Subject: [PATCH v4 1/8] cxl/memdev: Add support for the Inject Poison mailbox command Date: Fri, 10 Mar 2023 10:49:02 -0800 Message-Id: <5e17d5f924ebeb2ba03b4c501bc3cf4fa2bb60f0.1678471465.git.alison.schofield@intel.com> X-Mailer: git-send-email 2.37.3 In-Reply-To: References: MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-cxl@vger.kernel.org From: Alison Schofield CXL devices optionally support the INJECT POISON mailbox command. Add a sysfs attribute and memdev driver support for injecting poison. The attribute is only visible for devices supporting the capability when the kernel is built with CONFIG_CXL_POISON_INJECT. When a Device Physical Address (DPA) is written to the inject_poison sysfs attribute, send an inject poison command to the device for the specified address. Per the CXL Specification (3.0 8.2.9.8.4.2), after receiving a valid inject poison request, the device will return poison when the address is accessed through the CXL.mem bus. Injecting poison adds the address to the device's Poison List and the error source is set to Injected. In addition, the device adds a poison creation event to its internal Informational Event log, updates the Event Status register, and if configured, interrupts the host. Also, per the CXL Specification, it is not an error to inject poison into an address that already has poison present and no error is returned from the device. Signed-off-by: Alison Schofield Reviewed-by: Jonathan Cameron --- Documentation/ABI/testing/sysfs-bus-cxl | 22 ++++++ drivers/cxl/Kconfig | 11 +++ drivers/cxl/core/memdev.c | 97 +++++++++++++++++++++++++ drivers/cxl/cxlmem.h | 5 ++ 4 files changed, 135 insertions(+) diff --git a/Documentation/ABI/testing/sysfs-bus-cxl b/Documentation/ABI/testing/sysfs-bus-cxl index 02776fee6d4c..e82bbc90390d 100644 --- a/Documentation/ABI/testing/sysfs-bus-cxl +++ b/Documentation/ABI/testing/sysfs-bus-cxl @@ -429,3 +429,25 @@ Description: attribute is only visible for devices supporting the capability. The retrieved errors are logged as kernel trace events with the label 'cxl_poison'. + + +What: /sys/bus/cxl/devices/memX/inject_poison +Date: March, 2023 +KernelVersion: v6.4 +Contact: linux-cxl@vger.kernel.org +Description: + (WO) When a Device Physical Address (DPA) is written to this + attribute, the memdev driver sends an inject poison command to + the device for the specified address. The DPA must be 64-byte + aligned and the length of the injected poison is 64-bytes. If + successful, the device returns poison when the address is + accessed through the CXL.mem bus. Injecting poison adds the + address to the device's Poison List and the error source is set + to Injected. In addition, the device adds a poison creation + event to its internal Informational Event log, updates the + Event Status register, and if configured, interrupts the host. + It is not an error to inject poison into an address that + already has poison present and no error is returned. The + inject_poison attribute is only visible for devices supporting + the capability. Kconfig option CXL_POISON_INJECT must be on + to enable this option. The default is off. diff --git a/drivers/cxl/Kconfig b/drivers/cxl/Kconfig index ff4e78117b31..a7ca0bbb8475 100644 --- a/drivers/cxl/Kconfig +++ b/drivers/cxl/Kconfig @@ -139,4 +139,15 @@ config CXL_REGION_INVALIDATION_TEST If unsure, or if this kernel is meant for production environments, say N. +config CXL_POISON_INJECT + bool "CXL: Support CXL Memory Device Poison Inject" + depends on CXL_MEM + help + Selecting this option creates the sysfs attributes inject_poison + and clear_poison for CXL memory devices supporting the capability. + This option is intended for debug scenarios only and is disabled + by default. See Documentation/ABI/testing/sysfs-bus-cxl. + + If unsure, say N. + endif diff --git a/drivers/cxl/core/memdev.c b/drivers/cxl/core/memdev.c index 5e65818d2171..5ea175ef5e6b 100644 --- a/drivers/cxl/core/memdev.c +++ b/drivers/cxl/core/memdev.c @@ -168,6 +168,92 @@ static ssize_t trigger_poison_list_store(struct device *dev, } static DEVICE_ATTR_WO(trigger_poison_list); +static int cxl_dpa_mapped(struct device *dev, void *data) +{ + struct cxl_endpoint_decoder *cxled; + u64 *dpa = data; + + if (!is_endpoint_decoder(dev)) + return 0; + + cxled = to_cxl_endpoint_decoder(dev); + if (!cxled->dpa_res || !resource_size(cxled->dpa_res)) + return 0; + + if (*dpa <= cxled->dpa_res->end && *dpa >= cxled->dpa_res->start) { + dev_dbg(dev, "dpa:0x%llx mapped in region:%s\n", + *dpa, dev_name(&cxled->cxld.region->dev)); + return 1; + } + + return 0; +} + +static int cxl_validate_poison_dpa(struct cxl_memdev *cxlmd, u64 dpa) +{ + struct cxl_dev_state *cxlds = cxlmd->cxlds; + struct cxl_port *port; + int rc; + + if (!resource_size(&cxlds->dpa_res)) { + dev_dbg(cxlds->dev, "device has no dpa resource\n"); + return -EINVAL; + } + if (dpa < cxlds->dpa_res.start || dpa > cxlds->dpa_res.end) { + dev_dbg(cxlds->dev, "dpa:0x%llx not in resource:%pR\n", + dpa, &cxlds->dpa_res); + return -EINVAL; + } + if (!IS_ALIGNED(dpa, 64)) { + dev_dbg(cxlds->dev, "dpa:0x%llx is not 64-byte aligned\n", dpa); + return -EINVAL; + } + port = dev_get_drvdata(&cxlmd->dev); + if (port && is_cxl_endpoint(port) && port->commit_end != -1) { + rc = device_for_each_child(&port->dev, &dpa, cxl_dpa_mapped); + if (rc) + return -EINVAL; + } + + return 0; +} + +static ssize_t inject_poison_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t len) +{ + struct cxl_memdev *cxlmd = to_cxl_memdev(dev); + struct cxl_mbox_inject_poison inject; + struct cxl_mbox_cmd mbox_cmd; + u64 dpa; + int rc; + + rc = kstrtou64(buf, 0, &dpa); + if (rc) + return rc; + + down_read(&cxl_dpa_rwsem); + rc = cxl_validate_poison_dpa(cxlmd, dpa); + if (rc) { + up_read(&cxl_dpa_rwsem); + return rc; + } + + inject = (struct cxl_mbox_inject_poison) { + .address = cpu_to_le64(dpa) + }; + mbox_cmd = (struct cxl_mbox_cmd) { + .opcode = CXL_MBOX_OP_INJECT_POISON, + .size_in = sizeof(inject), + .payload_in = &inject, + }; + rc = cxl_internal_send_cmd(cxlmd->cxlds, &mbox_cmd); + + up_read(&cxl_dpa_rwsem); + return rc ? rc : len; +} +static DEVICE_ATTR_WO(inject_poison); + static struct attribute *cxl_memdev_attributes[] = { &dev_attr_serial.attr, &dev_attr_firmware_version.attr, @@ -175,6 +261,7 @@ static struct attribute *cxl_memdev_attributes[] = { &dev_attr_label_storage_size.attr, &dev_attr_numa_node.attr, &dev_attr_trigger_poison_list.attr, + &dev_attr_inject_poison.attr, NULL, }; @@ -201,6 +288,16 @@ static umode_t cxl_memdev_visible(struct kobject *kobj, struct attribute *a, to_cxl_memdev(dev)->cxlds->enabled_cmds)) return 0; } + if (a == &dev_attr_inject_poison.attr) { + struct device *dev = kobj_to_dev(kobj); + + if (!IS_ENABLED(CONFIG_CXL_POISON_INJECT)) + return 0; + + if (!test_bit(CXL_MEM_COMMAND_ID_INJECT_POISON, + to_cxl_memdev(dev)->cxlds->enabled_cmds)) + return 0; + } return a->mode; } diff --git a/drivers/cxl/cxlmem.h b/drivers/cxl/cxlmem.h index a6eb1b42eb88..01d27f362cd6 100644 --- a/drivers/cxl/cxlmem.h +++ b/drivers/cxl/cxlmem.h @@ -602,6 +602,11 @@ struct cxl_mbox_poison_payload_out { #define CXL_POISON_SOURCE_INJECTED 3 #define CXL_POISON_SOURCE_VENDOR 7 +/* Inject & Clear Poison CXL 3.0 Spec 8.2.9.8.4.2/3 */ +struct cxl_mbox_inject_poison { + __le64 address; +}; + /** * struct cxl_mem_command - Driver representation of a memory device command * @info: Command information as it exists for the UAPI From patchwork Fri Mar 10 18:49:03 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alison Schofield X-Patchwork-Id: 13169956 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 66C15C6FA99 for ; Fri, 10 Mar 2023 18:49:29 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230245AbjCJSt2 (ORCPT ); Fri, 10 Mar 2023 13:49:28 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:37304 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229589AbjCJSt2 (ORCPT ); Fri, 10 Mar 2023 13:49:28 -0500 Received: from mga12.intel.com (mga12.intel.com [192.55.52.136]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id EB18DE190D for ; Fri, 10 Mar 2023 10:49:26 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1678474166; x=1710010166; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=coP8Dj9fVFKw2AdhTjSXNfCbezadZAo7RdO+AQhrLdM=; b=cQ60wb+9Eu8KqcRTZIFnmW/hVamB8twRybpxENcmIKbahTzAvMtZyQGp 5HpRIT3ZUPBd49kyF2ChhxGRDSuFT2gyy8jlRlHWqbimjJIOWb6Reyu1r JLgQAw1KTiTbPBDk9tVef1P2Vb7ebdOTnLaLDBhWktn0lbMl0Q4gjGiFn lLDrZDSpSDqnNVoaIV2kmTxK+5QSaAbxQBNEJkoFbem6NyjXQgQdBXdds Aw2ZDvqcz1qi3jjCkYwDw6i6rPdlDmyPGH9JKi1z2wBoJwesw2uZkkNX7 ebxxeEW/gqQvNM2RJvPn5QP5sS0XPgOYkGa9GP/WOZhEu9iSYTE4B0JRK w==; X-IronPort-AV: E=McAfee;i="6500,9779,10645"; a="316452294" X-IronPort-AV: E=Sophos;i="5.98,250,1673942400"; d="scan'208";a="316452294" Received: from fmsmga007.fm.intel.com ([10.253.24.52]) by fmsmga106.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 10 Mar 2023 10:49:26 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=McAfee;i="6500,9779,10645"; a="680292294" X-IronPort-AV: E=Sophos;i="5.98,250,1673942400"; d="scan'208";a="680292294" Received: from aschofie-mobl2.amr.corp.intel.com (HELO localhost) ([10.255.228.62]) by fmsmga007-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 10 Mar 2023 10:49:25 -0800 From: alison.schofield@intel.com To: Dan Williams , Ira Weiny , Vishal Verma , Ben Widawsky , Dave Jiang Cc: Alison Schofield , linux-cxl@vger.kernel.org, Jonathan Cameron Subject: [PATCH v4 2/8] cxl/memdev: Add support for the Clear Poison mailbox command Date: Fri, 10 Mar 2023 10:49:03 -0800 Message-Id: <98843b78e53834be2d79a95c6b6a51cea295fc2b.1678471465.git.alison.schofield@intel.com> X-Mailer: git-send-email 2.37.3 In-Reply-To: References: MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-cxl@vger.kernel.org From: Alison Schofield CXL devices optionally support the CLEAR POISON mailbox command. Add a sysfs attribute and memdev driver support for clearing poison. The attribute is only visible for devices supporting the capability when the kernel is built with CONFIG_CXL_POISON_INJECT. When a Device Physical Address (DPA) is written to the clear_poison sysfs attribute, send a clear poison command to the device for the specified address. Per the CXL Specification (3.0 8.2.9.8.4.3), after receiving a valid clear poison request, the device removes the address from the device's Poison List and writes 0 (zero) for 64 bytes starting at address. If the device cannot clear poison from the address, it returns a permanent media error and -ENXIO is returned to the user. Additionally, and per the spec also, it is not an error to clear poison of an address that is not poisoned. In this case, the device does not overwrite the address and the device does not return an error. *Implementation note: Although the CXL specification defines the clear command to accept 64 bytes of 'write-data' to be used when clearing the poisoned address, this implementation always uses 0 (zeros) for the write-data. Signed-off-by: Alison Schofield Reviewed-by: Jonathan Cameron --- Documentation/ABI/testing/sysfs-bus-cxl | 18 ++++++++ drivers/cxl/core/memdev.c | 59 +++++++++++++++++++++++++ drivers/cxl/cxlmem.h | 6 +++ 3 files changed, 83 insertions(+) diff --git a/Documentation/ABI/testing/sysfs-bus-cxl b/Documentation/ABI/testing/sysfs-bus-cxl index e82bbc90390d..d277f18699be 100644 --- a/Documentation/ABI/testing/sysfs-bus-cxl +++ b/Documentation/ABI/testing/sysfs-bus-cxl @@ -451,3 +451,21 @@ Description: inject_poison attribute is only visible for devices supporting the capability. Kconfig option CXL_POISON_INJECT must be on to enable this option. The default is off. + + +What: /sys/bus/cxl/devices/memX/clear_poison +Date: March, 2023 +KernelVersion: v6.4 +Contact: linux-cxl@vger.kernel.org +Description: + (WO) When a Device Physical Address (DPA) is written to this + attribute, the memdev driver sends a clear poison command to + the device for the specified address. Clearing poison removes + the address from the device's Poison List and writes 0 (zero) + for 64 bytes starting at address. It is not an error to clear + poison from an address that does not have poison set, and if + poison was not set, the address is not overwritten. If the + device cannot clear poison from the address, -ENXIO is returned. + The clear_poison attribute is only visible for devices + supporting the capability. Kconfig option CXL_POISON_INJECT + must be on to enable this option. The default is off. diff --git a/drivers/cxl/core/memdev.c b/drivers/cxl/core/memdev.c index 5ea175ef5e6b..5dd334c4caf2 100644 --- a/drivers/cxl/core/memdev.c +++ b/drivers/cxl/core/memdev.c @@ -254,6 +254,53 @@ static ssize_t inject_poison_store(struct device *dev, } static DEVICE_ATTR_WO(inject_poison); +static ssize_t clear_poison_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t len) +{ + struct cxl_memdev *cxlmd = to_cxl_memdev(dev); + struct cxl_mbox_clear_poison clear; + struct cxl_mbox_cmd mbox_cmd; + u64 dpa; + int rc; + + rc = kstrtou64(buf, 0, &dpa); + if (rc) + return rc; + + down_read(&cxl_dpa_rwsem); + rc = cxl_validate_poison_dpa(cxlmd, dpa); + if (rc) { + up_read(&cxl_dpa_rwsem); + return rc; + } + + /* + * In CXL 3.0 Spec 8.2.9.8.4.3, the Clear Poison mailbox command + * is defined to accept 64 bytes of 'write-data', along with the + * address to clear. The device writes the data into the address + * atomically, while clearing poison if the location is marked as + * being poisoned. + * + * Always use '0' for the write-data. + */ + clear = (struct cxl_mbox_clear_poison) { + .address = cpu_to_le64(dpa) + }; + + mbox_cmd = (struct cxl_mbox_cmd) { + .opcode = CXL_MBOX_OP_CLEAR_POISON, + .size_in = sizeof(clear), + .payload_in = &clear, + }; + + rc = cxl_internal_send_cmd(cxlmd->cxlds, &mbox_cmd); + + up_read(&cxl_dpa_rwsem); + return rc ? rc : len; +} +static DEVICE_ATTR_WO(clear_poison); + static struct attribute *cxl_memdev_attributes[] = { &dev_attr_serial.attr, &dev_attr_firmware_version.attr, @@ -262,6 +309,7 @@ static struct attribute *cxl_memdev_attributes[] = { &dev_attr_numa_node.attr, &dev_attr_trigger_poison_list.attr, &dev_attr_inject_poison.attr, + &dev_attr_clear_poison.attr, NULL, }; @@ -298,6 +346,17 @@ static umode_t cxl_memdev_visible(struct kobject *kobj, struct attribute *a, to_cxl_memdev(dev)->cxlds->enabled_cmds)) return 0; } + if (a == &dev_attr_clear_poison.attr) { + struct device *dev = kobj_to_dev(kobj); + + if (!IS_ENABLED(CONFIG_CXL_POISON_INJECT)) + return 0; + + if (!test_bit(CXL_MEM_COMMAND_ID_CLEAR_POISON, + to_cxl_memdev(dev)->cxlds->enabled_cmds)) { + return 0; + } + } return a->mode; } diff --git a/drivers/cxl/cxlmem.h b/drivers/cxl/cxlmem.h index 01d27f362cd6..8a15274789a6 100644 --- a/drivers/cxl/cxlmem.h +++ b/drivers/cxl/cxlmem.h @@ -607,6 +607,12 @@ struct cxl_mbox_inject_poison { __le64 address; }; +/* Clear Poison CXL 3.0 Spec 8.2.9.8.4.3 */ +struct cxl_mbox_clear_poison { + __le64 address; + u8 write_data[CXL_POISON_LEN_MULT]; +} __packed; + /** * struct cxl_mem_command - Driver representation of a memory device command * @info: Command information as it exists for the UAPI From patchwork Fri Mar 10 18:49:04 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alison Schofield X-Patchwork-Id: 13169959 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 7A091C74A44 for ; Fri, 10 Mar 2023 18:49:32 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230284AbjCJStb (ORCPT ); Fri, 10 Mar 2023 13:49:31 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:37374 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230325AbjCJStb (ORCPT ); Fri, 10 Mar 2023 13:49:31 -0500 Received: from mga12.intel.com (mga12.intel.com [192.55.52.136]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 52329111B07 for ; Fri, 10 Mar 2023 10:49:29 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1678474169; x=1710010169; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=l5qydJc2qTxClYAA3khPwiAT8pVGyO4LrUT5kTe7wxc=; b=aN5g1dVPSbFExoqv07IpEq6U3Z9XLKog97Htqtn/necaRpvy2gvzkgmu OBQUM8+2qcsTCstyOjUc6GfHpz0WuYTk2cZVKC0wU9UYzeX69ZfHA6dwV oL/+dbyZ5GDAZcgsa9izS/yrwemc5vjU2rMogHoSBL4B7skSBTrpAB6YQ kzpojgGH2Q91vl5bNzKu0aj/y0wlfSK3ZGAGAXgKGd2+dZ6ZDtBlUXPnS IhJmhPzoXp64FZzoAuSKFLT7cHRt5cmZUsVGsOx3M9aB6vFPlgdyhEPUC yGooDIJHy661YYbRQwraUiL269Wu7cpQGjA6fTjDLvFN9RK/WsWmrnq5h g==; X-IronPort-AV: E=McAfee;i="6500,9779,10645"; a="316452314" X-IronPort-AV: E=Sophos;i="5.98,250,1673942400"; d="scan'208";a="316452314" Received: from fmsmga007.fm.intel.com ([10.253.24.52]) by fmsmga106.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 10 Mar 2023 10:49:27 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=McAfee;i="6500,9779,10645"; a="680292302" X-IronPort-AV: E=Sophos;i="5.98,250,1673942400"; d="scan'208";a="680292302" Received: from aschofie-mobl2.amr.corp.intel.com (HELO localhost) ([10.255.228.62]) by fmsmga007-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 10 Mar 2023 10:49:27 -0800 From: alison.schofield@intel.com To: Dan Williams , Ira Weiny , Vishal Verma , Ben Widawsky , Dave Jiang Cc: Alison Schofield , linux-cxl@vger.kernel.org, Jonathan Cameron Subject: [PATCH v4 3/8] tools/testing/cxl: Mock the Inject Poison mailbox command Date: Fri, 10 Mar 2023 10:49:04 -0800 Message-Id: <3326dba0f9522d081284606d233cfd62ff4e1330.1678471465.git.alison.schofield@intel.com> X-Mailer: git-send-email 2.37.3 In-Reply-To: References: MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-cxl@vger.kernel.org From: Alison Schofield Mock the injection of poison by storing the device:address entries in mock_poison_list[]. Enforce a limit of 8 poison injections per memdev device and 128 total entries for the cxl_test mock driver. Introducing the mock_poison[] list here, makes it available for use in the mock of Clear Poison, and the mock of Get Poison List. Signed-off-by: Alison Schofield Reviewed-by: Jonathan Cameron --- tools/testing/cxl/test/mem.c | 77 ++++++++++++++++++++++++++++++++++++ 1 file changed, 77 insertions(+) diff --git a/tools/testing/cxl/test/mem.c b/tools/testing/cxl/test/mem.c index 2fa9c18d4c2c..4fca886e2a7c 100644 --- a/tools/testing/cxl/test/mem.c +++ b/tools/testing/cxl/test/mem.c @@ -16,6 +16,9 @@ #define DEV_SIZE SZ_2G #define EFFECT(x) (1U << x) +#define MOCK_INJECT_DEV_MAX 8 +#define MOCK_INJECT_TEST_MAX 128 + static struct cxl_cel_entry mock_cel[] = { { .opcode = cpu_to_le16(CXL_MBOX_OP_GET_SUPPORTED_LOGS), @@ -45,6 +48,10 @@ static struct cxl_cel_entry mock_cel[] = { .opcode = cpu_to_le16(CXL_MBOX_OP_GET_POISON), .effect = cpu_to_le16(0), }, + { + .opcode = cpu_to_le16(CXL_MBOX_OP_INJECT_POISON), + .effect = cpu_to_le16(0), + }, }; /* See CXL 2.0 Table 181 Get Health Info Output Payload */ @@ -474,6 +481,7 @@ static int mock_id(struct cxl_dev_state *cxlds, struct cxl_mbox_cmd *cmd) cpu_to_le64(SZ_256M / CXL_CAPACITY_MULTIPLIER), .total_capacity = cpu_to_le64(DEV_SIZE / CXL_CAPACITY_MULTIPLIER), + .inject_poison_limit = cpu_to_le16(MOCK_INJECT_DEV_MAX), }; put_unaligned_le24(CXL_POISON_LIST_MAX, id.poison_list_max_mer); @@ -895,6 +903,11 @@ static int mock_health_info(struct cxl_dev_state *cxlds, return 0; } +static struct mock_poison { + struct cxl_dev_state *cxlds; + u64 dpa; +} mock_poison_list[MOCK_INJECT_TEST_MAX]; + static int mock_get_poison(struct cxl_dev_state *cxlds, struct cxl_mbox_cmd *cmd) { @@ -923,6 +936,67 @@ static int mock_get_poison(struct cxl_dev_state *cxlds, return 0; } +static bool mock_poison_dev_max_injected(struct cxl_dev_state *cxlds) +{ + int count = 0; + + for (int i = 0; i < MOCK_INJECT_TEST_MAX; i++) { + if (mock_poison_list[i].cxlds == cxlds) + count++; + } + return (count >= MOCK_INJECT_DEV_MAX); +} + +static bool mock_poison_add(struct cxl_dev_state *cxlds, u64 dpa) +{ + if (mock_poison_dev_max_injected(cxlds)) { + dev_dbg(cxlds->dev, + "Device poison injection limit has been reached: %d\n", + MOCK_INJECT_DEV_MAX); + return false; + } + + for (int i = 0; i < MOCK_INJECT_TEST_MAX; i++) { + if (!mock_poison_list[i].cxlds) { + mock_poison_list[i].cxlds = cxlds; + mock_poison_list[i].dpa = dpa; + return true; + } + } + dev_dbg(cxlds->dev, + "Mock test poison injection limit has been reached: %d\n", + MOCK_INJECT_TEST_MAX); + + return false; +} + +static bool mock_poison_found(struct cxl_dev_state *cxlds, u64 dpa) +{ + for (int i = 0; i < MOCK_INJECT_TEST_MAX; i++) { + if (mock_poison_list[i].cxlds == cxlds && + mock_poison_list[i].dpa == dpa) + return true; + } + return false; +} + +static int mock_inject_poison(struct cxl_dev_state *cxlds, + struct cxl_mbox_cmd *cmd) +{ + struct cxl_mbox_inject_poison *pi = cmd->payload_in; + u64 dpa = le64_to_cpu(pi->address); + + if (mock_poison_found(cxlds, dpa)) { + /* Not an error to inject poison if already poisoned */ + dev_dbg(cxlds->dev, "DPA: 0x%llx already poisoned\n", dpa); + return 0; + } + if (!mock_poison_add(cxlds, dpa)) + return -ENXIO; + + return 0; +} + static int cxl_mock_mbox_send(struct cxl_dev_state *cxlds, struct cxl_mbox_cmd *cmd) { struct device *dev = cxlds->dev; @@ -980,6 +1054,9 @@ static int cxl_mock_mbox_send(struct cxl_dev_state *cxlds, struct cxl_mbox_cmd * case CXL_MBOX_OP_GET_POISON: rc = mock_get_poison(cxlds, cmd); break; + case CXL_MBOX_OP_INJECT_POISON: + rc = mock_inject_poison(cxlds, cmd); + break; default: break; } From patchwork Fri Mar 10 18:49:05 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alison Schofield X-Patchwork-Id: 13169958 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 9EA1EC6FD19 for ; Fri, 10 Mar 2023 18:49:31 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230256AbjCJSta (ORCPT ); Fri, 10 Mar 2023 13:49:30 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:37332 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229589AbjCJSta (ORCPT ); Fri, 10 Mar 2023 13:49:30 -0500 Received: from mga14.intel.com (mga14.intel.com [192.55.52.115]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 38269E190D for ; Fri, 10 Mar 2023 10:49:29 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1678474169; x=1710010169; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=jy1UQLJ3GWQhq9KyEdeSl/Ei3C69x5gUL0OGBx9pdqg=; b=jKxMeW21AdUmrBK6tr1wGttfgccqoSefNBEe8MBPQiYVzlvFmcWEpGfF o4OObhjEQD92d2qVuxybw47FWS2iXoieThVLYjSjbbBBHgF4uAxdVL1JH /0TeoBdGV1T53M/L1Nd6OdV/uDV0YqfSPRbGVQpvIfvToDLF2Y+leAviX jcvoQNVjC0vMjYwIpiBIjKvl8Zc4UEH8aIZGerFsjBuovZkG7Xk5Dm9ka UgaSJMeIE7EHjw4ZU2EvbFBYN3X8UPxS7bIyQirnhvpdpqkkr0XMDKxaD zcvnXbJtCWKE390qgP/3FEBgow2h9bOFEAQFIRtqvUpgnEag/5b1rdhCq g==; X-IronPort-AV: E=McAfee;i="6500,9779,10645"; a="336824141" X-IronPort-AV: E=Sophos;i="5.98,250,1673942400"; d="scan'208";a="336824141" Received: from orsmga003.jf.intel.com ([10.7.209.27]) by fmsmga103.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 10 Mar 2023 10:49:28 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=McAfee;i="6500,9779,10645"; a="627906722" X-IronPort-AV: E=Sophos;i="5.98,250,1673942400"; d="scan'208";a="627906722" Received: from aschofie-mobl2.amr.corp.intel.com (HELO localhost) ([10.255.228.62]) by orsmga003-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 10 Mar 2023 10:49:28 -0800 From: alison.schofield@intel.com To: Dan Williams , Ira Weiny , Vishal Verma , Ben Widawsky , Dave Jiang Cc: Alison Schofield , linux-cxl@vger.kernel.org, Jonathan Cameron Subject: [PATCH v4 4/8] tools/testing/cxl: Mock the Clear Poison mailbox command Date: Fri, 10 Mar 2023 10:49:05 -0800 Message-Id: X-Mailer: git-send-email 2.37.3 In-Reply-To: References: MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-cxl@vger.kernel.org From: Alison Schofield Mock the clear of poison by deleting the device:address entry from the mock_poison_list[]. Behave like a real CXL device and do not fail if the address is not in the poison list, but offer a dev_dbg() message. Signed-off-by: Alison Schofield Reviewed-by: Jonathan Cameron --- tools/testing/cxl/test/mem.c | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/tools/testing/cxl/test/mem.c b/tools/testing/cxl/test/mem.c index 4fca886e2a7c..720147c7cb2b 100644 --- a/tools/testing/cxl/test/mem.c +++ b/tools/testing/cxl/test/mem.c @@ -52,6 +52,10 @@ static struct cxl_cel_entry mock_cel[] = { .opcode = cpu_to_le16(CXL_MBOX_OP_INJECT_POISON), .effect = cpu_to_le16(0), }, + { + .opcode = cpu_to_le16(CXL_MBOX_OP_CLEAR_POISON), + .effect = cpu_to_le16(0), + }, }; /* See CXL 2.0 Table 181 Get Health Info Output Payload */ @@ -997,6 +1001,35 @@ static int mock_inject_poison(struct cxl_dev_state *cxlds, return 0; } +static bool mock_poison_del(struct cxl_dev_state *cxlds, u64 dpa) +{ + for (int i = 0; i < MOCK_INJECT_TEST_MAX; i++) { + if (mock_poison_list[i].cxlds == cxlds && + mock_poison_list[i].dpa == dpa) { + mock_poison_list[i].cxlds = NULL; + return true; + } + } + return false; +} + +static int mock_clear_poison(struct cxl_dev_state *cxlds, + struct cxl_mbox_cmd *cmd) +{ + struct cxl_mbox_clear_poison *pi = cmd->payload_in; + u64 dpa = le64_to_cpu(pi->address); + + /* + * A real CXL device will write pi->write_data to the address + * being cleared. In this mock, just delete this address from + * the mock poison list. + */ + if (!mock_poison_del(cxlds, dpa)) + dev_dbg(cxlds->dev, "DPA: 0x%llx not in poison list\n", dpa); + + return 0; +} + static int cxl_mock_mbox_send(struct cxl_dev_state *cxlds, struct cxl_mbox_cmd *cmd) { struct device *dev = cxlds->dev; @@ -1057,6 +1090,9 @@ static int cxl_mock_mbox_send(struct cxl_dev_state *cxlds, struct cxl_mbox_cmd * case CXL_MBOX_OP_INJECT_POISON: rc = mock_inject_poison(cxlds, cmd); break; + case CXL_MBOX_OP_CLEAR_POISON: + rc = mock_clear_poison(cxlds, cmd); + break; default: break; } From patchwork Fri Mar 10 18:49:06 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alison Schofield X-Patchwork-Id: 13169960 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id DC16BC6FA99 for ; Fri, 10 Mar 2023 18:49:32 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230325AbjCJStc (ORCPT ); Fri, 10 Mar 2023 13:49:32 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:37378 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229589AbjCJStb (ORCPT ); Fri, 10 Mar 2023 13:49:31 -0500 Received: from mga14.intel.com (mga14.intel.com [192.55.52.115]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 78DE180E26 for ; Fri, 10 Mar 2023 10:49:30 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1678474170; x=1710010170; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=nDk3pV3liVAh1iI8uSZxNz8iRJV5YRcR+k+NYvbbV/M=; b=QKgHzWFJtxiA02Cx4PfmoWFS8vi4lMZ6z2WzDZ+xt1n4iPVZ/bvQYThT Rk0q6Kzo4pd07pLR7YK3MogPCyWY0zbu30Fn+PjU5r77LGVzGIUxPzqkZ eH7by6Pkedu+uaMaHNtrTDeWvLLkhnJu7TvynUSwGCmJBTSRnwCjRtIWH 5LDLOtxlz8/Ex7e1sGrB/x9VFAHh1QLIw9CJVPTzQbYEoaUFNVXdo4rcV sylce9zDCoFrbduQhpGLvZ1IA6d928mr8e7Yud0ISMdz5UPNlixYJrN9D TG4mjBpla8qo04EmB5q+gebI0eLFlMT/fGa0Y5eZvp8+al5t4zVoNgPfl g==; X-IronPort-AV: E=McAfee;i="6500,9779,10645"; a="336824153" X-IronPort-AV: E=Sophos;i="5.98,250,1673942400"; d="scan'208";a="336824153" Received: from orsmga003.jf.intel.com ([10.7.209.27]) by fmsmga103.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 10 Mar 2023 10:49:29 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=McAfee;i="6500,9779,10645"; a="627906736" X-IronPort-AV: E=Sophos;i="5.98,250,1673942400"; d="scan'208";a="627906736" Received: from aschofie-mobl2.amr.corp.intel.com (HELO localhost) ([10.255.228.62]) by orsmga003-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 10 Mar 2023 10:49:29 -0800 From: alison.schofield@intel.com To: Dan Williams , Ira Weiny , Vishal Verma , Ben Widawsky , Dave Jiang Cc: Alison Schofield , linux-cxl@vger.kernel.org, Jonathan Cameron Subject: [PATCH v4 5/8] tools/testing/cxl: Use injected poison for get poison list Date: Fri, 10 Mar 2023 10:49:06 -0800 Message-Id: X-Mailer: git-send-email 2.37.3 In-Reply-To: References: MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-cxl@vger.kernel.org From: Alison Schofield Prior to poison inject support, the mock of 'Get Poison List' returned a poison list containing a single mocked error record. Following the addition of poison inject and clear support to the mock driver, use the mock_poison_list[], rather than faking an error record. Mock_poison_list[] list tracks the actual poison inject and clear requests issued by userspace. Signed-off-by: Alison Schofield Reviewed-by: Jonathan Cameron --- tools/testing/cxl/test/mem.c | 59 ++++++++++++++++++++++++------------ 1 file changed, 40 insertions(+), 19 deletions(-) diff --git a/tools/testing/cxl/test/mem.c b/tools/testing/cxl/test/mem.c index 720147c7cb2b..9658d95236b7 100644 --- a/tools/testing/cxl/test/mem.c +++ b/tools/testing/cxl/test/mem.c @@ -912,31 +912,52 @@ static struct mock_poison { u64 dpa; } mock_poison_list[MOCK_INJECT_TEST_MAX]; +static struct cxl_mbox_poison_payload_out +*cxl_get_injected_po(struct cxl_dev_state *cxlds, u64 offset, u64 length) +{ + struct cxl_mbox_poison_payload_out *po; + int nr_records = 0; + u64 dpa; + + po = kzalloc(struct_size(po, record, MOCK_INJECT_DEV_MAX), GFP_KERNEL); + if (!po) + return NULL; + + for (int i = 0; i < MOCK_INJECT_TEST_MAX; i++) { + if (mock_poison_list[i].cxlds != cxlds) + continue; + if (mock_poison_list[i].dpa < offset || + mock_poison_list[i].dpa > offset + length - 1) + continue; + + dpa = mock_poison_list[i].dpa + CXL_POISON_SOURCE_INJECTED; + po->record[nr_records].address = cpu_to_le64(dpa); + po->record[nr_records].length = cpu_to_le32(1); + nr_records++; + if (nr_records == MOCK_INJECT_DEV_MAX) + break; + } + + /* Always return count, even when zero */ + po->count = cpu_to_le16(nr_records); + + return po; +} + static int mock_get_poison(struct cxl_dev_state *cxlds, struct cxl_mbox_cmd *cmd) { struct cxl_mbox_poison_payload_in *pi = cmd->payload_in; + struct cxl_mbox_poison_payload_out *po; + u64 offset = le64_to_cpu(pi->offset); + u64 length = le64_to_cpu(pi->length); + int nr_records; - /* Mock one poison record at pi.offset for 64 bytes */ - struct { - struct cxl_mbox_poison_payload_out po; - struct cxl_poison_record record; - } __packed mock_plist = { - .po = { - .count = cpu_to_le16(1), - }, - .record = { - .length = cpu_to_le32(1), - .address = cpu_to_le64(le64_to_cpu(pi->offset) + - CXL_POISON_SOURCE_INJECTED), - }, - }; + po = cxl_get_injected_po(cxlds, offset, length); + nr_records = le16_to_cpu(po->count); + memcpy(cmd->payload_out, po, struct_size(po, record, nr_records)); + cmd->size_out = struct_size(po, record, nr_records); - if (cmd->size_out < sizeof(mock_plist)) - return -EINVAL; - - memcpy(cmd->payload_out, &mock_plist, sizeof(mock_plist)); - cmd->size_out = sizeof(mock_plist); return 0; } From patchwork Fri Mar 10 18:49:07 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alison Schofield X-Patchwork-Id: 13169961 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 638A4C6FD19 for ; Fri, 10 Mar 2023 18:49:34 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230375AbjCJStd (ORCPT ); Fri, 10 Mar 2023 13:49:33 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:37400 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229589AbjCJStc (ORCPT ); Fri, 10 Mar 2023 13:49:32 -0500 Received: from mga14.intel.com (mga14.intel.com [192.55.52.115]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 95131E190D for ; Fri, 10 Mar 2023 10:49:31 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1678474171; x=1710010171; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=nUrQkHorGsPws7mIhp79mmrsAsjr4Bw+nOJj+7/gM90=; b=X38RvQufithso0mEZAJJOcBn2GS4BbrpMESh2WBu/pnciqNE4fJcwGmh X81DQF+vfscIfOwJtNl3oFJtx86EhhejHu35zEbyRhT2kJlyC62WcYVpS CZyZJSTyeZc/epygqEWWQPH6IXIvBBW5uoZlKDvoUBP43+FTMpJczt1jJ RwpG822gZsy5SSAYvhwsBewSADskGWQ2GLtkQBKHC60+eNnsLXwRrTPew Vq9rHFeDeZe0oS2ZsKeF95qDkajkImCafl3popEuGVTOP7EY7ni49FbkH R1Pbq2+pU1TYxbJM8eLbEf+ze2uburLZmJYXsTrw1JS66ZwsUXkgBVFeA A==; X-IronPort-AV: E=McAfee;i="6500,9779,10645"; a="336824163" X-IronPort-AV: E=Sophos;i="5.98,250,1673942400"; d="scan'208";a="336824163" Received: from orsmga003.jf.intel.com ([10.7.209.27]) by fmsmga103.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 10 Mar 2023 10:49:30 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=McAfee;i="6500,9779,10645"; a="627906750" X-IronPort-AV: E=Sophos;i="5.98,250,1673942400"; d="scan'208";a="627906750" Received: from aschofie-mobl2.amr.corp.intel.com (HELO localhost) ([10.255.228.62]) by orsmga003-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 10 Mar 2023 10:49:29 -0800 From: alison.schofield@intel.com To: Dan Williams , Ira Weiny , Vishal Verma , Ben Widawsky , Dave Jiang Cc: Alison Schofield , linux-cxl@vger.kernel.org, Jonathan Cameron Subject: [PATCH v4 6/8] tools/testing/cxl: Add a sysfs attr to test poison injection limits Date: Fri, 10 Mar 2023 10:49:07 -0800 Message-Id: <4ffd7453d7e9cb2575363f0ce442eb92f3c8d915.1678471465.git.alison.schofield@intel.com> X-Mailer: git-send-email 2.37.3 In-Reply-To: References: MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-cxl@vger.kernel.org From: Alison Schofield CXL devices may report a maximum number of addresses that a device allows to be poisoned using poison injection. When cxl_test creates mock CXL memory devices, it defaults to MOCK_INJECT_DEV_MAX==8 for all mocked memdevs. Add a sysfs attribute, poison_inject_max to module cxl_mock_mem so that users can set a custom device injection limit. Fail, and return -EBUSY, if the mock poison list is not empty. /sys/bus/platform/drivers/cxl_mock_mem/poison_inject_max A simple usage model is to set the attribute before running a test in order to emulate a device's poison handling. Signed-off-by: Alison Schofield Reviewed-by: Jonathan Cameron --- tools/testing/cxl/test/mem.c | 52 +++++++++++++++++++++++++++++++++--- 1 file changed, 48 insertions(+), 4 deletions(-) diff --git a/tools/testing/cxl/test/mem.c b/tools/testing/cxl/test/mem.c index 9658d95236b7..5c3b3e5a3b4b 100644 --- a/tools/testing/cxl/test/mem.c +++ b/tools/testing/cxl/test/mem.c @@ -19,6 +19,8 @@ #define MOCK_INJECT_DEV_MAX 8 #define MOCK_INJECT_TEST_MAX 128 +static unsigned int poison_inject_dev_max = MOCK_INJECT_DEV_MAX; + static struct cxl_cel_entry mock_cel[] = { { .opcode = cpu_to_le16(CXL_MBOX_OP_GET_SUPPORTED_LOGS), @@ -485,7 +487,7 @@ static int mock_id(struct cxl_dev_state *cxlds, struct cxl_mbox_cmd *cmd) cpu_to_le64(SZ_256M / CXL_CAPACITY_MULTIPLIER), .total_capacity = cpu_to_le64(DEV_SIZE / CXL_CAPACITY_MULTIPLIER), - .inject_poison_limit = cpu_to_le16(MOCK_INJECT_DEV_MAX), + .inject_poison_limit = cpu_to_le16(MOCK_INJECT_TEST_MAX), }; put_unaligned_le24(CXL_POISON_LIST_MAX, id.poison_list_max_mer); @@ -919,7 +921,7 @@ static struct cxl_mbox_poison_payload_out int nr_records = 0; u64 dpa; - po = kzalloc(struct_size(po, record, MOCK_INJECT_DEV_MAX), GFP_KERNEL); + po = kzalloc(struct_size(po, record, poison_inject_dev_max), GFP_KERNEL); if (!po) return NULL; @@ -934,7 +936,7 @@ static struct cxl_mbox_poison_payload_out po->record[nr_records].address = cpu_to_le64(dpa); po->record[nr_records].length = cpu_to_le32(1); nr_records++; - if (nr_records == MOCK_INJECT_DEV_MAX) + if (nr_records == poison_inject_dev_max) break; } @@ -969,7 +971,7 @@ static bool mock_poison_dev_max_injected(struct cxl_dev_state *cxlds) if (mock_poison_list[i].cxlds == cxlds) count++; } - return (count >= MOCK_INJECT_DEV_MAX); + return (count >= poison_inject_dev_max); } static bool mock_poison_add(struct cxl_dev_state *cxlds, u64 dpa) @@ -1051,6 +1053,47 @@ static int mock_clear_poison(struct cxl_dev_state *cxlds, return 0; } +static bool mock_poison_list_empty(void) +{ + for (int i = 0; i < MOCK_INJECT_TEST_MAX; i++) { + if (mock_poison_list[i].cxlds) + return false; + } + return true; +} + +static ssize_t poison_inject_max_show(struct device_driver *drv, char *buf) +{ + return sysfs_emit(buf, "%u\n", poison_inject_dev_max); +} + +static ssize_t poison_inject_max_store(struct device_driver *drv, + const char *buf, size_t len) +{ + int val; + + if (kstrtoint(buf, 0, &val) < 0) + return -EINVAL; + + if (!mock_poison_list_empty()) + return -EBUSY; + + if (val <= MOCK_INJECT_TEST_MAX) + poison_inject_dev_max = val; + else + return -EINVAL; + + return len; +} + +static DRIVER_ATTR_RW(poison_inject_max); + +static struct attribute *cxl_mock_mem_core_attrs[] = { + &driver_attr_poison_inject_max.attr, + NULL +}; +ATTRIBUTE_GROUPS(cxl_mock_mem_core); + static int cxl_mock_mbox_send(struct cxl_dev_state *cxlds, struct cxl_mbox_cmd *cmd) { struct device *dev = cxlds->dev; @@ -1259,6 +1302,7 @@ static struct platform_driver cxl_mock_mem_driver = { .driver = { .name = KBUILD_MODNAME, .dev_groups = cxl_mock_mem_groups, + .groups = cxl_mock_mem_core_groups, }, }; From patchwork Fri Mar 10 18:49:08 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alison Schofield X-Patchwork-Id: 13169962 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id E300BC76186 for ; Fri, 10 Mar 2023 18:49:34 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229589AbjCJSte (ORCPT ); Fri, 10 Mar 2023 13:49:34 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:37402 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230326AbjCJStc (ORCPT ); Fri, 10 Mar 2023 13:49:32 -0500 Received: from mga14.intel.com (mga14.intel.com [192.55.52.115]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id AA945115B7D for ; Fri, 10 Mar 2023 10:49:31 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1678474171; x=1710010171; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=WdJqltXxiVM4rr+PaU/bMie9WKLi+jaUFE8ZgpwNrHw=; b=N5i7CXzdBYRxP22I5trMUokF+WekoBmoEUck3q8sady357ms0SsbeitY P1h/te02xv5L8NS9mjeYTpzPA172TNov6qS6u59cPpHKe4iITZhQb5LTS XoE+6YxlX4K5P6UyzRc5bMpJ7dSUkZk+lWBdSExwyQCEj98mutVdHj/SJ 1J9UgcKD9HxV0WH23p2HzCc8LpSmtS/sroh5KdwdB9pmfQuoNoRu3GjNE c2p9gW32Gs0KUxoWfKj744GVbnCkfoctQHbR4lHYFEH1jsfjcWqgfxeDP EvYs1fKKrVHz4S28N7bc9RG9x/IMy/5+77LhmY4Q6aiiWa5/IcxaUzyJN A==; X-IronPort-AV: E=McAfee;i="6500,9779,10645"; a="336824175" X-IronPort-AV: E=Sophos;i="5.98,250,1673942400"; d="scan'208";a="336824175" Received: from orsmga003.jf.intel.com ([10.7.209.27]) by fmsmga103.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 10 Mar 2023 10:49:31 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=McAfee;i="6500,9779,10645"; a="627906770" X-IronPort-AV: E=Sophos;i="5.98,250,1673942400"; d="scan'208";a="627906770" Received: from aschofie-mobl2.amr.corp.intel.com (HELO localhost) ([10.255.228.62]) by orsmga003-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 10 Mar 2023 10:49:30 -0800 From: alison.schofield@intel.com To: Dan Williams , Ira Weiny , Vishal Verma , Ben Widawsky , Dave Jiang Cc: Alison Schofield , linux-cxl@vger.kernel.org Subject: [PATCH v4 7/8] cxl/memdev: Make inject and clear poison cmds kernel exclusive Date: Fri, 10 Mar 2023 10:49:08 -0800 Message-Id: <66f6c36d20fa6ab906fe800bcf7059d1f5a552e6.1678471465.git.alison.schofield@intel.com> X-Mailer: git-send-email 2.37.3 In-Reply-To: References: MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-cxl@vger.kernel.org From: Alison Schofield Inject and clear poison commands are intended to be used in debug mode only, and if improperly used, can lead to data corruption. The kernel provides a sysfs interface that provides the protection needed to issue these commands [1] The CXL driver defines Enabled commands in its ABI.[2] Enabled means that the device and the driver both support the command. If a device supports inject and/or clear, those commands are flagged Enabled. The ABI also defines another command flag: Exclusive. Exclusive commands are reserved for kernel use. The exclusive flags can be temporal, but for inject and clear, the status is permanent. Document the exclusivity of Inject and Clear in the ABI kernel doc. (Clean up a typo in kdoc too: 'CXL_MEM_COMMAND_FLAG_ENABLED') Create an exclusive commands bitmap in the memdev driver, add the inject and clear poison commands, and set it in the cxl_dev_state. [1] Documentation/ABI/testing/sysfs-bus-cxl [2] include/uapi/linux/cxl_mem.h Signed-off-by: Alison Schofield Reviewed-by: Jonathan Cameron --- drivers/cxl/core/memdev.c | 6 ++++++ include/uapi/linux/cxl_mem.h | 21 ++++++++++++++++----- 2 files changed, 22 insertions(+), 5 deletions(-) diff --git a/drivers/cxl/core/memdev.c b/drivers/cxl/core/memdev.c index 5dd334c4caf2..6ca2815d5c12 100644 --- a/drivers/cxl/core/memdev.c +++ b/drivers/cxl/core/memdev.c @@ -10,6 +10,8 @@ static DECLARE_RWSEM(cxl_memdev_rwsem); +static __read_mostly DECLARE_BITMAP(exclusive_cmds, CXL_MEM_COMMAND_ID_MAX); + /* * An entire PCI topology full of devices should be enough for any * config @@ -574,6 +576,10 @@ struct cxl_memdev *devm_cxl_add_memdev(struct cxl_dev_state *cxlds) cxlmd->cxlds = cxlds; cxlds->cxlmd = cxlmd; + set_bit(CXL_MEM_COMMAND_ID_INJECT_POISON, exclusive_cmds); + set_bit(CXL_MEM_COMMAND_ID_CLEAR_POISON, exclusive_cmds); + set_exclusive_cxl_commands(cxlds, exclusive_cmds); + cdev = &cxlmd->cdev; rc = cdev_device_add(cdev, dev); if (rc) diff --git a/include/uapi/linux/cxl_mem.h b/include/uapi/linux/cxl_mem.h index 86bbacf2a315..6f9ae244f7fd 100644 --- a/include/uapi/linux/cxl_mem.h +++ b/include/uapi/linux/cxl_mem.h @@ -74,17 +74,28 @@ static const struct { * @id: ID number for the command. * @flags: Flags that specify command behavior. * - * CXL_MEM_COMMAND_FLAG_USER_ENABLED + * CXL_MEM_COMMAND_FLAG_ENABLED * * The given command id is supported by the driver and is supported by * a related opcode on the device. * * CXL_MEM_COMMAND_FLAG_EXCLUSIVE * - * Requests with the given command id will terminate with EBUSY as the - * kernel actively owns management of the given resource. For example, - * the label-storage-area can not be written while the kernel is - * actively managing that space. + * The given command id is for kernel exclusive use and is not + * available to userspace. Requests will terminate with EBUSY. + * + * The exclusive flag may be temporal, and only set while the + * kernel actively owns management of the given resource. For + * example, the label-storage-area can not be written while the + * kernel is actively managing that space. + * + * The exclusive flag can be permanent, as in commands that can + * never be issued through the ioctl interface. + * + * INJECT_POISON and CLEAR_POISON are permanently kernel exclusive. + * They are supported through a sysfs interface that validates the + * safety of each command based on the state of the memdev. + * See: Documentation/ABI/testing/sysfs-bus-cxl * * @size_in: Expected input size, or ~0 if variable length. * @size_out: Expected output size, or ~0 if variable length. From patchwork Fri Mar 10 18:49:09 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alison Schofield X-Patchwork-Id: 13169963 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 71704C74A4B for ; Fri, 10 Mar 2023 18:49:35 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230326AbjCJSte (ORCPT ); Fri, 10 Mar 2023 13:49:34 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:37430 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230387AbjCJStd (ORCPT ); Fri, 10 Mar 2023 13:49:33 -0500 Received: from mga14.intel.com (mga14.intel.com [192.55.52.115]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 99E2E122389 for ; Fri, 10 Mar 2023 10:49:32 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1678474172; x=1710010172; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=kFyu2vqlFHUZvKFHwe4SPyjiSc9vLazrgoQorD5ju9E=; b=ewbToUwVS5Py8vjgzgarCQJu2v9bR7zN7d12wwWojmKUR4a1j8d8tNq2 IY2e2ptV4FUqRwBfCC4GqdNLjbwsuDdfIdqMRriLKo19babCj9Fi8J3wl ysR36fsDr7yC6uouTTt6cwJdA5RZM53CqraH/5hYdLaAAxMzD/yOXvrd3 h0ponQI1rsGH4odbPEO+eDgD9bOJW9NX3quyLsRVvLLaufkSE4z+djzw0 iE8Az691gb1kFUESno8pGKkb3XMzO2nEKWpt+lxG49WQQPMN6M1c69red RwvVX194kAGu4mgxxfBMvs+g3dhX3g6FIkUa6opin9PZtwbLpGLjArkR3 Q==; X-IronPort-AV: E=McAfee;i="6500,9779,10645"; a="336824188" X-IronPort-AV: E=Sophos;i="5.98,250,1673942400"; d="scan'208";a="336824188" Received: from orsmga003.jf.intel.com ([10.7.209.27]) by fmsmga103.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 10 Mar 2023 10:49:32 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=McAfee;i="6500,9779,10645"; a="627906792" X-IronPort-AV: E=Sophos;i="5.98,250,1673942400"; d="scan'208";a="627906792" Received: from aschofie-mobl2.amr.corp.intel.com (HELO localhost) ([10.255.228.62]) by orsmga003-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 10 Mar 2023 10:49:31 -0800 From: alison.schofield@intel.com To: Dan Williams , Ira Weiny , Vishal Verma , Ben Widawsky , Dave Jiang Cc: Alison Schofield , linux-cxl@vger.kernel.org Subject: [PATCH v4 8/8] cxl/mbox: Block inject and clear poison opcodes in raw mode Date: Fri, 10 Mar 2023 10:49:09 -0800 Message-Id: <6952da15b164e18e7f26fb26631839837d9797b3.1678471465.git.alison.schofield@intel.com> X-Mailer: git-send-email 2.37.3 In-Reply-To: References: MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-cxl@vger.kernel.org From: Alison Schofield Inject and clear poison are commands intended for debug environments, and can cause data corruption if issued without validation. They are kernel exclusive commands not available to userspace through ioctls, but could be submitted via the raw mode ioctl. Add inject and clear poison to the cxl_disabled_raw_commands[] list. Attempts by userspace to issue either command via the RAW ioctl fail with -EPERM. Signed-off-by: Alison Schofield Reviewed-by: Jonathan Cameron --- drivers/cxl/core/mbox.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/cxl/core/mbox.c b/drivers/cxl/core/mbox.c index 77fc811bdfed..4b5e65edbc71 100644 --- a/drivers/cxl/core/mbox.c +++ b/drivers/cxl/core/mbox.c @@ -89,6 +89,10 @@ static struct cxl_mem_command cxl_mem_commands[CXL_MEM_COMMAND_ID_MAX] = { * * CXL_MBOX_OP_[GET_]SCAN_MEDIA: The kernel provides a native error list that * is kept up to date with patrol notifications and error management. + * + * CXL_MBOX_OP_[INJECT|CLEAR]_POISON: The kernel provides a sysfs interface + * to these commands that ensures data protection of mapped resources. + * See: Documentation/ABI/testing/sysfs-bus-cxl */ static u16 cxl_disabled_raw_commands[] = { CXL_MBOX_OP_ACTIVATE_FW, @@ -97,6 +101,8 @@ static u16 cxl_disabled_raw_commands[] = { CXL_MBOX_OP_SET_SHUTDOWN_STATE, CXL_MBOX_OP_SCAN_MEDIA, CXL_MBOX_OP_GET_SCAN_MEDIA, + CXL_MBOX_OP_INJECT_POISON, + CXL_MBOX_OP_CLEAR_POISON, }; /*