Received: by 2002:ad5:474a:0:0:0:0:0 with SMTP id i10csp5297110imu; Tue, 13 Nov 2018 04:29:50 -0800 (PST) X-Google-Smtp-Source: AJdET5c1VumLejyoaLVeBZA/ZdoNA54TrjUxl7XRzNn2M1tIMLBzlFB73VBrv2l7wSV7tHZsQP5x X-Received: by 2002:a17:902:6949:: with SMTP id k9-v6mr2327060plt.84.1542112190432; Tue, 13 Nov 2018 04:29:50 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1542112190; cv=none; d=google.com; s=arc-20160816; b=znt32+NfLrhIIrRznGWKHJXS5Z1aDrQNd8knK76nFzlLMSSnL6a3+QyJCWaCdzpQYB hFg1DZ6dnOwgL79PXGN7zUdIgYHplmrhNVJWiDFFu4NuLAP0Notu7LsIHP8lr6WmiO+Q lgMD6zPGZDWhhkEJOu1KkG7PxIXO9W1VFqBCQjTk9+2LWuhPpvAovEtBoY0hskusGntA 5331Fs48izVDmN3+NF0U+r3NlLRJqEUjEnlA3oN9J9WMhAcGQG2qlZCO9v0BM3FUuLQT oGSyllgYqV7KOoo87g6ICBLCmCm3qNqV1wx4XCZX5biVD7Y/XeyT33/U5malAw+5j/S/ 6iNQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from; bh=IuCxfBVY6LS1qbSqgisLgWP8H5ih03QBkxCEQeHQErk=; b=mrx5+IaAANy0Vhr/3vXP6dw/6zFwU33VNVFLc7rX+3veNoXCdRoSen9kv965D7Y+ro wFn9X1d6+NMkPIWnzB1HTFaET3E6L+q9QlQqkL3aKuL/9Kj2v/fwlGqLIGTodXs9iTs4 fi/lgiR9h/vUffGsNZb4hZfpQJARUtXtTluLmnyKWmLd4V08tsRLcvkL9T9BldQ9By1w EeDIX4NS3S+DDRUrfMCEmhL7Z+SHyzyirlzwTjtD/I+U90KyD8pi/kluStQm36qAnzcy nYdFGhcKZ8slWhcsVpJH6LqEn4wbjq/sIH/0jdwSLnhimt/MDC95qTr21yuhQVfGOEZl 2Zyg== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=intel.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id q9si19997507pgi.89.2018.11.13.04.29.34; Tue, 13 Nov 2018 04:29:50 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=intel.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1733288AbeKMW00 (ORCPT + 99 others); Tue, 13 Nov 2018 17:26:26 -0500 Received: from mga03.intel.com ([134.134.136.65]:53375 "EHLO mga03.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1732645AbeKMW00 (ORCPT ); Tue, 13 Nov 2018 17:26:26 -0500 X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from orsmga002.jf.intel.com ([10.7.209.21]) by orsmga103.jf.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 13 Nov 2018 04:28:31 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.54,499,1534834800"; d="scan'208";a="108176700" Received: from ibanaga-mobl1.ger.corp.intel.com (HELO localhost) ([10.249.254.77]) by orsmga002.jf.intel.com with ESMTP; 13 Nov 2018 04:28:24 -0800 From: Jarkko Sakkinen To: linux-integrity@vger.kernel.org Cc: linux-security-module@vger.kernel.org, James Bottomley , Tomas Winkler , Tadeusz Struk , Stefan Berger , Nayna Jain , Jarkko Sakkinen , Peter Huewe , Jason Gunthorpe , Arnd Bergmann , Greg Kroah-Hartman , linux-kernel@vger.kernel.org (open list) Subject: [PATCH v6 15/17] tpm: introduce tpm_chip_start() and tpm_chip_stop() Date: Tue, 13 Nov 2018 14:26:04 +0200 Message-Id: <20181113122609.21643-16-jarkko.sakkinen@linux.intel.com> X-Mailer: git-send-email 2.19.1 In-Reply-To: <20181113122609.21643-1-jarkko.sakkinen@linux.intel.com> References: <20181113122609.21643-1-jarkko.sakkinen@linux.intel.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Encapsulate power gating and locality functionality to tpm_chip_start() and tpm_chip_stop() in order to clean up the branching mess in tpm_transmit(). Signed-off-by: Jarkko Sakkinen --- drivers/char/tpm/tpm-chip.c | 110 +++++++++++++++++++++++++++++++ drivers/char/tpm/tpm-interface.c | 87 +----------------------- drivers/char/tpm/tpm.h | 2 + 3 files changed, 115 insertions(+), 84 deletions(-) diff --git a/drivers/char/tpm/tpm-chip.c b/drivers/char/tpm/tpm-chip.c index 157505b0f755..65f1561eba81 100644 --- a/drivers/char/tpm/tpm-chip.c +++ b/drivers/char/tpm/tpm-chip.c @@ -37,6 +37,116 @@ struct class *tpm_class; struct class *tpmrm_class; dev_t tpm_devt; +static int tpm_request_locality(struct tpm_chip *chip, unsigned int flags) +{ + int rc; + + if (flags & TPM_TRANSMIT_NESTED) + return 0; + + if (!chip->ops->request_locality) + return 0; + + rc = chip->ops->request_locality(chip, 0); + if (rc < 0) + return rc; + + chip->locality = rc; + return 0; +} + +static void tpm_relinquish_locality(struct tpm_chip *chip, unsigned int flags) +{ + int rc; + + if (flags & TPM_TRANSMIT_NESTED) + return; + + if (!chip->ops->relinquish_locality) + return; + + rc = chip->ops->relinquish_locality(chip, chip->locality); + if (rc) + dev_err(&chip->dev, "%s: : error %d\n", __func__, rc); + + chip->locality = -1; +} + +static int tpm_cmd_ready(struct tpm_chip *chip, unsigned int flags) +{ + if (flags & TPM_TRANSMIT_NESTED) + return 0; + + if (!chip->ops->cmd_ready) + return 0; + + return chip->ops->cmd_ready(chip); +} + +static int tpm_go_idle(struct tpm_chip *chip, unsigned int flags) +{ + if (flags & TPM_TRANSMIT_NESTED) + return 0; + + if (!chip->ops->go_idle) + return 0; + + return chip->ops->go_idle(chip); +} + +/** + * tpm_chip_start() - power on the TPM + * @chip: a TPM chip to use + * @flags: TPM transmit flags + * + * Return: + * * The response length - OK + * * -errno - A system error + */ +int tpm_chip_start(struct tpm_chip *chip, unsigned int flags) +{ + int ret; + + if (chip->ops->clk_enable) + chip->ops->clk_enable(chip, true); + + if (chip->locality == -1) { + ret = tpm_request_locality(chip, flags); + if (ret) { + chip->ops->clk_enable(chip, false); + return ret; + } + } + + ret = tpm_cmd_ready(chip, flags); + if (ret) { + tpm_relinquish_locality(chip, flags); + if (chip->ops->clk_enable) + chip->ops->clk_enable(chip, false); + return ret; + } + + return 0; +} + +/** + * tpm_chip_stop() - power off the TPM + * @chip: a TPM chip to use + * @flags: TPM transmit flags + * + * Return: + * * The response length - OK + * * -errno - A system error + */ +void tpm_chip_stop(struct tpm_chip *chip, unsigned int flags) +{ + tpm_go_idle(chip, flags); + tpm_relinquish_locality(chip, flags); + if (chip->ops->clk_enable) + chip->ops->clk_enable(chip, false); +} + + /** * tpm_try_get_ops() - Get a ref to the tpm_chip * @chip: Chip to ref diff --git a/drivers/char/tpm/tpm-interface.c b/drivers/char/tpm/tpm-interface.c index 5865b9671d20..888c9923fca1 100644 --- a/drivers/char/tpm/tpm-interface.c +++ b/drivers/char/tpm/tpm-interface.c @@ -62,64 +62,6 @@ unsigned long tpm_calc_ordinal_duration(struct tpm_chip *chip, u32 ordinal) } EXPORT_SYMBOL_GPL(tpm_calc_ordinal_duration); -static int tpm_request_locality(struct tpm_chip *chip, unsigned int flags) -{ - int rc; - - if (flags & TPM_TRANSMIT_NESTED) - return 0; - - if (!chip->ops->request_locality) - return 0; - - rc = chip->ops->request_locality(chip, 0); - if (rc < 0) - return rc; - - chip->locality = rc; - - return 0; -} - -static void tpm_relinquish_locality(struct tpm_chip *chip, unsigned int flags) -{ - int rc; - - if (flags & TPM_TRANSMIT_NESTED) - return; - - if (!chip->ops->relinquish_locality) - return; - - rc = chip->ops->relinquish_locality(chip, chip->locality); - if (rc) - dev_err(&chip->dev, "%s: : error %d\n", __func__, rc); - - chip->locality = -1; -} - -static int tpm_cmd_ready(struct tpm_chip *chip, unsigned int flags) -{ - if (flags & TPM_TRANSMIT_NESTED) - return 0; - - if (!chip->ops->cmd_ready) - return 0; - - return chip->ops->cmd_ready(chip); -} - -static int tpm_go_idle(struct tpm_chip *chip, unsigned int flags) -{ - if (flags & TPM_TRANSMIT_NESTED) - return 0; - - if (!chip->ops->go_idle) - return 0; - - return chip->ops->go_idle(chip); -} - static ssize_t tpm_try_transmit(struct tpm_chip *chip, u8 *buf, size_t bufsiz, unsigned int flags) { @@ -212,7 +154,6 @@ ssize_t tpm_transmit(struct tpm_chip *chip, u8 *buf, size_t bufsiz, /* space for header and handles */ u8 save[TPM_HEADER_SIZE + 3*sizeof(u32)]; unsigned int delay_msec = TPM2_DURATION_SHORT; - bool has_locality = false; u32 rc = 0; ssize_t ret; const size_t save_size = min(sizeof(save), bufsiz); @@ -227,34 +168,12 @@ ssize_t tpm_transmit(struct tpm_chip *chip, u8 *buf, size_t bufsiz, memcpy(save, buf, save_size); for (;;) { - if (chip->ops->clk_enable != NULL) - chip->ops->clk_enable(chip, true); - - if (chip->locality == -1) { - ret = tpm_request_locality(chip, flags); - if (ret) - goto out_locality; - has_locality = true; - } - - ret = tpm_cmd_ready(chip, flags); + ret = tpm_chip_start(chip, flags); if (ret) - goto out_locality; - + return ret; ret = tpm_try_transmit(chip, buf, bufsiz, flags); + tpm_chip_stop(chip, flags); - /* This may fail but do not override ret. */ - tpm_go_idle(chip, flags); - -out_locality: - if (has_locality) - tpm_relinquish_locality(chip, flags); - - if (chip->ops->clk_enable != NULL) - chip->ops->clk_enable(chip, false); - - if (ret < 0) - break; rc = be32_to_cpu(header->return_code); if (rc != TPM2_RC_RETRY && rc != TPM2_RC_TESTING) break; diff --git a/drivers/char/tpm/tpm.h b/drivers/char/tpm/tpm.h index c7c06de651a0..c42a75710b70 100644 --- a/drivers/char/tpm/tpm.h +++ b/drivers/char/tpm/tpm.h @@ -523,6 +523,8 @@ static inline void tpm_msleep(unsigned int delay_msec) delay_msec * 1000); }; +int tpm_chip_start(struct tpm_chip *chip, unsigned int flags); +void tpm_chip_stop(struct tpm_chip *chip, unsigned int flags); struct tpm_chip *tpm_find_get_ops(struct tpm_chip *chip); __must_check int tpm_try_get_ops(struct tpm_chip *chip); void tpm_put_ops(struct tpm_chip *chip); -- 2.19.1