Received: by 2002:ad5:474a:0:0:0:0:0 with SMTP id i10csp144928imu; Thu, 8 Nov 2018 06:19:41 -0800 (PST) X-Google-Smtp-Source: AJdET5dHWFPwPsVVzKWWZkfgsw4omanNeOSpuNGGpzCdN4byU2LUmMHVBS3Ql0ev0PoxKzEy4LAT X-Received: by 2002:a62:32c4:: with SMTP id y187-v6mr4741784pfy.4.1541686781389; Thu, 08 Nov 2018 06:19:41 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1541686781; cv=none; d=google.com; s=arc-20160816; b=iXV6rGfmiEmE5Y4S9YRbpU1+X2QDr8B395HUvKqWDwIMIJSLH/+BcXhNo6nLat7Y4r c1/6XRH0zI6EolXkwMcZ5J8lRzlaewmGXzFmCH2DPgc85lB8K7GD5prDrO26YCxxVnOJ n7pALTcCSAWF9rLJbeoDrUpFkoAT3elzzLT1/1zipuUrwUR+QkZM1o9MgQtfWlFfr6rE T4y0Yix1I6THalzKRExFT026EfVqN7eQ2Rp70AfCIMs7qtOw20Age7eDk62HZFctpOJy Wgue7P6EzmBvQDDfwZTU/2cGxK91tVPm5hQR5YjbnVHjpkRplaMY7eiVLT9jpgqg5CQj 4tSw== 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=PWdZvt9SQMjzDMYsuz317drXV+s9zZdii3R+Ww1mhtLpiaF0RKbYCuy+HMc2a8WWzF ow1fGHjty94w2bfKKBiw8Yb8kBKC1Z+sx4xnRfN9ZJ78MosP5FBFnRSbtg7cr+gGskte dAsX2gnE0L5SH/jQ0Fh5W/6HAoZWA1p45Z0MJPqNLVNq3HBtkZuybxutUVfRdPL7aHOK SfFHBQbiGb93egRP40npz0omt0fY3KoDVtp8AZEQX4e7Yok+Wz/bXf/yQEJ5uq4mW1wu nLSmxfA7Fw7D8EKw5qY/+MQaeKaEYxUVKx2Oa2m2twL8ILIYxCmWhLLDyTWMiyrLbazX lpBg== 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 m26-v6si4344833pfe.80.2018.11.08.06.19.25; Thu, 08 Nov 2018 06:19:41 -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 S1727366AbeKHXxl (ORCPT + 99 others); Thu, 8 Nov 2018 18:53:41 -0500 Received: from mga12.intel.com ([192.55.52.136]:28392 "EHLO mga12.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726417AbeKHXxl (ORCPT ); Thu, 8 Nov 2018 18:53:41 -0500 X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from orsmga001.jf.intel.com ([10.7.209.18]) by fmsmga106.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 08 Nov 2018 06:18:00 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.54,478,1534834800"; d="scan'208";a="106534477" Received: from ibanaga-mobl1.ger.corp.intel.com (HELO localhost) ([10.249.254.75]) by orsmga001.jf.intel.com with ESMTP; 08 Nov 2018 06:17:53 -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 v5 15/17] tpm: introduce tpm_chip_start() and tpm_chip_stop() Date: Thu, 8 Nov 2018 16:15:36 +0200 Message-Id: <20181108141541.12832-16-jarkko.sakkinen@linux.intel.com> X-Mailer: git-send-email 2.19.1 In-Reply-To: <20181108141541.12832-1-jarkko.sakkinen@linux.intel.com> References: <20181108141541.12832-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