All of lore.kernel.org
 help / color / mirror / Atom feed
From: Rajiv Andrade <srajiv@linux.vnet.ibm.com>
To: linux-kernel@vger.kernel.org
Cc: zohar@us.ibm.com, dvelarde@us.ibm.com, serue@us.ibm.com,
	safford@us.ibm.com
Subject: [PATCH][resubmit] TPM: update char dev BKL pushdown
Date: Tue, 26 Aug 2008 17:56:25 -0300	[thread overview]
Message-ID: <1219784185.4768.6.camel@blackbox> (raw)

Now considering the num_opens to is_open change and the use of atomic_set
instead of atomic_dec and atomic_inc. This also includes additional comments on
tpm_open.

Signed-off-by: Mimi Zohar <zohar@us.ibm.com>
Signed-off-by: Rajiv Andrade <srajiv@linux.vnet.ibm.com>

---
 drivers/char/tpm/tpm.c |   35 ++++++++++++++++++-----------------
 drivers/char/tpm/tpm.h |    2 +-
 2 files changed, 19 insertions(+), 18 deletions(-)

diff --git a/drivers/char/tpm/tpm.c b/drivers/char/tpm/tpm.c
index ae766d8..09829f3 100644
--- a/drivers/char/tpm/tpm.c
+++ b/drivers/char/tpm/tpm.c
@@ -954,13 +954,16 @@ EXPORT_SYMBOL_GPL(tpm_store_cancel);
 
 /*
  * 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)
 {
 	int rc = 0, minor = iminor(inode);
 	struct tpm_chip *chip = NULL, *pos;
 
-	lock_kernel();
 	spin_lock(&driver_lock);
 
 	list_for_each_entry(pos, &tpm_chip_list, list) {
@@ -975,34 +978,31 @@ int tpm_open(struct inode *inode, struct file *file)
 		goto err_out;
 	}
 
-	if (chip->num_opens) {
+	if (atomic_read(&chip->is_open)) {
 		dev_dbg(chip->dev, "Another process owns this TPM\n");
 		rc = -EBUSY;
 		goto err_out;
 	}
 
-	chip->num_opens++;
-	get_device(chip->dev);
+	atomic_set(&chip->is_open, 1);
+	get_device(chip->dev); /* protect from chip disappearing */
 
 	spin_unlock(&driver_lock);
 
 	chip->data_buffer = kmalloc(TPM_BUFSIZE * sizeof(u8), GFP_KERNEL);
 	if (chip->data_buffer == NULL) {
-		chip->num_opens--;
+		atomic_set(&chip->is_open, 0);
 		put_device(chip->dev);
-		unlock_kernel();
 		return -ENOMEM;
 	}
 
 	atomic_set(&chip->data_pending, 0);
 
 	file->private_data = chip;
-	unlock_kernel();
 	return 0;
 
 err_out:
 	spin_unlock(&driver_lock);
-	unlock_kernel();
 	return rc;
 }
 EXPORT_SYMBOL_GPL(tpm_open);
@@ -1016,7 +1016,7 @@ int tpm_release(struct inode *inode, struct file *file)
 	file->private_data = NULL;
 	del_singleshot_timer_sync(&chip->user_read_timer);
 	atomic_set(&chip->data_pending, 0);
-	chip->num_opens--;
+	atomic_set(&chip->is_open, 0);
 	put_device(chip->dev);
 	kfree(chip->data_buffer);
 	spin_unlock(&driver_lock);
@@ -1082,7 +1082,12 @@ ssize_t tpm_read(struct file *file, char __user *buf,
 	return ret_size;
 }
 EXPORT_SYMBOL_GPL(tpm_read);
-
+/*
+ *   Called on unloading the driver.
+ *
+ *   First part unloading the chip is done here. The remainder
+ *   is done, when the device count reaches 0, in tpm_dev_release().
+ */
 void tpm_remove_hardware(struct device *dev)
 {
 	struct tpm_chip *chip = dev_get_drvdata(dev);
@@ -1231,20 +1236,16 @@ struct tpm_chip *tpm_register_hardware(struct device *dev, const struct tpm_vend
 		return NULL;
 	}
 
-	spin_lock(&driver_lock);
-
-	list_add(&chip->list, &tpm_chip_list);
-
-	spin_unlock(&driver_lock);
-
 	if (sysfs_create_group(&dev->kobj, chip->vendor.attr_group)) {
-		list_del(&chip->list);
 		misc_deregister(&chip->vendor.miscdev);
 		put_device(chip->dev);
 		return NULL;
 	}
 
 	chip->bios_dir = tpm_bios_log_setup(devname);
+	spin_lock(&driver_lock);
+	list_add(&chip->list, &tpm_chip_list);
+	spin_unlock(&driver_lock);
 
 	return chip;
 }
diff --git a/drivers/char/tpm/tpm.h b/drivers/char/tpm/tpm.h
index e885148..7e0d3fb 100644
--- a/drivers/char/tpm/tpm.h
+++ b/drivers/char/tpm/tpm.h
@@ -90,7 +90,7 @@ struct tpm_chip {
 	struct device *dev;	/* Device stuff */
 
 	int dev_num;		/* /dev/tpm# */
-	int num_opens;		/* only one allowed */
+	atomic_t is_open;	/* only one allowed */
 	int time_expired;
 
 	/* Data passed to and from the tpm via the read/write calls */
-- 
1.5.4.5




             reply	other threads:[~2008-08-26 21:00 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2008-08-26 20:56 Rajiv Andrade [this message]
2008-08-26 21:08 ` [PATCH][resubmit] TPM: update char dev BKL pushdown Alan Cox
2008-08-27  3:19   ` Serge E. Hallyn
2008-08-27 14:32     ` Rajiv Andrade
2008-08-26 21:29 ` Serge E. Hallyn

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1219784185.4768.6.camel@blackbox \
    --to=srajiv@linux.vnet.ibm.com \
    --cc=dvelarde@us.ibm.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=safford@us.ibm.com \
    --cc=serue@us.ibm.com \
    --cc=zohar@us.ibm.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.