From patchwork Tue Jul 11 22:09:47 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: srinivas pandruvada X-Patchwork-Id: 118733 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a59:a6b2:0:b0:3e4:2afc:c1 with SMTP id c18csp773333vqm; Tue, 11 Jul 2023 15:19:54 -0700 (PDT) X-Google-Smtp-Source: APBJJlHS8BUjz0pFtzy7uBCUDDedwh3AMeiGVCxfmlP7L0oOIpU+bgKZ1+KYX2KXznsEmfIM/Mbz X-Received: by 2002:a17:902:c3c6:b0:1b8:1c9e:444e with SMTP id j6-20020a170902c3c600b001b81c9e444emr18167839plj.25.1689113993911; Tue, 11 Jul 2023 15:19:53 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1689113993; cv=none; d=google.com; s=arc-20160816; b=aKYZbo04sQ14oHDo35cuXo1DTxlV4HlAZvibaNG6M/PUS+s56DMjToyWi91QKTTGMy ZyopX6NNugFXt/AsW/8EHZPStt6gXmoH2nU8RdfY8wZGnb/GoaE6UciiOr+dZtAlueZQ xoN+K+tfe+b2cZiKdHc+ABfGsP/gvsk9zjTxNB78awlkRrq8PxWuO+VyBhGI8XtIo6q5 vF7lOtGu94PcQkJ14XO+6PpWbIT40VVJpkOf+8itIa70ZB7GNvyk6DaBYeSsYPgP64Zr bi7ladegCKqmpJlt2Q0qRSEhmD9Xf2AwIKgq6vcWocC4i1ng3lLOIfTa27Dfb+jUCMe/ /IVA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=EBXEeHy+zNz8Tre0KYqCZeio60abvtLGgkCEBLjAtQ4=; fh=RrsDx1xcApjH9kmgnnjBG2OUTNMHeDctDKwtVs2JDHk=; b=E/MU0Lm3+MyRql6vzFqD5ze693FuWG+Cqsg/jUaO38BJnzbwZd+R1HXW+xEI/j8gsb u0p/ZAM56vI7cPL0yGYI3PldykcM603bWXN0wAH7PlvAq+NiLc5Yl3EPsucPMsK3wmdh jujlgOt0rj0dUFEHG258FIpqidDcD0MtrgBQrKIKvFYKzeoj5NhlNP+rXk1HTVkk7TLq Hn7Vfv7aY28q7JbGqllr5cmh4pwAg83b3W36mafRCfZSN0vlKXJxCoTp+3hgb7ucXgco 5MSuwWNefkBeZiKEygkv1e5fIgR/95Y+18dXay/NdFhpW1KWZq1TVK4ebwSF9ZdjgjzN 1wcg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@intel.com header.s=Intel header.b="mePjasp/"; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=intel.com Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id u3-20020a170902e5c300b001b872e3e3bfsi2190319plf.386.2023.07.11.15.19.39; Tue, 11 Jul 2023 15:19:53 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; dkim=pass header.i=@intel.com header.s=Intel header.b="mePjasp/"; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=intel.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231414AbjGKWKF (ORCPT + 99 others); Tue, 11 Jul 2023 18:10:05 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:53954 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231579AbjGKWKE (ORCPT ); Tue, 11 Jul 2023 18:10:04 -0400 Received: from mga17.intel.com (mga17.intel.com [192.55.52.151]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id B117A170C; Tue, 11 Jul 2023 15:10:02 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1689113402; x=1720649402; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=oVVY4tkhB4+/XYKjLG9Q1dSJgTuON5egCghoBYC94rM=; b=mePjasp/q8DqyttXIQuXSs4x18LTpk0kmKftxA2/Rzi/V9eq79mJ/SPi c/aYKk8K8Kkkmu2qNIpgf3zIPGQkmg6LGbSNbU3ngG1PNOcMgjJCZqFWy yIyWuUL7eKssL+h3j9Pl2cgebOrSMwmCLIWVZ6rSUqNgmv2TVoz260gzC mym8KpEUK8jES/uxDU7m/vdz6c8g/zRRfiG1XtezJWfGkG+1LKw5etj0P THq/atPIWrjXBbPn5BC3sO5yFR57CAfGOgbZ6wNBbiOvlWCBw4ZorTPbx /T2cxMy6mtiSn3ouvvpzqVy187FovIPMs8OKxS4fpjyWf7KwDVh/bT+ye w==; X-IronPort-AV: E=McAfee;i="6600,9927,10768"; a="345058982" X-IronPort-AV: E=Sophos;i="6.01,197,1684825200"; d="scan'208";a="345058982" Received: from fmsmga008.fm.intel.com ([10.253.24.58]) by fmsmga107.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 11 Jul 2023 15:10:01 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=McAfee;i="6600,9927,10768"; a="786795077" X-IronPort-AV: E=Sophos;i="6.01,197,1684825200"; d="scan'208";a="786795077" Received: from spandruv-desk.jf.intel.com ([10.54.75.8]) by fmsmga008.fm.intel.com with ESMTP; 11 Jul 2023 15:10:01 -0700 From: Srinivas Pandruvada To: hdegoede@redhat.com, markgross@kernel.org, ilpo.jarvinen@linux.intel.com, andriy.shevchenko@linux.intel.com Cc: platform-driver-x86@vger.kernel.org, linux-kernel@vger.kernel.org, Srinivas Pandruvada Subject: [PATCH v2 1/3] platform/x86/intel/tpmi: Read feature control status Date: Tue, 11 Jul 2023 15:09:47 -0700 Message-Id: <20230711220949.71881-2-srinivas.pandruvada@linux.intel.com> X-Mailer: git-send-email 2.40.1 In-Reply-To: <20230711220949.71881-1-srinivas.pandruvada@linux.intel.com> References: <20230711220949.71881-1-srinivas.pandruvada@linux.intel.com> MIME-Version: 1.0 X-Spam-Status: No, score=-2.0 required=5.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_EF,RCVD_IN_DNSWL_BLOCKED, SPF_HELO_NONE,SPF_NONE,T_SCC_BODY_TEXT_LINE,URIBL_BLOCKED autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1771164395468409915 X-GMAIL-MSGID: 1771164395468409915 Some of the PM features can be locked or disabled. In that case, write interface can be locked. This status is read via a mailbox. There is one TPMI ID which provides base address for interface and data register for mail box operation. The mailbox operations is defined in the TPMI specification. Refer to https://github.com/intel/tpmi_power_management/ for TPMI specifications. An API is exposed to feature drivers to read feature control status. Signed-off-by: Srinivas Pandruvada --- The external interface will be used by all feature drivers, will submit patch for that. v2 - Renaming of register names as suggested by llpo - cosmetic changes as suggested by llpo - size change to u32 for checking with max 4K size v1 This has all changes suggested by Andi drivers/platform/x86/intel/tpmi.c | 178 ++++++++++++++++++++++++++++++ include/linux/intel_tpmi.h | 2 + 2 files changed, 180 insertions(+) diff --git a/drivers/platform/x86/intel/tpmi.c b/drivers/platform/x86/intel/tpmi.c index d1fd6e69401c..024e7671687a 100644 --- a/drivers/platform/x86/intel/tpmi.c +++ b/drivers/platform/x86/intel/tpmi.c @@ -47,8 +47,11 @@ */ #include +#include +#include #include #include +#include #include #include @@ -98,6 +101,7 @@ struct intel_tpmi_pm_feature { * @feature_count: Number of TPMI of TPMI instances pointed by tpmi_features * @pfs_start: Start of PFS offset for the TPMI instances in this device * @plat_info: Stores platform info which can be used by the client drivers + * @tpmi_control_mem: Memory mapped IO for getting control information * * Stores the information for all TPMI devices enumerated from a single PCI device. */ @@ -107,6 +111,7 @@ struct intel_tpmi_info { int feature_count; u64 pfs_start; struct intel_tpmi_plat_info plat_info; + void __iomem *tpmi_control_mem; }; /** @@ -139,9 +144,16 @@ enum intel_tpmi_id { TPMI_ID_PEM = 1, /* Power and Perf excursion Monitor */ TPMI_ID_UNCORE = 2, /* Uncore Frequency Scaling */ TPMI_ID_SST = 5, /* Speed Select Technology */ + TPMI_CONTROL_ID = 0x80, /* Special ID for getting feature status */ TPMI_INFO_ID = 0x81, /* Special ID for PCI BDF and Package ID information */ }; +/* + * TPMI PFS and per feature memory size can't exceed 4K. + * Also PFS start and feature memory is 4K aligned. + */ +#define TPMI_MAX_BUFFER_SIZE (4 * 1024) + /* Used during auxbus device creation */ static DEFINE_IDA(intel_vsec_tpmi_ida); @@ -175,6 +187,169 @@ struct resource *tpmi_get_resource_at_index(struct auxiliary_device *auxdev, int } EXPORT_SYMBOL_NS_GPL(tpmi_get_resource_at_index, INTEL_TPMI); +/* TPMI Control Interface */ + +#define TPMI_CONTROL_STATUS_OFFSET 0x00 +#define TPMI_COMMAND_OFFSET 0x08 + +/* + * Spec is calling for max 1 seconds to get ownership at the worst + * case. Read at 10 ms timeouts and repeat up to 1 second. + */ +#define TPMI_CONTROL_TIMEOUT_US (10 * USEC_PER_MSEC) +#define TPMI_CONTROL_TIMEOUT_MAX_US USEC_PER_SEC + +#define TPMI_RB_TIMEOUT_US (10 * USEC_PER_MSEC) +#define TPMI_RB_TIMEOUT_MAX_US USEC_PER_SEC + +/* TPMI Control status register defines */ + +#define TPMI_CONTROL_STATUS_RB BIT_ULL(0) + +#define TPMI_CONTROL_STATUS_OWNER GENMASK_ULL(5, 4) +#define TPMI_OWNER_NONE 0 +#define TPMI_OWNER_IN_BAND 1 + +#define TPMI_CONTROL_STATUS_CPL BIT_ULL(6) +#define TPMI_CONTROL_STATUS_RESULT GENMASK_ULL(15, 8) +#define TPMI_CONTROL_STATUS_LEN GENMASK_ULL(31, 16) + +#define TPMI_CMD_PKT_LEN 2 +#define TPMI_CMD_STATUS_SUCCESS 0x40 + +/* TPMI command data registers */ +#define TMPI_CONTROL_DATA_CMD GENMASK_ULL(7, 0) +#define TMPI_CONTROL_DATA_VAL GENMASK_ULL(63, 32) +#define TPMI_CONTROL_DATA_VAL_FEATURE GENMASK_ULL(48, 40) + +/* Command to send via control interface */ +#define TPMI_CONTROL_GET_STATE_CMD 0x10 + +#define TPMI_CONTROL_CMD_MASK GENMASK_ULL(48, 40) + +#define TPMI_CMD_LEN_MASK GENMASK_ULL(18, 16) + +#define TPMI_STATE_DISABLED BIT_ULL(0) +#define TPMI_STATE_LOCKED BIT_ULL(31) + +/* Mutex to complete get feature status without interruption */ +static DEFINE_MUTEX(tpmi_dev_lock); + +static int tpmi_wait_for_owner(struct intel_tpmi_info *tpmi_info, u8 owner) +{ + u64 control; + + return read_poll_timeout(readq, control, + owner == FIELD_GET(TPMI_CONTROL_STATUS_OWNER, control), + TPMI_CONTROL_TIMEOUT_US, TPMI_CONTROL_TIMEOUT_MAX_US, false, + tpmi_info->tpmi_control_mem + TPMI_CONTROL_STATUS_OFFSET); +} + +static int tpmi_read_feature_status(struct intel_tpmi_info *tpmi_info, int feature_id, + int *locked, int *disabled) +{ + u64 control, data; + int ret; + + if (!tpmi_info->tpmi_control_mem) + return -EFAULT; + + mutex_lock(&tpmi_dev_lock); + + /* Wait for owner bit set to 0 (none) */ + ret = tpmi_wait_for_owner(tpmi_info, TPMI_OWNER_NONE); + if (ret) + goto err_unlock; + + /* set command id to 0x10 for TPMI_GET_STATE */ + data = FIELD_PREP(TMPI_CONTROL_DATA_CMD, TPMI_CONTROL_GET_STATE_CMD); + + /* 32 bits for DATA offset and +8 for feature_id field */ + data |= FIELD_PREP(TPMI_CONTROL_DATA_VAL_FEATURE, feature_id); + + /* Write at command offset for qword access */ + writeq(data, tpmi_info->tpmi_control_mem + TPMI_COMMAND_OFFSET); + + /* Wait for owner bit set to in-band */ + ret = tpmi_wait_for_owner(tpmi_info, TPMI_OWNER_IN_BAND); + if (ret) + goto err_unlock; + + /* Set Run Busy and packet length of 2 dwords */ + control = TPMI_CONTROL_STATUS_RB; + control |= FIELD_PREP(TPMI_CONTROL_STATUS_LEN, TPMI_CMD_PKT_LEN); + + /* Write at status offset for qword access */ + writeq(control, tpmi_info->tpmi_control_mem + TPMI_CONTROL_STATUS_OFFSET); + + /* Wait for Run Busy clear */ + ret = read_poll_timeout(readq, control, !(control & TPMI_CONTROL_STATUS_RB), + TPMI_RB_TIMEOUT_US, TPMI_RB_TIMEOUT_MAX_US, false, + tpmi_info->tpmi_control_mem + TPMI_CONTROL_STATUS_OFFSET); + if (ret) + goto done_proc; + + control = FIELD_GET(TPMI_CONTROL_STATUS_RESULT, control); + if (control != TPMI_CMD_STATUS_SUCCESS) { + ret = -EBUSY; + goto done_proc; + } + + /* Response is ready */ + data = readq(tpmi_info->tpmi_control_mem + TPMI_COMMAND_OFFSET); + data = FIELD_GET(TMPI_CONTROL_DATA_VAL, data); + + *disabled = 0; + *locked = 0; + + if (!(data & TPMI_STATE_DISABLED)) + *disabled = 1; + + if (data & TPMI_STATE_LOCKED) + *locked = 1; + + ret = 0; + +done_proc: + /* Set CPL "completion" bit */ + writeq(TPMI_CONTROL_STATUS_CPL, tpmi_info->tpmi_control_mem + TPMI_CONTROL_STATUS_OFFSET); + +err_unlock: + mutex_unlock(&tpmi_dev_lock); + + return ret; +} + +int tpmi_get_feature_status(struct auxiliary_device *auxdev, int feature_id, + int *locked, int *disabled) +{ + struct intel_vsec_device *intel_vsec_dev = dev_to_ivdev(auxdev->dev.parent); + struct intel_tpmi_info *tpmi_info = auxiliary_get_drvdata(&intel_vsec_dev->auxdev); + + return tpmi_read_feature_status(tpmi_info, feature_id, locked, disabled); +} +EXPORT_SYMBOL_NS_GPL(tpmi_get_feature_status, INTEL_TPMI); + +static void tpmi_set_control_base(struct auxiliary_device *auxdev, + struct intel_tpmi_info *tpmi_info, + struct intel_tpmi_pm_feature *pfs) +{ + void __iomem *mem; + u32 size; + + size = pfs->pfs_header.num_entries * pfs->pfs_header.entry_size * sizeof(u32); + /* This size is coming from trusted hardware, but verify anyway */ + if (size > TPMI_MAX_BUFFER_SIZE) + return; + + mem = devm_ioremap(&auxdev->dev, pfs->vsec_offset, size); + if (!mem) + return; + + /* mem is pointing to TPMI CONTROL base */ + tpmi_info->tpmi_control_mem = mem; +} + static const char *intel_tpmi_name(enum intel_tpmi_id id) { switch (id) { @@ -367,6 +542,9 @@ static int intel_vsec_tpmi_init(struct auxiliary_device *auxdev) */ if (pfs->pfs_header.tpmi_id == TPMI_INFO_ID) tpmi_process_info(tpmi_info, pfs); + + if (pfs->pfs_header.tpmi_id == TPMI_CONTROL_ID) + tpmi_set_control_base(auxdev, tpmi_info, pfs); } tpmi_info->pfs_start = pfs_start; diff --git a/include/linux/intel_tpmi.h b/include/linux/intel_tpmi.h index f505788c05da..04d937ad4dc4 100644 --- a/include/linux/intel_tpmi.h +++ b/include/linux/intel_tpmi.h @@ -27,4 +27,6 @@ struct intel_tpmi_plat_info *tpmi_get_platform_data(struct auxiliary_device *aux struct resource *tpmi_get_resource_at_index(struct auxiliary_device *auxdev, int index); int tpmi_get_resource_count(struct auxiliary_device *auxdev); +int tpmi_get_feature_status(struct auxiliary_device *auxdev, int feature_id, int *locked, + int *disabled); #endif From patchwork Tue Jul 11 22:09:48 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: srinivas pandruvada X-Patchwork-Id: 118735 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a59:a6b2:0:b0:3e4:2afc:c1 with SMTP id c18csp774713vqm; Tue, 11 Jul 2023 15:22:58 -0700 (PDT) X-Google-Smtp-Source: APBJJlHsjqvFM1KtQsRkjx4amEYhGUC6yYnqCplFtGs4PNrJXGzakLZUSgAcbaTMI4aCfXEPy2DQ X-Received: by 2002:a05:6a20:428b:b0:131:6464:217b with SMTP id o11-20020a056a20428b00b001316464217bmr8806981pzj.16.1689114177924; Tue, 11 Jul 2023 15:22:57 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1689114177; cv=none; d=google.com; s=arc-20160816; b=TekyXliew0KJoDibj2ZM6NTJUHrU8F1WCXnLM/z2l1LZlzHTyfI6LgtRBAZTuriDjP fYiycI2DPgzz3XPNTFupemvIk4FyH1bDgRFxWPWH1Isj2DMLt2xU4mqIg+x+VNnHZGu+ iBw2EZ+kqyauXDoETg09dT3QNHxM4vyDv7CcISrS9dxFPmnsi8N+GsZcLVp84miqhMu1 vWdWkF+e+eInYN1F7JWeF4XGFc0fNAQ8ToC2dgiyqub4t5+HJAJw2wGJoeJhT0W8DfdM +K3YqWnfa1QB2ZQjsb8l5rbR3Xnj3PVMSjWS4tkq7cmFfnD2OX7Q5xg83CmD9Z7Ciwf1 sMOw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=PDyMq0pixTO1FPWiGTiYGlxjPCzJFNQKbGOYvUgQ62M=; fh=RrsDx1xcApjH9kmgnnjBG2OUTNMHeDctDKwtVs2JDHk=; b=tcU+mxctV42GnfJrZFUXjDK0C9hnZ6C6qV/JZ7kUq/MLQZNdmyp08/Qa+xsRyqN88B sEaG4W1m2fY/ej59D9doWt6l8XgO6zV12FTxjaW1Ltajd8vq++wygSKEPK2kGWO9gySY 0u5suo+uPqEKbmyOPDr/KN9CNgR8b/c95qvvJWinjctVdaIuWVvNEDPT1ASl68vJ2YV/ w745GRSq7CvyPWBBVPhInT7hOlpg0C35qZQepwQ8j7E8QriqG8H0gm5VdUFQ02FTekVy M+cH6flWmz+/u6lcS5n3VX2s8vPrG2hEz6Pg1NcBjg19S0c08zfaqGVIYOlrYurJWlfx 5XRw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@intel.com header.s=Intel header.b=kqfG0b3F; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=intel.com Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id h69-20020a638348000000b0055bc27f07aasi1961029pge.273.2023.07.11.15.22.44; Tue, 11 Jul 2023 15:22:57 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; dkim=pass header.i=@intel.com header.s=Intel header.b=kqfG0b3F; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=intel.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231858AbjGKWKL (ORCPT + 99 others); Tue, 11 Jul 2023 18:10:11 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:53966 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231436AbjGKWKF (ORCPT ); Tue, 11 Jul 2023 18:10:05 -0400 Received: from mga17.intel.com (mga17.intel.com [192.55.52.151]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 2F7DB1705; Tue, 11 Jul 2023 15:10:04 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1689113404; x=1720649404; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=EVisxnnbHY7c+TnTp7XAWfuY9eiDyTJuwiGBELqCLY4=; b=kqfG0b3F+ezK+WmhHHgx8CAzXcRoG3ySr5IS2gb57z5zl/RQ3VO89smS TWSfSMmXS8cRxg6eRZGJ34xF9E8LRrlh4deS6AZcfAbtgwPk+Tm8pnG5b XAgNtWFP3k+HOKas53PYny48VHayFmTFCPMjdO0sPk8gIOFm6DO48bULE 8dhfIRiIw/e7p3xYt/3blnUn8JUDw02y4pdW67Ndhawswy3cW88K6J3lX y23n21f3pOz3xy1aWZY5c+nhKtm1xsG5G/7MYLp9724NfpRTQrFP3VprJ 0q3H1uc/LovrjgKGVUXYhMh+bcQbqQ2JXGS3UCipp2fgbyejzu6a/9bJK g==; X-IronPort-AV: E=McAfee;i="6600,9927,10768"; a="345058985" X-IronPort-AV: E=Sophos;i="6.01,197,1684825200"; d="scan'208";a="345058985" Received: from fmsmga008.fm.intel.com ([10.253.24.58]) by fmsmga107.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 11 Jul 2023 15:10:01 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=McAfee;i="6600,9927,10768"; a="786795079" X-IronPort-AV: E=Sophos;i="6.01,197,1684825200"; d="scan'208";a="786795079" Received: from spandruv-desk.jf.intel.com ([10.54.75.8]) by fmsmga008.fm.intel.com with ESMTP; 11 Jul 2023 15:10:01 -0700 From: Srinivas Pandruvada To: hdegoede@redhat.com, markgross@kernel.org, ilpo.jarvinen@linux.intel.com, andriy.shevchenko@linux.intel.com Cc: platform-driver-x86@vger.kernel.org, linux-kernel@vger.kernel.org, Srinivas Pandruvada Subject: [PATCH v2 2/3] platform/x86/intel/tpmi: Add debugfs interface Date: Tue, 11 Jul 2023 15:09:48 -0700 Message-Id: <20230711220949.71881-3-srinivas.pandruvada@linux.intel.com> X-Mailer: git-send-email 2.40.1 In-Reply-To: <20230711220949.71881-1-srinivas.pandruvada@linux.intel.com> References: <20230711220949.71881-1-srinivas.pandruvada@linux.intel.com> MIME-Version: 1.0 X-Spam-Status: No, score=-2.0 required=5.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_EF,RCVD_IN_DNSWL_BLOCKED, SPF_HELO_NONE,SPF_NONE,T_SCC_BODY_TEXT_LINE,URIBL_BLOCKED autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1771164587871277981 X-GMAIL-MSGID: 1771164587871277981 Add debugfs interface for debugging TPMI configuration and register contents. This shows PFS (PM Feature structure) for each TPMI device. For each feature, show full register contents and allow to modify register at an offset. This debugfs interface is not present on locked down kernel with no DEVMEM access and without CAP_SYS_RAWIO permission. Signed-off-by: Srinivas Pandruvada --- v2 - Check for locked down kernel and permissions - Move help to documentation folder - Cosmetic changes - size check drivers/platform/x86/intel/tpmi.c | 236 +++++++++++++++++++++++++++++- 1 file changed, 229 insertions(+), 7 deletions(-) diff --git a/drivers/platform/x86/intel/tpmi.c b/drivers/platform/x86/intel/tpmi.c index 024e7671687a..bed4336c208b 100644 --- a/drivers/platform/x86/intel/tpmi.c +++ b/drivers/platform/x86/intel/tpmi.c @@ -48,12 +48,15 @@ #include #include +#include #include #include #include #include #include #include +#include +#include #include "vsec.h" @@ -86,12 +89,14 @@ struct intel_tpmi_pfs_entry { * @vsec_offset: Starting MMIO address for this feature in bytes. Essentially * this offset = "Address" from VSEC header + PFS Capability * offset for this feature entry. + * @vsec_dev: Pointer to intel_vsec_device structure for this TPMI device * * Represents TPMI instance information for one TPMI ID. */ struct intel_tpmi_pm_feature { struct intel_tpmi_pfs_entry pfs_header; unsigned int vsec_offset; + struct intel_vsec_device *vsec_dev; }; /** @@ -102,6 +107,7 @@ struct intel_tpmi_pm_feature { * @pfs_start: Start of PFS offset for the TPMI instances in this device * @plat_info: Stores platform info which can be used by the client drivers * @tpmi_control_mem: Memory mapped IO for getting control information + * @dbgfs_dir: debugfs entry pointer * * Stores the information for all TPMI devices enumerated from a single PCI device. */ @@ -112,6 +118,7 @@ struct intel_tpmi_info { u64 pfs_start; struct intel_tpmi_plat_info plat_info; void __iomem *tpmi_control_mem; + struct dentry *dbgfs_dir; }; /** @@ -330,6 +337,205 @@ int tpmi_get_feature_status(struct auxiliary_device *auxdev, int feature_id, } EXPORT_SYMBOL_NS_GPL(tpmi_get_feature_status, INTEL_TPMI); +static int tpmi_pfs_dbg_show(struct seq_file *s, void *unused) +{ + struct intel_tpmi_info *tpmi_info = s->private; + int i, ret; + + seq_printf(s, "tpmi PFS start offset 0x:%llx\n", tpmi_info->pfs_start); + seq_puts(s, "tpmi_id\t\tentries\t\tsize\t\tcap_offset\tattribute\tvsec_offset\tlocked\tdisabled\n"); + for (i = 0; i < tpmi_info->feature_count; ++i) { + struct intel_tpmi_pm_feature *pfs; + int locked, disabled; + + pfs = &tpmi_info->tpmi_features[i]; + ret = tpmi_read_feature_status(tpmi_info, pfs->pfs_header.tpmi_id, &locked, + &disabled); + if (ret) { + locked = 'U'; + disabled = 'U'; + } else { + disabled = disabled ? 'Y' : 'N'; + locked = locked ? 'Y' : 'N'; + } + seq_printf(s, "0x%02x\t\t0x%02x\t\t0x%04x\t\t0x%04x\t\t0x%02x\t\t0x%08x\t%c\t%c\n", + pfs->pfs_header.tpmi_id, pfs->pfs_header.num_entries, + pfs->pfs_header.entry_size, pfs->pfs_header.cap_offset, + pfs->pfs_header.attribute, pfs->vsec_offset, locked, disabled); + } + + return 0; +} +DEFINE_SHOW_ATTRIBUTE(tpmi_pfs_dbg); + +#define MEM_DUMP_COLUMN_COUNT 8 + +static int tpmi_mem_dump_show(struct seq_file *s, void *unused) +{ + size_t row_size = MEM_DUMP_COLUMN_COUNT * sizeof(u32); + struct intel_tpmi_pm_feature *pfs = s->private; + int count, ret = 0; + void __iomem *mem; + u32 off, size; + u8 *buffer; + + off = pfs->vsec_offset; + + mutex_lock(&tpmi_dev_lock); + + for (count = 0; count < pfs->pfs_header.num_entries; ++count) { + size = pfs->pfs_header.entry_size * sizeof(u32); + /* The size is from a trusted hardware, but verify anyway */ + if (size > TPMI_MAX_BUFFER_SIZE) { + /* + * The next offset depends on the current size. So, can't skip to the + * display of the next entry. Simply return from this function with error. + */ + ret = -EIO; + goto done_mem_show; + } + + buffer = kmalloc(size, GFP_KERNEL); + if (!buffer) { + ret = -ENOMEM; + goto done_mem_show; + } + + seq_printf(s, "TPMI Instance:%d offset:0x%x\n", count, off); + + mem = ioremap(off, size); + if (!mem) { + ret = -ENOMEM; + kfree(buffer); + goto done_mem_show; + } + + memcpy_fromio(buffer, mem, size); + + seq_hex_dump(s, " ", DUMP_PREFIX_OFFSET, row_size, sizeof(u32), buffer, size, + false); + + iounmap(mem); + kfree(buffer); + + off += size; + } + +done_mem_show: + mutex_unlock(&tpmi_dev_lock); + + return ret; +} +DEFINE_SHOW_ATTRIBUTE(tpmi_mem_dump); + +static ssize_t mem_write(struct file *file, const char __user *userbuf, size_t len, loff_t *ppos) +{ + struct seq_file *m = file->private_data; + struct intel_tpmi_pm_feature *pfs = m->private; + u32 addr, value, punit, size; + u32 num_elems, *array; + void __iomem *mem; + int ret; + + size = pfs->pfs_header.entry_size * sizeof(u32); + if (size > TPMI_MAX_BUFFER_SIZE) + return -EIO; + + ret = parse_int_array_user(userbuf, len, (int **)&array); + if (ret < 0) + return ret; + + num_elems = *array; + if (num_elems != 3) { + ret = -EINVAL; + goto exit_write; + } + + punit = array[1]; + addr = array[2]; + value = array[3]; + + if (punit >= pfs->pfs_header.num_entries) { + ret = -EINVAL; + goto exit_write; + } + + if (addr >= size) { + ret = -EINVAL; + goto exit_write; + } + + mutex_lock(&tpmi_dev_lock); + + mem = ioremap(pfs->vsec_offset + punit * size, size); + if (!mem) { + ret = -ENOMEM; + goto unlock_mem_write; + } + + writel(value, mem + addr); + + iounmap(mem); + + ret = len; + +unlock_mem_write: + mutex_unlock(&tpmi_dev_lock); + +exit_write: + kfree(array); + + return ret; +} + +static int mem_write_show(struct seq_file *s, void *unused) +{ + return 0; +} + +static int mem_write_open(struct inode *inode, struct file *file) +{ + return single_open(file, mem_write_show, inode->i_private); +} + +static const struct file_operations mem_write_ops = { + .open = mem_write_open, + .read = seq_read, + .write = mem_write, + .llseek = seq_lseek, + .release = single_release, +}; + +#define tpmi_to_dev(info) (&info->vsec_dev->pcidev->dev) + +static void tpmi_dbgfs_register(struct intel_tpmi_info *tpmi_info) +{ + struct dentry *top_dir; + char name[64]; + int i; + + snprintf(name, sizeof(name), "tpmi-%s", dev_name(tpmi_to_dev(tpmi_info))); + top_dir = debugfs_create_dir(name, NULL); + if (IS_ERR_OR_NULL(top_dir)) + return; + + tpmi_info->dbgfs_dir = top_dir; + + debugfs_create_file("pfs_dump", 0444, top_dir, tpmi_info, &tpmi_pfs_dbg_fops); + + for (i = 0; i < tpmi_info->feature_count; ++i) { + struct intel_tpmi_pm_feature *pfs; + struct dentry *dir; + + pfs = &tpmi_info->tpmi_features[i]; + snprintf(name, sizeof(name), "tpmi-id-%02x", pfs->pfs_header.tpmi_id); + dir = debugfs_create_dir(name, top_dir); + + debugfs_create_file("mem_dump", 0444, dir, pfs, &tpmi_mem_dump_fops); + debugfs_create_file("mem_write", 0644, dir, pfs, &mem_write_ops); + } +} + static void tpmi_set_control_base(struct auxiliary_device *auxdev, struct intel_tpmi_info *tpmi_info, struct intel_tpmi_pm_feature *pfs) @@ -491,7 +697,7 @@ static int intel_vsec_tpmi_init(struct auxiliary_device *auxdev) struct pci_dev *pci_dev = vsec_dev->pcidev; struct intel_tpmi_info *tpmi_info; u64 pfs_start = 0; - int i; + int ret, i; tpmi_info = devm_kzalloc(&auxdev->dev, sizeof(*tpmi_info), GFP_KERNEL); if (!tpmi_info) @@ -514,6 +720,7 @@ static int intel_vsec_tpmi_init(struct auxiliary_device *auxdev) int size, ret; pfs = &tpmi_info->tpmi_features[i]; + pfs->vsec_dev = vsec_dev; res = &vsec_dev->resource[i]; if (!res) @@ -551,7 +758,20 @@ static int intel_vsec_tpmi_init(struct auxiliary_device *auxdev) auxiliary_set_drvdata(auxdev, tpmi_info); - return tpmi_create_devices(tpmi_info); + ret = tpmi_create_devices(tpmi_info); + if (ret) + return ret; + + /* + * Allow debugfs when security policy allows. Everything this debugfs + * interface provides, can also be done via /dev/mem access. If + * /dev/mem interface is locked, don't allow debugfs to present any + * information. Also check for CAP_SYS_RAWIO as /dev/mem interface. + */ + if (!security_locked_down(LOCKDOWN_DEV_MEM) && capable(CAP_SYS_RAWIO)) + tpmi_dbgfs_register(tpmi_info); + + return 0; } static int tpmi_probe(struct auxiliary_device *auxdev, @@ -560,11 +780,12 @@ static int tpmi_probe(struct auxiliary_device *auxdev, return intel_vsec_tpmi_init(auxdev); } -/* - * Remove callback is not needed currently as there is no - * cleanup required. All memory allocs are device managed. All - * devices created by this modules are also device managed. - */ +static void tpmi_remove(struct auxiliary_device *auxdev) +{ + struct intel_tpmi_info *tpmi_info = auxiliary_get_drvdata(auxdev); + + debugfs_remove_recursive(tpmi_info->dbgfs_dir); +} static const struct auxiliary_device_id tpmi_id_table[] = { { .name = "intel_vsec.tpmi" }, @@ -575,6 +796,7 @@ MODULE_DEVICE_TABLE(auxiliary, tpmi_id_table); static struct auxiliary_driver tpmi_aux_driver = { .id_table = tpmi_id_table, .probe = tpmi_probe, + .remove = tpmi_remove, }; module_auxiliary_driver(tpmi_aux_driver); From patchwork Tue Jul 11 22:09:49 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: srinivas pandruvada X-Patchwork-Id: 118737 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a59:a6b2:0:b0:3e4:2afc:c1 with SMTP id c18csp786550vqm; Tue, 11 Jul 2023 15:53:37 -0700 (PDT) X-Google-Smtp-Source: APBJJlEbySAde6n4gD3IZB8OXfmbTR5J9Aa2+2goKeGu6aDaQ4RMVCwr+46Em3VszHo7GUCFLNoV X-Received: by 2002:a05:6a00:148f:b0:682:4c9f:aa0 with SMTP id v15-20020a056a00148f00b006824c9f0aa0mr18923684pfu.29.1689116016588; Tue, 11 Jul 2023 15:53:36 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1689116016; cv=none; d=google.com; s=arc-20160816; b=0hEHMNLnNFxfyHWsIqkwEDVYi3rDr+34Dmqr4NSOxps+o7msKDRsUmjsN6WPcsMaSF 0W8hhdueR9dVM1o9NEtytpEWiEpoieE32Jq44FczFbbM6Yx/Kqc83Kzp9IkqHOLmdXkw yxx5eEC8FChmgFgrJfBY5ENP+wsxYE1O68ovExzSf+7JLA1scaKyVTAdxwOvW5milckU c7jKR5y9YufRDJILPJ42ttR1KLWeAvLi6VALpIKjsTPUJ9ZU5et1gk/27wiKti2fd6vS 8eaoCy2oYWyqF9+qTzLHEgbpI5Fzq1MjQmTTm6Q7fXIn8qkAH7MndQ9LwdrKWNU3mXZK KyyA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=JP/LdeQCy6XjTgbTwLi+o0D+siLVBHd3ysuAT/c1cOw=; fh=RrsDx1xcApjH9kmgnnjBG2OUTNMHeDctDKwtVs2JDHk=; b=Aoow/qMlltfLKr2K0/GaK6hL52JLQWUJMU1ubHCBaiGr2XUFYfTijuRK2U3CebOMHB BUMNgzFtCQ/b7tc3Dsqn44sK8K4HT+dqXJ7uuEmaSZiCxWhx1sSQ6s4PGx3YCH5IJibl Gtc1oeWoDpqPBPQCbgH6+vfCweUW9bSu0j1Q1lZY7/1wEYRoAnm5P3rSKsbTvll5ZLUa ZwyEk5u66Uf25LI/3SVw6yD7jD4Na83A/XMz3ZCvNxx+tNzzWg5xBw7CzeX7jVi/N32G aHXDBq4mhtFpR46Ytv4+qC7a3B0o+rIdulIqgT9F6cRZWl4sfAW45rp6R5UxAZ2I1m07 x+IQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@intel.com header.s=Intel header.b=GkPYbedE; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=intel.com Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id cb5-20020a056a00430500b006749ad285e8si2152262pfb.97.2023.07.11.15.53.23; Tue, 11 Jul 2023 15:53:36 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; dkim=pass header.i=@intel.com header.s=Intel header.b=GkPYbedE; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=intel.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231830AbjGKWKH (ORCPT + 99 others); Tue, 11 Jul 2023 18:10:07 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:53964 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231625AbjGKWKF (ORCPT ); Tue, 11 Jul 2023 18:10:05 -0400 Received: from mga17.intel.com (mga17.intel.com [192.55.52.151]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 481B7170E; Tue, 11 Jul 2023 15:10:04 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1689113404; x=1720649404; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=k3E1tQ1O4ThXJCHrWKSmtS5nCbAQMLnu5/Dj8fpnRNk=; b=GkPYbedEZgdr91XKXzhCI9jHcl6abUfwX3XiBxOvVgdLgNk0Zb89+8eV pMrpBylHchQIOEZhI6LWcRqI8a89dIt7lrtgc/6dJOrfZ39rwz9Rem2eK DIgmnUpMJuhQuuPi8nyomaJ9iJoWcPvxGNNbnpnDX0RkIl5y/L3w2QjEi QonUkNHyktTBwU7VaM2rTfMGzCQce1ZbND38q5FeMsuQLo01fy8CyNl1d dprE8TAcrY2UWcfAVK/WKpxPi6tkBkOYXwu7bgl4hqspp68ZqWEzFTbdc 5md5wIv2S6L+mOn1zKFPDJJvHPd6PFB80KrZTl7XJLkak4JqTf7tyTzDu Q==; X-IronPort-AV: E=McAfee;i="6600,9927,10768"; a="345058988" X-IronPort-AV: E=Sophos;i="6.01,197,1684825200"; d="scan'208";a="345058988" Received: from fmsmga008.fm.intel.com ([10.253.24.58]) by fmsmga107.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 11 Jul 2023 15:10:02 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=McAfee;i="6600,9927,10768"; a="786795081" X-IronPort-AV: E=Sophos;i="6.01,197,1684825200"; d="scan'208";a="786795081" Received: from spandruv-desk.jf.intel.com ([10.54.75.8]) by fmsmga008.fm.intel.com with ESMTP; 11 Jul 2023 15:10:01 -0700 From: Srinivas Pandruvada To: hdegoede@redhat.com, markgross@kernel.org, ilpo.jarvinen@linux.intel.com, andriy.shevchenko@linux.intel.com Cc: platform-driver-x86@vger.kernel.org, linux-kernel@vger.kernel.org, Srinivas Pandruvada Subject: [PATCH v2 3/3] doc: TPMI: Add debugfs documentation Date: Tue, 11 Jul 2023 15:09:49 -0700 Message-Id: <20230711220949.71881-4-srinivas.pandruvada@linux.intel.com> X-Mailer: git-send-email 2.40.1 In-Reply-To: <20230711220949.71881-1-srinivas.pandruvada@linux.intel.com> References: <20230711220949.71881-1-srinivas.pandruvada@linux.intel.com> MIME-Version: 1.0 X-Spam-Status: No, score=-2.0 required=5.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_EF,RCVD_IN_DNSWL_BLOCKED, SPF_HELO_NONE,SPF_NONE,T_SCC_BODY_TEXT_LINE,URIBL_BLOCKED autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1771166516068121228 X-GMAIL-MSGID: 1771166516068121228 Describe fields in the TPMI debugfs folder. Signed-off-by: Srinivas Pandruvada --- v2 New. Documentation/ABI/testing/debugfs-tpmi | 31 ++++++++++++++++++++++++++ MAINTAINERS | 1 + 2 files changed, 32 insertions(+) create mode 100644 Documentation/ABI/testing/debugfs-tpmi diff --git a/Documentation/ABI/testing/debugfs-tpmi b/Documentation/ABI/testing/debugfs-tpmi new file mode 100644 index 000000000000..9b530c1aaa2d --- /dev/null +++ b/Documentation/ABI/testing/debugfs-tpmi @@ -0,0 +1,31 @@ +What: /sys/kernel/debug/tpmi-/pfs_dump +Date: December 2023 +KernelVersion: 6.6 +Contact: srinivas.pandruvada@linux.intel.com +Description: +The PFS (PM Feature Structure) table, shows details of each power +management feature. This includes: +tpmi_id, number of entries, entry size, offset, vsec offset, lock status +and disabled status. +Users: Debugging, any user space test suite + +What: /sys/kernel/debug/tpmi-/tpmi-id-/mem_dump +Date: December 2023 +KernelVersion: 6.6 +Contact: srinivas.pandruvada@linux.intel.com +Description: +Shows the memory dump of the MMIO region for a TPMI ID. +Users: Debugging, any user space test suite + +What: /sys/kernel/debug/tpmi-/tpmi-id-/mem_write +Date: December 2023 +KernelVersion: 6.6 +Contact: srinivas.pandruvada@linux.intel.com +Description: +Allows to write at any offset. It doesn't check for Read/Write access +as hardware will not allow to write at read-only memory. This write is +at offset multiples of 4. The format is instance,offset,contents. +Example: +echo 0,0x20,0xff > mem_write +echo 1,64,64 > mem_write +Users: Debugging, any user space test suite diff --git a/MAINTAINERS b/MAINTAINERS index 5761b02183a7..4d439121fb36 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -10720,6 +10720,7 @@ INTEL TPMI DRIVER M: Srinivas Pandruvada L: platform-driver-x86@vger.kernel.org S: Maintained +F: Documentation/ABI/testing/debugfs-tpmi F: drivers/platform/x86/intel/tpmi.c F: include/linux/intel_tpmi.h