From patchwork Fri Feb 19 12:42:07 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Stefan Berger X-Patchwork-Id: 8360561 Return-Path: X-Original-To: patchwork-tpmdd-devel@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork1.web.kernel.org (Postfix) with ESMTP id 57C509F372 for ; Fri, 19 Feb 2016 12:42:32 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 522AB20499 for ; Fri, 19 Feb 2016 12:42:31 +0000 (UTC) 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 mail.kernel.org (Postfix) with ESMTPS id 09DE7204A2 for ; Fri, 19 Feb 2016 12:42:30 +0000 (UTC) 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 1aWkOC-00074J-NH; Fri, 19 Feb 2016 12:42:28 +0000 Received: from sog-mx-2.v43.ch3.sourceforge.com ([172.29.43.192] helo=mx.sourceforge.net) by sfs-ml-4.v29.ch3.sourceforge.com with esmtp (Exim 4.76) (envelope-from ) id 1aWkOB-00073s-ON for tpmdd-devel@lists.sourceforge.net; Fri, 19 Feb 2016 12:42:27 +0000 X-ACL-Warn: Received: from e31.co.us.ibm.com ([32.97.110.149]) by sog-mx-2.v43.ch3.sourceforge.com with esmtps (TLSv1:AES256-SHA:256) (Exim 4.76) id 1aWkOA-0005Px-Ot for tpmdd-devel@lists.sourceforge.net; Fri, 19 Feb 2016 12:42:27 +0000 Received: from localhost by e31.co.us.ibm.com with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted for from ; Fri, 19 Feb 2016 05:42:20 -0700 Received: from d03dlp03.boulder.ibm.com (9.17.202.179) by e31.co.us.ibm.com (192.168.1.131) with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted; Fri, 19 Feb 2016 05:42:18 -0700 X-IBM-Helo: d03dlp03.boulder.ibm.com X-IBM-MailFrom: stefanb@linux.vnet.ibm.com X-IBM-RcptTo: tpmdd-devel@lists.sourceforge.net Received: from b03cxnp08026.gho.boulder.ibm.com (b03cxnp08026.gho.boulder.ibm.com [9.17.130.18]) by d03dlp03.boulder.ibm.com (Postfix) with ESMTP id 23F0B19D803F for ; Fri, 19 Feb 2016 05:30:15 -0700 (MST) Received: from d03av03.boulder.ibm.com (d03av03.boulder.ibm.com [9.17.195.169]) by b03cxnp08026.gho.boulder.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id u1JCgHEU25886954 for ; Fri, 19 Feb 2016 05:42:17 -0700 Received: from d03av03.boulder.ibm.com (localhost [127.0.0.1]) by d03av03.boulder.ibm.com (8.14.4/8.14.4/NCO v10.0 AVout) with ESMTP id u1JCgG4i029274 for ; Fri, 19 Feb 2016 05:42:17 -0700 Received: from dhcp-9-2-140-43.watson.ibm.com (dhcp-9-2-140-28.watson.ibm.com [9.2.140.28]) by d03av03.boulder.ibm.com (8.14.4/8.14.4/NCO v10.0 AVin) with ESMTP id u1JCgALN028880; Fri, 19 Feb 2016 05:42:16 -0700 From: Stefan Berger To: tpmdd-devel@lists.sourceforge.net Date: Fri, 19 Feb 2016 07:42:07 -0500 Message-Id: <1455885728-10315-11-git-send-email-stefanb@linux.vnet.ibm.com> X-Mailer: git-send-email 2.4.3 In-Reply-To: <1455885728-10315-1-git-send-email-stefanb@linux.vnet.ibm.com> References: <1455885728-10315-1-git-send-email-stefanb@linux.vnet.ibm.com> X-TM-AS-MML: disable X-Content-Scanned: Fidelis XPS MAILER x-cbid: 16021912-8236-0000-0000-000016456897 X-Spam-Score: -0.0 (/) X-Headers-End: 1aWkOA-0005Px-Ot Subject: [tpmdd-devel] [PATCH v3 10/11] tpm: Initialize TPM and get durations and timeouts 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 X-Spam-Status: No, score=-6.9 required=5.0 tests=BAYES_00, HK_RANDOM_ENVFROM, RCVD_IN_DNSWL_HI, RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Add the retrieval of TPM 1.2 durations and timeouts. Since this requires the startup of the TPM, do this for TPM 1.2 and TPM 2. Signed-off-by: Stefan Berger --- drivers/char/tpm/tpm-vtpm.c | 85 ++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 76 insertions(+), 9 deletions(-) diff --git a/drivers/char/tpm/tpm-vtpm.c b/drivers/char/tpm/tpm-vtpm.c index 823c94a..fc2fe53 100644 --- a/drivers/char/tpm/tpm-vtpm.c +++ b/drivers/char/tpm/tpm-vtpm.c @@ -45,8 +45,11 @@ struct vtpm_dev { size_t req_len; /* length of queued TPM request */ size_t resp_len; /* length of queued TPM response */ u8 buffer[TPM_BUFSIZE]; /* request/response buffer */ + + struct work_struct work; /* task that retrieves TPM timeouts */ }; +static struct workqueue_struct *workqueue; static void vtpm_delete_device_pair(struct vtpm_dev *vtpm_dev); @@ -67,6 +70,9 @@ static ssize_t vtpm_fops_read(struct file *filp, char __user *buf, size_t len; int sig, rc; + if (!test_bit(STATE_OPENED_BIT, &vtpm_dev->state)) + return -EPIPE; + sig = wait_event_interruptible(vtpm_dev->wq, vtpm_dev->req_len != 0); if (sig) return -EINTR; @@ -107,6 +113,9 @@ static ssize_t vtpm_fops_write(struct file *filp, const char __user *buf, { struct vtpm_dev *vtpm_dev = filp->private_data; + if (!test_bit(STATE_OPENED_BIT, &vtpm_dev->state)) + return -EPIPE; + if (count > sizeof(vtpm_dev->buffer) || !test_bit(STATE_WAIT_RESPONSE_BIT, &vtpm_dev->state)) return -EIO; @@ -147,6 +156,8 @@ static unsigned int vtpm_fops_poll(struct file *filp, poll_table *wait) ret = POLLOUT; if (vtpm_dev->req_len) ret |= POLLIN | POLLRDNORM; + if (!test_bit(STATE_OPENED_BIT, &vtpm_dev->state)) + ret |= POLLHUP; return ret; } @@ -320,6 +331,54 @@ static const struct tpm_class_ops vtpm_tpm_ops = { }; /* + * Code related to the startup of the TPM 2 and startup of TPM 1.2 + + * retrieval of timeouts and durations. + */ + +static void vtpm_dev_work(struct work_struct *work) +{ + struct vtpm_dev *vtpm_dev = container_of(work, struct vtpm_dev, work); + int rc; + + if (vtpm_dev->flags & VTPM_FLAG_TPM2) + rc = tpm2_startup(vtpm_dev->chip, TPM2_SU_CLEAR); + else + rc = tpm_get_timeouts(vtpm_dev->chip); + + if (rc) + goto err; + + rc = tpm_chip_register(vtpm_dev->chip); + if (rc) + goto err; + + return; + +err: + vtpm_fops_undo_open(vtpm_dev); +} + +/* + * vtpm_dev_work_stop: make sure the work has finished + * + * This function is useful when user space closed the fd + * while the driver still determines timeouts. + */ +static void vtpm_dev_work_stop(struct vtpm_dev *vtpm_dev) +{ + vtpm_fops_undo_open(vtpm_dev); + flush_work(&vtpm_dev->work); +} + +/* + * vtpm_dev_work_start: Schedule the work for TPM 1.2 & 2 initialization + */ +static inline void vtpm_dev_work_start(struct vtpm_dev *vtpm_dev) +{ + queue_work(workqueue, &vtpm_dev->work); +} + +/* * Code related to creation and deletion of device pairs */ static struct vtpm_dev *vtpm_create_vtpm_dev(void) @@ -334,6 +393,7 @@ static struct vtpm_dev *vtpm_create_vtpm_dev(void) init_waitqueue_head(&vtpm_dev->wq); spin_lock_init(&vtpm_dev->buf_lock); + INIT_WORK(&vtpm_dev->work, vtpm_dev_work); chip = tpm_chip_alloc(NULL, &vtpm_tpm_ops); if (IS_ERR(chip)) { @@ -401,9 +461,7 @@ static struct file *vtpm_create_device_pair( if (vtpm_dev->flags & VTPM_FLAG_TPM2) vtpm_dev->chip->flags |= TPM_CHIP_FLAG_TPM2; - rc = tpm_chip_register(vtpm_dev->chip); - if (rc) - goto err_vtpm_fput; + vtpm_dev_work_start(vtpm_dev); vtpm_new_pair->fd = fd; vtpm_new_pair->major = MAJOR(vtpm_dev->chip->dev.devt); @@ -412,12 +470,6 @@ static struct file *vtpm_create_device_pair( return file; -err_vtpm_fput: - put_unused_fd(fd); - fput(file); - - return ERR_PTR(rc); - err_put_unused_fd: put_unused_fd(fd); @@ -432,6 +484,8 @@ err_delete_vtpm_dev: */ static void vtpm_delete_device_pair(struct vtpm_dev *vtpm_dev) { + vtpm_dev_work_stop(vtpm_dev); + tpm_chip_unregister(vtpm_dev->chip); vtpm_fops_undo_open(vtpm_dev); @@ -526,11 +580,24 @@ static int __init vtpm_module_init(void) return rc; } + workqueue = create_workqueue("tpm-vtpm"); + if (!workqueue) { + pr_err("couldn't create workqueue\n"); + rc = -ENOMEM; + goto err_vtpmx_cleanup; + } + return 0; + +err_vtpmx_cleanup: + vtpmx_cleanup(); + + return rc; } static void __exit vtpm_module_exit(void) { + destroy_workqueue(workqueue); vtpmx_cleanup(); }