From: Jason G. <jgu...@ob...> - 2013-09-23 18:15:12
|
While writing two new TPM drivers I noticed that there was a big and growing mess in drivers/char/tpm. This series of patches is the first batch of patches containing my attempt to fix it. This series makes several small repetitive changes to all the drivers. These are bundled in with the commits changing the core, because the core API is changed and everything must be kept together to retain bisect-ability. I have decided not to tackle the lifetime issues in this series. My first attempt was flawed. I have presented the series in the full linear format. It is available on my github: https://github.com/jgunthorpe/linux/commits/tpm-devel The branch is not stable, I will rebase and rewrite history as needed. All patches have been compile tested on x86-64 (including vtpm, I have a hack to make that happen) and all patches are checkpatch.pl clean. I have tested tpm_tis (PPC32), tpm_i2c_atmel and tpm_i2c_nuvoton (ARM32) on my hardware here. There is very little new code here, the majority of lines is just code motion to remove duplication. Patches 1 -> 6, 12 - These are just simple cleanups that I discovered while doing the other work. Patch 7 - This is important to unify the sysfs code. I've choosen to simplify and not make the TPM version bus-dependent. Patch 8-9 - The drivers have this duplication of the file_operations and sysfs code. This series pulls all of that code out of the drivers and into the core Patches 10->11 - This is the first step in making the TPM subsystem be like other subsystems in the kernel. Patches 13 - This cleans up the struct tpm_chip by hiding stuff that isn't public This is already a fair clean up, but there is still more to do someday: * The lifetime issues around struct tpm_chip/etc and the way userspace can hold /dev/tpmX open even after the driver has detached. * struct tpm_chip and struct tpm_vendor_specific need to be merged * The above two structs have many members that are never used by the core code. These members need to be migrated into driver private structures * The resulting merged struct should live in linux/include/tpm.h like all other device classes in the kernel. * Several drivers need clean up to move singleton static variables into dynamic structures * Consolidate TCG defined constants that are duplicated in many drivers * Consolidate device startup (tpm_startup, tpm_get_timeoutes) into core code If this series is successful I may be able to do some of the above as well. Jason Gunthorpe (13): tpm: ibmvtpm: Use %zd formatting for size_t format arguments tpm atmel: Call request_region with the correct base tpm: xen-tpmfront: Fix default durations tpm: Store devname in the tpm_chip tpm: Use container_of to locate the tpm_chip in tpm_open tpm: Remove redundant dev_set_drvdata tpm: Remove tpm_show_caps_1_2 tpm: Pull everything related to /dev/tpmX into tpm-dev.c tpm: Pull everything related to sysfs into tpm-sysfs.c tpm: Create a tpm_class_ops structure and use it in the drivers tpm: Use the ops structure instead of a copy in tpm_vendor_specific tpm: st33: Remove chip->data_buffer access from this driver tpm: Make tpm-dev allocate a per-file structure drivers/char/tpm/Makefile | 2 +- drivers/char/tpm/tpm-dev.c | 213 +++++++++++++++ drivers/char/tpm/tpm-sysfs.c | 318 ++++++++++++++++++++++ drivers/char/tpm/tpm.c | 524 +++--------------------------------- drivers/char/tpm/tpm.h | 86 +++--- drivers/char/tpm/tpm_atmel.c | 30 +-- drivers/char/tpm/tpm_i2c_atmel.c | 42 +-- drivers/char/tpm/tpm_i2c_infineon.c | 44 +-- drivers/char/tpm/tpm_i2c_nuvoton.c | 42 +-- drivers/char/tpm/tpm_i2c_stm_st33.c | 51 +--- drivers/char/tpm/tpm_ibmvtpm.c | 44 +-- drivers/char/tpm/tpm_infineon.c | 28 +- drivers/char/tpm/tpm_nsc.c | 28 +- drivers/char/tpm/tpm_spi_stm_st33.c | 50 +--- drivers/char/tpm/tpm_tis.c | 43 +-- drivers/char/tpm/xen-tpmfront.c | 57 +--- include/linux/tpm.h | 15 ++ 17 files changed, 638 insertions(+), 979 deletions(-) create mode 100644 drivers/char/tpm/tpm-dev.c create mode 100644 drivers/char/tpm/tpm-sysfs.c -- 1.8.1.2 |
From: Jason G. <jgu...@ob...> - 2013-09-23 18:16:15
|
This suppresses compile warnings on 32 bit builds. Signed-off-by: Jason Gunthorpe <jgu...@ob...> --- drivers/char/tpm/tpm_ibmvtpm.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/char/tpm/tpm_ibmvtpm.c b/drivers/char/tpm/tpm_ibmvtpm.c index 56b07c3..838f043 100644 --- a/drivers/char/tpm/tpm_ibmvtpm.c +++ b/drivers/char/tpm/tpm_ibmvtpm.c @@ -98,7 +98,7 @@ static int tpm_ibmvtpm_recv(struct tpm_chip *chip, u8 *buf, size_t count) if (count < len) { dev_err(ibmvtpm->dev, - "Invalid size in recv: count=%ld, crq_size=%d\n", + "Invalid size in recv: count=%zd, crq_size=%d\n", count, len); return -EIO; } @@ -136,7 +136,7 @@ static int tpm_ibmvtpm_send(struct tpm_chip *chip, u8 *buf, size_t count) if (count > ibmvtpm->rtce_size) { dev_err(ibmvtpm->dev, - "Invalid size in send: count=%ld, rtce_size=%d\n", + "Invalid size in send: count=%zd, rtce_size=%d\n", count, ibmvtpm->rtce_size); return -EIO; } -- 1.8.1.2 |
From: Peter H. <Pet...@gm...> - 2013-10-01 21:57:21
|
Am Montag, 23. September 2013, 20:14:31 schrieb Jason Gunthorpe: > This suppresses compile warnings on 32 bit builds. > > Signed-off-by: Jason Gunthorpe <jgu...@ob...> Reviewed-by: Peter Huewe <pet...@gm...> Signed-off-by: Peter Huewe <pet...@gm...> Staged here https://github.com/PeterHuewe/linux-tpmdd for-james |
From: Ashley D L. <ad...@li...> - 2013-10-02 19:36:58
|
On Mon, 2013-09-23 at 12:14 -0600, Jason Gunthorpe wrote: > This suppresses compile warnings on 32 bit builds. > > Signed-off-by: Jason Gunthorpe <jgu...@ob...> Looks good to me. Acked-by: Ashley Lai <ad...@li...> Thanks, --Ashley Lai |
From: Jason G. <jgu...@ob...> - 2013-09-23 18:16:15
|
misc_open sets the file->private_date to the misc_dev when calling open. We can use container_of to go from the misc_dev back to the tpm_chip. Future clean ups will move tpm_open into a new file and this change means we do not have to export the tpm_chip list. Signed-off-by: Jason Gunthorpe <jgu...@ob...> --- drivers/char/tpm/tpm.c | 21 ++++----------------- 1 file changed, 4 insertions(+), 17 deletions(-) diff --git a/drivers/char/tpm/tpm.c b/drivers/char/tpm/tpm.c index 71eb8c7..c3ab508 100644 --- a/drivers/char/tpm/tpm.c +++ b/drivers/char/tpm/tpm.c @@ -1170,38 +1170,25 @@ EXPORT_SYMBOL_GPL(wait_for_tpm_stat); */ int tpm_open(struct inode *inode, struct file *file) { - int minor = iminor(inode); - struct tpm_chip *chip = NULL, *pos; - - rcu_read_lock(); - list_for_each_entry_rcu(pos, &tpm_chip_list, list) { - if (pos->vendor.miscdev.minor == minor) { - chip = pos; - get_device(chip->dev); - break; - } - } - rcu_read_unlock(); - - if (!chip) - return -ENODEV; + struct miscdevice *misc = file->private_data; + struct tpm_chip *chip = container_of(misc, struct tpm_chip, + vendor.miscdev); if (test_and_set_bit(0, &chip->is_open)) { dev_dbg(chip->dev, "Another process owns this TPM\n"); - put_device(chip->dev); return -EBUSY; } chip->data_buffer = kzalloc(TPM_BUFSIZE, GFP_KERNEL); if (chip->data_buffer == NULL) { clear_bit(0, &chip->is_open); - put_device(chip->dev); return -ENOMEM; } atomic_set(&chip->data_pending, 0); file->private_data = chip; + get_device(chip->dev); return 0; } EXPORT_SYMBOL_GPL(tpm_open); -- 1.8.1.2 |
From: Peter H. <Pet...@gm...> - 2013-10-01 22:00:09
|
Am Montag, 23. September 2013, 20:14:35 schrieb Jason Gunthorpe: > misc_open sets the file->private_date to the misc_dev when calling > open. We can use container_of to go from the misc_dev back to the > tpm_chip. > > Future clean ups will move tpm_open into a new file and this change > means we do not have to export the tpm_chip list. > > Signed-off-by: Jason Gunthorpe <jgu...@ob...> Reviewed-by: Peter Huewe <pet...@gm...> Signed-off-by: Peter Huewe <pet...@gm...> Staged here https://github.com/PeterHuewe/linux-tpmdd for-james Nevertheless I'll try test this using several tpms/platforms. Peter |
From: Ashley L. <ad...@li...> - 2013-10-05 01:48:14
|
On Mon, 2013-09-23 at 12:14 -0600, Jason Gunthorpe wrote: > misc_open sets the file->private_date to the misc_dev when calling > open. We can use container_of to go from the misc_dev back to the > tpm_chip. > > Future clean ups will move tpm_open into a new file and this change > means we do not have to export the tpm_chip list. > > Signed-off-by: Jason Gunthorpe <jgu...@ob...> Acked-by: Ashley Lai <ad...@li...> Thanks, --Ashley Lai |
From: Jason G. <jgu...@ob...> - 2013-09-23 18:16:15
|
TPM drivers should not call dev_set_drvdata (or aliases), only the core code is allowed to call dev_set_drvdata, and it does it during tpm_register_hardware. These extra sets are harmless, but are an anti-pattern that many drivers have copied. Signed-off-by: Jason Gunthorpe <jgu...@ob...> --- drivers/char/tpm/tpm_i2c_infineon.c | 2 -- drivers/char/tpm/tpm_i2c_stm_st33.c | 2 -- drivers/char/tpm/tpm_spi_stm_st33.c | 1 - drivers/char/tpm/xen-tpmfront.c | 2 -- 4 files changed, 7 deletions(-) diff --git a/drivers/char/tpm/tpm_i2c_infineon.c b/drivers/char/tpm/tpm_i2c_infineon.c index b8735de..e33d8e5 100644 --- a/drivers/char/tpm/tpm_i2c_infineon.c +++ b/drivers/char/tpm/tpm_i2c_infineon.c @@ -685,7 +685,6 @@ out_vendor: chip->dev->release = NULL; chip->release = NULL; tpm_dev.client = NULL; - dev_set_drvdata(chip->dev, chip); out_err: return rc; } @@ -766,7 +765,6 @@ static int tpm_tis_i2c_remove(struct i2c_client *client) chip->dev->release = NULL; chip->release = NULL; tpm_dev.client = NULL; - dev_set_drvdata(chip->dev, chip); return 0; } diff --git a/drivers/char/tpm/tpm_i2c_stm_st33.c b/drivers/char/tpm/tpm_i2c_stm_st33.c index 5bb8e2d..1c68d93 100644 --- a/drivers/char/tpm/tpm_i2c_stm_st33.c +++ b/drivers/char/tpm/tpm_i2c_stm_st33.c @@ -746,8 +746,6 @@ tpm_st33_i2c_probe(struct i2c_client *client, const struct i2c_device_id *id) tpm_get_timeouts(chip); - i2c_set_clientdata(client, chip); - dev_info(chip->dev, "TPM I2C Initialized\n"); return 0; _irq_set: diff --git a/drivers/char/tpm/tpm_spi_stm_st33.c b/drivers/char/tpm/tpm_spi_stm_st33.c index 8d3e8e2..f5e3cd6 100644 --- a/drivers/char/tpm/tpm_spi_stm_st33.c +++ b/drivers/char/tpm/tpm_spi_stm_st33.c @@ -779,7 +779,6 @@ tpm_st33_spi_probe(struct spi_device *dev) tpm_get_timeouts(chip); /* attach chip datas to client */ - spi_set_drvdata(dev, chip); platform_data->bchipf = false; pr_info("TPM SPI Initialized\n"); diff --git a/drivers/char/tpm/xen-tpmfront.c b/drivers/char/tpm/xen-tpmfront.c index 6f2fe2b..7711928 100644 --- a/drivers/char/tpm/xen-tpmfront.c +++ b/drivers/char/tpm/xen-tpmfront.c @@ -379,8 +379,6 @@ static int tpmfront_probe(struct xenbus_device *dev, tpm_get_timeouts(priv->chip); - dev_set_drvdata(&dev->dev, priv->chip); - return rv; } -- 1.8.1.2 |
From: Peter H. <Pet...@gm...> - 2013-10-01 22:03:18
|
Am Montag, 23. September 2013, 20:14:36 schrieb Jason Gunthorpe: > TPM drivers should not call dev_set_drvdata (or aliases), only the core > code is allowed to call dev_set_drvdata, and it does it during > tpm_register_hardware. > > These extra sets are harmless, but are an anti-pattern that many drivers > have copied. > > Signed-off-by: Jason Gunthorpe <jgu...@ob...> > --- > drivers/char/tpm/tpm_i2c_infineon.c | 2 -- > drivers/char/tpm/tpm_i2c_stm_st33.c | 2 -- > drivers/char/tpm/tpm_spi_stm_st33.c | 1 - > drivers/char/tpm/xen-tpmfront.c | 2 -- > 4 files changed, 7 deletions(-) Nice catch. Except for the tpm_spi_stm_st33.c part Reviewed-by: Peter Huewe <pet...@gm...> Signed-off-by: Peter Huewe <pet...@gm...> Staged here https://github.com/PeterHuewe/linux-tpmdd for-james Since the tpm_spi_stm_st33 driver is not yet merged and was improved by you anyway, please include this improvement directly in the new driver. Thanks, Peter |
From: Ashley L. <ad...@li...> - 2013-10-05 02:14:23
|
On Mon, 2013-09-23 at 12:14 -0600, Jason Gunthorpe wrote: > TPM drivers should not call dev_set_drvdata (or aliases), only the core > code is allowed to call dev_set_drvdata, and it does it during > tpm_register_hardware. > > These extra sets are harmless, but are an anti-pattern that many drivers > have copied. > > Signed-off-by: Jason Gunthorpe <jgu...@ob...> > diff --git a/drivers/char/tpm/tpm_spi_stm_st33.c b/drivers/char/tpm/tpm_spi_stm_st33.c > index 8d3e8e2..f5e3cd6 100644 > --- a/drivers/char/tpm/tpm_spi_stm_st33.c > +++ b/drivers/char/tpm/tpm_spi_stm_st33.c > @@ -779,7 +779,6 @@ tpm_st33_spi_probe(struct spi_device *dev) > tpm_get_timeouts(chip); > > /* attach chip datas to client */ Looks good except this comment needs to be removed. Since this driver is not merged, please remove this line in the new driver. > - spi_set_drvdata(dev, chip); > platform_data->bchipf = false; > Acked-by: Ashley Lai <ad...@li...> Thanks, --Ashley Lai |
From: Jason G. <jgu...@ob...> - 2013-09-23 18:16:16
|
CLASS-dev.c is a common idiom for Linux subsystems This pulls all the code related to the miscdev into tpm-dev.c and makes it static. The identical file_operation structs in the drivers are purged and the tpm common code unconditionally creates the miscdev. Signed-off-by: Jason Gunthorpe <jgu...@ob...> --- drivers/char/tpm/Makefile | 2 +- drivers/char/tpm/tpm-dev.c | 199 ++++++++++++++++++++++++++++++++++++ drivers/char/tpm/tpm.c | 178 ++------------------------------ drivers/char/tpm/tpm.h | 11 +- drivers/char/tpm/tpm_atmel.c | 10 -- drivers/char/tpm/tpm_i2c_atmel.c | 10 -- drivers/char/tpm/tpm_i2c_infineon.c | 10 -- drivers/char/tpm/tpm_i2c_nuvoton.c | 10 -- drivers/char/tpm/tpm_i2c_stm_st33.c | 10 -- drivers/char/tpm/tpm_ibmvtpm.c | 10 -- drivers/char/tpm/tpm_infineon.c | 10 -- drivers/char/tpm/tpm_nsc.c | 10 -- drivers/char/tpm/tpm_spi_stm_st33.c | 10 -- drivers/char/tpm/tpm_tis.c | 11 -- drivers/char/tpm/xen-tpmfront.c | 12 --- 15 files changed, 216 insertions(+), 287 deletions(-) create mode 100644 drivers/char/tpm/tpm-dev.c diff --git a/drivers/char/tpm/Makefile b/drivers/char/tpm/Makefile index 55dfe87..5a73665 100644 --- a/drivers/char/tpm/Makefile +++ b/drivers/char/tpm/Makefile @@ -1,7 +1,7 @@ # # Makefile for the kernel tpm device drivers. # -obj-$(CONFIG_TCG_TPM) += tpm.o +obj-$(CONFIG_TCG_TPM) += tpm.o tpm-dev.o ifdef CONFIG_ACPI obj-$(CONFIG_TCG_TPM) += tpm_bios.o tpm_bios-objs += tpm_eventlog.o tpm_acpi.o tpm_ppi.o diff --git a/drivers/char/tpm/tpm-dev.c b/drivers/char/tpm/tpm-dev.c new file mode 100644 index 0000000..8d94e97 --- /dev/null +++ b/drivers/char/tpm/tpm-dev.c @@ -0,0 +1,199 @@ +/* + * Copyright (C) 2004 IBM Corporation + * Authors: + * Leendert van Doorn <lee...@wa...> + * Dave Safford <sa...@wa...> + * Reiner Sailer <sa...@wa...> + * Kylene Hall <kj...@us...> + * + * Copyright (C) 2013 Obsidian Reearch Corp + * Jason Gunthorpe <jgu...@ob...> + * + * Device file system interface to the TPM + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation, version 2 of the + * License. + * + */ +#include <linux/miscdevice.h> +#include <linux/slab.h> +#include <linux/uaccess.h> +#include "tpm.h" + +static void user_reader_timeout(unsigned long ptr) +{ + struct tpm_chip *chip = (struct tpm_chip *) ptr; + + schedule_work(&chip->work); +} + +static void timeout_work(struct work_struct *work) +{ + struct tpm_chip *chip = container_of(work, struct tpm_chip, work); + + mutex_lock(&chip->buffer_mutex); + atomic_set(&chip->data_pending, 0); + memset(chip->data_buffer, 0, TPM_BUFSIZE); + mutex_unlock(&chip->buffer_mutex); +} + +static int tpm_open(struct inode *inode, struct file *file) +{ + struct miscdevice *misc = file->private_data; + struct tpm_chip *chip = container_of(misc, struct tpm_chip, + vendor.miscdev); + + /* It's assured that the chip will be opened just once, + * by the check of is_open variable, which is protected + * by driver_lock. */ + if (test_and_set_bit(0, &chip->is_open)) { + dev_dbg(chip->dev, "Another process owns this TPM\n"); + return -EBUSY; + } + + chip->data_buffer = kzalloc(TPM_BUFSIZE, GFP_KERNEL); + if (chip->data_buffer == NULL) { + clear_bit(0, &chip->is_open); + return -ENOMEM; + } + + atomic_set(&chip->data_pending, 0); + + file->private_data = chip; + get_device(chip->dev); + return 0; +} + +static ssize_t tpm_read(struct file *file, char __user *buf, + size_t size, loff_t *off) +{ + struct tpm_chip *chip = file->private_data; + ssize_t ret_size; + int rc; + + del_singleshot_timer_sync(&chip->user_read_timer); + flush_work(&chip->work); + ret_size = atomic_read(&chip->data_pending); + if (ret_size > 0) { /* relay data */ + ssize_t orig_ret_size = ret_size; + if (size < ret_size) + ret_size = size; + + mutex_lock(&chip->buffer_mutex); + rc = copy_to_user(buf, chip->data_buffer, ret_size); + memset(chip->data_buffer, 0, orig_ret_size); + if (rc) + ret_size = -EFAULT; + + mutex_unlock(&chip->buffer_mutex); + } + + atomic_set(&chip->data_pending, 0); + + return ret_size; +} + +static ssize_t tpm_write(struct file *file, const char __user *buf, + size_t size, loff_t *off) +{ + struct tpm_chip *chip = file->private_data; + size_t in_size = size; + ssize_t out_size; + + /* cannot perform a write until the read has cleared + either via tpm_read or a user_read_timer timeout. + This also prevents splitted buffered writes from blocking here. + */ + if (atomic_read(&chip->data_pending) != 0) + return -EBUSY; + + if (in_size > TPM_BUFSIZE) + return -E2BIG; + + mutex_lock(&chip->buffer_mutex); + + if (copy_from_user + (chip->data_buffer, (void __user *) buf, in_size)) { + mutex_unlock(&chip->buffer_mutex); + return -EFAULT; + } + + /* atomic tpm command send and result receive */ + out_size = tpm_transmit(chip, chip->data_buffer, TPM_BUFSIZE); + if (out_size < 0) { + mutex_unlock(&chip->buffer_mutex); + return out_size; + } + + atomic_set(&chip->data_pending, out_size); + mutex_unlock(&chip->buffer_mutex); + + /* Set a timeout by which the reader must come claim the result */ + mod_timer(&chip->user_read_timer, jiffies + (60 * HZ)); + + return in_size; +} + +/* + * Called on file close + */ +static int tpm_release(struct inode *inode, struct file *file) +{ + struct tpm_chip *chip = file->private_data; + + del_singleshot_timer_sync(&chip->user_read_timer); + flush_work(&chip->work); + file->private_data = NULL; + atomic_set(&chip->data_pending, 0); + kzfree(chip->data_buffer); + clear_bit(0, &chip->is_open); + put_device(chip->dev); + return 0; +} + +static const struct file_operations tpm_fops = { + .owner = THIS_MODULE, + .llseek = no_llseek, + .open = tpm_open, + .read = tpm_read, + .write = tpm_write, + .release = tpm_release, +}; + +int tpm_dev_add_device(struct tpm_chip *chip) +{ + int rc; + + mutex_init(&chip->buffer_mutex); + INIT_WORK(&chip->work, timeout_work); + + setup_timer(&chip->user_read_timer, user_reader_timeout, + (unsigned long)chip); + + chip->vendor.miscdev.fops = &tpm_fops; + if (chip->dev_num == 0) + chip->vendor.miscdev.minor = TPM_MINOR; + else + chip->vendor.miscdev.minor = MISC_DYNAMIC_MINOR; + + chip->vendor.miscdev.name = chip->devname; + chip->vendor.miscdev.parent = chip->dev; + + rc = misc_register(&chip->vendor.miscdev); + if (rc) { + chip->vendor.miscdev.name = NULL; + dev_warn(chip->dev, + "unable to misc_register %s, minor %d err=%d\n", + chip->vendor.miscdev.name, + chip->vendor.miscdev.minor, rc); + } + return rc; +} + +void tpm_dev_del_device(struct tpm_chip *chip) +{ + if (chip->vendor.miscdev.name) + misc_deregister(&chip->vendor.miscdev); +} diff --git a/drivers/char/tpm/tpm.c b/drivers/char/tpm/tpm.c index 72f0c68..63f1c45 100644 --- a/drivers/char/tpm/tpm.c +++ b/drivers/char/tpm/tpm.c @@ -312,23 +312,6 @@ static const u8 tpm_ordinal_duration[TPM_MAX_ORDINAL] = { TPM_MEDIUM, }; -static void user_reader_timeout(unsigned long ptr) -{ - struct tpm_chip *chip = (struct tpm_chip *) ptr; - - schedule_work(&chip->work); -} - -static void timeout_work(struct work_struct *work) -{ - struct tpm_chip *chip = container_of(work, struct tpm_chip, work); - - mutex_lock(&chip->buffer_mutex); - atomic_set(&chip->data_pending, 0); - memset(chip->data_buffer, 0, TPM_BUFSIZE); - mutex_unlock(&chip->buffer_mutex); -} - /* * Returns max number of jiffies to wait */ @@ -355,8 +338,8 @@ EXPORT_SYMBOL_GPL(tpm_calc_ordinal_duration); /* * Internal kernel interface to transmit TPM commands */ -static ssize_t tpm_transmit(struct tpm_chip *chip, const char *buf, - size_t bufsiz) +ssize_t tpm_transmit(struct tpm_chip *chip, const char *buf, + size_t bufsiz) { ssize_t rc; u32 count, ordinal; @@ -1151,127 +1134,6 @@ again: return -ETIME; } EXPORT_SYMBOL_GPL(wait_for_tpm_stat); -/* - * Device file system interface to the TPM - * - * It's assured that the chip will be opened just once, - * by the check of is_open variable, which is protected - * by driver_lock. - */ -int tpm_open(struct inode *inode, struct file *file) -{ - struct miscdevice *misc = file->private_data; - struct tpm_chip *chip = container_of(misc, struct tpm_chip, - vendor.miscdev); - - if (test_and_set_bit(0, &chip->is_open)) { - dev_dbg(chip->dev, "Another process owns this TPM\n"); - return -EBUSY; - } - - chip->data_buffer = kzalloc(TPM_BUFSIZE, GFP_KERNEL); - if (chip->data_buffer == NULL) { - clear_bit(0, &chip->is_open); - return -ENOMEM; - } - - atomic_set(&chip->data_pending, 0); - - file->private_data = chip; - get_device(chip->dev); - return 0; -} -EXPORT_SYMBOL_GPL(tpm_open); - -/* - * Called on file close - */ -int tpm_release(struct inode *inode, struct file *file) -{ - struct tpm_chip *chip = file->private_data; - - del_singleshot_timer_sync(&chip->user_read_timer); - flush_work(&chip->work); - file->private_data = NULL; - atomic_set(&chip->data_pending, 0); - kzfree(chip->data_buffer); - clear_bit(0, &chip->is_open); - put_device(chip->dev); - return 0; -} -EXPORT_SYMBOL_GPL(tpm_release); - -ssize_t tpm_write(struct file *file, const char __user *buf, - size_t size, loff_t *off) -{ - struct tpm_chip *chip = file->private_data; - size_t in_size = size; - ssize_t out_size; - - /* cannot perform a write until the read has cleared - either via tpm_read or a user_read_timer timeout. - This also prevents splitted buffered writes from blocking here. - */ - if (atomic_read(&chip->data_pending) != 0) - return -EBUSY; - - if (in_size > TPM_BUFSIZE) - return -E2BIG; - - mutex_lock(&chip->buffer_mutex); - - if (copy_from_user - (chip->data_buffer, (void __user *) buf, in_size)) { - mutex_unlock(&chip->buffer_mutex); - return -EFAULT; - } - - /* atomic tpm command send and result receive */ - out_size = tpm_transmit(chip, chip->data_buffer, TPM_BUFSIZE); - if (out_size < 0) { - mutex_unlock(&chip->buffer_mutex); - return out_size; - } - - atomic_set(&chip->data_pending, out_size); - mutex_unlock(&chip->buffer_mutex); - - /* Set a timeout by which the reader must come claim the result */ - mod_timer(&chip->user_read_timer, jiffies + (60 * HZ)); - - return in_size; -} -EXPORT_SYMBOL_GPL(tpm_write); - -ssize_t tpm_read(struct file *file, char __user *buf, - size_t size, loff_t *off) -{ - struct tpm_chip *chip = file->private_data; - ssize_t ret_size; - int rc; - - del_singleshot_timer_sync(&chip->user_read_timer); - flush_work(&chip->work); - ret_size = atomic_read(&chip->data_pending); - if (ret_size > 0) { /* relay data */ - ssize_t orig_ret_size = ret_size; - if (size < ret_size) - ret_size = size; - - mutex_lock(&chip->buffer_mutex); - rc = copy_to_user(buf, chip->data_buffer, ret_size); - memset(chip->data_buffer, 0, orig_ret_size); - if (rc) - ret_size = -EFAULT; - - mutex_unlock(&chip->buffer_mutex); - } - - atomic_set(&chip->data_pending, 0); - - return ret_size; -} -EXPORT_SYMBOL_GPL(tpm_read); void tpm_remove_hardware(struct device *dev) { @@ -1287,7 +1149,7 @@ void tpm_remove_hardware(struct device *dev) spin_unlock(&driver_lock); synchronize_rcu(); - misc_deregister(&chip->vendor.miscdev); + tpm_dev_del_device(chip); sysfs_remove_group(&dev->kobj, chip->vendor.attr_group); tpm_remove_ppi(&dev->kobj); tpm_bios_log_teardown(chip->bios_dir); @@ -1480,15 +1342,9 @@ struct tpm_chip *tpm_register_hardware(struct device *dev, if (chip == NULL) return NULL; - mutex_init(&chip->buffer_mutex); mutex_init(&chip->tpm_mutex); INIT_LIST_HEAD(&chip->list); - INIT_WORK(&chip->work, timeout_work); - - setup_timer(&chip->user_read_timer, user_reader_timeout, - (unsigned long)chip); - memcpy(&chip->vendor, entry, sizeof(struct tpm_vendor_specific)); chip->dev_num = find_first_zero_bit(dev_mask, TPM_NUM_DEVICES); @@ -1496,40 +1352,26 @@ struct tpm_chip *tpm_register_hardware(struct device *dev, if (chip->dev_num >= TPM_NUM_DEVICES) { dev_err(dev, "No available tpm device numbers\n"); goto out_free; - } else if (chip->dev_num == 0) - chip->vendor.miscdev.minor = TPM_MINOR; - else - chip->vendor.miscdev.minor = MISC_DYNAMIC_MINOR; + } set_bit(chip->dev_num, dev_mask); scnprintf(chip->devname, sizeof(chip->devname), "%s%d", "tpm", chip->dev_num); - chip->vendor.miscdev.name = chip->devname; - chip->vendor.miscdev.parent = dev; chip->dev = get_device(dev); chip->release = dev->release; dev->release = tpm_dev_release; dev_set_drvdata(dev, chip); - if (misc_register(&chip->vendor.miscdev)) { - dev_err(chip->dev, - "unable to misc_register %s, minor %d\n", - chip->vendor.miscdev.name, - chip->vendor.miscdev.minor); + if (tpm_dev_add_device(chip)) goto put_device; - } - if (sysfs_create_group(&dev->kobj, chip->vendor.attr_group)) { - misc_deregister(&chip->vendor.miscdev); - goto put_device; - } + if (sysfs_create_group(&dev->kobj, chip->vendor.attr_group)) + goto del_misc; - if (tpm_add_ppi(&dev->kobj)) { - misc_deregister(&chip->vendor.miscdev); - goto put_device; - } + if (tpm_add_ppi(&dev->kobj)) + goto del_misc; chip->bios_dir = tpm_bios_log_setup(chip->devname); @@ -1540,6 +1382,8 @@ struct tpm_chip *tpm_register_hardware(struct device *dev, return chip; +del_misc: + tpm_dev_del_device(chip); put_device: put_device(chip->dev); out_free: diff --git a/drivers/char/tpm/tpm.h b/drivers/char/tpm/tpm.h index f328478..496228c 100644 --- a/drivers/char/tpm/tpm.h +++ b/drivers/char/tpm/tpm.h @@ -323,25 +323,24 @@ struct tpm_cmd_t { ssize_t tpm_getcap(struct device *, __be32, cap_t *, const char *); +ssize_t tpm_transmit(struct tpm_chip *chip, const char *buf, + size_t bufsiz); extern int tpm_get_timeouts(struct tpm_chip *); extern void tpm_gen_interrupt(struct tpm_chip *); extern int tpm_do_selftest(struct tpm_chip *); extern unsigned long tpm_calc_ordinal_duration(struct tpm_chip *, u32); extern struct tpm_chip* tpm_register_hardware(struct device *, const struct tpm_vendor_specific *); -extern int tpm_open(struct inode *, struct file *); -extern int tpm_release(struct inode *, struct file *); -extern void tpm_dev_release(struct device *dev); extern void tpm_dev_vendor_release(struct tpm_chip *); -extern ssize_t tpm_write(struct file *, const char __user *, size_t, - loff_t *); -extern ssize_t tpm_read(struct file *, char __user *, size_t, loff_t *); extern void tpm_remove_hardware(struct device *); extern int tpm_pm_suspend(struct device *); extern int tpm_pm_resume(struct device *); extern int wait_for_tpm_stat(struct tpm_chip *, u8, unsigned long, wait_queue_head_t *, bool); +int tpm_dev_add_device(struct tpm_chip *chip); +void tpm_dev_del_device(struct tpm_chip *chip); + #ifdef CONFIG_ACPI extern int tpm_add_ppi(struct kobject *); extern void tpm_remove_ppi(struct kobject *); diff --git a/drivers/char/tpm/tpm_atmel.c b/drivers/char/tpm/tpm_atmel.c index c9a528d..9692e2f 100644 --- a/drivers/char/tpm/tpm_atmel.c +++ b/drivers/char/tpm/tpm_atmel.c @@ -121,15 +121,6 @@ static bool tpm_atml_req_canceled(struct tpm_chip *chip, u8 status) return (status == ATML_STATUS_READY); } -static const struct file_operations atmel_ops = { - .owner = THIS_MODULE, - .llseek = no_llseek, - .open = tpm_open, - .read = tpm_read, - .write = tpm_write, - .release = tpm_release, -}; - static DEVICE_ATTR(pubek, S_IRUGO, tpm_show_pubek, NULL); static DEVICE_ATTR(pcrs, S_IRUGO, tpm_show_pcrs, NULL); static DEVICE_ATTR(caps, S_IRUGO, tpm_show_caps, NULL); @@ -154,7 +145,6 @@ static const struct tpm_vendor_specific tpm_atmel = { .req_complete_val = ATML_STATUS_DATA_AVAIL, .req_canceled = tpm_atml_req_canceled, .attr_group = &atmel_attr_grp, - .miscdev = { .fops = &atmel_ops, }, }; static struct platform_device *pdev; diff --git a/drivers/char/tpm/tpm_i2c_atmel.c b/drivers/char/tpm/tpm_i2c_atmel.c index e986d01..f9cee5f 100644 --- a/drivers/char/tpm/tpm_i2c_atmel.c +++ b/drivers/char/tpm/tpm_i2c_atmel.c @@ -135,15 +135,6 @@ static u8 i2c_atmel_read_status(struct tpm_chip *chip) return ATMEL_STS_OK; } -static const struct file_operations i2c_atmel_ops = { - .owner = THIS_MODULE, - .llseek = no_llseek, - .open = tpm_open, - .read = tpm_read, - .write = tpm_write, - .release = tpm_release, -}; - static DEVICE_ATTR(pubek, S_IRUGO, tpm_show_pubek, NULL); static DEVICE_ATTR(pcrs, S_IRUGO, tpm_show_pcrs, NULL); static DEVICE_ATTR(enabled, S_IRUGO, tpm_show_enabled, NULL); @@ -187,7 +178,6 @@ static const struct tpm_vendor_specific i2c_atmel = { .req_complete_val = ATMEL_STS_OK, .req_canceled = i2c_atmel_req_canceled, .attr_group = &i2c_atmel_attr_grp, - .miscdev.fops = &i2c_atmel_ops, }; static int i2c_atmel_probe(struct i2c_client *client, diff --git a/drivers/char/tpm/tpm_i2c_infineon.c b/drivers/char/tpm/tpm_i2c_infineon.c index fefd2aa..c1ba7fa 100644 --- a/drivers/char/tpm/tpm_i2c_infineon.c +++ b/drivers/char/tpm/tpm_i2c_infineon.c @@ -566,15 +566,6 @@ static bool tpm_tis_i2c_req_canceled(struct tpm_chip *chip, u8 status) return (status == TPM_STS_COMMAND_READY); } -static const struct file_operations tis_ops = { - .owner = THIS_MODULE, - .llseek = no_llseek, - .open = tpm_open, - .read = tpm_read, - .write = tpm_write, - .release = tpm_release, -}; - static DEVICE_ATTR(pubek, S_IRUGO, tpm_show_pubek, NULL); static DEVICE_ATTR(pcrs, S_IRUGO, tpm_show_pcrs, NULL); static DEVICE_ATTR(enabled, S_IRUGO, tpm_show_enabled, NULL); @@ -613,7 +604,6 @@ static struct tpm_vendor_specific tpm_tis_i2c = { .req_complete_val = TPM_STS_DATA_AVAIL | TPM_STS_VALID, .req_canceled = tpm_tis_i2c_req_canceled, .attr_group = &tis_attr_grp, - .miscdev.fops = &tis_ops, }; static int tpm_tis_i2c_init(struct device *dev) diff --git a/drivers/char/tpm/tpm_i2c_nuvoton.c b/drivers/char/tpm/tpm_i2c_nuvoton.c index 6276fea..3766fe7 100644 --- a/drivers/char/tpm/tpm_i2c_nuvoton.c +++ b/drivers/char/tpm/tpm_i2c_nuvoton.c @@ -456,15 +456,6 @@ static bool i2c_nuvoton_req_canceled(struct tpm_chip *chip, u8 status) return (status == TPM_STS_COMMAND_READY); } -static const struct file_operations i2c_nuvoton_ops = { - .owner = THIS_MODULE, - .llseek = no_llseek, - .open = tpm_open, - .read = tpm_read, - .write = tpm_write, - .release = tpm_release, -}; - static DEVICE_ATTR(pubek, S_IRUGO, tpm_show_pubek, NULL); static DEVICE_ATTR(pcrs, S_IRUGO, tpm_show_pcrs, NULL); static DEVICE_ATTR(enabled, S_IRUGO, tpm_show_enabled, NULL); @@ -503,7 +494,6 @@ static const struct tpm_vendor_specific tpm_i2c = { .req_complete_val = TPM_STS_DATA_AVAIL | TPM_STS_VALID, .req_canceled = i2c_nuvoton_req_canceled, .attr_group = &i2c_nuvoton_attr_grp, - .miscdev.fops = &i2c_nuvoton_ops, }; /* The only purpose for the handler is to signal to any waiting threads that diff --git a/drivers/char/tpm/tpm_i2c_stm_st33.c b/drivers/char/tpm/tpm_i2c_stm_st33.c index b069afb..2328c5e 100644 --- a/drivers/char/tpm/tpm_i2c_stm_st33.c +++ b/drivers/char/tpm/tpm_i2c_stm_st33.c @@ -569,15 +569,6 @@ static bool tpm_st33_i2c_req_canceled(struct tpm_chip *chip, u8 status) return (status == TPM_STS_COMMAND_READY); } -static const struct file_operations tpm_st33_i2c_fops = { - .owner = THIS_MODULE, - .llseek = no_llseek, - .read = tpm_read, - .write = tpm_write, - .open = tpm_open, - .release = tpm_release, -}; - static DEVICE_ATTR(pubek, S_IRUGO, tpm_show_pubek, NULL); static DEVICE_ATTR(pcrs, S_IRUGO, tpm_show_pcrs, NULL); static DEVICE_ATTR(enabled, S_IRUGO, tpm_show_enabled, NULL); @@ -611,7 +602,6 @@ static struct tpm_vendor_specific st_i2c_tpm = { .req_complete_val = TPM_STS_DATA_AVAIL | TPM_STS_VALID, .req_canceled = tpm_st33_i2c_req_canceled, .attr_group = &stm_tpm_attr_grp, - .miscdev = {.fops = &tpm_st33_i2c_fops,}, }; static int interrupts; diff --git a/drivers/char/tpm/tpm_ibmvtpm.c b/drivers/char/tpm/tpm_ibmvtpm.c index 2783a42..88a0121 100644 --- a/drivers/char/tpm/tpm_ibmvtpm.c +++ b/drivers/char/tpm/tpm_ibmvtpm.c @@ -403,15 +403,6 @@ static bool tpm_ibmvtpm_req_canceled(struct tpm_chip *chip, u8 status) return (status == 0); } -static const struct file_operations ibmvtpm_ops = { - .owner = THIS_MODULE, - .llseek = no_llseek, - .open = tpm_open, - .read = tpm_read, - .write = tpm_write, - .release = tpm_release, -}; - static DEVICE_ATTR(pubek, S_IRUGO, tpm_show_pubek, NULL); static DEVICE_ATTR(pcrs, S_IRUGO, tpm_show_pcrs, NULL); static DEVICE_ATTR(enabled, S_IRUGO, tpm_show_enabled, NULL); @@ -448,7 +439,6 @@ static const struct tpm_vendor_specific tpm_ibmvtpm = { .req_complete_val = 0, .req_canceled = tpm_ibmvtpm_req_canceled, .attr_group = &ibmvtpm_attr_grp, - .miscdev = { .fops = &ibmvtpm_ops, }, }; static const struct dev_pm_ops tpm_ibmvtpm_pm_ops = { diff --git a/drivers/char/tpm/tpm_infineon.c b/drivers/char/tpm/tpm_infineon.c index 2b480c2..c75c10c 100644 --- a/drivers/char/tpm/tpm_infineon.c +++ b/drivers/char/tpm/tpm_infineon.c @@ -386,15 +386,6 @@ static struct attribute *inf_attrs[] = { static struct attribute_group inf_attr_grp = {.attrs = inf_attrs }; -static const struct file_operations inf_ops = { - .owner = THIS_MODULE, - .llseek = no_llseek, - .open = tpm_open, - .read = tpm_read, - .write = tpm_write, - .release = tpm_release, -}; - static const struct tpm_vendor_specific tpm_inf = { .recv = tpm_inf_recv, .send = tpm_inf_send, @@ -403,7 +394,6 @@ static const struct tpm_vendor_specific tpm_inf = { .req_complete_mask = 0, .req_complete_val = 0, .attr_group = &inf_attr_grp, - .miscdev = {.fops = &inf_ops,}, }; static const struct pnp_device_id tpm_inf_pnp_tbl[] = { diff --git a/drivers/char/tpm/tpm_nsc.c b/drivers/char/tpm/tpm_nsc.c index 770c46f..a4acac9 100644 --- a/drivers/char/tpm/tpm_nsc.c +++ b/drivers/char/tpm/tpm_nsc.c @@ -232,15 +232,6 @@ static bool tpm_nsc_req_canceled(struct tpm_chip *chip, u8 status) return (status == NSC_STATUS_RDY); } -static const struct file_operations nsc_ops = { - .owner = THIS_MODULE, - .llseek = no_llseek, - .open = tpm_open, - .read = tpm_read, - .write = tpm_write, - .release = tpm_release, -}; - static DEVICE_ATTR(pubek, S_IRUGO, tpm_show_pubek, NULL); static DEVICE_ATTR(pcrs, S_IRUGO, tpm_show_pcrs, NULL); static DEVICE_ATTR(caps, S_IRUGO, tpm_show_caps, NULL); @@ -265,7 +256,6 @@ static const struct tpm_vendor_specific tpm_nsc = { .req_complete_val = NSC_STATUS_OBF, .req_canceled = tpm_nsc_req_canceled, .attr_group = &nsc_attr_grp, - .miscdev = { .fops = &nsc_ops, }, }; static struct platform_device *pdev = NULL; diff --git a/drivers/char/tpm/tpm_spi_stm_st33.c b/drivers/char/tpm/tpm_spi_stm_st33.c index 7b8899d..99854e8 100644 --- a/drivers/char/tpm/tpm_spi_stm_st33.c +++ b/drivers/char/tpm/tpm_spi_stm_st33.c @@ -591,15 +591,6 @@ out: return size; } -static const struct file_operations tpm_st33_spi_fops = { - .owner = THIS_MODULE, - .llseek = no_llseek, - .read = tpm_read, - .write = tpm_write, - .open = tpm_open, - .release = tpm_release, -}; - static DEVICE_ATTR(pubek, S_IRUGO, tpm_show_pubek, NULL); static DEVICE_ATTR(pcrs, S_IRUGO, tpm_show_pcrs, NULL); static DEVICE_ATTR(enabled, S_IRUGO, tpm_show_enabled, NULL); @@ -630,7 +621,6 @@ static struct tpm_vendor_specific st_spi_tpm = { .cancel = tpm_stm_spi_cancel, .status = tpm_stm_spi_status, .attr_group = &stm_tpm_attr_grp, - .miscdev = {.fops = &tpm_st33_spi_fops,}, }; static int evaluate_latency(struct tpm_chip *chip) diff --git a/drivers/char/tpm/tpm_tis.c b/drivers/char/tpm/tpm_tis.c index 1b74459..46f57f5 100644 --- a/drivers/char/tpm/tpm_tis.c +++ b/drivers/char/tpm/tpm_tis.c @@ -432,15 +432,6 @@ static bool tpm_tis_req_canceled(struct tpm_chip *chip, u8 status) } } -static const struct file_operations tis_ops = { - .owner = THIS_MODULE, - .llseek = no_llseek, - .open = tpm_open, - .read = tpm_read, - .write = tpm_write, - .release = tpm_release, -}; - static DEVICE_ATTR(pubek, S_IRUGO, tpm_show_pubek, NULL); static DEVICE_ATTR(pcrs, S_IRUGO, tpm_show_pcrs, NULL); static DEVICE_ATTR(enabled, S_IRUGO, tpm_show_enabled, NULL); @@ -479,8 +470,6 @@ static struct tpm_vendor_specific tpm_tis = { .req_complete_val = TPM_STS_DATA_AVAIL | TPM_STS_VALID, .req_canceled = tpm_tis_req_canceled, .attr_group = &tis_attr_grp, - .miscdev = { - .fops = &tis_ops,}, }; static irqreturn_t tis_int_probe(int irq, void *dev_id) diff --git a/drivers/char/tpm/xen-tpmfront.c b/drivers/char/tpm/xen-tpmfront.c index 7711928..12a4ab2 100644 --- a/drivers/char/tpm/xen-tpmfront.c +++ b/drivers/char/tpm/xen-tpmfront.c @@ -168,15 +168,6 @@ ssize_t tpm_store_locality(struct device *dev, struct device_attribute *attr, return len; } -static const struct file_operations vtpm_ops = { - .owner = THIS_MODULE, - .llseek = no_llseek, - .open = tpm_open, - .read = tpm_read, - .write = tpm_write, - .release = tpm_release, -}; - static DEVICE_ATTR(pubek, S_IRUGO, tpm_show_pubek, NULL); static DEVICE_ATTR(pcrs, S_IRUGO, tpm_show_pcrs, NULL); static DEVICE_ATTR(enabled, S_IRUGO, tpm_show_enabled, NULL); @@ -219,9 +210,6 @@ static const struct tpm_vendor_specific tpm_vtpm = { .req_complete_val = VTPM_STATUS_IDLE | VTPM_STATUS_RESULT, .req_canceled = vtpm_req_canceled, .attr_group = &vtpm_attr_grp, - .miscdev = { - .fops = &vtpm_ops, - }, }; static irqreturn_t tpmif_interrupt(int dummy, void *dev_id) -- 1.8.1.2 |
From: Jason G. <jgu...@ob...> - 2013-09-23 18:16:15
|
Just put the memory directly in the chip structure, rather than in a 2nd dedicated kmalloc. Signed-off-by: Jason Gunthorpe <jgu...@ob...> --- drivers/char/tpm/tpm.c | 17 ++++++----------- drivers/char/tpm/tpm.h | 1 + 2 files changed, 7 insertions(+), 11 deletions(-) diff --git a/drivers/char/tpm/tpm.c b/drivers/char/tpm/tpm.c index e3c974a..71eb8c7 100644 --- a/drivers/char/tpm/tpm.c +++ b/drivers/char/tpm/tpm.c @@ -1463,7 +1463,6 @@ void tpm_dev_vendor_release(struct tpm_chip *chip) chip->vendor.release(chip->dev); clear_bit(chip->dev_num, dev_mask); - kfree(chip->vendor.miscdev.name); } EXPORT_SYMBOL_GPL(tpm_dev_vendor_release); @@ -1496,17 +1495,13 @@ EXPORT_SYMBOL_GPL(tpm_dev_release); struct tpm_chip *tpm_register_hardware(struct device *dev, const struct tpm_vendor_specific *entry) { -#define DEVNAME_SIZE 7 - - char *devname; struct tpm_chip *chip; /* Driver specific per-device data */ chip = kzalloc(sizeof(*chip), GFP_KERNEL); - devname = kmalloc(DEVNAME_SIZE, GFP_KERNEL); - if (chip == NULL || devname == NULL) - goto out_free; + if (chip == NULL) + return NULL; mutex_init(&chip->buffer_mutex); mutex_init(&chip->tpm_mutex); @@ -1531,8 +1526,9 @@ struct tpm_chip *tpm_register_hardware(struct device *dev, set_bit(chip->dev_num, dev_mask); - scnprintf(devname, DEVNAME_SIZE, "%s%d", "tpm", chip->dev_num); - chip->vendor.miscdev.name = devname; + scnprintf(chip->devname, sizeof(chip->devname), "%s%d", "tpm", + chip->dev_num); + chip->vendor.miscdev.name = chip->devname; chip->vendor.miscdev.parent = dev; chip->dev = get_device(dev); @@ -1558,7 +1554,7 @@ struct tpm_chip *tpm_register_hardware(struct device *dev, goto put_device; } - chip->bios_dir = tpm_bios_log_setup(devname); + chip->bios_dir = tpm_bios_log_setup(chip->devname); /* Make chip available */ spin_lock(&driver_lock); @@ -1571,7 +1567,6 @@ put_device: put_device(chip->dev); out_free: kfree(chip); - kfree(devname); return NULL; } EXPORT_SYMBOL_GPL(tpm_register_hardware); diff --git a/drivers/char/tpm/tpm.h b/drivers/char/tpm/tpm.h index a7bfc17..0df18b5 100644 --- a/drivers/char/tpm/tpm.h +++ b/drivers/char/tpm/tpm.h @@ -122,6 +122,7 @@ struct tpm_chip { struct device *dev; /* Device stuff */ int dev_num; /* /dev/tpm# */ + char devname[7]; unsigned long is_open; /* only one allowed */ int time_expired; -- 1.8.1.2 |
From: Peter H. <Pet...@gm...> - 2013-10-01 21:59:07
|
Am Montag, 23. September 2013, 20:14:34 schrieb Jason Gunthorpe: > Just put the memory directly in the chip structure, rather than > in a 2nd dedicated kmalloc. > > Signed-off-by: Jason Gunthorpe <jgu...@ob...> Reviewed-by: Peter Huewe <pet...@gm...> Signed-off-by: Peter Huewe <pet...@gm...> Staged here https://github.com/PeterHuewe/linux-tpmdd for-james Thanks, Peter |
From: Ashley L. <ad...@li...> - 2013-10-04 15:58:28
|
On Mon, 2013-09-23 at 12:14 -0600, Jason Gunthorpe wrote: > Just put the memory directly in the chip structure, rather than > in a 2nd dedicated kmalloc. > > Signed-off-by: Jason Gunthorpe <jgu...@ob...> Acked-by: Ashley Lai <ad...@li...> Thanks, --Ashley Lai |
From: Jason G. <jgu...@ob...> - 2013-09-23 18:16:15
|
The version of the TPM should not depend on the bus it is connected through. 1.1, 1.2 and soon 2.0 TPMS will be all be able to use the same bus interfaces. Make tpm_show_caps try the 1.2 capability first. If that fails then fall back to the 1.1 capability. This effectively auto-detects what interface the TPM supports at run-time. Signed-off-by: Jason Gunthorpe <jgu...@ob...> --- drivers/char/tpm/tpm.c | 56 +++++++++++++++---------------------- drivers/char/tpm/tpm.h | 2 -- drivers/char/tpm/tpm_i2c_atmel.c | 2 +- drivers/char/tpm/tpm_i2c_infineon.c | 2 +- drivers/char/tpm/tpm_i2c_nuvoton.c | 2 +- drivers/char/tpm/tpm_i2c_stm_st33.c | 2 +- drivers/char/tpm/tpm_ibmvtpm.c | 2 +- drivers/char/tpm/tpm_spi_stm_st33.c | 2 +- drivers/char/tpm/tpm_tis.c | 2 +- 9 files changed, 30 insertions(+), 42 deletions(-) diff --git a/drivers/char/tpm/tpm.c b/drivers/char/tpm/tpm.c index c3ab508..72f0c68 100644 --- a/drivers/char/tpm/tpm.c +++ b/drivers/char/tpm/tpm.c @@ -1020,43 +1020,33 @@ ssize_t tpm_show_caps(struct device *dev, struct device_attribute *attr, str += sprintf(str, "Manufacturer: 0x%x\n", be32_to_cpu(cap.manufacturer_id)); - rc = tpm_getcap(dev, CAP_VERSION_1_1, &cap, - "attempting to determine the 1.1 version"); - if (rc) - return 0; - str += sprintf(str, - "TCG version: %d.%d\nFirmware version: %d.%d\n", - cap.tpm_version.Major, cap.tpm_version.Minor, - cap.tpm_version.revMajor, cap.tpm_version.revMinor); - return str - buf; -} -EXPORT_SYMBOL_GPL(tpm_show_caps); - -ssize_t tpm_show_caps_1_2(struct device * dev, - struct device_attribute * attr, char *buf) -{ - cap_t cap; - ssize_t rc; - char *str = buf; - - rc = tpm_getcap(dev, TPM_CAP_PROP_MANUFACTURER, &cap, - "attempting to determine the manufacturer"); - if (rc) - return 0; - str += sprintf(str, "Manufacturer: 0x%x\n", - be32_to_cpu(cap.manufacturer_id)); + /* Try to get a TPM version 1.2 TPM_CAP_VERSION_INFO */ rc = tpm_getcap(dev, CAP_VERSION_1_2, &cap, "attempting to determine the 1.2 version"); - if (rc) - return 0; - str += sprintf(str, - "TCG version: %d.%d\nFirmware version: %d.%d\n", - cap.tpm_version_1_2.Major, cap.tpm_version_1_2.Minor, - cap.tpm_version_1_2.revMajor, - cap.tpm_version_1_2.revMinor); + if (!rc) { + str += sprintf(str, + "TCG version: %d.%d\nFirmware version: %d.%d\n", + cap.tpm_version_1_2.Major, + cap.tpm_version_1_2.Minor, + cap.tpm_version_1_2.revMajor, + cap.tpm_version_1_2.revMinor); + } else { + /* Otherwise just use TPM_STRUCT_VER */ + rc = tpm_getcap(dev, CAP_VERSION_1_1, &cap, + "attempting to determine the 1.1 version"); + if (rc) + return 0; + str += sprintf(str, + "TCG version: %d.%d\nFirmware version: %d.%d\n", + cap.tpm_version.Major, + cap.tpm_version.Minor, + cap.tpm_version.revMajor, + cap.tpm_version.revMinor); + } + return str - buf; } -EXPORT_SYMBOL_GPL(tpm_show_caps_1_2); +EXPORT_SYMBOL_GPL(tpm_show_caps); ssize_t tpm_show_durations(struct device *dev, struct device_attribute *attr, char *buf) diff --git a/drivers/char/tpm/tpm.h b/drivers/char/tpm/tpm.h index 0df18b5..f328478 100644 --- a/drivers/char/tpm/tpm.h +++ b/drivers/char/tpm/tpm.h @@ -59,8 +59,6 @@ extern ssize_t tpm_show_pcrs(struct device *, struct device_attribute *attr, char *); extern ssize_t tpm_show_caps(struct device *, struct device_attribute *attr, char *); -extern ssize_t tpm_show_caps_1_2(struct device *, struct device_attribute *attr, - char *); extern ssize_t tpm_store_cancel(struct device *, struct device_attribute *attr, const char *, size_t); extern ssize_t tpm_show_enabled(struct device *, struct device_attribute *attr, diff --git a/drivers/char/tpm/tpm_i2c_atmel.c b/drivers/char/tpm/tpm_i2c_atmel.c index 79877f0..e986d01 100644 --- a/drivers/char/tpm/tpm_i2c_atmel.c +++ b/drivers/char/tpm/tpm_i2c_atmel.c @@ -150,7 +150,7 @@ static DEVICE_ATTR(enabled, S_IRUGO, tpm_show_enabled, NULL); static DEVICE_ATTR(active, S_IRUGO, tpm_show_active, NULL); static DEVICE_ATTR(owned, S_IRUGO, tpm_show_owned, NULL); static DEVICE_ATTR(temp_deactivated, S_IRUGO, tpm_show_temp_deactivated, NULL); -static DEVICE_ATTR(caps, S_IRUGO, tpm_show_caps_1_2, NULL); +static DEVICE_ATTR(caps, S_IRUGO, tpm_show_caps, NULL); static DEVICE_ATTR(cancel, S_IWUSR | S_IWGRP, NULL, tpm_store_cancel); static DEVICE_ATTR(durations, S_IRUGO, tpm_show_durations, NULL); static DEVICE_ATTR(timeouts, S_IRUGO, tpm_show_timeouts, NULL); diff --git a/drivers/char/tpm/tpm_i2c_infineon.c b/drivers/char/tpm/tpm_i2c_infineon.c index e33d8e5..fefd2aa 100644 --- a/drivers/char/tpm/tpm_i2c_infineon.c +++ b/drivers/char/tpm/tpm_i2c_infineon.c @@ -581,7 +581,7 @@ static DEVICE_ATTR(enabled, S_IRUGO, tpm_show_enabled, NULL); static DEVICE_ATTR(active, S_IRUGO, tpm_show_active, NULL); static DEVICE_ATTR(owned, S_IRUGO, tpm_show_owned, NULL); static DEVICE_ATTR(temp_deactivated, S_IRUGO, tpm_show_temp_deactivated, NULL); -static DEVICE_ATTR(caps, S_IRUGO, tpm_show_caps_1_2, NULL); +static DEVICE_ATTR(caps, S_IRUGO, tpm_show_caps, NULL); static DEVICE_ATTR(cancel, S_IWUSR | S_IWGRP, NULL, tpm_store_cancel); static DEVICE_ATTR(durations, S_IRUGO, tpm_show_durations, NULL); static DEVICE_ATTR(timeouts, S_IRUGO, tpm_show_timeouts, NULL); diff --git a/drivers/char/tpm/tpm_i2c_nuvoton.c b/drivers/char/tpm/tpm_i2c_nuvoton.c index 4f74e7d..6276fea 100644 --- a/drivers/char/tpm/tpm_i2c_nuvoton.c +++ b/drivers/char/tpm/tpm_i2c_nuvoton.c @@ -471,7 +471,7 @@ static DEVICE_ATTR(enabled, S_IRUGO, tpm_show_enabled, NULL); static DEVICE_ATTR(active, S_IRUGO, tpm_show_active, NULL); static DEVICE_ATTR(owned, S_IRUGO, tpm_show_owned, NULL); static DEVICE_ATTR(temp_deactivated, S_IRUGO, tpm_show_temp_deactivated, NULL); -static DEVICE_ATTR(caps, S_IRUGO, tpm_show_caps_1_2, NULL); +static DEVICE_ATTR(caps, S_IRUGO, tpm_show_caps, NULL); static DEVICE_ATTR(cancel, S_IWUSR | S_IWGRP, NULL, tpm_store_cancel); static DEVICE_ATTR(durations, S_IRUGO, tpm_show_durations, NULL); static DEVICE_ATTR(timeouts, S_IRUGO, tpm_show_timeouts, NULL); diff --git a/drivers/char/tpm/tpm_i2c_stm_st33.c b/drivers/char/tpm/tpm_i2c_stm_st33.c index 1c68d93..b069afb 100644 --- a/drivers/char/tpm/tpm_i2c_stm_st33.c +++ b/drivers/char/tpm/tpm_i2c_stm_st33.c @@ -584,7 +584,7 @@ static DEVICE_ATTR(enabled, S_IRUGO, tpm_show_enabled, NULL); static DEVICE_ATTR(active, S_IRUGO, tpm_show_active, NULL); static DEVICE_ATTR(owned, S_IRUGO, tpm_show_owned, NULL); static DEVICE_ATTR(temp_deactivated, S_IRUGO, tpm_show_temp_deactivated, NULL); -static DEVICE_ATTR(caps, S_IRUGO, tpm_show_caps_1_2, NULL); +static DEVICE_ATTR(caps, S_IRUGO, tpm_show_caps, NULL); static DEVICE_ATTR(cancel, S_IWUSR | S_IWGRP, NULL, tpm_store_cancel); static struct attribute *stm_tpm_attrs[] = { diff --git a/drivers/char/tpm/tpm_ibmvtpm.c b/drivers/char/tpm/tpm_ibmvtpm.c index 838f043..2783a42 100644 --- a/drivers/char/tpm/tpm_ibmvtpm.c +++ b/drivers/char/tpm/tpm_ibmvtpm.c @@ -419,7 +419,7 @@ static DEVICE_ATTR(active, S_IRUGO, tpm_show_active, NULL); static DEVICE_ATTR(owned, S_IRUGO, tpm_show_owned, NULL); static DEVICE_ATTR(temp_deactivated, S_IRUGO, tpm_show_temp_deactivated, NULL); -static DEVICE_ATTR(caps, S_IRUGO, tpm_show_caps_1_2, NULL); +static DEVICE_ATTR(caps, S_IRUGO, tpm_show_caps, NULL); static DEVICE_ATTR(cancel, S_IWUSR | S_IWGRP, NULL, tpm_store_cancel); static DEVICE_ATTR(durations, S_IRUGO, tpm_show_durations, NULL); static DEVICE_ATTR(timeouts, S_IRUGO, tpm_show_timeouts, NULL); diff --git a/drivers/char/tpm/tpm_spi_stm_st33.c b/drivers/char/tpm/tpm_spi_stm_st33.c index f5e3cd6..7b8899d 100644 --- a/drivers/char/tpm/tpm_spi_stm_st33.c +++ b/drivers/char/tpm/tpm_spi_stm_st33.c @@ -606,7 +606,7 @@ static DEVICE_ATTR(enabled, S_IRUGO, tpm_show_enabled, NULL); static DEVICE_ATTR(active, S_IRUGO, tpm_show_active, NULL); static DEVICE_ATTR(owned, S_IRUGO, tpm_show_owned, NULL); static DEVICE_ATTR(temp_deactivated, S_IRUGO, tpm_show_temp_deactivated, NULL); -static DEVICE_ATTR(caps, S_IRUGO, tpm_show_caps_1_2, NULL); +static DEVICE_ATTR(caps, S_IRUGO, tpm_show_caps, NULL); static DEVICE_ATTR(cancel, S_IWUSR | S_IWGRP, NULL, tpm_store_cancel); static struct attribute *stm_tpm_attrs[] = { diff --git a/drivers/char/tpm/tpm_tis.c b/drivers/char/tpm/tpm_tis.c index 5796d01..1b74459 100644 --- a/drivers/char/tpm/tpm_tis.c +++ b/drivers/char/tpm/tpm_tis.c @@ -448,7 +448,7 @@ static DEVICE_ATTR(active, S_IRUGO, tpm_show_active, NULL); static DEVICE_ATTR(owned, S_IRUGO, tpm_show_owned, NULL); static DEVICE_ATTR(temp_deactivated, S_IRUGO, tpm_show_temp_deactivated, NULL); -static DEVICE_ATTR(caps, S_IRUGO, tpm_show_caps_1_2, NULL); +static DEVICE_ATTR(caps, S_IRUGO, tpm_show_caps, NULL); static DEVICE_ATTR(cancel, S_IWUSR | S_IWGRP, NULL, tpm_store_cancel); static DEVICE_ATTR(durations, S_IRUGO, tpm_show_durations, NULL); static DEVICE_ATTR(timeouts, S_IRUGO, tpm_show_timeouts, NULL); -- 1.8.1.2 |
From: Jason G. <jgu...@ob...> - 2013-09-23 18:16:17
|
CLASS-sysfs.c is a common idiom for linux subsystems. This pulls all the sysfs attribute functions and related code into tpm-sysfs.c. To support this change some constants are moved from tpm.c to tpm.h and __tpm_pcr_read is made non-static and is called tpm_pcr_read_dev. Signed-off-by: Jason Gunthorpe <jgu...@ob...> --- drivers/char/tpm/Makefile | 2 +- drivers/char/tpm/tpm-sysfs.c | 318 ++++++++++++++++++++++++++++++++++++ drivers/char/tpm/tpm.c | 279 +------------------------------ drivers/char/tpm/tpm.h | 54 +++--- drivers/char/tpm/tpm_atmel.c | 16 -- drivers/char/tpm/tpm_i2c_atmel.c | 30 ---- drivers/char/tpm/tpm_i2c_infineon.c | 30 ---- drivers/char/tpm/tpm_i2c_nuvoton.c | 30 ---- drivers/char/tpm/tpm_i2c_stm_st33.c | 25 --- drivers/char/tpm/tpm_ibmvtpm.c | 28 ---- drivers/char/tpm/tpm_infineon.c | 16 -- drivers/char/tpm/tpm_nsc.c | 16 -- drivers/char/tpm/tpm_spi_stm_st33.c | 25 --- drivers/char/tpm/tpm_tis.c | 30 ---- drivers/char/tpm/xen-tpmfront.c | 34 ---- 15 files changed, 355 insertions(+), 578 deletions(-) create mode 100644 drivers/char/tpm/tpm-sysfs.c diff --git a/drivers/char/tpm/Makefile b/drivers/char/tpm/Makefile index 5a73665..2c876a9 100644 --- a/drivers/char/tpm/Makefile +++ b/drivers/char/tpm/Makefile @@ -1,7 +1,7 @@ # # Makefile for the kernel tpm device drivers. # -obj-$(CONFIG_TCG_TPM) += tpm.o tpm-dev.o +obj-$(CONFIG_TCG_TPM) += tpm.o tpm-dev.o tpm-sysfs.o ifdef CONFIG_ACPI obj-$(CONFIG_TCG_TPM) += tpm_bios.o tpm_bios-objs += tpm_eventlog.o tpm_acpi.o tpm_ppi.o diff --git a/drivers/char/tpm/tpm-sysfs.c b/drivers/char/tpm/tpm-sysfs.c new file mode 100644 index 0000000..3bcfed0 --- /dev/null +++ b/drivers/char/tpm/tpm-sysfs.c @@ -0,0 +1,318 @@ +/* + * Copyright (C) 2004 IBM Corporation + * Authors: + * Leendert van Doorn <lee...@wa...> + * Dave Safford <sa...@wa...> + * Reiner Sailer <sa...@wa...> + * Kylene Hall <kj...@us...> + * + * Copyright (C) 2013 Obsidian Reearch Corp + * Jason Gunthorpe <jgu...@ob...> + * + * sysfs filesystem inspection interface to the TPM + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation, version 2 of the + * License. + * + */ +#include <linux/device.h> +#include "tpm.h" + +/* XXX for now this helper is duplicated in tpm.c */ +static ssize_t transmit_cmd(struct tpm_chip *chip, struct tpm_cmd_t *cmd, + int len, const char *desc) +{ + int err; + + len = tpm_transmit(chip, (u8 *) cmd, len); + if (len < 0) + return len; + else if (len < TPM_HEADER_SIZE) + return -EFAULT; + + err = be32_to_cpu(cmd->header.out.return_code); + if (err != 0 && desc) + dev_err(chip->dev, "A TPM error (%d) occurred %s\n", err, desc); + + return err; +} + +#define READ_PUBEK_RESULT_SIZE 314 +#define TPM_ORD_READPUBEK cpu_to_be32(124) +static struct tpm_input_header tpm_readpubek_header = { + .tag = TPM_TAG_RQU_COMMAND, + .length = cpu_to_be32(30), + .ordinal = TPM_ORD_READPUBEK +}; +static ssize_t pubek_show(struct device *dev, struct device_attribute *attr, + char *buf) +{ + u8 *data; + struct tpm_cmd_t tpm_cmd; + ssize_t err; + int i, rc; + char *str = buf; + + struct tpm_chip *chip = dev_get_drvdata(dev); + + tpm_cmd.header.in = tpm_readpubek_header; + err = transmit_cmd(chip, &tpm_cmd, READ_PUBEK_RESULT_SIZE, + "attempting to read the PUBEK"); + if (err) + goto out; + + /* + ignore header 10 bytes + algorithm 32 bits (1 == RSA ) + encscheme 16 bits + sigscheme 16 bits + parameters (RSA 12->bytes: keybit, #primes, expbit) + keylenbytes 32 bits + 256 byte modulus + ignore checksum 20 bytes + */ + data = tpm_cmd.params.readpubek_out_buffer; + str += + sprintf(str, + "Algorithm: %02X %02X %02X %02X\n" + "Encscheme: %02X %02X\n" + "Sigscheme: %02X %02X\n" + "Parameters: %02X %02X %02X %02X " + "%02X %02X %02X %02X " + "%02X %02X %02X %02X\n" + "Modulus length: %d\n" + "Modulus:\n", + data[0], data[1], data[2], data[3], + data[4], data[5], + data[6], data[7], + data[12], data[13], data[14], data[15], + data[16], data[17], data[18], data[19], + data[20], data[21], data[22], data[23], + be32_to_cpu(*((__be32 *) (data + 24)))); + + for (i = 0; i < 256; i++) { + str += sprintf(str, "%02X ", data[i + 28]); + if ((i + 1) % 16 == 0) + str += sprintf(str, "\n"); + } +out: + rc = str - buf; + return rc; +} +static DEVICE_ATTR_RO(pubek); + +static ssize_t pcrs_show(struct device *dev, struct device_attribute *attr, + char *buf) +{ + cap_t cap; + u8 digest[TPM_DIGEST_SIZE]; + ssize_t rc; + int i, j, num_pcrs; + char *str = buf; + struct tpm_chip *chip = dev_get_drvdata(dev); + + rc = tpm_getcap(dev, TPM_CAP_PROP_PCR, &cap, + "attempting to determine the number of PCRS"); + if (rc) + return 0; + + num_pcrs = be32_to_cpu(cap.num_pcrs); + for (i = 0; i < num_pcrs; i++) { + rc = tpm_pcr_read_dev(chip, i, digest); + if (rc) + break; + str += sprintf(str, "PCR-%02d: ", i); + for (j = 0; j < TPM_DIGEST_SIZE; j++) + str += sprintf(str, "%02X ", digest[j]); + str += sprintf(str, "\n"); + } + return str - buf; +} +static DEVICE_ATTR_RO(pcrs); + +static ssize_t enabled_show(struct device *dev, struct device_attribute *attr, + char *buf) +{ + cap_t cap; + ssize_t rc; + + rc = tpm_getcap(dev, TPM_CAP_FLAG_PERM, &cap, + "attempting to determine the permanent enabled state"); + if (rc) + return 0; + + rc = sprintf(buf, "%d\n", !cap.perm_flags.disable); + return rc; +} +static DEVICE_ATTR_RO(enabled); + +ssize_t active_show(struct device *dev, struct device_attribute *attr, + char *buf) +{ + cap_t cap; + ssize_t rc; + + rc = tpm_getcap(dev, TPM_CAP_FLAG_PERM, &cap, + "attempting to determine the permanent active state"); + if (rc) + return 0; + + rc = sprintf(buf, "%d\n", !cap.perm_flags.deactivated); + return rc; +} +static DEVICE_ATTR_RO(active); + +static ssize_t owned_show(struct device *dev, struct device_attribute *attr, + char *buf) +{ + cap_t cap; + ssize_t rc; + + rc = tpm_getcap(dev, TPM_CAP_PROP_OWNER, &cap, + "attempting to determine the owner state"); + if (rc) + return 0; + + rc = sprintf(buf, "%d\n", cap.owned); + return rc; +} +static DEVICE_ATTR_RO(owned); + +static ssize_t temp_deactivated_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + cap_t cap; + ssize_t rc; + + rc = tpm_getcap(dev, TPM_CAP_FLAG_VOL, &cap, + "attempting to determine the temporary state"); + if (rc) + return 0; + + rc = sprintf(buf, "%d\n", cap.stclear_flags.deactivated); + return rc; +} +static DEVICE_ATTR_RO(temp_deactivated); + +static ssize_t caps_show(struct device *dev, struct device_attribute *attr, + char *buf) +{ + cap_t cap; + ssize_t rc; + char *str = buf; + + rc = tpm_getcap(dev, TPM_CAP_PROP_MANUFACTURER, &cap, + "attempting to determine the manufacturer"); + if (rc) + return 0; + str += sprintf(str, "Manufacturer: 0x%x\n", + be32_to_cpu(cap.manufacturer_id)); + + /* Try to get a TPM version 1.2 TPM_CAP_VERSION_INFO */ + rc = tpm_getcap(dev, CAP_VERSION_1_2, &cap, + "attempting to determine the 1.2 version"); + if (!rc) { + str += sprintf(str, + "TCG version: %d.%d\nFirmware version: %d.%d\n", + cap.tpm_version_1_2.Major, + cap.tpm_version_1_2.Minor, + cap.tpm_version_1_2.revMajor, + cap.tpm_version_1_2.revMinor); + } else { + /* Otherwise just use TPM_STRUCT_VER */ + rc = tpm_getcap(dev, CAP_VERSION_1_1, &cap, + "attempting to determine the 1.1 version"); + if (rc) + return 0; + str += sprintf(str, + "TCG version: %d.%d\nFirmware version: %d.%d\n", + cap.tpm_version.Major, + cap.tpm_version.Minor, + cap.tpm_version.revMajor, + cap.tpm_version.revMinor); + } + + return str - buf; +} +static DEVICE_ATTR_RO(caps); + +static ssize_t cancel_store(struct device *dev, struct device_attribute *attr, + const char *buf, size_t count) +{ + struct tpm_chip *chip = dev_get_drvdata(dev); + if (chip == NULL) + return 0; + + chip->vendor.cancel(chip); + return count; +} +static DEVICE_ATTR_WO(cancel); + +static ssize_t durations_show(struct device *dev, struct device_attribute *attr, + char *buf) +{ + struct tpm_chip *chip = dev_get_drvdata(dev); + + if (chip->vendor.duration[TPM_LONG] == 0) + return 0; + + return sprintf(buf, "%d %d %d [%s]\n", + jiffies_to_usecs(chip->vendor.duration[TPM_SHORT]), + jiffies_to_usecs(chip->vendor.duration[TPM_MEDIUM]), + jiffies_to_usecs(chip->vendor.duration[TPM_LONG]), + chip->vendor.duration_adjusted + ? "adjusted" : "original"); +} +static DEVICE_ATTR_RO(durations); + +static ssize_t timeouts_show(struct device *dev, struct device_attribute *attr, + char *buf) +{ + struct tpm_chip *chip = dev_get_drvdata(dev); + + return sprintf(buf, "%d %d %d %d [%s]\n", + jiffies_to_usecs(chip->vendor.timeout_a), + jiffies_to_usecs(chip->vendor.timeout_b), + jiffies_to_usecs(chip->vendor.timeout_c), + jiffies_to_usecs(chip->vendor.timeout_d), + chip->vendor.timeout_adjusted + ? "adjusted" : "original"); +} +static DEVICE_ATTR_RO(timeouts); + +static struct attribute *tpm_dev_attrs[] = { + &dev_attr_pubek.attr, + &dev_attr_pcrs.attr, + &dev_attr_enabled.attr, + &dev_attr_active.attr, + &dev_attr_owned.attr, + &dev_attr_temp_deactivated.attr, + &dev_attr_caps.attr, + &dev_attr_cancel.attr, + &dev_attr_durations.attr, + &dev_attr_timeouts.attr, + NULL, +}; + +static const struct attribute_group tpm_dev_group = { + .attrs = tpm_dev_attrs, +}; + +int tpm_sysfs_add_device(struct tpm_chip *chip) +{ + int err; + err = sysfs_create_group(&chip->dev->kobj, + &tpm_dev_group); + + if (err) + dev_err(chip->dev, + "failed to create sysfs attributes, %d\n", err); + return err; +} + +void tpm_sysfs_del_device(struct tpm_chip *chip) +{ + sysfs_remove_group(&chip->dev->kobj, &tpm_dev_group); +} diff --git a/drivers/char/tpm/tpm.c b/drivers/char/tpm/tpm.c index 63f1c45..39758f8 100644 --- a/drivers/char/tpm/tpm.c +++ b/drivers/char/tpm/tpm.c @@ -32,13 +32,6 @@ #include "tpm.h" #include "tpm_eventlog.h" -enum tpm_duration { - TPM_SHORT = 0, - TPM_MEDIUM = 1, - TPM_LONG = 2, - TPM_UNDEFINED, -}; - #define TPM_MAX_ORDINAL 243 #define TSC_MAX_ORDINAL 12 #define TPM_PROTECTED_COMMAND 0x00 @@ -404,24 +397,6 @@ out: #define TPM_DIGEST_SIZE 20 #define TPM_RET_CODE_IDX 6 -enum tpm_capabilities { - TPM_CAP_FLAG = cpu_to_be32(4), - TPM_CAP_PROP = cpu_to_be32(5), - CAP_VERSION_1_1 = cpu_to_be32(0x06), - CAP_VERSION_1_2 = cpu_to_be32(0x1A) -}; - -enum tpm_sub_capabilities { - TPM_CAP_PROP_PCR = cpu_to_be32(0x101), - TPM_CAP_PROP_MANUFACTURER = cpu_to_be32(0x103), - TPM_CAP_FLAG_PERM = cpu_to_be32(0x108), - TPM_CAP_FLAG_VOL = cpu_to_be32(0x109), - TPM_CAP_PROP_OWNER = cpu_to_be32(0x111), - TPM_CAP_PROP_TIS_TIMEOUT = cpu_to_be32(0x115), - TPM_CAP_PROP_TIS_DURATION = cpu_to_be32(0x120), - -}; - static ssize_t transmit_cmd(struct tpm_chip *chip, struct tpm_cmd_t *cmd, int len, const char *desc) { @@ -441,7 +416,6 @@ static ssize_t transmit_cmd(struct tpm_chip *chip, struct tpm_cmd_t *cmd, } #define TPM_INTERNAL_RESULT_SIZE 200 -#define TPM_TAG_RQU_COMMAND cpu_to_be16(193) #define TPM_ORD_GET_CAP cpu_to_be32(101) #define TPM_ORD_GET_RANDOM cpu_to_be32(70) @@ -641,70 +615,6 @@ static int tpm_continue_selftest(struct tpm_chip *chip) return rc; } -ssize_t tpm_show_enabled(struct device * dev, struct device_attribute * attr, - char *buf) -{ - cap_t cap; - ssize_t rc; - - rc = tpm_getcap(dev, TPM_CAP_FLAG_PERM, &cap, - "attempting to determine the permanent enabled state"); - if (rc) - return 0; - - rc = sprintf(buf, "%d\n", !cap.perm_flags.disable); - return rc; -} -EXPORT_SYMBOL_GPL(tpm_show_enabled); - -ssize_t tpm_show_active(struct device * dev, struct device_attribute * attr, - char *buf) -{ - cap_t cap; - ssize_t rc; - - rc = tpm_getcap(dev, TPM_CAP_FLAG_PERM, &cap, - "attempting to determine the permanent active state"); - if (rc) - return 0; - - rc = sprintf(buf, "%d\n", !cap.perm_flags.deactivated); - return rc; -} -EXPORT_SYMBOL_GPL(tpm_show_active); - -ssize_t tpm_show_owned(struct device * dev, struct device_attribute * attr, - char *buf) -{ - cap_t cap; - ssize_t rc; - - rc = tpm_getcap(dev, TPM_CAP_PROP_OWNER, &cap, - "attempting to determine the owner state"); - if (rc) - return 0; - - rc = sprintf(buf, "%d\n", cap.owned); - return rc; -} -EXPORT_SYMBOL_GPL(tpm_show_owned); - -ssize_t tpm_show_temp_deactivated(struct device * dev, - struct device_attribute * attr, char *buf) -{ - cap_t cap; - ssize_t rc; - - rc = tpm_getcap(dev, TPM_CAP_FLAG_VOL, &cap, - "attempting to determine the temporary state"); - if (rc) - return 0; - - rc = sprintf(buf, "%d\n", cap.stclear_flags.deactivated); - return rc; -} -EXPORT_SYMBOL_GPL(tpm_show_temp_deactivated); - /* * tpm_chip_find_get - return tpm_chip for given chip number */ @@ -734,7 +644,7 @@ static struct tpm_input_header pcrread_header = { .ordinal = TPM_ORDINAL_PCRREAD }; -static int __tpm_pcr_read(struct tpm_chip *chip, int pcr_idx, u8 *res_buf) +int tpm_pcr_read_dev(struct tpm_chip *chip, int pcr_idx, u8 *res_buf) { int rc; struct tpm_cmd_t cmd; @@ -769,7 +679,7 @@ int tpm_pcr_read(u32 chip_num, int pcr_idx, u8 *res_buf) chip = tpm_chip_find_get(chip_num); if (chip == NULL) return -ENODEV; - rc = __tpm_pcr_read(chip, pcr_idx, res_buf); + rc = tpm_pcr_read_dev(chip, pcr_idx, res_buf); tpm_chip_put(chip); return rc; } @@ -894,187 +804,6 @@ int tpm_send(u32 chip_num, void *cmd, size_t buflen) } EXPORT_SYMBOL_GPL(tpm_send); -ssize_t tpm_show_pcrs(struct device *dev, struct device_attribute *attr, - char *buf) -{ - cap_t cap; - u8 digest[TPM_DIGEST_SIZE]; - ssize_t rc; - int i, j, num_pcrs; - char *str = buf; - struct tpm_chip *chip = dev_get_drvdata(dev); - - rc = tpm_getcap(dev, TPM_CAP_PROP_PCR, &cap, - "attempting to determine the number of PCRS"); - if (rc) - return 0; - - num_pcrs = be32_to_cpu(cap.num_pcrs); - for (i = 0; i < num_pcrs; i++) { - rc = __tpm_pcr_read(chip, i, digest); - if (rc) - break; - str += sprintf(str, "PCR-%02d: ", i); - for (j = 0; j < TPM_DIGEST_SIZE; j++) - str += sprintf(str, "%02X ", digest[j]); - str += sprintf(str, "\n"); - } - return str - buf; -} -EXPORT_SYMBOL_GPL(tpm_show_pcrs); - -#define READ_PUBEK_RESULT_SIZE 314 -#define TPM_ORD_READPUBEK cpu_to_be32(124) -static struct tpm_input_header tpm_readpubek_header = { - .tag = TPM_TAG_RQU_COMMAND, - .length = cpu_to_be32(30), - .ordinal = TPM_ORD_READPUBEK -}; - -ssize_t tpm_show_pubek(struct device *dev, struct device_attribute *attr, - char *buf) -{ - u8 *data; - struct tpm_cmd_t tpm_cmd; - ssize_t err; - int i, rc; - char *str = buf; - - struct tpm_chip *chip = dev_get_drvdata(dev); - - tpm_cmd.header.in = tpm_readpubek_header; - err = transmit_cmd(chip, &tpm_cmd, READ_PUBEK_RESULT_SIZE, - "attempting to read the PUBEK"); - if (err) - goto out; - - /* - ignore header 10 bytes - algorithm 32 bits (1 == RSA ) - encscheme 16 bits - sigscheme 16 bits - parameters (RSA 12->bytes: keybit, #primes, expbit) - keylenbytes 32 bits - 256 byte modulus - ignore checksum 20 bytes - */ - data = tpm_cmd.params.readpubek_out_buffer; - str += - sprintf(str, - "Algorithm: %02X %02X %02X %02X\n" - "Encscheme: %02X %02X\n" - "Sigscheme: %02X %02X\n" - "Parameters: %02X %02X %02X %02X " - "%02X %02X %02X %02X " - "%02X %02X %02X %02X\n" - "Modulus length: %d\n" - "Modulus:\n", - data[0], data[1], data[2], data[3], - data[4], data[5], - data[6], data[7], - data[12], data[13], data[14], data[15], - data[16], data[17], data[18], data[19], - data[20], data[21], data[22], data[23], - be32_to_cpu(*((__be32 *) (data + 24)))); - - for (i = 0; i < 256; i++) { - str += sprintf(str, "%02X ", data[i + 28]); - if ((i + 1) % 16 == 0) - str += sprintf(str, "\n"); - } -out: - rc = str - buf; - return rc; -} -EXPORT_SYMBOL_GPL(tpm_show_pubek); - - -ssize_t tpm_show_caps(struct device *dev, struct device_attribute *attr, - char *buf) -{ - cap_t cap; - ssize_t rc; - char *str = buf; - - rc = tpm_getcap(dev, TPM_CAP_PROP_MANUFACTURER, &cap, - "attempting to determine the manufacturer"); - if (rc) - return 0; - str += sprintf(str, "Manufacturer: 0x%x\n", - be32_to_cpu(cap.manufacturer_id)); - - /* Try to get a TPM version 1.2 TPM_CAP_VERSION_INFO */ - rc = tpm_getcap(dev, CAP_VERSION_1_2, &cap, - "attempting to determine the 1.2 version"); - if (!rc) { - str += sprintf(str, - "TCG version: %d.%d\nFirmware version: %d.%d\n", - cap.tpm_version_1_2.Major, - cap.tpm_version_1_2.Minor, - cap.tpm_version_1_2.revMajor, - cap.tpm_version_1_2.revMinor); - } else { - /* Otherwise just use TPM_STRUCT_VER */ - rc = tpm_getcap(dev, CAP_VERSION_1_1, &cap, - "attempting to determine the 1.1 version"); - if (rc) - return 0; - str += sprintf(str, - "TCG version: %d.%d\nFirmware version: %d.%d\n", - cap.tpm_version.Major, - cap.tpm_version.Minor, - cap.tpm_version.revMajor, - cap.tpm_version.revMinor); - } - - return str - buf; -} -EXPORT_SYMBOL_GPL(tpm_show_caps); - -ssize_t tpm_show_durations(struct device *dev, struct device_attribute *attr, - char *buf) -{ - struct tpm_chip *chip = dev_get_drvdata(dev); - - if (chip->vendor.duration[TPM_LONG] == 0) - return 0; - - return sprintf(buf, "%d %d %d [%s]\n", - jiffies_to_usecs(chip->vendor.duration[TPM_SHORT]), - jiffies_to_usecs(chip->vendor.duration[TPM_MEDIUM]), - jiffies_to_usecs(chip->vendor.duration[TPM_LONG]), - chip->vendor.duration_adjusted - ? "adjusted" : "original"); -} -EXPORT_SYMBOL_GPL(tpm_show_durations); - -ssize_t tpm_show_timeouts(struct device *dev, struct device_attribute *attr, - char *buf) -{ - struct tpm_chip *chip = dev_get_drvdata(dev); - - return sprintf(buf, "%d %d %d %d [%s]\n", - jiffies_to_usecs(chip->vendor.timeout_a), - jiffies_to_usecs(chip->vendor.timeout_b), - jiffies_to_usecs(chip->vendor.timeout_c), - jiffies_to_usecs(chip->vendor.timeout_d), - chip->vendor.timeout_adjusted - ? "adjusted" : "original"); -} -EXPORT_SYMBOL_GPL(tpm_show_timeouts); - -ssize_t tpm_store_cancel(struct device *dev, struct device_attribute *attr, - const char *buf, size_t count) -{ - struct tpm_chip *chip = dev_get_drvdata(dev); - if (chip == NULL) - return 0; - - chip->vendor.cancel(chip); - return count; -} -EXPORT_SYMBOL_GPL(tpm_store_cancel); - static bool wait_for_tpm_stat_cond(struct tpm_chip *chip, u8 mask, bool check_cancel, bool *canceled) { @@ -1150,7 +879,7 @@ void tpm_remove_hardware(struct device *dev) synchronize_rcu(); tpm_dev_del_device(chip); - sysfs_remove_group(&dev->kobj, chip->vendor.attr_group); + tpm_sysfs_del_device(chip); tpm_remove_ppi(&dev->kobj); tpm_bios_log_teardown(chip->bios_dir); @@ -1367,7 +1096,7 @@ struct tpm_chip *tpm_register_hardware(struct device *dev, if (tpm_dev_add_device(chip)) goto put_device; - if (sysfs_create_group(&dev->kobj, chip->vendor.attr_group)) + if (tpm_sysfs_add_device(chip)) goto del_misc; if (tpm_add_ppi(&dev->kobj)) diff --git a/drivers/char/tpm/tpm.h b/drivers/char/tpm/tpm.h index 496228c..14ba162 100644 --- a/drivers/char/tpm/tpm.h +++ b/drivers/char/tpm/tpm.h @@ -46,6 +46,14 @@ enum tpm_addr { TPM_ADDR = 0x4E, }; +/* Indexes the duration array */ +enum tpm_duration { + TPM_SHORT = 0, + TPM_MEDIUM = 1, + TPM_LONG = 2, + TPM_UNDEFINED, +}; + #define TPM_WARN_RETRY 0x800 #define TPM_WARN_DOING_SELFTEST 0x802 #define TPM_ERR_DEACTIVATED 0x6 @@ -53,27 +61,6 @@ enum tpm_addr { #define TPM_ERR_INVALID_POSTINIT 38 #define TPM_HEADER_SIZE 10 -extern ssize_t tpm_show_pubek(struct device *, struct device_attribute *attr, - char *); -extern ssize_t tpm_show_pcrs(struct device *, struct device_attribute *attr, - char *); -extern ssize_t tpm_show_caps(struct device *, struct device_attribute *attr, - char *); -extern ssize_t tpm_store_cancel(struct device *, struct device_attribute *attr, - const char *, size_t); -extern ssize_t tpm_show_enabled(struct device *, struct device_attribute *attr, - char *); -extern ssize_t tpm_show_active(struct device *, struct device_attribute *attr, - char *); -extern ssize_t tpm_show_owned(struct device *, struct device_attribute *attr, - char *); -extern ssize_t tpm_show_temp_deactivated(struct device *, - struct device_attribute *attr, char *); -extern ssize_t tpm_show_durations(struct device *, - struct device_attribute *attr, char *); -extern ssize_t tpm_show_timeouts(struct device *, - struct device_attribute *attr, char *); - struct tpm_chip; struct tpm_vendor_specific { @@ -95,7 +82,6 @@ struct tpm_vendor_specific { u8 (*status) (struct tpm_chip *); void (*release) (struct device *); struct miscdevice miscdev; - struct attribute_group *attr_group; struct list_head list; int locality; unsigned long timeout_a, timeout_b, timeout_c, timeout_d; /* jiffies */ @@ -171,6 +157,8 @@ struct tpm_output_header { __be32 return_code; } __packed; +#define TPM_TAG_RQU_COMMAND cpu_to_be16(193) + struct stclear_flags_t { __be16 tag; u8 deactivated; @@ -244,6 +232,24 @@ typedef union { struct duration_t duration; } cap_t; +enum tpm_capabilities { + TPM_CAP_FLAG = cpu_to_be32(4), + TPM_CAP_PROP = cpu_to_be32(5), + CAP_VERSION_1_1 = cpu_to_be32(0x06), + CAP_VERSION_1_2 = cpu_to_be32(0x1A) +}; + +enum tpm_sub_capabilities { + TPM_CAP_PROP_PCR = cpu_to_be32(0x101), + TPM_CAP_PROP_MANUFACTURER = cpu_to_be32(0x103), + TPM_CAP_FLAG_PERM = cpu_to_be32(0x108), + TPM_CAP_FLAG_VOL = cpu_to_be32(0x109), + TPM_CAP_PROP_OWNER = cpu_to_be32(0x111), + TPM_CAP_PROP_TIS_TIMEOUT = cpu_to_be32(0x115), + TPM_CAP_PROP_TIS_DURATION = cpu_to_be32(0x120), + +}; + struct tpm_getcap_params_in { __be32 cap; __be32 subcap_size; @@ -340,6 +346,10 @@ extern int wait_for_tpm_stat(struct tpm_chip *, u8, unsigned long, int tpm_dev_add_device(struct tpm_chip *chip); void tpm_dev_del_device(struct tpm_chip *chip); +int tpm_sysfs_add_device(struct tpm_chip *chip); +void tpm_sysfs_del_device(struct tpm_chip *chip); + +int tpm_pcr_read_dev(struct tpm_chip *chip, int pcr_idx, u8 *res_buf); #ifdef CONFIG_ACPI extern int tpm_add_ppi(struct kobject *); diff --git a/drivers/char/tpm/tpm_atmel.c b/drivers/char/tpm/tpm_atmel.c index 9692e2f..7e665d0 100644 --- a/drivers/char/tpm/tpm_atmel.c +++ b/drivers/char/tpm/tpm_atmel.c @@ -121,21 +121,6 @@ static bool tpm_atml_req_canceled(struct tpm_chip *chip, u8 status) return (status == ATML_STATUS_READY); } -static DEVICE_ATTR(pubek, S_IRUGO, tpm_show_pubek, NULL); -static DEVICE_ATTR(pcrs, S_IRUGO, tpm_show_pcrs, NULL); -static DEVICE_ATTR(caps, S_IRUGO, tpm_show_caps, NULL); -static DEVICE_ATTR(cancel, S_IWUSR |S_IWGRP, NULL, tpm_store_cancel); - -static struct attribute* atmel_attrs[] = { - &dev_attr_pubek.attr, - &dev_attr_pcrs.attr, - &dev_attr_caps.attr, - &dev_attr_cancel.attr, - NULL, -}; - -static struct attribute_group atmel_attr_grp = { .attrs = atmel_attrs }; - static const struct tpm_vendor_specific tpm_atmel = { .recv = tpm_atml_recv, .send = tpm_atml_send, @@ -144,7 +129,6 @@ static const struct tpm_vendor_specific tpm_atmel = { .req_complete_mask = ATML_STATUS_BUSY | ATML_STATUS_DATA_AVAIL, .req_complete_val = ATML_STATUS_DATA_AVAIL, .req_canceled = tpm_atml_req_canceled, - .attr_group = &atmel_attr_grp, }; static struct platform_device *pdev; diff --git a/drivers/char/tpm/tpm_i2c_atmel.c b/drivers/char/tpm/tpm_i2c_atmel.c index f9cee5f..8476a05 100644 --- a/drivers/char/tpm/tpm_i2c_atmel.c +++ b/drivers/char/tpm/tpm_i2c_atmel.c @@ -135,35 +135,6 @@ static u8 i2c_atmel_read_status(struct tpm_chip *chip) return ATMEL_STS_OK; } -static DEVICE_ATTR(pubek, S_IRUGO, tpm_show_pubek, NULL); -static DEVICE_ATTR(pcrs, S_IRUGO, tpm_show_pcrs, NULL); -static DEVICE_ATTR(enabled, S_IRUGO, tpm_show_enabled, NULL); -static DEVICE_ATTR(active, S_IRUGO, tpm_show_active, NULL); -static DEVICE_ATTR(owned, S_IRUGO, tpm_show_owned, NULL); -static DEVICE_ATTR(temp_deactivated, S_IRUGO, tpm_show_temp_deactivated, NULL); -static DEVICE_ATTR(caps, S_IRUGO, tpm_show_caps, NULL); -static DEVICE_ATTR(cancel, S_IWUSR | S_IWGRP, NULL, tpm_store_cancel); -static DEVICE_ATTR(durations, S_IRUGO, tpm_show_durations, NULL); -static DEVICE_ATTR(timeouts, S_IRUGO, tpm_show_timeouts, NULL); - -static struct attribute *i2c_atmel_attrs[] = { - &dev_attr_pubek.attr, - &dev_attr_pcrs.attr, - &dev_attr_enabled.attr, - &dev_attr_active.attr, - &dev_attr_owned.attr, - &dev_attr_temp_deactivated.attr, - &dev_attr_caps.attr, - &dev_attr_cancel.attr, - &dev_attr_durations.attr, - &dev_attr_timeouts.attr, - NULL, -}; - -static struct attribute_group i2c_atmel_attr_grp = { - .attrs = i2c_atmel_attrs -}; - static bool i2c_atmel_req_canceled(struct tpm_chip *chip, u8 status) { return 0; @@ -177,7 +148,6 @@ static const struct tpm_vendor_specific i2c_atmel = { .req_complete_mask = ATMEL_STS_OK, .req_complete_val = ATMEL_STS_OK, .req_canceled = i2c_atmel_req_canceled, - .attr_group = &i2c_atmel_attr_grp, }; static int i2c_atmel_probe(struct i2c_client *client, diff --git a/drivers/char/tpm/tpm_i2c_infineon.c b/drivers/char/tpm/tpm_i2c_infineon.c index c1ba7fa..ac1218f 100644 --- a/drivers/char/tpm/tpm_i2c_infineon.c +++ b/drivers/char/tpm/tpm_i2c_infineon.c @@ -566,35 +566,6 @@ static bool tpm_tis_i2c_req_canceled(struct tpm_chip *chip, u8 status) return (status == TPM_STS_COMMAND_READY); } -static DEVICE_ATTR(pubek, S_IRUGO, tpm_show_pubek, NULL); -static DEVICE_ATTR(pcrs, S_IRUGO, tpm_show_pcrs, NULL); -static DEVICE_ATTR(enabled, S_IRUGO, tpm_show_enabled, NULL); -static DEVICE_ATTR(active, S_IRUGO, tpm_show_active, NULL); -static DEVICE_ATTR(owned, S_IRUGO, tpm_show_owned, NULL); -static DEVICE_ATTR(temp_deactivated, S_IRUGO, tpm_show_temp_deactivated, NULL); -static DEVICE_ATTR(caps, S_IRUGO, tpm_show_caps, NULL); -static DEVICE_ATTR(cancel, S_IWUSR | S_IWGRP, NULL, tpm_store_cancel); -static DEVICE_ATTR(durations, S_IRUGO, tpm_show_durations, NULL); -static DEVICE_ATTR(timeouts, S_IRUGO, tpm_show_timeouts, NULL); - -static struct attribute *tis_attrs[] = { - &dev_attr_pubek.attr, - &dev_attr_pcrs.attr, - &dev_attr_enabled.attr, - &dev_attr_active.attr, - &dev_attr_owned.attr, - &dev_attr_temp_deactivated.attr, - &dev_attr_caps.attr, - &dev_attr_cancel.attr, - &dev_attr_durations.attr, - &dev_attr_timeouts.attr, - NULL, -}; - -static struct attribute_group tis_attr_grp = { - .attrs = tis_attrs -}; - static struct tpm_vendor_specific tpm_tis_i2c = { .status = tpm_tis_i2c_status, .recv = tpm_tis_i2c_recv, @@ -603,7 +574,6 @@ static struct tpm_vendor_specific tpm_tis_i2c = { .req_complete_mask = TPM_STS_DATA_AVAIL | TPM_STS_VALID, .req_complete_val = TPM_STS_DATA_AVAIL | TPM_STS_VALID, .req_canceled = tpm_tis_i2c_req_canceled, - .attr_group = &tis_attr_grp, }; static int tpm_tis_i2c_init(struct device *dev) diff --git a/drivers/char/tpm/tpm_i2c_nuvoton.c b/drivers/char/tpm/tpm_i2c_nuvoton.c index 3766fe7..5cb9670 100644 --- a/drivers/char/tpm/tpm_i2c_nuvoton.c +++ b/drivers/char/tpm/tpm_i2c_nuvoton.c @@ -456,35 +456,6 @@ static bool i2c_nuvoton_req_canceled(struct tpm_chip *chip, u8 status) return (status == TPM_STS_COMMAND_READY); } -static DEVICE_ATTR(pubek, S_IRUGO, tpm_show_pubek, NULL); -static DEVICE_ATTR(pcrs, S_IRUGO, tpm_show_pcrs, NULL); -static DEVICE_ATTR(enabled, S_IRUGO, tpm_show_enabled, NULL); -static DEVICE_ATTR(active, S_IRUGO, tpm_show_active, NULL); -static DEVICE_ATTR(owned, S_IRUGO, tpm_show_owned, NULL); -static DEVICE_ATTR(temp_deactivated, S_IRUGO, tpm_show_temp_deactivated, NULL); -static DEVICE_ATTR(caps, S_IRUGO, tpm_show_caps, NULL); -static DEVICE_ATTR(cancel, S_IWUSR | S_IWGRP, NULL, tpm_store_cancel); -static DEVICE_ATTR(durations, S_IRUGO, tpm_show_durations, NULL); -static DEVICE_ATTR(timeouts, S_IRUGO, tpm_show_timeouts, NULL); - -static struct attribute *i2c_nuvoton_attrs[] = { - &dev_attr_pubek.attr, - &dev_attr_pcrs.attr, - &dev_attr_enabled.attr, - &dev_attr_active.attr, - &dev_attr_owned.attr, - &dev_attr_temp_deactivated.attr, - &dev_attr_caps.attr, - &dev_attr_cancel.attr, - &dev_attr_durations.attr, - &dev_attr_timeouts.attr, - NULL, -}; - -static struct attribute_group i2c_nuvoton_attr_grp = { - .attrs = i2c_nuvoton_attrs -}; - static const struct tpm_vendor_specific tpm_i2c = { .status = i2c_nuvoton_read_status, .recv = i2c_nuvoton_recv, @@ -493,7 +464,6 @@ static const struct tpm_vendor_specific tpm_i2c = { .req_complete_mask = TPM_STS_DATA_AVAIL | TPM_STS_VALID, .req_complete_val = TPM_STS_DATA_AVAIL | TPM_STS_VALID, .req_canceled = i2c_nuvoton_req_canceled, - .attr_group = &i2c_nuvoton_attr_grp, }; /* The only purpose for the handler is to signal to any waiting threads that diff --git a/drivers/char/tpm/tpm_i2c_stm_st33.c b/drivers/char/tpm/tpm_i2c_stm_st33.c index 2328c5e..588e763 100644 --- a/drivers/char/tpm/tpm_i2c_stm_st33.c +++ b/drivers/char/tpm/tpm_i2c_stm_st33.c @@ -569,30 +569,6 @@ static bool tpm_st33_i2c_req_canceled(struct tpm_chip *chip, u8 status) return (status == TPM_STS_COMMAND_READY); } -static DEVICE_ATTR(pubek, S_IRUGO, tpm_show_pubek, NULL); -static DEVICE_ATTR(pcrs, S_IRUGO, tpm_show_pcrs, NULL); -static DEVICE_ATTR(enabled, S_IRUGO, tpm_show_enabled, NULL); -static DEVICE_ATTR(active, S_IRUGO, tpm_show_active, NULL); -static DEVICE_ATTR(owned, S_IRUGO, tpm_show_owned, NULL); -static DEVICE_ATTR(temp_deactivated, S_IRUGO, tpm_show_temp_deactivated, NULL); -static DEVICE_ATTR(caps, S_IRUGO, tpm_show_caps, NULL); -static DEVICE_ATTR(cancel, S_IWUSR | S_IWGRP, NULL, tpm_store_cancel); - -static struct attribute *stm_tpm_attrs[] = { - &dev_attr_pubek.attr, - &dev_attr_pcrs.attr, - &dev_attr_enabled.attr, - &dev_attr_active.attr, - &dev_attr_owned.attr, - &dev_attr_temp_deactivated.attr, - &dev_attr_caps.attr, - &dev_attr_cancel.attr, NULL, -}; - -static struct attribute_group stm_tpm_attr_grp = { - .attrs = stm_tpm_attrs -}; - static struct tpm_vendor_specific st_i2c_tpm = { .send = tpm_stm_i2c_send, .recv = tpm_stm_i2c_recv, @@ -601,7 +577,6 @@ static struct tpm_vendor_specific st_i2c_tpm = { .req_complete_mask = TPM_STS_DATA_AVAIL | TPM_STS_VALID, .req_complete_val = TPM_STS_DATA_AVAIL | TPM_STS_VALID, .req_canceled = tpm_st33_i2c_req_canceled, - .attr_group = &stm_tpm_attr_grp, }; static int interrupts; diff --git a/drivers/char/tpm/tpm_ibmvtpm.c b/drivers/char/tpm/tpm_ibmvtpm.c index 88a0121..6217d1d 100644 --- a/drivers/char/tpm/tpm_ibmvtpm.c +++ b/drivers/char/tpm/tpm_ibmvtpm.c @@ -403,33 +403,6 @@ static bool tpm_ibmvtpm_req_canceled(struct tpm_chip *chip, u8 status) return (status == 0); } -static DEVICE_ATTR(pubek, S_IRUGO, tpm_show_pubek, NULL); -static DEVICE_ATTR(pcrs, S_IRUGO, tpm_show_pcrs, NULL); -static DEVICE_ATTR(enabled, S_IRUGO, tpm_show_enabled, NULL); -static DEVICE_ATTR(active, S_IRUGO, tpm_show_active, NULL); -static DEVICE_ATTR(owned, S_IRUGO, tpm_show_owned, NULL); -static DEVICE_ATTR(temp_deactivated, S_IRUGO, tpm_show_temp_deactivated, - NULL); -static DEVICE_ATTR(caps, S_IRUGO, tpm_show_caps, NULL); -static DEVICE_ATTR(cancel, S_IWUSR | S_IWGRP, NULL, tpm_store_cancel); -static DEVICE_ATTR(durations, S_IRUGO, tpm_show_durations, NULL); -static DEVICE_ATTR(timeouts, S_IRUGO, tpm_show_timeouts, NULL); - -static struct attribute *ibmvtpm_attrs[] = { - &dev_attr_pubek.attr, - &dev_attr_pcrs.attr, - &dev_attr_enabled.attr, - &dev_attr_active.attr, - &dev_attr_owned.attr, - &dev_attr_temp_deactivated.attr, - &dev_attr_caps.attr, - &dev_attr_cancel.attr, - &dev_attr_durations.attr, - &dev_attr_timeouts.attr, NULL, -}; - -static struct attribute_group ibmvtpm_attr_grp = { .attrs = ibmvtpm_attrs }; - static const struct tpm_vendor_specific tpm_ibmvtpm = { .recv = tpm_ibmvtpm_recv, .send = tpm_ibmvtpm_send, @@ -438,7 +411,6 @@ static const struct tpm_vendor_specific tpm_ibmvtpm = { .req_complete_mask = 0, .req_complete_val = 0, .req_canceled = tpm_ibmvtpm_req_canceled, - .attr_group = &ibmvtpm_attr_grp, }; static const struct dev_pm_ops tpm_ibmvtpm_pm_ops = { diff --git a/drivers/char/tpm/tpm_infineon.c b/drivers/char/tpm/tpm_infineon.c index c75c10c..9525be5 100644 --- a/drivers/char/tpm/tpm_infineon.c +++ b/drivers/char/tpm/tpm_infineon.c @@ -371,21 +371,6 @@ static u8 tpm_inf_status(struct tpm_chip *chip) return tpm_data_in(STAT); } -static DEVICE_ATTR(pubek, S_IRUGO, tpm_show_pubek, NULL); -static DEVICE_ATTR(pcrs, S_IRUGO, tpm_show_pcrs, NULL); -static DEVICE_ATTR(caps, S_IRUGO, tpm_show_caps, NULL); -static DEVICE_ATTR(cancel, S_IWUSR | S_IWGRP, NULL, tpm_store_cancel); - -static struct attribute *inf_attrs[] = { - &dev_attr_pubek.attr, - &dev_attr_pcrs.attr, - &dev_attr_caps.attr, - &dev_attr_cancel.attr, - NULL, -}; - -static struct attribute_group inf_attr_grp = {.attrs = inf_attrs }; - static const struct tpm_vendor_specific tpm_inf = { .recv = tpm_inf_recv, .send = tpm_inf_send, @@ -393,7 +378,6 @@ static const struct tpm_vendor_specific tpm_inf = { .status = tpm_inf_status, .req_complete_mask = 0, .req_complete_val = 0, - .attr_group = &inf_attr_grp, }; static const struct pnp_device_id tpm_inf_pnp_tbl[] = { diff --git a/drivers/char/tpm/tpm_nsc.c b/drivers/char/tpm/tpm_nsc.c index a4acac9..ad980be 100644 --- a/drivers/char/tpm/tpm_nsc.c +++ b/drivers/char/tpm/tpm_nsc.c @@ -232,21 +232,6 @@ static bool tpm_nsc_req_canceled(struct tpm_chip *chip, u8 status) return (status == NSC_STATUS_RDY); } -static DEVICE_ATTR(pubek, S_IRUGO, tpm_show_pubek, NULL); -static DEVICE_ATTR(pcrs, S_IRUGO, tpm_show_pcrs, NULL); -static DEVICE_ATTR(caps, S_IRUGO, tpm_show_caps, NULL); -static DEVICE_ATTR(cancel, S_IWUSR|S_IWGRP, NULL, tpm_store_cancel); - -static struct attribute * nsc_attrs[] = { - &dev_attr_pubek.attr, - &dev_attr_pcrs.attr, - &dev_attr_caps.attr, - &dev_attr_cancel.attr, - NULL, -}; - -static struct attribute_group nsc_attr_grp = { .attrs = nsc_attrs }; - static const struct tpm_vendor_specific tpm_nsc = { .recv = tpm_nsc_recv, .send = tpm_nsc_send, @@ -255,7 +240,6 @@ static const struct tpm_vendor_specific tpm_nsc = { .req_complete_mask = NSC_STATUS_OBF, .req_complete_val = NSC_STATUS_OBF, .req_canceled = tpm_nsc_req_canceled, - .attr_group = &nsc_attr_grp, }; static struct platform_device *pdev = NULL; diff --git a/drivers/char/tpm/tpm_spi_stm_st33.c b/drivers/char/tpm/tpm_spi_stm_st33.c index 99854e8..af46f0d 100644 --- a/drivers/char/tpm/tpm_spi_stm_st33.c +++ b/drivers/char/tpm/tpm_spi_stm_st33.c @@ -591,36 +591,11 @@ out: return size; } -static DEVICE_ATTR(pubek, S_IRUGO, tpm_show_pubek, NULL); -static DEVICE_ATTR(pcrs, S_IRUGO, tpm_show_pcrs, NULL); -static DEVICE_ATTR(enabled, S_IRUGO, tpm_show_enabled, NULL); -static DEVICE_ATTR(active, S_IRUGO, tpm_show_active, NULL); -static DEVICE_ATTR(owned, S_IRUGO, tpm_show_owned, NULL); -static DEVICE_ATTR(temp_deactivated, S_IRUGO, tpm_show_temp_deactivated, NULL); -static DEVICE_ATTR(caps, S_IRUGO, tpm_show_caps, NULL); -static DEVICE_ATTR(cancel, S_IWUSR | S_IWGRP, NULL, tpm_store_cancel); - -static struct attribute *stm_tpm_attrs[] = { - &dev_attr_pubek.attr, - &dev_attr_pcrs.attr, - &dev_attr_enabled.attr, - &dev_attr_active.attr, - &dev_attr_owned.attr, - &dev_attr_temp_deactivated.attr, - &dev_attr_caps.attr, - &dev_attr_cancel.attr, NULL, -}; - -static struct attribute_group stm_tpm_attr_grp = { - .attrs = stm_tpm_attrs -}; - static struct tpm_vendor_specific st_spi_tpm = { .send = tpm_stm_spi_send, .recv = tpm_stm_spi_recv, .cancel = tpm_stm_spi_cancel, .status = tpm_stm_spi_status, - .attr_group = &stm_tpm_attr_grp, }; static int evaluate_latency(struct tpm_chip *chip) diff --git a/drivers/char/tpm/tpm_tis.c b/drivers/char/tpm/tpm_tis.c index 46f57f5..a362ede 100644 --- a/drivers/char/tpm/tpm_tis.c +++ b/drivers/char/tpm/tpm_tis.c @@ -432,35 +432,6 @@ static bool tpm_tis_req_canceled(struct tpm_chip *chip, u8 status) } } -static DEVICE_ATTR(pubek, S_IRUGO, tpm_show_pubek, NULL); -static DEVICE_ATTR(pcrs, S_IRUGO, tpm_show_pcrs, NULL); -static DEVICE_ATTR(enabled, S_IRUGO, tpm_show_enabled, NULL); -static DEVICE_ATTR(active, S_IRUGO, tpm_show_active, NULL); -static DEVICE_ATTR(owned, S_IRUGO, tpm_show_owned, NULL); -static DEVICE_ATTR(temp_deactivated, S_IRUGO, tpm_show_temp_deactivated, - NULL); -static DEVICE_ATTR(caps, S_IRUGO, tpm_show_caps, NULL); -static DEVICE_ATTR(cancel, S_IWUSR | S_IWGRP, NULL, tpm_store_cancel); -static DEVICE_ATTR(durations, S_IRUGO, tpm_show_durations, NULL); -static DEVICE_ATTR(timeouts, S_IRUGO, tpm_show_timeouts, NULL); - -static struct attribute *tis_attrs[] = { - &dev_attr_pubek.attr, - &dev_attr_pcrs.attr, - &dev_attr_enabled.attr, - &dev_attr_active.attr, - &dev_attr_owned.attr, - &dev_attr_temp_deactivated.attr, - &dev_attr_caps.attr, - &dev_attr_cancel.attr, - &dev_attr_durations.attr, - &dev_attr_timeouts.attr, NULL, -}; - -static struct attribute_group tis_attr_grp = { - .attrs = tis_attrs -}; - static struct tpm_vendor_specific tpm_tis = { .status = tpm_tis_status, .recv = tpm_tis_recv, @@ -469,7 +440,6 @@ static struct tpm_vendor_specific tpm_tis = { .req_complete_mask = TPM_STS_DATA_AVAIL | TPM_STS_VALID, .req_complete_val = TPM_STS_DATA_AVAIL | TPM_STS_VALID, .req_canceled = tpm_tis_req_canceled, - .attr_group = &tis_attr_grp, }; static irqreturn_t tis_int_probe(int irq, void *dev_id) diff --git a/drivers/char/tpm/xen-tpmfront.c b/drivers/char/tpm/xen-tpmfront.c index 12a4ab2..7892557 100644 --- a/drivers/char/tpm/xen-tpmfront.c +++ b/drivers/char/tpm/xen-tpmfront.c @@ -168,39 +168,6 @@ ssize_t tpm_store_locality(struct device *dev, struct device_attribute *attr, return len; } -static DEVICE_ATTR(pubek, S_IRUGO, tpm_show_pubek, NULL); -static DEVICE_ATTR(pcrs, S_IRUGO, tpm_show_pcrs, NULL); -static DEVICE_ATTR(enabled, S_IRUGO, tpm_show_enabled, NULL); -static DEVICE_ATTR(active, S_IRUGO, tpm_show_active, NULL); -static DEVICE_ATTR(owned, S_IRUGO, tpm_show_owned, NULL); -static DEVICE_ATTR(temp_deactivated, S_IRUGO, tpm_show_temp_deactivated, - NULL); -static DEVICE_ATTR(caps, S_IRUGO, tpm_show_caps, NULL); -static DEVICE_ATTR(cancel, S_IWUSR | S_IWGRP, NULL, tpm_store_cancel); -static DEVICE_ATTR(durations, S_IRUGO, tpm_show_durations, NULL); -static DEVICE_ATTR(timeouts, S_IRUGO, tpm_show_timeouts, NULL); -static DEVICE_ATTR(locality, S_IRUGO | S_IWUSR, tpm_show_locality, - tpm_store_locality); - -static struct attribute *vtpm_attrs[] = { - &dev_attr_pubek.attr, - &dev_attr_pcrs.attr, - &dev_attr_enabled.attr, - &dev_attr_active.attr, - &dev_attr_owned.attr, - &dev_attr_temp_deactivated.attr, - &dev_attr_caps.attr, - &dev_attr_cancel.attr, - &dev_attr_durations.attr, - &dev_attr_timeouts.attr, - &dev_attr_locality.attr, - NULL, -}; - -static struct attribute_group vtpm_attr_grp = { - .attrs = vtpm_attrs, -}; - static const struct tpm_vendor_specific tpm_vtpm = { .status = vtpm_status, .recv = vtpm_recv, @@ -209,7 +176,6 @@ static const struct tpm_vendor_specific tpm_vtpm = { .req_complete_mask = VTPM_STATUS_IDLE | VTPM_STATUS_RESULT, .req_complete_val = VTPM_STATUS_IDLE | VTPM_STATUS_RESULT, .req_canceled = vtpm_req_canceled, - .attr_group = &vtpm_attr_grp, }; static irqreturn_t tpmif_interrupt(int dummy, void *dev_id) -- 1.8.1.2 |
From: Jason G. <jgu...@ob...> - 2013-09-23 18:16:18
|
All the default durations were being set to 10 minutes which is way too long for the timeouts. Normal values for the longest duration are around 5 mins, and short duration ar around .5s. Further, these are just the default, tpm_get_timeouts will set them to values from the TPM (or throw an error). Just remove them. Cc: Daniel De Graaf <dg...@ty...> Cc: Konrad Rzeszutek Wilk <kon...@or...> Signed-off-by: Jason Gunthorpe <jgu...@ob...> --- drivers/char/tpm/xen-tpmfront.c | 7 ------- 1 file changed, 7 deletions(-) diff --git a/drivers/char/tpm/xen-tpmfront.c b/drivers/char/tpm/xen-tpmfront.c index 7a7929b..6f2fe2b 100644 --- a/drivers/char/tpm/xen-tpmfront.c +++ b/drivers/char/tpm/xen-tpmfront.c @@ -210,8 +210,6 @@ static struct attribute_group vtpm_attr_grp = { .attrs = vtpm_attrs, }; -#define TPM_LONG_TIMEOUT (10 * 60 * HZ) - static const struct tpm_vendor_specific tpm_vtpm = { .status = vtpm_status, .recv = vtpm_recv, @@ -224,11 +222,6 @@ static const struct tpm_vendor_specific tpm_vtpm = { .miscdev = { .fops = &vtpm_ops, }, - .duration = { - TPM_LONG_TIMEOUT, - TPM_LONG_TIMEOUT, - TPM_LONG_TIMEOUT, - }, }; static irqreturn_t tpmif_interrupt(int dummy, void *dev_id) -- 1.8.1.2 |
From: Jason G. <jgu...@ob...> - 2013-09-23 18:16:15
|
Commit e0dd03caf20d040a0a86b6bd74028ec9bda545f5 changed the code path here so that ateml_get_base_addr no longer directly altered the tpm_vendor_specific structure, and instead placed the base address on the stack. The commit missed updating the request_region call, which would have resulted in request_region being called with 0 as the base address. I don't know if request_region(0, ..) will fail, if so the driver has been broken since 2006 and we should remove it from the tree as it has no users. Signed-off-by: Jason Gunthorpe <jgu...@ob...> --- drivers/char/tpm/tpm_atmel.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/char/tpm/tpm_atmel.c b/drivers/char/tpm/tpm_atmel.c index 99d6820..c9a528d 100644 --- a/drivers/char/tpm/tpm_atmel.c +++ b/drivers/char/tpm/tpm_atmel.c @@ -202,7 +202,7 @@ static int __init init_atmel(void) have_region = (atmel_request_region - (tpm_atmel.base, region_size, "tpm_atmel0") == NULL) ? 0 : 1; + (base, region_size, "tpm_atmel0") == NULL) ? 0 : 1; pdev = platform_device_register_simple("tpm_atmel", -1, NULL, 0); if (IS_ERR(pdev)) { -- 1.8.1.2 |
From: Jason G. <jgu...@ob...> - 2013-09-23 18:19:28
|
This builds on the last commit to use the ops structure in the core and reduce the size of tpm_vendor_specific. Signed-off-by: Jason Gunthorpe <jgu...@ob...> --- drivers/char/tpm/tpm-sysfs.c | 2 +- drivers/char/tpm/tpm.c | 35 +++++++++++++---------------------- drivers/char/tpm/tpm.h | 9 +-------- drivers/char/tpm/tpm_i2c_stm_st33.c | 4 ++-- drivers/char/tpm/tpm_spi_stm_st33.c | 4 ++-- 5 files changed, 19 insertions(+), 35 deletions(-) diff --git a/drivers/char/tpm/tpm-sysfs.c b/drivers/char/tpm/tpm-sysfs.c index 3bcfed0..d2a8bca 100644 --- a/drivers/char/tpm/tpm-sysfs.c +++ b/drivers/char/tpm/tpm-sysfs.c @@ -245,7 +245,7 @@ static ssize_t cancel_store(struct device *dev, struct device_attribute *attr, if (chip == NULL) return 0; - chip->vendor.cancel(chip); + chip->ops->cancel(chip); return count; } static DEVICE_ATTR_WO(cancel); diff --git a/drivers/char/tpm/tpm.c b/drivers/char/tpm/tpm.c index 60b04df..eef2edd 100644 --- a/drivers/char/tpm/tpm.c +++ b/drivers/char/tpm/tpm.c @@ -353,7 +353,8 @@ ssize_t tpm_transmit(struct tpm_chip *chip, const char *buf, mutex_lock(&chip->tpm_mutex); - if ((rc = chip->vendor.send(chip, (u8 *) buf, count)) < 0) { + rc = chip->ops->send(chip, (u8 *) buf, count); + if (rc < 0) { dev_err(chip->dev, "tpm_transmit: tpm_send: error %zd\n", rc); goto out; @@ -364,12 +365,12 @@ ssize_t tpm_transmit(struct tpm_chip *chip, const char *buf, stop = jiffies + tpm_calc_ordinal_duration(chip, ordinal); do { - u8 status = chip->vendor.status(chip); - if ((status & chip->vendor.req_complete_mask) == - chip->vendor.req_complete_val) + u8 status = chip->ops->status(chip); + if ((status & chip->ops->req_complete_mask) == + chip->ops->req_complete_val) goto out_recv; - if (chip->vendor.req_canceled(chip, status)) { + if (chip->ops->req_canceled(chip, status)) { dev_err(chip->dev, "Operation Canceled\n"); rc = -ECANCELED; goto out; @@ -379,13 +380,13 @@ ssize_t tpm_transmit(struct tpm_chip *chip, const char *buf, rmb(); } while (time_before(jiffies, stop)); - chip->vendor.cancel(chip); + chip->ops->cancel(chip); dev_err(chip->dev, "Operation Timed out\n"); rc = -ETIME; goto out; out_recv: - rc = chip->vendor.recv(chip, (u8 *) buf, bufsiz); + rc = chip->ops->recv(chip, (u8 *) buf, bufsiz); if (rc < 0) dev_err(chip->dev, "tpm_transmit: tpm_recv: error %zd\n", rc); @@ -807,12 +808,12 @@ EXPORT_SYMBOL_GPL(tpm_send); static bool wait_for_tpm_stat_cond(struct tpm_chip *chip, u8 mask, bool check_cancel, bool *canceled) { - u8 status = chip->vendor.status(chip); + u8 status = chip->ops->status(chip); *canceled = false; if ((status & mask) == mask) return true; - if (check_cancel && chip->vendor.req_canceled(chip, status)) { + if (check_cancel && chip->ops->req_canceled(chip, status)) { *canceled = true; return true; } @@ -828,7 +829,7 @@ int wait_for_tpm_stat(struct tpm_chip *chip, u8 mask, unsigned long timeout, bool canceled = false; /* check current status */ - status = chip->vendor.status(chip); + status = chip->ops->status(chip); if ((status & mask) == mask) return 0; @@ -855,7 +856,7 @@ again: } else { do { msleep(TPM_TIMEOUT); - status = chip->vendor.status(chip); + status = chip->ops->status(chip); if ((status & mask) == mask) return 0; } while (time_before(jiffies, stop)); @@ -1027,9 +1028,6 @@ void tpm_dev_vendor_release(struct tpm_chip *chip) if (!chip) return; - if (chip->vendor.release) - chip->vendor.release(chip->dev); - clear_bit(chip->dev_num, dev_mask); } EXPORT_SYMBOL_GPL(tpm_dev_vendor_release); @@ -1074,14 +1072,7 @@ struct tpm_chip *tpm_register_hardware(struct device *dev, mutex_init(&chip->tpm_mutex); INIT_LIST_HEAD(&chip->list); - chip->vendor.req_complete_mask = ops->req_complete_mask; - chip->vendor.req_complete_val = ops->req_complete_val; - chip->vendor.req_canceled = ops->req_canceled; - chip->vendor.recv = ops->recv; - chip->vendor.send = ops->send; - chip->vendor.cancel = ops->cancel; - chip->vendor.status = ops->status; - + chip->ops = ops; chip->dev_num = find_first_zero_bit(dev_mask, TPM_NUM_DEVICES); if (chip->dev_num >= TPM_NUM_DEVICES) { diff --git a/drivers/char/tpm/tpm.h b/drivers/char/tpm/tpm.h index a56af2c..7b0a46e 100644 --- a/drivers/char/tpm/tpm.h +++ b/drivers/char/tpm/tpm.h @@ -64,9 +64,6 @@ enum tpm_duration { struct tpm_chip; struct tpm_vendor_specific { - u8 req_complete_mask; - u8 req_complete_val; - bool (*req_canceled)(struct tpm_chip *chip, u8 status); void __iomem *iobase; /* ioremapped address */ unsigned long base; /* TPM base address */ @@ -76,11 +73,6 @@ struct tpm_vendor_specific { int region_size; int have_region; - int (*recv) (struct tpm_chip *, u8 *, size_t); - int (*send) (struct tpm_chip *, u8 *, size_t); - void (*cancel) (struct tpm_chip *); - u8 (*status) (struct tpm_chip *); - void (*release) (struct device *); struct miscdevice miscdev; struct list_head list; int locality; @@ -104,6 +96,7 @@ struct tpm_vendor_specific { struct tpm_chip { struct device *dev; /* Device stuff */ + const struct tpm_class_ops *ops; int dev_num; /* /dev/tpm# */ char devname[7]; diff --git a/drivers/char/tpm/tpm_i2c_stm_st33.c b/drivers/char/tpm/tpm_i2c_stm_st33.c index 0ef5d94..cd8c3e3 100644 --- a/drivers/char/tpm/tpm_i2c_stm_st33.c +++ b/drivers/char/tpm/tpm_i2c_stm_st33.c @@ -559,7 +559,7 @@ static int tpm_stm_i2c_recv(struct tpm_chip *chip, unsigned char *buf, } out: - chip->vendor.cancel(chip); + chip->ops->cancel(chip); release_locality(chip); return size; } @@ -808,7 +808,7 @@ static int tpm_st33_i2c_pm_resume(struct device *dev) if (power_mgt) { gpio_set_value(pin_infos->io_lpcpd, 1); ret = wait_for_serirq_timeout(chip, - (chip->vendor.status(chip) & + (chip->ops->status(chip) & TPM_STS_VALID) == TPM_STS_VALID, chip->vendor.timeout_b); } else { diff --git a/drivers/char/tpm/tpm_spi_stm_st33.c b/drivers/char/tpm/tpm_spi_stm_st33.c index 619545f..22f6e83 100644 --- a/drivers/char/tpm/tpm_spi_stm_st33.c +++ b/drivers/char/tpm/tpm_spi_stm_st33.c @@ -586,7 +586,7 @@ static int tpm_stm_spi_recv(struct tpm_chip *chip, unsigned char *buf, } out: - chip->vendor.cancel(chip); + chip->ops->cancel(chip); release_locality(chip); return size; } @@ -843,7 +843,7 @@ static int tpm_st33_spi_pm_resume(struct device *dev) if (power_mgt) { gpio_set_value(pin_infos->io_lpcpd, 1); ret = wait_for_serirq_timeout(chip, - (chip->vendor.status(chip) & + (chip->ops->status(chip) & TPM_STS_VALID) == TPM_STS_VALID, chip->vendor.timeout_b); } else { -- 1.8.1.2 |
From: Jason G. <jgu...@ob...> - 2013-09-23 18:19:41
|
This replaces the static initialization of a tpm_vendor_specific structure in the drivers with the standard Linux idiom of providing a const structure of function pointers. Signed-off-by: Jason Gunthorpe <jgu...@ob...> --- drivers/char/tpm/tpm.c | 10 ++++++++-- drivers/char/tpm/tpm.h | 6 +++--- drivers/char/tpm/tpm_atmel.c | 2 +- drivers/char/tpm/tpm_i2c_atmel.c | 2 +- drivers/char/tpm/tpm_i2c_infineon.c | 2 +- drivers/char/tpm/tpm_i2c_nuvoton.c | 2 +- drivers/char/tpm/tpm_i2c_stm_st33.c | 2 +- drivers/char/tpm/tpm_ibmvtpm.c | 2 +- drivers/char/tpm/tpm_infineon.c | 2 +- drivers/char/tpm/tpm_nsc.c | 2 +- drivers/char/tpm/tpm_spi_stm_st33.c | 2 +- drivers/char/tpm/tpm_tis.c | 2 +- drivers/char/tpm/xen-tpmfront.c | 2 +- include/linux/tpm.h | 15 +++++++++++++++ 14 files changed, 37 insertions(+), 16 deletions(-) diff --git a/drivers/char/tpm/tpm.c b/drivers/char/tpm/tpm.c index 39758f8..60b04df 100644 --- a/drivers/char/tpm/tpm.c +++ b/drivers/char/tpm/tpm.c @@ -1061,7 +1061,7 @@ EXPORT_SYMBOL_GPL(tpm_dev_release); * pci_disable_device */ struct tpm_chip *tpm_register_hardware(struct device *dev, - const struct tpm_vendor_specific *entry) + const struct tpm_class_ops *ops) { struct tpm_chip *chip; @@ -1074,7 +1074,13 @@ struct tpm_chip *tpm_register_hardware(struct device *dev, mutex_init(&chip->tpm_mutex); INIT_LIST_HEAD(&chip->list); - memcpy(&chip->vendor, entry, sizeof(struct tpm_vendor_specific)); + chip->vendor.req_complete_mask = ops->req_complete_mask; + chip->vendor.req_complete_val = ops->req_complete_val; + chip->vendor.req_canceled = ops->req_canceled; + chip->vendor.recv = ops->recv; + chip->vendor.send = ops->send; + chip->vendor.cancel = ops->cancel; + chip->vendor.status = ops->status; chip->dev_num = find_first_zero_bit(dev_mask, TPM_NUM_DEVICES); diff --git a/drivers/char/tpm/tpm.h b/drivers/char/tpm/tpm.h index 14ba162..a56af2c 100644 --- a/drivers/char/tpm/tpm.h +++ b/drivers/char/tpm/tpm.h @@ -64,8 +64,8 @@ enum tpm_duration { struct tpm_chip; struct tpm_vendor_specific { - const u8 req_complete_mask; - const u8 req_complete_val; + u8 req_complete_mask; + u8 req_complete_val; bool (*req_canceled)(struct tpm_chip *chip, u8 status); void __iomem *iobase; /* ioremapped address */ unsigned long base; /* TPM base address */ @@ -336,7 +336,7 @@ extern void tpm_gen_interrupt(struct tpm_chip *); extern int tpm_do_selftest(struct tpm_chip *); extern unsigned long tpm_calc_ordinal_duration(struct tpm_chip *, u32); extern struct tpm_chip* tpm_register_hardware(struct device *, - const struct tpm_vendor_specific *); + const struct tpm_class_ops *ops); extern void tpm_dev_vendor_release(struct tpm_chip *); extern void tpm_remove_hardware(struct device *); extern int tpm_pm_suspend(struct device *); diff --git a/drivers/char/tpm/tpm_atmel.c b/drivers/char/tpm/tpm_atmel.c index 7e665d0..6069d13 100644 --- a/drivers/char/tpm/tpm_atmel.c +++ b/drivers/char/tpm/tpm_atmel.c @@ -121,7 +121,7 @@ static bool tpm_atml_req_canceled(struct tpm_chip *chip, u8 status) return (status == ATML_STATUS_READY); } -static const struct tpm_vendor_specific tpm_atmel = { +static const struct tpm_class_ops tpm_atmel = { .recv = tpm_atml_recv, .send = tpm_atml_send, .cancel = tpm_atml_cancel, diff --git a/drivers/char/tpm/tpm_i2c_atmel.c b/drivers/char/tpm/tpm_i2c_atmel.c index 8476a05..ecdd32a 100644 --- a/drivers/char/tpm/tpm_i2c_atmel.c +++ b/drivers/char/tpm/tpm_i2c_atmel.c @@ -140,7 +140,7 @@ static bool i2c_atmel_req_canceled(struct tpm_chip *chip, u8 status) return 0; } -static const struct tpm_vendor_specific i2c_atmel = { +static const struct tpm_class_ops i2c_atmel = { .status = i2c_atmel_read_status, .recv = i2c_atmel_recv, .send = i2c_atmel_send, diff --git a/drivers/char/tpm/tpm_i2c_infineon.c b/drivers/char/tpm/tpm_i2c_infineon.c index ac1218f..52b9b2b 100644 --- a/drivers/char/tpm/tpm_i2c_infineon.c +++ b/drivers/char/tpm/tpm_i2c_infineon.c @@ -566,7 +566,7 @@ static bool tpm_tis_i2c_req_canceled(struct tpm_chip *chip, u8 status) return (status == TPM_STS_COMMAND_READY); } -static struct tpm_vendor_specific tpm_tis_i2c = { +static const struct tpm_class_ops tpm_tis_i2c = { .status = tpm_tis_i2c_status, .recv = tpm_tis_i2c_recv, .send = tpm_tis_i2c_send, diff --git a/drivers/char/tpm/tpm_i2c_nuvoton.c b/drivers/char/tpm/tpm_i2c_nuvoton.c index 5cb9670..ea60aa3 100644 --- a/drivers/char/tpm/tpm_i2c_nuvoton.c +++ b/drivers/char/tpm/tpm_i2c_nuvoton.c @@ -456,7 +456,7 @@ static bool i2c_nuvoton_req_canceled(struct tpm_chip *chip, u8 status) return (status == TPM_STS_COMMAND_READY); } -static const struct tpm_vendor_specific tpm_i2c = { +static const struct tpm_class_ops tpm_i2c = { .status = i2c_nuvoton_read_status, .recv = i2c_nuvoton_recv, .send = i2c_nuvoton_send, diff --git a/drivers/char/tpm/tpm_i2c_stm_st33.c b/drivers/char/tpm/tpm_i2c_stm_st33.c index 588e763..0ef5d94 100644 --- a/drivers/char/tpm/tpm_i2c_stm_st33.c +++ b/drivers/char/tpm/tpm_i2c_stm_st33.c @@ -569,7 +569,7 @@ static bool tpm_st33_i2c_req_canceled(struct tpm_chip *chip, u8 status) return (status == TPM_STS_COMMAND_READY); } -static struct tpm_vendor_specific st_i2c_tpm = { +static const struct tpm_class_ops st_i2c_tpm = { .send = tpm_stm_i2c_send, .recv = tpm_stm_i2c_recv, .cancel = tpm_stm_i2c_cancel, diff --git a/drivers/char/tpm/tpm_ibmvtpm.c b/drivers/char/tpm/tpm_ibmvtpm.c index 6217d1d..e915747 100644 --- a/drivers/char/tpm/tpm_ibmvtpm.c +++ b/drivers/char/tpm/tpm_ibmvtpm.c @@ -403,7 +403,7 @@ static bool tpm_ibmvtpm_req_canceled(struct tpm_chip *chip, u8 status) return (status == 0); } -static const struct tpm_vendor_specific tpm_ibmvtpm = { +static const struct tpm_class_ops tpm_ibmvtpm = { .recv = tpm_ibmvtpm_recv, .send = tpm_ibmvtpm_send, .cancel = tpm_ibmvtpm_cancel, diff --git a/drivers/char/tpm/tpm_infineon.c b/drivers/char/tpm/tpm_infineon.c index 9525be5..dc0a255 100644 --- a/drivers/char/tpm/tpm_infineon.c +++ b/drivers/char/tpm/tpm_infineon.c @@ -371,7 +371,7 @@ static u8 tpm_inf_status(struct tpm_chip *chip) return tpm_data_in(STAT); } -static const struct tpm_vendor_specific tpm_inf = { +static const struct tpm_class_ops tpm_inf = { .recv = tpm_inf_recv, .send = tpm_inf_send, .cancel = tpm_inf_cancel, diff --git a/drivers/char/tpm/tpm_nsc.c b/drivers/char/tpm/tpm_nsc.c index ad980be..3179ec9 100644 --- a/drivers/char/tpm/tpm_nsc.c +++ b/drivers/char/tpm/tpm_nsc.c @@ -232,7 +232,7 @@ static bool tpm_nsc_req_canceled(struct tpm_chip *chip, u8 status) return (status == NSC_STATUS_RDY); } -static const struct tpm_vendor_specific tpm_nsc = { +static const struct tpm_class_ops tpm_nsc = { .recv = tpm_nsc_recv, .send = tpm_nsc_send, .cancel = tpm_nsc_cancel, diff --git a/drivers/char/tpm/tpm_spi_stm_st33.c b/drivers/char/tpm/tpm_spi_stm_st33.c index af46f0d..619545f 100644 --- a/drivers/char/tpm/tpm_spi_stm_st33.c +++ b/drivers/char/tpm/tpm_spi_stm_st33.c @@ -591,7 +591,7 @@ out: return size; } -static struct tpm_vendor_specific st_spi_tpm = { +static const struct tpm_class_ops st_spi_tpm = { .send = tpm_stm_spi_send, .recv = tpm_stm_spi_recv, .cancel = tpm_stm_spi_cancel, diff --git a/drivers/char/tpm/tpm_tis.c b/drivers/char/tpm/tpm_tis.c index a362ede..8094b08 100644 --- a/drivers/char/tpm/tpm_tis.c +++ b/drivers/char/tpm/tpm_tis.c @@ -432,7 +432,7 @@ static bool tpm_tis_req_canceled(struct tpm_chip *chip, u8 status) } } -static struct tpm_vendor_specific tpm_tis = { +static const struct tpm_class_ops tpm_tis = { .status = tpm_tis_status, .recv = tpm_tis_recv, .send = tpm_tis_send, diff --git a/drivers/char/tpm/xen-tpmfront.c b/drivers/char/tpm/xen-tpmfront.c index 7892557..60d5420 100644 --- a/drivers/char/tpm/xen-tpmfront.c +++ b/drivers/char/tpm/xen-tpmfront.c @@ -168,7 +168,7 @@ ssize_t tpm_store_locality(struct device *dev, struct device_attribute *attr, return len; } -static const struct tpm_vendor_specific tpm_vtpm = { +static const struct tpm_class_ops tpm_vtpm = { .status = vtpm_status, .recv = vtpm_recv, .send = vtpm_send, diff --git a/include/linux/tpm.h b/include/linux/tpm.h index 9a9051b..a14bf63 100644 --- a/include/linux/tpm.h +++ b/include/linux/tpm.h @@ -29,6 +29,21 @@ */ #define TPM_ANY_NUM 0xFFFF +struct tpm_chip; + +struct tpm_class_ops { + const u8 req_complete_mask; + const u8 req_complete_val; + bool (*req_canceled)(struct tpm_chip *chip, u8 status); + int (*recv) (struct tpm_chip *chip, u8 *buf, size_t len); + int (*send) (struct tpm_chip *chip, u8 *buf, size_t len); + void (*cancel) (struct tpm_chip *chip); + u8 (*status) (struct tpm_chip *chip); +}; + +struct tpm_chip *tpmm_alloc_dev(struct device *dev, + const struct tpm_class_ops *ops); + #if defined(CONFIG_TCG_TPM) || defined(CONFIG_TCG_TPM_MODULE) extern int tpm_pcr_read(u32 chip_num, int pcr_idx, u8 *res_buf); -- 1.8.1.2 |
From: Jason G. <jgu...@ob...> - 2013-09-23 18:20:11
|
For some reason this driver thinks that chip->data_buffer needs to be set before it can call tpm_pm_*. This is not true. data_buffer is used only by /dev/tpmX, which is why it is managed exclusively by the fops functions. Cc: Mathias Leblanc <mat...@st...> Signed-off-by: Jason Gunthorpe <jgu...@ob...> --- drivers/char/tpm/tpm_i2c_stm_st33.c | 8 -------- drivers/char/tpm/tpm_spi_stm_st33.c | 8 -------- 2 files changed, 16 deletions(-) diff --git a/drivers/char/tpm/tpm_i2c_stm_st33.c b/drivers/char/tpm/tpm_i2c_stm_st33.c index cd8c3e3..cb39876 100644 --- a/drivers/char/tpm/tpm_i2c_stm_st33.c +++ b/drivers/char/tpm/tpm_i2c_stm_st33.c @@ -770,24 +770,18 @@ static int tpm_st33_i2c_remove(struct i2c_client *client) #ifdef CONFIG_PM_SLEEP /* * tpm_st33_i2c_pm_suspend suspend the TPM device - * Added: Work around when suspend and no tpm application is running, suspend - * may fail because chip->data_buffer is not set (only set in tpm_open in Linux - * TPM core) * @param: client, the i2c_client drescription (TPM I2C description). * @param: mesg, the power management message. * @return: 0 in case of success. */ static int tpm_st33_i2c_pm_suspend(struct device *dev) { - struct tpm_chip *chip = dev_get_drvdata(dev); struct st33zp24_platform_data *pin_infos = dev->platform_data; int ret = 0; if (power_mgt) { gpio_set_value(pin_infos->io_lpcpd, 0); } else { - if (chip->data_buffer == NULL) - chip->data_buffer = pin_infos->tpm_i2c_buffer[0]; ret = tpm_pm_suspend(dev); } return ret; @@ -812,8 +806,6 @@ static int tpm_st33_i2c_pm_resume(struct device *dev) TPM_STS_VALID) == TPM_STS_VALID, chip->vendor.timeout_b); } else { - if (chip->data_buffer == NULL) - chip->data_buffer = pin_infos->tpm_i2c_buffer[0]; ret = tpm_pm_resume(dev); if (!ret) tpm_do_selftest(chip); diff --git a/drivers/char/tpm/tpm_spi_stm_st33.c b/drivers/char/tpm/tpm_spi_stm_st33.c index 22f6e83..81c61f6 100644 --- a/drivers/char/tpm/tpm_spi_stm_st33.c +++ b/drivers/char/tpm/tpm_spi_stm_st33.c @@ -808,22 +808,16 @@ static int tpm_st33_spi_remove(struct spi_device *client) #ifdef CONFIG_PM_SLEEP /* * tpm_st33_spi_pm_suspend suspend the TPM device - * Added: Work around when suspend and no tpm application is running, suspend - * may fail because chip->data_buffer is not set (only set in tpm_open in Linux - * TPM core) * @return: 0 in case of success. */ static int tpm_st33_spi_pm_suspend(struct device *dev) { - struct tpm_chip *chip = dev_get_drvdata(dev); struct st33zp24_platform_data *pin_infos = dev->platform_data; int ret = 0; if (power_mgt) gpio_set_value(pin_infos->io_lpcpd, 0); else { - if (chip->data_buffer == NULL) - chip->data_buffer = pin_infos->tpm_spi_buffer[0]; ret = tpm_pm_suspend(dev); } return ret; @@ -847,8 +841,6 @@ static int tpm_st33_spi_pm_resume(struct device *dev) TPM_STS_VALID) == TPM_STS_VALID, chip->vendor.timeout_b); } else { - if (chip->data_buffer == NULL) - chip->data_buffer = pin_infos->tpm_spi_buffer[0]; ret = tpm_pm_resume(dev); if (!ret) tpm_do_selftest(chip); -- 1.8.1.2 |
From: Jason G. <jgu...@ob...> - 2013-09-23 18:20:32
|
This consolidates everything that is only used within tpm-dev.c into tpm-dev.c and out of the publicly visible struct tpm_chip. The per-file allocation lays the ground work for someday fixing the strange forced O_EXCL behaviour of the current code. Signed-off-by: Jason Gunthorpe <jgu...@ob...> --- drivers/char/tpm/tpm-dev.c | 100 ++++++++++++++++++++++++++------------------- drivers/char/tpm/tpm.h | 7 ---- 2 files changed, 57 insertions(+), 50 deletions(-) diff --git a/drivers/char/tpm/tpm-dev.c b/drivers/char/tpm/tpm-dev.c index 8d94e97..f492eb6 100644 --- a/drivers/char/tpm/tpm-dev.c +++ b/drivers/char/tpm/tpm-dev.c @@ -22,21 +22,34 @@ #include <linux/uaccess.h> #include "tpm.h" +struct file_priv { + struct tpm_chip *chip; + + /* Data passed to and from the tpm via the read/write calls */ + atomic_t data_pending; + struct mutex buffer_mutex; + + struct timer_list user_read_timer; /* user needs to claim result */ + struct work_struct work; + + u8 data_buffer[TPM_BUFSIZE]; +}; + static void user_reader_timeout(unsigned long ptr) { - struct tpm_chip *chip = (struct tpm_chip *) ptr; + struct file_priv *priv = (struct file_priv *)ptr; - schedule_work(&chip->work); + schedule_work(&priv->work); } static void timeout_work(struct work_struct *work) { - struct tpm_chip *chip = container_of(work, struct tpm_chip, work); + struct file_priv *priv = container_of(work, struct file_priv, work); - mutex_lock(&chip->buffer_mutex); - atomic_set(&chip->data_pending, 0); - memset(chip->data_buffer, 0, TPM_BUFSIZE); - mutex_unlock(&chip->buffer_mutex); + mutex_lock(&priv->buffer_mutex); + atomic_set(&priv->data_pending, 0); + memset(priv->data_buffer, 0, sizeof(priv->data_buffer)); + mutex_unlock(&priv->buffer_mutex); } static int tpm_open(struct inode *inode, struct file *file) @@ -44,6 +57,7 @@ static int tpm_open(struct inode *inode, struct file *file) struct miscdevice *misc = file->private_data; struct tpm_chip *chip = container_of(misc, struct tpm_chip, vendor.miscdev); + struct file_priv *priv; /* It's assured that the chip will be opened just once, * by the check of is_open variable, which is protected @@ -53,15 +67,20 @@ static int tpm_open(struct inode *inode, struct file *file) return -EBUSY; } - chip->data_buffer = kzalloc(TPM_BUFSIZE, GFP_KERNEL); - if (chip->data_buffer == NULL) { + priv = kzalloc(sizeof(*priv), GFP_KERNEL); + if (priv == NULL) { clear_bit(0, &chip->is_open); return -ENOMEM; } - atomic_set(&chip->data_pending, 0); + priv->chip = chip; + atomic_set(&priv->data_pending, 0); + mutex_init(&priv->buffer_mutex); + setup_timer(&priv->user_read_timer, user_reader_timeout, + (unsigned long)priv); + INIT_WORK(&priv->work, timeout_work); - file->private_data = chip; + file->private_data = priv; get_device(chip->dev); return 0; } @@ -69,28 +88,28 @@ static int tpm_open(struct inode *inode, struct file *file) static ssize_t tpm_read(struct file *file, char __user *buf, size_t size, loff_t *off) { - struct tpm_chip *chip = file->private_data; + struct file_priv *priv = file->private_data; ssize_t ret_size; int rc; - del_singleshot_timer_sync(&chip->user_read_timer); - flush_work(&chip->work); - ret_size = atomic_read(&chip->data_pending); + del_singleshot_timer_sync(&priv->user_read_timer); + flush_work(&priv->work); + ret_size = atomic_read(&priv->data_pending); if (ret_size > 0) { /* relay data */ ssize_t orig_ret_size = ret_size; if (size < ret_size) ret_size = size; - mutex_lock(&chip->buffer_mutex); - rc = copy_to_user(buf, chip->data_buffer, ret_size); - memset(chip->data_buffer, 0, orig_ret_size); + mutex_lock(&priv->buffer_mutex); + rc = copy_to_user(buf, priv->data_buffer, ret_size); + memset(priv->data_buffer, 0, orig_ret_size); if (rc) ret_size = -EFAULT; - mutex_unlock(&chip->buffer_mutex); + mutex_unlock(&priv->buffer_mutex); } - atomic_set(&chip->data_pending, 0); + atomic_set(&priv->data_pending, 0); return ret_size; } @@ -98,7 +117,7 @@ static ssize_t tpm_read(struct file *file, char __user *buf, static ssize_t tpm_write(struct file *file, const char __user *buf, size_t size, loff_t *off) { - struct tpm_chip *chip = file->private_data; + struct file_priv *priv = file->private_data; size_t in_size = size; ssize_t out_size; @@ -106,32 +125,33 @@ static ssize_t tpm_write(struct file *file, const char __user *buf, either via tpm_read or a user_read_timer timeout. This also prevents splitted buffered writes from blocking here. */ - if (atomic_read(&chip->data_pending) != 0) + if (atomic_read(&priv->data_pending) != 0) return -EBUSY; if (in_size > TPM_BUFSIZE) return -E2BIG; - mutex_lock(&chip->buffer_mutex); + mutex_lock(&priv->buffer_mutex); if (copy_from_user - (chip->data_buffer, (void __user *) buf, in_size)) { - mutex_unlock(&chip->buffer_mutex); + (priv->data_buffer, (void __user *) buf, in_size)) { + mutex_unlock(&priv->buffer_mutex); return -EFAULT; } /* atomic tpm command send and result receive */ - out_size = tpm_transmit(chip, chip->data_buffer, TPM_BUFSIZE); + out_size = tpm_transmit(priv->chip, priv->data_buffer, + sizeof(priv->data_buffer)); if (out_size < 0) { - mutex_unlock(&chip->buffer_mutex); + mutex_unlock(&priv->buffer_mutex); return out_size; } - atomic_set(&chip->data_pending, out_size); - mutex_unlock(&chip->buffer_mutex); + atomic_set(&priv->data_pending, out_size); + mutex_unlock(&priv->buffer_mutex); /* Set a timeout by which the reader must come claim the result */ - mod_timer(&chip->user_read_timer, jiffies + (60 * HZ)); + mod_timer(&priv->user_read_timer, jiffies + (60 * HZ)); return in_size; } @@ -141,15 +161,15 @@ static ssize_t tpm_write(struct file *file, const char __user *buf, */ static int tpm_release(struct inode *inode, struct file *file) { - struct tpm_chip *chip = file->private_data; + struct file_priv *priv = file->private_data; - del_singleshot_timer_sync(&chip->user_read_timer); - flush_work(&chip->work); + del_singleshot_timer_sync(&priv->user_read_timer); + flush_work(&priv->work); file->private_data = NULL; - atomic_set(&chip->data_pending, 0); - kzfree(chip->data_buffer); - clear_bit(0, &chip->is_open); - put_device(chip->dev); + atomic_set(&priv->data_pending, 0); + clear_bit(0, &priv->chip->is_open); + put_device(priv->chip->dev); + kfree(priv); return 0; } @@ -166,12 +186,6 @@ int tpm_dev_add_device(struct tpm_chip *chip) { int rc; - mutex_init(&chip->buffer_mutex); - INIT_WORK(&chip->work, timeout_work); - - setup_timer(&chip->user_read_timer, user_reader_timeout, - (unsigned long)chip); - chip->vendor.miscdev.fops = &tpm_fops; if (chip->dev_num == 0) chip->vendor.miscdev.minor = TPM_MINOR; diff --git a/drivers/char/tpm/tpm.h b/drivers/char/tpm/tpm.h index 7b0a46e..e4d0888 100644 --- a/drivers/char/tpm/tpm.h +++ b/drivers/char/tpm/tpm.h @@ -103,13 +103,6 @@ struct tpm_chip { unsigned long is_open; /* only one allowed */ int time_expired; - /* Data passed to and from the tpm via the read/write calls */ - u8 *data_buffer; - atomic_t data_pending; - struct mutex buffer_mutex; - - struct timer_list user_read_timer; /* user needs to claim result */ - struct work_struct work; struct mutex tpm_mutex; /* tpm is processing */ struct tpm_vendor_specific vendor; -- 1.8.1.2 |
From: Konrad R. W. <kon...@or...> - 2013-09-23 18:52:27
|
On Mon, Sep 23, 2013 at 12:14:33PM -0600, Jason Gunthorpe wrote: > All the default durations were being set to 10 minutes which is > way too long for the timeouts. Normal values for the longest > duration are around 5 mins, and short duration ar around .5s. > > Further, these are just the default, tpm_get_timeouts will set > them to values from the TPM (or throw an error). > > Just remove them. Sounds sensible. Daniel? > > Cc: Daniel De Graaf <dg...@ty...> > Cc: Konrad Rzeszutek Wilk <kon...@or...> > Signed-off-by: Jason Gunthorpe <jgu...@ob...> > --- > drivers/char/tpm/xen-tpmfront.c | 7 ------- > 1 file changed, 7 deletions(-) > > diff --git a/drivers/char/tpm/xen-tpmfront.c b/drivers/char/tpm/xen-tpmfront.c > index 7a7929b..6f2fe2b 100644 > --- a/drivers/char/tpm/xen-tpmfront.c > +++ b/drivers/char/tpm/xen-tpmfront.c > @@ -210,8 +210,6 @@ static struct attribute_group vtpm_attr_grp = { > .attrs = vtpm_attrs, > }; > > -#define TPM_LONG_TIMEOUT (10 * 60 * HZ) > - > static const struct tpm_vendor_specific tpm_vtpm = { > .status = vtpm_status, > .recv = vtpm_recv, > @@ -224,11 +222,6 @@ static const struct tpm_vendor_specific tpm_vtpm = { > .miscdev = { > .fops = &vtpm_ops, > }, > - .duration = { > - TPM_LONG_TIMEOUT, > - TPM_LONG_TIMEOUT, > - TPM_LONG_TIMEOUT, > - }, > }; > > static irqreturn_t tpmif_interrupt(int dummy, void *dev_id) > -- > 1.8.1.2 > |
From: Daniel De G. <dg...@ty...> - 2013-09-23 19:13:02
|
On 09/23/2013 02:51 PM, Konrad Rzeszutek Wilk wrote: > On Mon, Sep 23, 2013 at 12:14:33PM -0600, Jason Gunthorpe wrote: >> All the default durations were being set to 10 minutes which is >> way too long for the timeouts. Normal values for the longest >> duration are around 5 mins, and short duration ar around .5s. >> >> Further, these are just the default, tpm_get_timeouts will set >> them to values from the TPM (or throw an error). >> >> Just remove them. > > Sounds sensible. > > Daniel? Also sounds good to me. I believe this was just a remnant of the old xen-tpmfront code that didn't get removed once the timeouts were being read from the backend. >> >> Cc: Daniel De Graaf <dg...@ty...> >> Cc: Konrad Rzeszutek Wilk <kon...@or...> >> Signed-off-by: Jason Gunthorpe <jgu...@ob...> >> --- >> drivers/char/tpm/xen-tpmfront.c | 7 ------- >> 1 file changed, 7 deletions(-) >> >> diff --git a/drivers/char/tpm/xen-tpmfront.c b/drivers/char/tpm/xen-tpmfront.c >> index 7a7929b..6f2fe2b 100644 >> --- a/drivers/char/tpm/xen-tpmfront.c >> +++ b/drivers/char/tpm/xen-tpmfront.c >> @@ -210,8 +210,6 @@ static struct attribute_group vtpm_attr_grp = { >> .attrs = vtpm_attrs, >> }; >> >> -#define TPM_LONG_TIMEOUT (10 * 60 * HZ) >> - >> static const struct tpm_vendor_specific tpm_vtpm = { >> .status = vtpm_status, >> .recv = vtpm_recv, >> @@ -224,11 +222,6 @@ static const struct tpm_vendor_specific tpm_vtpm = { >> .miscdev = { >> .fops = &vtpm_ops, >> }, >> - .duration = { >> - TPM_LONG_TIMEOUT, >> - TPM_LONG_TIMEOUT, >> - TPM_LONG_TIMEOUT, >> - }, >> }; >> >> static irqreturn_t tpmif_interrupt(int dummy, void *dev_id) >> -- >> 1.8.1.2 >> > > -- Daniel De Graaf National Security Agency |
From: Daniel De G. <dg...@ty...> - 2013-09-23 19:10:39
|
On 09/23/2013 02:14 PM, Jason Gunthorpe wrote: > CLASS-sysfs.c is a common idiom for linux subsystems. > > This pulls all the sysfs attribute functions and related code > into tpm-sysfs.c. To support this change some constants are moved > from tpm.c to tpm.h and __tpm_pcr_read is made non-static and is > called tpm_pcr_read_dev. > > Signed-off-by: Jason Gunthorpe <jgu...@ob...> [...] > diff --git a/drivers/char/tpm/xen-tpmfront.c b/drivers/char/tpm/xen-tpmfront.c > index 12a4ab2..7892557 100644 > --- a/drivers/char/tpm/xen-tpmfront.c > +++ b/drivers/char/tpm/xen-tpmfront.c [...] > -static DEVICE_ATTR(durations, S_IRUGO, tpm_show_durations, NULL); > -static DEVICE_ATTR(timeouts, S_IRUGO, tpm_show_timeouts, NULL); > -static DEVICE_ATTR(locality, S_IRUGO | S_IWUSR, tpm_show_locality, > - tpm_store_locality); This patch drops the "locality" sysfs attribute from xen-tpmfront. Since that attribute is currently only implemented for the xen TPM driver, it is best to leave it there for now (and its show/store functions could also be made static, an oversight I just noticed now). If this attribute is later made available on other TPM drivers, it may need to contain device-specific logic, but such an implementation is well outside the scope of this series. -- Daniel De Graaf National Security Agency |