From patchwork Fri Feb 19 12:42:04 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Stefan Berger X-Patchwork-Id: 585185 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 A5C60140556 for ; Fri, 19 Feb 2016 23:42:31 +1100 (AEDT) Received: from localhost ([127.0.0.1] helo=sfs-ml-2.v29.ch3.sourceforge.com) by sfs-ml-2.v29.ch3.sourceforge.com with esmtp (Exim 4.76) (envelope-from ) id 1aWkO9-0002Cc-Ld; Fri, 19 Feb 2016 12:42:25 +0000 Received: from sog-mx-4.v43.ch3.sourceforge.com ([172.29.43.194] helo=mx.sourceforge.net) by sfs-ml-2.v29.ch3.sourceforge.com with esmtp (Exim 4.76) (envelope-from ) id 1aWkO8-0002CL-35 for tpmdd-devel@lists.sourceforge.net; Fri, 19 Feb 2016 12:42:24 +0000 X-ACL-Warn: Received: from e34.co.us.ibm.com ([32.97.110.152]) by sog-mx-4.v43.ch3.sourceforge.com with esmtps (TLSv1:AES256-SHA:256) (Exim 4.76) id 1aWkO7-0000d1-3F for tpmdd-devel@lists.sourceforge.net; Fri, 19 Feb 2016 12:42:24 +0000 Received: from localhost by e34.co.us.ibm.com with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted for from ; Fri, 19 Feb 2016 05:42:17 -0700 Received: from d03dlp03.boulder.ibm.com (9.17.202.179) by e34.co.us.ibm.com (192.168.1.134) with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted; Fri, 19 Feb 2016 05:42:16 -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 b03cxnp07028.gho.boulder.ibm.com (b03cxnp07028.gho.boulder.ibm.com [9.17.130.15]) by d03dlp03.boulder.ibm.com (Postfix) with ESMTP id 1ED4719D8041 for ; Fri, 19 Feb 2016 05:30:13 -0700 (MST) Received: from d03av03.boulder.ibm.com (d03av03.boulder.ibm.com [9.17.195.169]) by b03cxnp07028.gho.boulder.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id u1JCgFgc31260924 for ; Fri, 19 Feb 2016 05:42:15 -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 u1JCgElm029156 for ; Fri, 19 Feb 2016 05:42:15 -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 u1JCgALK028880; Fri, 19 Feb 2016 05:42:14 -0700 From: Stefan Berger To: tpmdd-devel@lists.sourceforge.net Date: Fri, 19 Feb 2016 07:42:04 -0500 Message-Id: <1455885728-10315-8-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-0017-0000-0000-0000124852EE X-Spam-Score: -0.0 (/) X-Spam-Report: Spam Filtering performed by mx.sourceforge.net. See http://spamassassin.org/tag/ for more details. -0.0 RP_MATCHES_RCVD Envelope sender domain matches handover relay domain X-Headers-End: 1aWkO7-0000d1-3F Subject: [tpmdd-devel] [PATCH v3 07/11] tpm: Replace device number bitmap with IDR 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 Replace the device number bitmap with IDR. Extend the number of devices we can create to 64k. Since an IDR allows us to associate a pointer with an ID, we use this now to rewrite tpm_chip_find_get() to simply look up the chip pointer by the given device ID. Protect the IDR calls with a mutex. Signed-off-by: Stefan Berger --- drivers/char/tpm/tpm-chip.c | 81 +++++++++++++++++++++------------------- drivers/char/tpm/tpm-interface.c | 1 + drivers/char/tpm/tpm.h | 5 +-- 3 files changed, 46 insertions(+), 41 deletions(-) diff --git a/drivers/char/tpm/tpm-chip.c b/drivers/char/tpm/tpm-chip.c index 2270e47..4fd36ba 100644 --- a/drivers/char/tpm/tpm-chip.c +++ b/drivers/char/tpm/tpm-chip.c @@ -29,9 +29,8 @@ #include "tpm.h" #include "tpm_eventlog.h" -static DECLARE_BITMAP(dev_mask, TPM_NUM_DEVICES); -static LIST_HEAD(tpm_chip_list); -static DEFINE_SPINLOCK(driver_lock); +DEFINE_IDR(dev_nums_idr); +static DEFINE_MUTEX(idr_lock); struct class *tpm_class; dev_t tpm_devt; @@ -88,18 +87,27 @@ EXPORT_SYMBOL_GPL(tpm_put_ops); */ struct tpm_chip *tpm_chip_find_get(int chip_num) { - struct tpm_chip *pos, *chip = NULL; + struct tpm_chip *chip; + int chip_next, chip_prev; - rcu_read_lock(); - list_for_each_entry_rcu(pos, &tpm_chip_list, list) { - if (chip_num != TPM_ANY_NUM && chip_num != pos->dev_num) - continue; + if (chip_num == TPM_ANY_NUM) + chip_next = 0; + + mutex_lock(&idr_lock); + + do { + if (chip_num == TPM_ANY_NUM) { + chip_prev = chip_next; + chip = idr_get_next(&dev_nums_idr, &chip_next); + } else + chip = idr_find_slowpath(&dev_nums_idr, chip_num); + + if (chip && !tpm_try_get_ops(chip)) + break; + } while (chip_num == TPM_ANY_NUM && chip_prev != chip_next); + + mutex_unlock(&idr_lock); - if (!tpm_try_get_ops(pos)) - chip = pos; - break; - } - rcu_read_unlock(); return chip; } @@ -113,9 +121,10 @@ static void tpm_dev_release(struct device *dev) { struct tpm_chip *chip = container_of(dev, struct tpm_chip, dev); - spin_lock(&driver_lock); - clear_bit(chip->dev_num, dev_mask); - spin_unlock(&driver_lock); + mutex_lock(&idr_lock); + idr_remove(&dev_nums_idr, chip->dev_num); + mutex_unlock(&idr_lock); + kfree(chip); } @@ -141,19 +150,16 @@ struct tpm_chip *tpm_chip_alloc(struct device *dev, init_rwsem(&chip->ops_sem); mutex_init(&chip->tpm_mutex); - INIT_LIST_HEAD(&chip->list); - - spin_lock(&driver_lock); - chip->dev_num = find_first_zero_bit(dev_mask, TPM_NUM_DEVICES); - if (chip->dev_num < TPM_NUM_DEVICES) - set_bit(chip->dev_num, dev_mask); - spin_unlock(&driver_lock); - if (chip->dev_num >= TPM_NUM_DEVICES) { + mutex_lock(&idr_lock); + err = idr_alloc(&dev_nums_idr, NULL, 0, TPM_NUM_DEVICES, GFP_KERNEL); + mutex_unlock(&idr_lock); + if (err < 0) { dev_err(dev, "No available tpm device numbers\n"); kfree(chip); - return ERR_PTR(-ENOMEM); + return ERR_PTR(err); } + chip->dev_num = err; chip->ops = ops; @@ -247,12 +253,6 @@ static int tpm_dev_add_device(struct tpm_chip *chip) static void tpm_dev_del_device(struct tpm_chip *chip) { cdev_del(&chip->cdev); - - /* Make the driver uncallable. */ - down_write(&chip->ops_sem); - chip->ops = NULL; - up_write(&chip->ops_sem); - device_del(&chip->dev); } @@ -312,9 +312,9 @@ int tpm_chip_register(struct tpm_chip *chip) goto out_err; /* Make the chip available. */ - spin_lock(&driver_lock); - list_add_tail_rcu(&chip->list, &tpm_chip_list); - spin_unlock(&driver_lock); + mutex_lock(&idr_lock); + idr_replace(&dev_nums_idr, chip, chip->dev_num); + mutex_unlock(&idr_lock); chip->flags |= TPM_CHIP_FLAG_REGISTERED; @@ -349,10 +349,15 @@ void tpm_chip_unregister(struct tpm_chip *chip) if (!(chip->flags & TPM_CHIP_FLAG_REGISTERED)) return; - spin_lock(&driver_lock); - list_del_rcu(&chip->list); - spin_unlock(&driver_lock); - synchronize_rcu(); + /* Make the driver uncallable. */ + down_write(&chip->ops_sem); + chip->ops = NULL; + up_write(&chip->ops_sem); + + /* hide the chip now */ + mutex_lock(&idr_lock); + idr_replace(&dev_nums_idr, NULL, chip->dev_num); + mutex_unlock(&idr_lock); if (!(chip->flags & TPM_CHIP_FLAG_TPM2)) sysfs_remove_link(&chip->dev.parent->kobj, "ppi"); diff --git a/drivers/char/tpm/tpm-interface.c b/drivers/char/tpm/tpm-interface.c index 1dfe2ce..f2ae217 100644 --- a/drivers/char/tpm/tpm-interface.c +++ b/drivers/char/tpm/tpm-interface.c @@ -1121,6 +1121,7 @@ static int __init tpm_init(void) static void __exit tpm_exit(void) { + idr_destroy(&dev_nums_idr); class_destroy(tpm_class); unregister_chrdev_region(tpm_devt, TPM_NUM_DEVICES); } diff --git a/drivers/char/tpm/tpm.h b/drivers/char/tpm/tpm.h index 25efe8f..2ca5fb4 100644 --- a/drivers/char/tpm/tpm.h +++ b/drivers/char/tpm/tpm.h @@ -34,7 +34,7 @@ enum tpm_const { TPM_MINOR = 224, /* officially assigned */ TPM_BUFSIZE = 4096, - TPM_NUM_DEVICES = 256, + TPM_NUM_DEVICES = 65536, TPM_RETRY = 50, /* 5 seconds */ }; @@ -199,8 +199,6 @@ struct tpm_chip { acpi_handle acpi_dev_handle; char ppi_version[TPM_PPI_VERSION_LEN + 1]; #endif /* CONFIG_ACPI */ - - struct list_head list; }; #define to_tpm_chip(d) container_of(d, struct tpm_chip, dev) @@ -496,6 +494,7 @@ static inline void tpm_buf_append_u32(struct tpm_buf *buf, const u32 value) extern struct class *tpm_class; extern dev_t tpm_devt; extern const struct file_operations tpm_fops; +extern struct idr dev_nums_idr; ssize_t tpm_getcap(struct device *, __be32, cap_t *, const char *); ssize_t tpm_transmit(struct tpm_chip *chip, const char *buf,