From patchwork Fri May 12 23:40:58 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Josh Zimmerman X-Patchwork-Id: 761883 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.sourceforge.net (lists.sourceforge.net [216.34.181.88]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 3wPmhM0SPvz9s7w for ; Sat, 13 May 2017 09:41:23 +1000 (AEST) Received: from localhost ([127.0.0.1] helo=sfs-ml-4.v29.ch3.sourceforge.com) by sfs-ml-4.v29.ch3.sourceforge.com with esmtp (Exim 4.76) (envelope-from ) id 1d9KBS-0006hy-PB; Fri, 12 May 2017 23:41:18 +0000 Received: from sog-mx-3.v43.ch3.sourceforge.com ([172.29.43.193] helo=mx.sourceforge.net) by sfs-ml-4.v29.ch3.sourceforge.com with esmtp (Exim 4.76) (envelope-from ) id 1d9KBR-0006hs-2W for tpmdd-devel@lists.sourceforge.net; Fri, 12 May 2017 23:41:17 +0000 Received-SPF: pass (sog-mx-3.v43.ch3.sourceforge.com: domain of google.com designates 74.125.83.52 as permitted sender) client-ip=74.125.83.52; envelope-from=joshz@google.com; helo=mail-pg0-f52.google.com; Received: from mail-pg0-f52.google.com ([74.125.83.52]) by sog-mx-3.v43.ch3.sourceforge.com with esmtps (TLSv1:AES128-SHA:128) (Exim 4.76) id 1d9KBN-0003F6-Is for tpmdd-devel@lists.sourceforge.net; Fri, 12 May 2017 23:41:17 +0000 Received: by mail-pg0-f52.google.com with SMTP id u28so36568569pgn.1 for ; Fri, 12 May 2017 16:41:13 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id; bh=PKLVCIUsAHvJ5yHTC/n3rXOa7ILAeV+wCvETvVLUqUY=; b=fa3TjvHavfHnxn89jFRD1zfW1e8DMz8oU1RW+HICja0XWkaUgBz2nBgZMw0ojleBXo dWYnlTEozB2iGKCGMP7GGKwIhCALV3RStY0YVxtrsGdKqAu0X1iVX1jmM9G0/C7cT+XH fljZxIed3sj0aSjtytd0Gfv1uDFMIaYrFCgWgoQKWvrGVlEd2YcV3383NoWPRytHKey5 fVLjL5YLCZJ3yEEU2fGZ89sXzuotAAp/Zua1QYIOq3wd0FF3vt7/Cl6yXxfI5LJhOsp7 J4WH1gUeFRkZtLOBPyZE4fv4+vPSoIk2kAmnOXDfpJnr0ITq5Ze/yrtTFm4c0Lm0VU4O NzsA== X-Gm-Message-State: AODbwcCUrE/D3k0dxYmKYATJA+sF2MqhMzKjhlHXM9U3HvcKKcCOkAHp OD6rUccEbu6T4FA5BFyexg== X-Received: by 10.99.127.80 with SMTP id p16mr6743131pgn.180.1494632467700; Fri, 12 May 2017 16:41:07 -0700 (PDT) Received: from angband.kir.corp.google.com ([100.119.30.20]) by smtp.googlemail.com with ESMTPSA id 190sm7358303pfz.15.2017.05.12.16.41.07 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Fri, 12 May 2017 16:41:07 -0700 (PDT) From: Josh Zimmerman To: Peter Huewe , Marcel Selhorst , Jarkko Sakkinen , Jason Gunthorpe , tpmdd-devel@lists.sourceforge.net Date: Fri, 12 May 2017 16:40:58 -0700 Message-Id: <20170512234058.25716-1-joshz@google.com> X-Mailer: git-send-email 2.13.0.rc2.291.g57267f2277-goog X-Spam-Score: -1.1 (-) X-Spam-Report: Spam Filtering performed by mx.sourceforge.net. See http://spamassassin.org/tag/ for more details. -0.0 RCVD_IN_DNSWL_NONE RBL: Sender listed at http://www.dnswl.org/, no trust [74.125.83.52 listed in list.dnswl.org] -1.5 SPF_CHECK_PASS SPF reports sender host as permitted sender for sender-domain -0.0 SPF_PASS SPF: sender matches SPF record -0.0 RP_MATCHES_RCVD Envelope sender domain matches handover relay domain -0.1 DKIM_VALID_AU Message has a valid DKIM or DK signature from author's domain 0.1 DKIM_SIGNED Message has a DKIM or DK signature, not necessarily valid -0.1 DKIM_VALID Message has at least one valid DKIM or DK signature 0.5 RCVD_IN_SORBS_SPAM RBL: SORBS: sender is a spam source [74.125.83.52 listed in dnsbl.sorbs.net] X-Headers-End: 1d9KBN-0003F6-Is Subject: [tpmdd-devel] [PATCH] tpm: Issue a TPM2_Shutdown for TPM2 devices. X-BeenThere: tpmdd-devel@lists.sourceforge.net X-Mailman-Version: 2.1.9 Precedence: list List-Id: Tpm Device Driver maintainance List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: tpmdd-devel-bounces@lists.sourceforge.net If a TPM2 loses power without a TPM2_Shutdown command being issued, it may lose some state that has yet to be persisted to NVRam, and will increment the DA counter (meaning that after too many disorderly reboots, the TPM will lock the user out). This is a variant of https://patchwork.kernel.org/patch/9516631/. It differs in that: * It only changes behavior on TPM2 devices, to avoid invoking the unbounded-waiting sysfs codepath that was discussed on that patch, and to avoid racing on chip->ops. * It modifies tpm-chip rather than tpm_i2c_infineon, so that it can change behavior for all TPM2 devices. This patch is dependent on '[PATCH] Add "shutdown" to "struct class".' http://marc.info/?l=linux-kernel&m=149463235025420&w=2 Signed-off-by: Josh Zimmerman --- drivers/base/core.c | 5 +++++ drivers/char/tpm/tpm-chip.c | 19 +++++++++++++++++++ drivers/char/tpm/tpm-sysfs.c | 2 ++ include/linux/device.h | 4 +++- 4 files changed, 29 insertions(+), 1 deletion(-) diff --git a/drivers/base/core.c b/drivers/base/core.c index 6bb60fb6a30b..687668d9afbe 100644 --- a/drivers/base/core.c +++ b/drivers/base/core.c @@ -2667,6 +2667,11 @@ void device_shutdown(void) pm_runtime_get_noresume(dev); pm_runtime_barrier(dev); + if (dev->class && dev->class->shutdown) { + if (initcall_debug) + dev_info(dev, "shutdown\n"); + dev->class->shutdown(dev); + } if (dev->bus && dev->bus->shutdown) { if (initcall_debug) dev_info(dev, "shutdown\n"); diff --git a/drivers/char/tpm/tpm-chip.c b/drivers/char/tpm/tpm-chip.c index 9dec9f551b83..024dadc0a829 100644 --- a/drivers/char/tpm/tpm-chip.c +++ b/drivers/char/tpm/tpm-chip.c @@ -142,6 +142,24 @@ static void tpm_devs_release(struct device *dev) put_device(&chip->dev); } +static void tpm_shutdown(struct device *dev) +{ + struct tpm_chip *chip = container_of(dev, struct tpm_chip, dev); + // TPM 2.0 requires that the TPM2_Shutdown() command be issued prior to + // loss of power. If it is not, the DA counter will be incremented and, + // eventually, the user will be locked out of their TPM. + // XXX: This codepath relies on the fact that sysfs is not enabled for + // TPM2: sysfs uses an implicit lock on chip->ops, so this use could + // race if TPM2 has sysfs support enabled before TPM sysfs's implicit + // locking is fixed. + if (chip->flags & TPM_CHIP_FLAG_TPM2) { + down_read(&chip->ops_sem); + tpm2_shutdown(chip, TPM_SU_CLEAR); + chip->ops = NULL; + up_read(&chip->ops_sem); + } +} + /** * tpm_chip_alloc() - allocate a new struct tpm_chip instance * @pdev: device to which the chip is associated @@ -181,6 +199,7 @@ struct tpm_chip *tpm_chip_alloc(struct device *pdev, device_initialize(&chip->devs); chip->dev.class = tpm_class; + chip->dev.class.shutdown = tpm_shutdown; chip->dev.release = tpm_dev_release; chip->dev.parent = pdev; chip->dev.groups = chip->groups; diff --git a/drivers/char/tpm/tpm-sysfs.c b/drivers/char/tpm/tpm-sysfs.c index 55405dbe43fa..6256f6e174b0 100644 --- a/drivers/char/tpm/tpm-sysfs.c +++ b/drivers/char/tpm/tpm-sysfs.c @@ -294,6 +294,8 @@ static const struct attribute_group tpm_dev_group = { void tpm_sysfs_add_device(struct tpm_chip *chip) { + // XXX: Before this restriction is removed, tpm_sysfs must be updated + // to explicitly lock chip->ops. if (chip->flags & TPM_CHIP_FLAG_TPM2) return; diff --git a/include/linux/device.h b/include/linux/device.h index 9ef518af5515..a150f8d3b3f1 100644 --- a/include/linux/device.h +++ b/include/linux/device.h @@ -378,6 +378,7 @@ int subsys_virtual_register(struct bus_type *subsys, * @suspend: Used to put the device to sleep mode, usually to a low power * state. * @resume: Used to bring the device from the sleep mode. + * @shutdown: Called at shut-down time to quiesce the device. * @ns_type: Callbacks so sysfs can detemine namespaces. * @namespace: Namespace of the device belongs to this class. * @pm: The default device power management operations of this class. @@ -407,6 +408,7 @@ struct class { int (*suspend)(struct device *dev, pm_message_t state); int (*resume)(struct device *dev); + int (*shutdown)(struct device *dev); const struct kobj_ns_type_operations *ns_type; const void *(*namespace)(struct device *dev); @@ -1228,7 +1230,7 @@ static inline int devtmpfs_delete_node(struct device *dev) { return 0; } static inline int devtmpfs_mount(const char *mountpoint) { return 0; } #endif -/* drivers/base/power/shutdown.c */ +/* drivers/base/core.c */ extern void device_shutdown(void); /* debugging and troubleshooting/diagnostic helpers. */