All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v3 00/11] Multi-instance vTPM driver
@ 2016-02-19 12:41 Stefan Berger
  2016-02-19 12:41 ` [PATCH v3 01/11] tpm: fix the cleanup of struct tpm_chip Stefan Berger
       [not found] ` <1455885728-10315-1-git-send-email-stefanb-23VcF4HTsmIX0ybBhKVfKdBPR1lH4CV8@public.gmane.org>
  0 siblings, 2 replies; 60+ messages in thread
From: Stefan Berger @ 2016-02-19 12:41 UTC (permalink / raw)
  To: tpmdd-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f

The following series of patches implements a multi-instance vTPM driver
that can dynamically create TPM 'server' and client device pairs.

Using an ioctl on the provided /dev/vtpmx, a client-side vTPM device
and a server side file descriptor is created. The file descriptor must
be passed to a TPM emulator. The device driver will initialize the
emulated TPM using TPM 1.2 or TPM 2 startup commands and it will read
the command durations from the device in case of a TPM 1.2. The choice
of emulated TPM device (1.2 or 2) must be provided with a flag in
the ioctl.

The driver is based on Linux 4.4 and uses several recently posted patches
from Jason and Jarkko. I may have adapted them to fit on top of Linux 4.4.

   Stefan


Jarkko Sakkinen (1):
  tpm: fix the cleanup of struct tpm_chip

Jason Gunthorpe (4):
  tpm: Get rid of chip->pdev
  tpm: Get rid of devname
  tpm: Provide strong locking for device removal
  tpm: Split out the devm stuff from tpmm_chip_alloc

Stefan Berger (6):
  tpm: Get rid of module locking
  tpm: Replace device number bitmap with IDR
  tpm: Introduce TPM_CHIP_FLAG_VIRTUAL
  tpm: Driver for supporting multiple emulated TPMs
  tpm: Initialize TPM and get durations and timeouts
  A test program for vTPM device creation

 drivers/char/tpm/Kconfig            |  10 +
 drivers/char/tpm/Makefile           |   1 +
 drivers/char/tpm/tpm-chip.c         | 217 +++++++++----
 drivers/char/tpm/tpm-dev.c          |  15 +-
 drivers/char/tpm/tpm-interface.c    |  49 +--
 drivers/char/tpm/tpm-sysfs.c        |  20 +-
 drivers/char/tpm/tpm-vtpm.c         | 610 ++++++++++++++++++++++++++++++++++++
 drivers/char/tpm/tpm.h              |  30 +-
 drivers/char/tpm/tpm2-cmd.c         |   8 +-
 drivers/char/tpm/tpm_atmel.c        |  14 +-
 drivers/char/tpm/tpm_eventlog.c     |   2 +-
 drivers/char/tpm/tpm_eventlog.h     |   2 +-
 drivers/char/tpm/tpm_i2c_atmel.c    |  16 +-
 drivers/char/tpm/tpm_i2c_infineon.c |   6 +-
 drivers/char/tpm/tpm_i2c_nuvoton.c  |  24 +-
 drivers/char/tpm/tpm_infineon.c     |  22 +-
 drivers/char/tpm/tpm_nsc.c          |  20 +-
 drivers/char/tpm/tpm_tis.c          |  18 +-
 include/uapi/linux/Kbuild           |   1 +
 include/uapi/linux/vtpm.h           |  38 +++
 vtpmctrl.c                          | 163 ++++++++++
 21 files changed, 1111 insertions(+), 175 deletions(-)
 create mode 100644 drivers/char/tpm/tpm-vtpm.c
 create mode 100644 include/uapi/linux/vtpm.h
 create mode 100644 vtpmctrl.c

-- 
2.4.3


------------------------------------------------------------------------------
Site24x7 APM Insight: Get Deep Visibility into Application Performance
APM + Mobile APM + RUM: Monitor 3 App instances at just $35/Month
Monitor end-to-end web transactions and take corrective actions now
Troubleshoot faster and improve end-user experience. Signup Now!
http://pubads.g.doubleclick.net/gampad/clk?id=272487151&iu=/4140

^ permalink raw reply	[flat|nested] 60+ messages in thread

* [PATCH v3 01/11] tpm: fix the cleanup of struct tpm_chip
  2016-02-19 12:41 [PATCH v3 00/11] Multi-instance vTPM driver Stefan Berger
@ 2016-02-19 12:41 ` Stefan Berger
       [not found] ` <1455885728-10315-1-git-send-email-stefanb-23VcF4HTsmIX0ybBhKVfKdBPR1lH4CV8@public.gmane.org>
  1 sibling, 0 replies; 60+ messages in thread
From: Stefan Berger @ 2016-02-19 12:41 UTC (permalink / raw)
  To: tpmdd-devel; +Cc: jarkko.sakkinen, jgunthorpe, stable

From: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com>

If the initialization fails before tpm_chip_register(), put_device()
will be not called, which causes release callback not to be called.
This patch fixes the issue by adding put_device() to devres list of
the parent device.

Fixes: 313d21eeab ("tpm: device class for tpm")
Signed-off-by: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com>
cc: stable@vger.kernel.org
---
 drivers/char/tpm/tpm-chip.c | 9 ++++++++-
 1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/drivers/char/tpm/tpm-chip.c b/drivers/char/tpm/tpm-chip.c
index 45cc39a..ab32437 100644
--- a/drivers/char/tpm/tpm-chip.c
+++ b/drivers/char/tpm/tpm-chip.c
@@ -88,6 +88,7 @@ struct tpm_chip *tpmm_chip_alloc(struct device *dev,
 				 const struct tpm_class_ops *ops)
 {
 	struct tpm_chip *chip;
+	int err;
 
 	chip = kzalloc(sizeof(*chip), GFP_KERNEL);
 	if (chip == NULL)
@@ -136,6 +137,12 @@ struct tpm_chip *tpmm_chip_alloc(struct device *dev,
 	chip->cdev.owner = chip->pdev->driver->owner;
 	chip->cdev.kobj.parent = &chip->dev.kobj;
 
+	err = devm_add_action(dev, (void (*)(void *)) put_device, &chip->dev);
+	if (err) {
+		put_device(&chip->dev);
+		return ERR_PTR(err);
+	}
+
 	return chip;
 }
 EXPORT_SYMBOL_GPL(tpmm_chip_alloc);
@@ -171,7 +178,7 @@ static int tpm_dev_add_device(struct tpm_chip *chip)
 static void tpm_dev_del_device(struct tpm_chip *chip)
 {
 	cdev_del(&chip->cdev);
-	device_unregister(&chip->dev);
+	device_del(&chip->dev);
 }
 
 static int tpm1_chip_register(struct tpm_chip *chip)
-- 
2.4.3


^ permalink raw reply related	[flat|nested] 60+ messages in thread

* [PATCH v3 02/11] tpm: Get rid of chip->pdev
       [not found] ` <1455885728-10315-1-git-send-email-stefanb-23VcF4HTsmIX0ybBhKVfKdBPR1lH4CV8@public.gmane.org>
@ 2016-02-19 12:41   ` Stefan Berger
       [not found]     ` <1455885728-10315-3-git-send-email-stefanb-23VcF4HTsmIX0ybBhKVfKdBPR1lH4CV8@public.gmane.org>
  2016-02-19 12:42   ` [PATCH v3 03/11] tpm: Get rid of devname Stefan Berger
                     ` (9 subsequent siblings)
  10 siblings, 1 reply; 60+ messages in thread
From: Stefan Berger @ 2016-02-19 12:41 UTC (permalink / raw)
  To: tpmdd-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f

From: Jason Gunthorpe <jgunthorpe-ePGOBjL8dl3ta4EC/59zMFaTQe2KTcn/@public.gmane.org>

This is a hold over from before the struct device conversion.

- All prints should be using &chip->dev, which is the Linux
  standard. This changes prints to use tpm0 as the device name,
  not the PnP/etc ID.
- The few places involving sysfs/modules that really do need the
  parent just use chip->dev.parent instead
- We no longer need to get_device(pdev) in any places since it is no
  longer used by any of the code. The kref on the parent is held
  by the device core during device_add and dropped in device_del

Signed-off-by: Jason Gunthorpe <jgunthorpe-ePGOBjL8dl3ta4EC/59zMFaTQe2KTcn/@public.gmane.org>
---
 drivers/char/tpm/tpm-chip.c         | 15 ++++++---------
 drivers/char/tpm/tpm-dev.c          |  4 +---
 drivers/char/tpm/tpm-interface.c    | 30 ++++++++++++++++--------------
 drivers/char/tpm/tpm-sysfs.c        |  6 +++---
 drivers/char/tpm/tpm.h              |  3 +--
 drivers/char/tpm/tpm2-cmd.c         |  8 ++++----
 drivers/char/tpm/tpm_atmel.c        | 14 +++++++-------
 drivers/char/tpm/tpm_i2c_atmel.c    | 16 ++++++++--------
 drivers/char/tpm/tpm_i2c_infineon.c |  6 +++---
 drivers/char/tpm/tpm_i2c_nuvoton.c  | 22 +++++++++++-----------
 drivers/char/tpm/tpm_infineon.c     | 22 +++++++++++-----------
 drivers/char/tpm/tpm_nsc.c          | 20 ++++++++++----------
 drivers/char/tpm/tpm_tis.c          | 14 +++++++-------
 13 files changed, 88 insertions(+), 92 deletions(-)

diff --git a/drivers/char/tpm/tpm-chip.c b/drivers/char/tpm/tpm-chip.c
index ab32437..5ed9bed 100644
--- a/drivers/char/tpm/tpm-chip.c
+++ b/drivers/char/tpm/tpm-chip.c
@@ -49,7 +49,7 @@ struct tpm_chip *tpm_chip_find_get(int chip_num)
 		if (chip_num != TPM_ANY_NUM && chip_num != pos->dev_num)
 			continue;
 
-		if (try_module_get(pos->pdev->driver->owner)) {
+		if (try_module_get(pos->dev.parent->driver->owner)) {
 			chip = pos;
 			break;
 		}
@@ -113,13 +113,11 @@ struct tpm_chip *tpmm_chip_alloc(struct device *dev,
 
 	scnprintf(chip->devname, sizeof(chip->devname), "tpm%d", chip->dev_num);
 
-	chip->pdev = dev;
-
 	dev_set_drvdata(dev, chip);
 
 	chip->dev.class = tpm_class;
 	chip->dev.release = tpm_dev_release;
-	chip->dev.parent = chip->pdev;
+	chip->dev.parent = dev;
 #ifdef CONFIG_ACPI
 	chip->dev.groups = chip->groups;
 #endif
@@ -134,7 +132,7 @@ struct tpm_chip *tpmm_chip_alloc(struct device *dev,
 	device_initialize(&chip->dev);
 
 	cdev_init(&chip->cdev, &tpm_fops);
-	chip->cdev.owner = chip->pdev->driver->owner;
+	chip->cdev.owner = dev->driver->owner;
 	chip->cdev.kobj.parent = &chip->dev.kobj;
 
 	err = devm_add_action(dev, (void (*)(void *)) put_device, &chip->dev);
@@ -241,9 +239,8 @@ int tpm_chip_register(struct tpm_chip *chip)
 	chip->flags |= TPM_CHIP_FLAG_REGISTERED;
 
 	if (!(chip->flags & TPM_CHIP_FLAG_TPM2)) {
-		rc = __compat_only_sysfs_link_entry_to_kobj(&chip->pdev->kobj,
-							    &chip->dev.kobj,
-							    "ppi");
+		rc = __compat_only_sysfs_link_entry_to_kobj(
+		    &chip->dev.parent->kobj, &chip->dev.kobj, "ppi");
 		if (rc && rc != -ENOENT) {
 			tpm_chip_unregister(chip);
 			return rc;
@@ -278,7 +275,7 @@ void tpm_chip_unregister(struct tpm_chip *chip)
 	synchronize_rcu();
 
 	if (!(chip->flags & TPM_CHIP_FLAG_TPM2))
-		sysfs_remove_link(&chip->pdev->kobj, "ppi");
+		sysfs_remove_link(&chip->dev.parent->kobj, "ppi");
 
 	tpm1_chip_unregister(chip);
 	tpm_dev_del_device(chip);
diff --git a/drivers/char/tpm/tpm-dev.c b/drivers/char/tpm/tpm-dev.c
index de0337e..4009765 100644
--- a/drivers/char/tpm/tpm-dev.c
+++ b/drivers/char/tpm/tpm-dev.c
@@ -61,7 +61,7 @@ static int tpm_open(struct inode *inode, struct file *file)
 	 * 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->pdev, "Another process owns this TPM\n");
+		dev_dbg(&chip->dev, "Another process owns this TPM\n");
 		return -EBUSY;
 	}
 
@@ -79,7 +79,6 @@ static int tpm_open(struct inode *inode, struct file *file)
 	INIT_WORK(&priv->work, timeout_work);
 
 	file->private_data = priv;
-	get_device(chip->pdev);
 	return 0;
 }
 
@@ -166,7 +165,6 @@ static int tpm_release(struct inode *inode, struct file *file)
 	file->private_data = NULL;
 	atomic_set(&priv->data_pending, 0);
 	clear_bit(0, &priv->chip->is_open);
-	put_device(priv->chip->pdev);
 	kfree(priv);
 	return 0;
 }
diff --git a/drivers/char/tpm/tpm-interface.c b/drivers/char/tpm/tpm-interface.c
index c50637d..65dc7fd 100644
--- a/drivers/char/tpm/tpm-interface.c
+++ b/drivers/char/tpm/tpm-interface.c
@@ -343,7 +343,7 @@ ssize_t tpm_transmit(struct tpm_chip *chip, const char *buf,
 	if (count == 0)
 		return -ENODATA;
 	if (count > bufsiz) {
-		dev_err(chip->pdev,
+		dev_err(&chip->dev,
 			"invalid count value %x %zx\n", count, bufsiz);
 		return -E2BIG;
 	}
@@ -352,7 +352,7 @@ ssize_t tpm_transmit(struct tpm_chip *chip, const char *buf,
 
 	rc = chip->ops->send(chip, (u8 *) buf, count);
 	if (rc < 0) {
-		dev_err(chip->pdev,
+		dev_err(&chip->dev,
 			"tpm_transmit: tpm_send: error %zd\n", rc);
 		goto out;
 	}
@@ -371,7 +371,7 @@ ssize_t tpm_transmit(struct tpm_chip *chip, const char *buf,
 			goto out_recv;
 
 		if (chip->ops->req_canceled(chip, status)) {
-			dev_err(chip->pdev, "Operation Canceled\n");
+			dev_err(&chip->dev, "Operation Canceled\n");
 			rc = -ECANCELED;
 			goto out;
 		}
@@ -381,14 +381,14 @@ ssize_t tpm_transmit(struct tpm_chip *chip, const char *buf,
 	} while (time_before(jiffies, stop));
 
 	chip->ops->cancel(chip);
-	dev_err(chip->pdev, "Operation Timed out\n");
+	dev_err(&chip->dev, "Operation Timed out\n");
 	rc = -ETIME;
 	goto out;
 
 out_recv:
 	rc = chip->ops->recv(chip, (u8 *) buf, bufsiz);
 	if (rc < 0)
-		dev_err(chip->pdev,
+		dev_err(&chip->dev,
 			"tpm_transmit: tpm_recv: error %zd\n", rc);
 out:
 	mutex_unlock(&chip->tpm_mutex);
@@ -414,7 +414,7 @@ ssize_t tpm_transmit_cmd(struct tpm_chip *chip, void *cmd,
 
 	err = be32_to_cpu(header->return_code);
 	if (err != 0 && desc)
-		dev_err(chip->pdev, "A TPM error (%d) occurred %s\n", err,
+		dev_err(&chip->dev, "A TPM error (%d) occurred %s\n", err,
 			desc);
 
 	return err;
@@ -510,7 +510,7 @@ int tpm_get_timeouts(struct tpm_chip *chip)
 	if (rc == TPM_ERR_INVALID_POSTINIT) {
 		/* The TPM is not started, we are the first to talk to it.
 		   Execute a startup command. */
-		dev_info(chip->pdev, "Issuing TPM_STARTUP");
+		dev_info(&chip->dev, "Issuing TPM_STARTUP");
 		if (tpm_startup(chip, TPM_ST_CLEAR))
 			return rc;
 
@@ -522,7 +522,7 @@ int tpm_get_timeouts(struct tpm_chip *chip)
 				  NULL);
 	}
 	if (rc) {
-		dev_err(chip->pdev,
+		dev_err(&chip->dev,
 			"A TPM error (%zd) occurred attempting to determine the timeouts\n",
 			rc);
 		goto duration;
@@ -561,7 +561,7 @@ int tpm_get_timeouts(struct tpm_chip *chip)
 
 	/* Report adjusted timeouts */
 	if (chip->vendor.timeout_adjusted) {
-		dev_info(chip->pdev,
+		dev_info(&chip->dev,
 			 HW_ERR "Adjusting reported timeouts: A %lu->%luus B %lu->%luus C %lu->%luus D %lu->%luus\n",
 			 old_timeout[0], new_timeout[0],
 			 old_timeout[1], new_timeout[1],
@@ -608,7 +608,7 @@ duration:
 		chip->vendor.duration[TPM_MEDIUM] *= 1000;
 		chip->vendor.duration[TPM_LONG] *= 1000;
 		chip->vendor.duration_adjusted = true;
-		dev_info(chip->pdev, "Adjusting TPM timeout parameters.");
+		dev_info(&chip->dev, "Adjusting TPM timeout parameters.");
 	}
 	return 0;
 }
@@ -798,7 +798,9 @@ int tpm_do_selftest(struct tpm_chip *chip)
 		 * around 300ms while the self test is ongoing, keep trying
 		 * until the self test duration expires. */
 		if (rc == -ETIME) {
-			dev_info(chip->pdev, HW_ERR "TPM command timed out during continue self test");
+			dev_info(
+			    &chip->dev, HW_ERR
+			    "TPM command timed out during continue self test");
 			msleep(delay_msec);
 			continue;
 		}
@@ -808,7 +810,7 @@ int tpm_do_selftest(struct tpm_chip *chip)
 
 		rc = be32_to_cpu(cmd.header.out.return_code);
 		if (rc == TPM_ERR_DISABLED || rc == TPM_ERR_DEACTIVATED) {
-			dev_info(chip->pdev,
+			dev_info(&chip->dev,
 				 "TPM is disabled/deactivated (0x%X)\n", rc);
 			/* TPM is disabled and/or deactivated; driver can
 			 * proceed and TPM does handle commands for
@@ -961,10 +963,10 @@ int tpm_pm_suspend(struct device *dev)
 	}
 
 	if (rc)
-		dev_err(chip->pdev,
+		dev_err(&chip->dev,
 			"Error (%d) sending savestate before suspend\n", rc);
 	else if (try > 0)
-		dev_warn(chip->pdev, "TPM savestate took %dms\n",
+		dev_warn(&chip->dev, "TPM savestate took %dms\n",
 			 try * TPM_TIMEOUT_RETRY);
 
 	return rc;
diff --git a/drivers/char/tpm/tpm-sysfs.c b/drivers/char/tpm/tpm-sysfs.c
index ee66fd4..d93736a 100644
--- a/drivers/char/tpm/tpm-sysfs.c
+++ b/drivers/char/tpm/tpm-sysfs.c
@@ -284,16 +284,16 @@ static const struct attribute_group tpm_dev_group = {
 int tpm_sysfs_add_device(struct tpm_chip *chip)
 {
 	int err;
-	err = sysfs_create_group(&chip->pdev->kobj,
+	err = sysfs_create_group(&chip->dev.parent->kobj,
 				 &tpm_dev_group);
 
 	if (err)
-		dev_err(chip->pdev,
+		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->pdev->kobj, &tpm_dev_group);
+	sysfs_remove_group(&chip->dev.parent->kobj, &tpm_dev_group);
 }
diff --git a/drivers/char/tpm/tpm.h b/drivers/char/tpm/tpm.h
index a4257a3..1ce6547 100644
--- a/drivers/char/tpm/tpm.h
+++ b/drivers/char/tpm/tpm.h
@@ -171,7 +171,6 @@ enum tpm_chip_flags {
 };
 
 struct tpm_chip {
-	struct device *pdev;	/* Device stuff */
 	struct device dev;
 	struct cdev cdev;
 
@@ -203,7 +202,7 @@ struct tpm_chip {
 
 static inline void tpm_chip_put(struct tpm_chip *chip)
 {
-	module_put(chip->pdev->driver->owner);
+	module_put(chip->dev.parent->driver->owner);
 }
 
 static inline int tpm_read_index(int base, int index)
diff --git a/drivers/char/tpm/tpm2-cmd.c b/drivers/char/tpm/tpm2-cmd.c
index c121304..68508d4 100644
--- a/drivers/char/tpm/tpm2-cmd.c
+++ b/drivers/char/tpm/tpm2-cmd.c
@@ -553,7 +553,7 @@ static void tpm2_flush_context(struct tpm_chip *chip, u32 handle)
 
 	rc = tpm_buf_init(&buf, TPM2_ST_NO_SESSIONS, TPM2_CC_FLUSH_CONTEXT);
 	if (rc) {
-		dev_warn(chip->pdev, "0x%08x was not flushed, out of memory\n",
+		dev_warn(&chip->dev, "0x%08x was not flushed, out of memory\n",
 			 handle);
 		return;
 	}
@@ -562,7 +562,7 @@ static void tpm2_flush_context(struct tpm_chip *chip, u32 handle)
 
 	rc = tpm_transmit_cmd(chip, buf.data, PAGE_SIZE, "flushing context");
 	if (rc)
-		dev_warn(chip->pdev, "0x%08x was not flushed, rc=%d\n", handle,
+		dev_warn(&chip->dev, "0x%08x was not flushed, rc=%d\n", handle,
 			 rc);
 
 	tpm_buf_destroy(&buf);
@@ -724,7 +724,7 @@ void tpm2_shutdown(struct tpm_chip *chip, u16 shutdown_type)
 	 * except print the error code on a system failure.
 	 */
 	if (rc < 0)
-		dev_warn(chip->pdev, "transmit returned %d while stopping the TPM",
+		dev_warn(&chip->dev, "transmit returned %d while stopping the TPM",
 			 rc);
 }
 EXPORT_SYMBOL_GPL(tpm2_shutdown);
@@ -791,7 +791,7 @@ static int tpm2_start_selftest(struct tpm_chip *chip, bool full)
 	 * immediately. This is a workaround for that.
 	 */
 	if (rc == TPM2_RC_TESTING) {
-		dev_warn(chip->pdev, "Got RC_TESTING, ignoring\n");
+		dev_warn(&chip->dev, "Got RC_TESTING, ignoring\n");
 		rc = 0;
 	}
 
diff --git a/drivers/char/tpm/tpm_atmel.c b/drivers/char/tpm/tpm_atmel.c
index dfadad0..a48a878 100644
--- a/drivers/char/tpm/tpm_atmel.c
+++ b/drivers/char/tpm/tpm_atmel.c
@@ -49,7 +49,7 @@ static int tpm_atml_recv(struct tpm_chip *chip, u8 *buf, size_t count)
 	for (i = 0; i < 6; i++) {
 		status = ioread8(chip->vendor.iobase + 1);
 		if ((status & ATML_STATUS_DATA_AVAIL) == 0) {
-			dev_err(chip->pdev, "error reading header\n");
+			dev_err(&chip->dev, "error reading header\n");
 			return -EIO;
 		}
 		*buf++ = ioread8(chip->vendor.iobase);
@@ -60,12 +60,12 @@ static int tpm_atml_recv(struct tpm_chip *chip, u8 *buf, size_t count)
 	size = be32_to_cpu(*native_size);
 
 	if (count < size) {
-		dev_err(chip->pdev,
+		dev_err(&chip->dev,
 			"Recv size(%d) less than available space\n", size);
 		for (; i < size; i++) {	/* clear the waiting data anyway */
 			status = ioread8(chip->vendor.iobase + 1);
 			if ((status & ATML_STATUS_DATA_AVAIL) == 0) {
-				dev_err(chip->pdev, "error reading data\n");
+				dev_err(&chip->dev, "error reading data\n");
 				return -EIO;
 			}
 		}
@@ -76,7 +76,7 @@ static int tpm_atml_recv(struct tpm_chip *chip, u8 *buf, size_t count)
 	for (; i < size; i++) {
 		status = ioread8(chip->vendor.iobase + 1);
 		if ((status & ATML_STATUS_DATA_AVAIL) == 0) {
-			dev_err(chip->pdev, "error reading data\n");
+			dev_err(&chip->dev, "error reading data\n");
 			return -EIO;
 		}
 		*buf++ = ioread8(chip->vendor.iobase);
@@ -86,7 +86,7 @@ static int tpm_atml_recv(struct tpm_chip *chip, u8 *buf, size_t count)
 	status = ioread8(chip->vendor.iobase + 1);
 
 	if (status & ATML_STATUS_DATA_AVAIL) {
-		dev_err(chip->pdev, "data available is stuck\n");
+		dev_err(&chip->dev, "data available is stuck\n");
 		return -EIO;
 	}
 
@@ -97,9 +97,9 @@ static int tpm_atml_send(struct tpm_chip *chip, u8 *buf, size_t count)
 {
 	int i;
 
-	dev_dbg(chip->pdev, "tpm_atml_send:\n");
+	dev_dbg(&chip->dev, "tpm_atml_send:\n");
 	for (i = 0; i < count; i++) {
-		dev_dbg(chip->pdev, "%d 0x%x(%d)\n",  i, buf[i], buf[i]);
+		dev_dbg(&chip->dev, "%d 0x%x(%d)\n",  i, buf[i], buf[i]);
  		iowrite8(buf[i], chip->vendor.iobase);
 	}
 
diff --git a/drivers/char/tpm/tpm_i2c_atmel.c b/drivers/char/tpm/tpm_i2c_atmel.c
index 8dfb88b..dd8f0eb 100644
--- a/drivers/char/tpm/tpm_i2c_atmel.c
+++ b/drivers/char/tpm/tpm_i2c_atmel.c
@@ -52,7 +52,7 @@ struct priv_data {
 static int i2c_atmel_send(struct tpm_chip *chip, u8 *buf, size_t len)
 {
 	struct priv_data *priv = chip->vendor.priv;
-	struct i2c_client *client = to_i2c_client(chip->pdev);
+	struct i2c_client *client = to_i2c_client(chip->dev.parent);
 	s32 status;
 
 	priv->len = 0;
@@ -62,7 +62,7 @@ static int i2c_atmel_send(struct tpm_chip *chip, u8 *buf, size_t len)
 
 	status = i2c_master_send(client, buf, len);
 
-	dev_dbg(chip->pdev,
+	dev_dbg(&chip->dev,
 		"%s(buf=%*ph len=%0zx) -> sts=%d\n", __func__,
 		(int)min_t(size_t, 64, len), buf, len, status);
 	return status;
@@ -71,7 +71,7 @@ static int i2c_atmel_send(struct tpm_chip *chip, u8 *buf, size_t len)
 static int i2c_atmel_recv(struct tpm_chip *chip, u8 *buf, size_t count)
 {
 	struct priv_data *priv = chip->vendor.priv;
-	struct i2c_client *client = to_i2c_client(chip->pdev);
+	struct i2c_client *client = to_i2c_client(chip->dev.parent);
 	struct tpm_output_header *hdr =
 		(struct tpm_output_header *)priv->buffer;
 	u32 expected_len;
@@ -88,7 +88,7 @@ static int i2c_atmel_recv(struct tpm_chip *chip, u8 *buf, size_t count)
 		return -ENOMEM;
 
 	if (priv->len >= expected_len) {
-		dev_dbg(chip->pdev,
+		dev_dbg(&chip->dev,
 			"%s early(buf=%*ph count=%0zx) -> ret=%d\n", __func__,
 			(int)min_t(size_t, 64, expected_len), buf, count,
 			expected_len);
@@ -97,7 +97,7 @@ static int i2c_atmel_recv(struct tpm_chip *chip, u8 *buf, size_t count)
 	}
 
 	rc = i2c_master_recv(client, buf, expected_len);
-	dev_dbg(chip->pdev,
+	dev_dbg(&chip->dev,
 		"%s reread(buf=%*ph count=%0zx) -> ret=%d\n", __func__,
 		(int)min_t(size_t, 64, expected_len), buf, count,
 		expected_len);
@@ -106,13 +106,13 @@ static int i2c_atmel_recv(struct tpm_chip *chip, u8 *buf, size_t count)
 
 static void i2c_atmel_cancel(struct tpm_chip *chip)
 {
-	dev_err(chip->pdev, "TPM operation cancellation was requested, but is not supported");
+	dev_err(&chip->dev, "TPM operation cancellation was requested, but is not supported");
 }
 
 static u8 i2c_atmel_read_status(struct tpm_chip *chip)
 {
 	struct priv_data *priv = chip->vendor.priv;
-	struct i2c_client *client = to_i2c_client(chip->pdev);
+	struct i2c_client *client = to_i2c_client(chip->dev.parent);
 	int rc;
 
 	/* The TPM fails the I2C read until it is ready, so we do the entire
@@ -125,7 +125,7 @@ static u8 i2c_atmel_read_status(struct tpm_chip *chip)
 	/* Once the TPM has completed the command the command remains readable
 	 * until another command is issued. */
 	rc = i2c_master_recv(client, priv->buffer, sizeof(priv->buffer));
-	dev_dbg(chip->pdev,
+	dev_dbg(&chip->dev,
 		"%s: sts=%d", __func__, rc);
 	if (rc <= 0)
 		return 0;
diff --git a/drivers/char/tpm/tpm_i2c_infineon.c b/drivers/char/tpm/tpm_i2c_infineon.c
index 63d5d22..f2aa99e 100644
--- a/drivers/char/tpm/tpm_i2c_infineon.c
+++ b/drivers/char/tpm/tpm_i2c_infineon.c
@@ -446,7 +446,7 @@ static int tpm_tis_i2c_recv(struct tpm_chip *chip, u8 *buf, size_t count)
 	/* read first 10 bytes, including tag, paramsize, and result */
 	size = recv_data(chip, buf, TPM_HEADER_SIZE);
 	if (size < TPM_HEADER_SIZE) {
-		dev_err(chip->pdev, "Unable to read header\n");
+		dev_err(&chip->dev, "Unable to read header\n");
 		goto out;
 	}
 
@@ -459,14 +459,14 @@ static int tpm_tis_i2c_recv(struct tpm_chip *chip, u8 *buf, size_t count)
 	size += recv_data(chip, &buf[TPM_HEADER_SIZE],
 			  expected - TPM_HEADER_SIZE);
 	if (size < expected) {
-		dev_err(chip->pdev, "Unable to read remainder of result\n");
+		dev_err(&chip->dev, "Unable to read remainder of result\n");
 		size = -ETIME;
 		goto out;
 	}
 
 	wait_for_stat(chip, TPM_STS_VALID, chip->vendor.timeout_c, &status);
 	if (status & TPM_STS_DATA_AVAIL) {	/* retry? */
-		dev_err(chip->pdev, "Error left over data\n");
+		dev_err(&chip->dev, "Error left over data\n");
 		size = -EIO;
 		goto out;
 	}
diff --git a/drivers/char/tpm/tpm_i2c_nuvoton.c b/drivers/char/tpm/tpm_i2c_nuvoton.c
index 847f159..a1e1474 100644
--- a/drivers/char/tpm/tpm_i2c_nuvoton.c
+++ b/drivers/char/tpm/tpm_i2c_nuvoton.c
@@ -96,13 +96,13 @@ static s32 i2c_nuvoton_write_buf(struct i2c_client *client, u8 offset, u8 size,
 /* read TPM_STS register */
 static u8 i2c_nuvoton_read_status(struct tpm_chip *chip)
 {
-	struct i2c_client *client = to_i2c_client(chip->pdev);
+	struct i2c_client *client = to_i2c_client(chip->dev.parent);
 	s32 status;
 	u8 data;
 
 	status = i2c_nuvoton_read_buf(client, TPM_STS, 1, &data);
 	if (status <= 0) {
-		dev_err(chip->pdev, "%s() error return %d\n", __func__,
+		dev_err(&chip->dev, "%s() error return %d\n", __func__,
 			status);
 		data = TPM_STS_ERR_VAL;
 	}
@@ -127,13 +127,13 @@ static s32 i2c_nuvoton_write_status(struct i2c_client *client, u8 data)
 /* write commandReady to TPM_STS register */
 static void i2c_nuvoton_ready(struct tpm_chip *chip)
 {
-	struct i2c_client *client = to_i2c_client(chip->pdev);
+	struct i2c_client *client = to_i2c_client(chip->dev.parent);
 	s32 status;
 
 	/* this causes the current command to be aborted */
 	status = i2c_nuvoton_write_status(client, TPM_STS_COMMAND_READY);
 	if (status < 0)
-		dev_err(chip->pdev,
+		dev_err(&chip->dev,
 			"%s() fail to write TPM_STS.commandReady\n", __func__);
 }
 
@@ -212,7 +212,7 @@ static int i2c_nuvoton_wait_for_stat(struct tpm_chip *chip, u8 mask, u8 value,
 				return 0;
 		} while (time_before(jiffies, stop));
 	}
-	dev_err(chip->pdev, "%s(%02x, %02x) -> timeout\n", __func__, mask,
+	dev_err(&chip->dev, "%s(%02x, %02x) -> timeout\n", __func__, mask,
 		value);
 	return -ETIMEDOUT;
 }
@@ -240,7 +240,7 @@ static int i2c_nuvoton_recv_data(struct i2c_client *client,
 					       &chip->vendor.read_queue) == 0) {
 		burst_count = i2c_nuvoton_get_burstcount(client, chip);
 		if (burst_count < 0) {
-			dev_err(chip->pdev,
+			dev_err(&chip->dev,
 				"%s() fail to read burstCount=%d\n", __func__,
 				burst_count);
 			return -EIO;
@@ -249,12 +249,12 @@ static int i2c_nuvoton_recv_data(struct i2c_client *client,
 		rc = i2c_nuvoton_read_buf(client, TPM_DATA_FIFO_R,
 					  bytes2read, &buf[size]);
 		if (rc < 0) {
-			dev_err(chip->pdev,
+			dev_err(&chip->dev,
 				"%s() fail on i2c_nuvoton_read_buf()=%d\n",
 				__func__, rc);
 			return -EIO;
 		}
-		dev_dbg(chip->pdev, "%s(%d):", __func__, bytes2read);
+		dev_dbg(&chip->dev, "%s(%d):", __func__, bytes2read);
 		size += bytes2read;
 	}
 
@@ -264,7 +264,7 @@ static int i2c_nuvoton_recv_data(struct i2c_client *client,
 /* Read TPM command results */
 static int i2c_nuvoton_recv(struct tpm_chip *chip, u8 *buf, size_t count)
 {
-	struct device *dev = chip->pdev;
+	struct device *dev = chip->dev.parent;
 	struct i2c_client *client = to_i2c_client(dev);
 	s32 rc;
 	int expected, status, burst_count, retries, size = 0;
@@ -334,7 +334,7 @@ static int i2c_nuvoton_recv(struct tpm_chip *chip, u8 *buf, size_t count)
 		break;
 	}
 	i2c_nuvoton_ready(chip);
-	dev_dbg(chip->pdev, "%s() -> %d\n", __func__, size);
+	dev_dbg(&chip->dev, "%s() -> %d\n", __func__, size);
 	return size;
 }
 
@@ -347,7 +347,7 @@ static int i2c_nuvoton_recv(struct tpm_chip *chip, u8 *buf, size_t count)
  */
 static int i2c_nuvoton_send(struct tpm_chip *chip, u8 *buf, size_t len)
 {
-	struct device *dev = chip->pdev;
+	struct device *dev = chip->dev.parent;
 	struct i2c_client *client = to_i2c_client(dev);
 	u32 ordinal;
 	size_t count = 0;
diff --git a/drivers/char/tpm/tpm_infineon.c b/drivers/char/tpm/tpm_infineon.c
index 6c488e6..e3cf9f3 100644
--- a/drivers/char/tpm/tpm_infineon.c
+++ b/drivers/char/tpm/tpm_infineon.c
@@ -195,9 +195,9 @@ static int wait(struct tpm_chip *chip, int wait_for_bit)
 	}
 	if (i == TPM_MAX_TRIES) {	/* timeout occurs */
 		if (wait_for_bit == STAT_XFE)
-			dev_err(chip->pdev, "Timeout in wait(STAT_XFE)\n");
+			dev_err(&chip->dev, "Timeout in wait(STAT_XFE)\n");
 		if (wait_for_bit == STAT_RDA)
-			dev_err(chip->pdev, "Timeout in wait(STAT_RDA)\n");
+			dev_err(&chip->dev, "Timeout in wait(STAT_RDA)\n");
 		return -EIO;
 	}
 	return 0;
@@ -220,7 +220,7 @@ static void wait_and_send(struct tpm_chip *chip, u8 sendbyte)
 static void tpm_wtx(struct tpm_chip *chip)
 {
 	number_of_wtx++;
-	dev_info(chip->pdev, "Granting WTX (%02d / %02d)\n",
+	dev_info(&chip->dev, "Granting WTX (%02d / %02d)\n",
 		 number_of_wtx, TPM_MAX_WTX_PACKAGES);
 	wait_and_send(chip, TPM_VL_VER);
 	wait_and_send(chip, TPM_CTRL_WTX);
@@ -231,7 +231,7 @@ static void tpm_wtx(struct tpm_chip *chip)
 
 static void tpm_wtx_abort(struct tpm_chip *chip)
 {
-	dev_info(chip->pdev, "Aborting WTX\n");
+	dev_info(&chip->dev, "Aborting WTX\n");
 	wait_and_send(chip, TPM_VL_VER);
 	wait_and_send(chip, TPM_CTRL_WTX_ABORT);
 	wait_and_send(chip, 0x00);
@@ -257,7 +257,7 @@ recv_begin:
 	}
 
 	if (buf[0] != TPM_VL_VER) {
-		dev_err(chip->pdev,
+		dev_err(&chip->dev,
 			"Wrong transport protocol implementation!\n");
 		return -EIO;
 	}
@@ -272,7 +272,7 @@ recv_begin:
 		}
 
 		if ((size == 0x6D00) && (buf[1] == 0x80)) {
-			dev_err(chip->pdev, "Error handling on vendor layer!\n");
+			dev_err(&chip->dev, "Error handling on vendor layer!\n");
 			return -EIO;
 		}
 
@@ -284,7 +284,7 @@ recv_begin:
 	}
 
 	if (buf[1] == TPM_CTRL_WTX) {
-		dev_info(chip->pdev, "WTX-package received\n");
+		dev_info(&chip->dev, "WTX-package received\n");
 		if (number_of_wtx < TPM_MAX_WTX_PACKAGES) {
 			tpm_wtx(chip);
 			goto recv_begin;
@@ -295,14 +295,14 @@ recv_begin:
 	}
 
 	if (buf[1] == TPM_CTRL_WTX_ABORT_ACK) {
-		dev_info(chip->pdev, "WTX-abort acknowledged\n");
+		dev_info(&chip->dev, "WTX-abort acknowledged\n");
 		return size;
 	}
 
 	if (buf[1] == TPM_CTRL_ERROR) {
-		dev_err(chip->pdev, "ERROR-package received:\n");
+		dev_err(&chip->dev, "ERROR-package received:\n");
 		if (buf[4] == TPM_INF_NAK)
-			dev_err(chip->pdev,
+			dev_err(&chip->dev,
 				"-> Negative acknowledgement"
 				" - retransmit command!\n");
 		return -EIO;
@@ -321,7 +321,7 @@ static int tpm_inf_send(struct tpm_chip *chip, u8 * buf, size_t count)
 
 	ret = empty_fifo(chip, 1);
 	if (ret) {
-		dev_err(chip->pdev, "Timeout while clearing FIFO\n");
+		dev_err(&chip->dev, "Timeout while clearing FIFO\n");
 		return -EIO;
 	}
 
diff --git a/drivers/char/tpm/tpm_nsc.c b/drivers/char/tpm/tpm_nsc.c
index 289389e..766370b 100644
--- a/drivers/char/tpm/tpm_nsc.c
+++ b/drivers/char/tpm/tpm_nsc.c
@@ -113,7 +113,7 @@ static int nsc_wait_for_ready(struct tpm_chip *chip)
 	}
 	while (time_before(jiffies, stop));
 
-	dev_info(chip->pdev, "wait for ready failed\n");
+	dev_info(&chip->dev, "wait for ready failed\n");
 	return -EBUSY;
 }
 
@@ -129,12 +129,12 @@ static int tpm_nsc_recv(struct tpm_chip *chip, u8 * buf, size_t count)
 		return -EIO;
 
 	if (wait_for_stat(chip, NSC_STATUS_F0, NSC_STATUS_F0, &data) < 0) {
-		dev_err(chip->pdev, "F0 timeout\n");
+		dev_err(&chip->dev, "F0 timeout\n");
 		return -EIO;
 	}
 	if ((data =
 	     inb(chip->vendor.base + NSC_DATA)) != NSC_COMMAND_NORMAL) {
-		dev_err(chip->pdev, "not in normal mode (0x%x)\n",
+		dev_err(&chip->dev, "not in normal mode (0x%x)\n",
 			data);
 		return -EIO;
 	}
@@ -143,7 +143,7 @@ static int tpm_nsc_recv(struct tpm_chip *chip, u8 * buf, size_t count)
 	for (p = buffer; p < &buffer[count]; p++) {
 		if (wait_for_stat
 		    (chip, NSC_STATUS_OBF, NSC_STATUS_OBF, &data) < 0) {
-			dev_err(chip->pdev,
+			dev_err(&chip->dev,
 				"OBF timeout (while reading data)\n");
 			return -EIO;
 		}
@@ -154,11 +154,11 @@ static int tpm_nsc_recv(struct tpm_chip *chip, u8 * buf, size_t count)
 
 	if ((data & NSC_STATUS_F0) == 0 &&
 	(wait_for_stat(chip, NSC_STATUS_F0, NSC_STATUS_F0, &data) < 0)) {
-		dev_err(chip->pdev, "F0 not set\n");
+		dev_err(&chip->dev, "F0 not set\n");
 		return -EIO;
 	}
 	if ((data = inb(chip->vendor.base + NSC_DATA)) != NSC_COMMAND_EOC) {
-		dev_err(chip->pdev,
+		dev_err(&chip->dev,
 			"expected end of command(0x%x)\n", data);
 		return -EIO;
 	}
@@ -189,19 +189,19 @@ static int tpm_nsc_send(struct tpm_chip *chip, u8 * buf, size_t count)
 		return -EIO;
 
 	if (wait_for_stat(chip, NSC_STATUS_IBF, 0, &data) < 0) {
-		dev_err(chip->pdev, "IBF timeout\n");
+		dev_err(&chip->dev, "IBF timeout\n");
 		return -EIO;
 	}
 
 	outb(NSC_COMMAND_NORMAL, chip->vendor.base + NSC_COMMAND);
 	if (wait_for_stat(chip, NSC_STATUS_IBR, NSC_STATUS_IBR, &data) < 0) {
-		dev_err(chip->pdev, "IBR timeout\n");
+		dev_err(&chip->dev, "IBR timeout\n");
 		return -EIO;
 	}
 
 	for (i = 0; i < count; i++) {
 		if (wait_for_stat(chip, NSC_STATUS_IBF, 0, &data) < 0) {
-			dev_err(chip->pdev,
+			dev_err(&chip->dev,
 				"IBF timeout (while writing data)\n");
 			return -EIO;
 		}
@@ -209,7 +209,7 @@ static int tpm_nsc_send(struct tpm_chip *chip, u8 * buf, size_t count)
 	}
 
 	if (wait_for_stat(chip, NSC_STATUS_IBF, 0, &data) < 0) {
-		dev_err(chip->pdev, "IBF timeout\n");
+		dev_err(&chip->dev, "IBF timeout\n");
 		return -EIO;
 	}
 	outb(NSC_COMMAND_EOC, chip->vendor.base + NSC_COMMAND);
diff --git a/drivers/char/tpm/tpm_tis.c b/drivers/char/tpm/tpm_tis.c
index 65f7eec..0b5fc41 100644
--- a/drivers/char/tpm/tpm_tis.c
+++ b/drivers/char/tpm/tpm_tis.c
@@ -293,7 +293,7 @@ static int tpm_tis_recv(struct tpm_chip *chip, u8 *buf, size_t count)
 	/* read first 10 bytes, including tag, paramsize, and result */
 	if ((size =
 	     recv_data(chip, buf, TPM_HEADER_SIZE)) < TPM_HEADER_SIZE) {
-		dev_err(chip->pdev, "Unable to read header\n");
+		dev_err(&chip->dev, "Unable to read header\n");
 		goto out;
 	}
 
@@ -306,7 +306,7 @@ static int tpm_tis_recv(struct tpm_chip *chip, u8 *buf, size_t count)
 	if ((size +=
 	     recv_data(chip, &buf[TPM_HEADER_SIZE],
 		       expected - TPM_HEADER_SIZE)) < expected) {
-		dev_err(chip->pdev, "Unable to read remainder of result\n");
+		dev_err(&chip->dev, "Unable to read remainder of result\n");
 		size = -ETIME;
 		goto out;
 	}
@@ -315,7 +315,7 @@ static int tpm_tis_recv(struct tpm_chip *chip, u8 *buf, size_t count)
 			  &chip->vendor.int_queue, false);
 	status = tpm_tis_status(chip);
 	if (status & TPM_STS_DATA_AVAIL) {	/* retry? */
-		dev_err(chip->pdev, "Error left over data\n");
+		dev_err(&chip->dev, "Error left over data\n");
 		size = -EIO;
 		goto out;
 	}
@@ -463,7 +463,7 @@ static int tpm_tis_send(struct tpm_chip *chip, u8 *buf, size_t len)
 		msleep(1);
 	if (!priv->irq_tested) {
 		disable_interrupts(chip);
-		dev_err(chip->pdev,
+		dev_err(&chip->dev,
 			FW_BUG "TPM interrupt not working, polling instead\n");
 	}
 	priv->irq_tested = true;
@@ -533,7 +533,7 @@ static int probe_itpm(struct tpm_chip *chip)
 
 	rc = tpm_tis_send_data(chip, cmd_getticks, len);
 	if (rc == 0) {
-		dev_info(chip->pdev, "Detected an iTPM.\n");
+		dev_info(&chip->dev, "Detected an iTPM.\n");
 		rc = 1;
 	} else
 		rc = -EFAULT;
@@ -766,7 +766,7 @@ static int tpm_tis_init(struct device *dev, struct tpm_info *tpm_info,
 			if (devm_request_irq
 			    (dev, i, tis_int_probe, IRQF_SHARED,
 			     chip->devname, chip) != 0) {
-				dev_info(chip->pdev,
+				dev_info(&chip->dev,
 					 "Unable to request irq: %d for probe\n",
 					 i);
 				continue;
@@ -818,7 +818,7 @@ static int tpm_tis_init(struct device *dev, struct tpm_info *tpm_info,
 		if (devm_request_irq
 		    (dev, chip->vendor.irq, tis_int_handler, IRQF_SHARED,
 		     chip->devname, chip) != 0) {
-			dev_info(chip->pdev,
+			dev_info(&chip->dev,
 				 "Unable to request irq: %d for use\n",
 				 chip->vendor.irq);
 			chip->vendor.irq = 0;
-- 
2.4.3


------------------------------------------------------------------------------
Site24x7 APM Insight: Get Deep Visibility into Application Performance
APM + Mobile APM + RUM: Monitor 3 App instances at just $35/Month
Monitor end-to-end web transactions and take corrective actions now
Troubleshoot faster and improve end-user experience. Signup Now!
http://pubads.g.doubleclick.net/gampad/clk?id=272487151&iu=/4140

^ permalink raw reply related	[flat|nested] 60+ messages in thread

* [PATCH v3 03/11] tpm: Get rid of devname
       [not found] ` <1455885728-10315-1-git-send-email-stefanb-23VcF4HTsmIX0ybBhKVfKdBPR1lH4CV8@public.gmane.org>
  2016-02-19 12:41   ` [PATCH v3 02/11] tpm: Get rid of chip->pdev Stefan Berger
@ 2016-02-19 12:42   ` Stefan Berger
       [not found]     ` <1455885728-10315-4-git-send-email-stefanb-23VcF4HTsmIX0ybBhKVfKdBPR1lH4CV8@public.gmane.org>
  2016-02-19 12:42   ` [PATCH v3 04/11] tpm: Provide strong locking for device removal Stefan Berger
                     ` (8 subsequent siblings)
  10 siblings, 1 reply; 60+ messages in thread
From: Stefan Berger @ 2016-02-19 12:42 UTC (permalink / raw)
  To: tpmdd-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f

From: Jason Gunthorpe <jgunthorpe-ePGOBjL8dl3ta4EC/59zMFaTQe2KTcn/@public.gmane.org>

Now that we have a proper struct device just use dev_name() to
access this value instead of keeping two copies.

Signed-off-by: Jason Gunthorpe <jgunthorpe-ePGOBjL8dl3ta4EC/59zMFaTQe2KTcn/@public.gmane.org>
---
 drivers/char/tpm/tpm-chip.c        | 16 ++++++++++------
 drivers/char/tpm/tpm.h             |  1 -
 drivers/char/tpm/tpm_eventlog.c    |  2 +-
 drivers/char/tpm/tpm_eventlog.h    |  2 +-
 drivers/char/tpm/tpm_i2c_nuvoton.c |  2 +-
 drivers/char/tpm/tpm_tis.c         |  4 ++--
 6 files changed, 15 insertions(+), 12 deletions(-)

diff --git a/drivers/char/tpm/tpm-chip.c b/drivers/char/tpm/tpm-chip.c
index 5ed9bed..5df0149 100644
--- a/drivers/char/tpm/tpm-chip.c
+++ b/drivers/char/tpm/tpm-chip.c
@@ -111,8 +111,6 @@ struct tpm_chip *tpmm_chip_alloc(struct device *dev,
 
 	set_bit(chip->dev_num, dev_mask);
 
-	scnprintf(chip->devname, sizeof(chip->devname), "tpm%d", chip->dev_num);
-
 	dev_set_drvdata(dev, chip);
 
 	chip->dev.class = tpm_class;
@@ -127,7 +125,9 @@ struct tpm_chip *tpmm_chip_alloc(struct device *dev,
 	else
 		chip->dev.devt = MKDEV(MAJOR(tpm_devt), chip->dev_num);
 
-	dev_set_name(&chip->dev, "%s", chip->devname);
+	err = dev_set_name(&chip->dev, "tpm%d", chip->dev_num);
+	if (err)
+		goto out;
 
 	device_initialize(&chip->dev);
 
@@ -142,6 +142,10 @@ struct tpm_chip *tpmm_chip_alloc(struct device *dev,
 	}
 
 	return chip;
+
+out:
+	put_device(&chip->dev);
+	return ERR_PTR(err);
 }
 EXPORT_SYMBOL_GPL(tpmm_chip_alloc);
 
@@ -153,7 +157,7 @@ static int tpm_dev_add_device(struct tpm_chip *chip)
 	if (rc) {
 		dev_err(&chip->dev,
 			"unable to cdev_add() %s, major %d, minor %d, err=%d\n",
-			chip->devname, MAJOR(chip->dev.devt),
+			dev_name(&chip->dev), MAJOR(chip->dev.devt),
 			MINOR(chip->dev.devt), rc);
 
 		device_unregister(&chip->dev);
@@ -164,7 +168,7 @@ static int tpm_dev_add_device(struct tpm_chip *chip)
 	if (rc) {
 		dev_err(&chip->dev,
 			"unable to device_register() %s, major %d, minor %d, err=%d\n",
-			chip->devname, MAJOR(chip->dev.devt),
+			dev_name(&chip->dev), MAJOR(chip->dev.devt),
 			MINOR(chip->dev.devt), rc);
 
 		return rc;
@@ -190,7 +194,7 @@ static int tpm1_chip_register(struct tpm_chip *chip)
 	if (rc)
 		return rc;
 
-	chip->bios_dir = tpm_bios_log_setup(chip->devname);
+	chip->bios_dir = tpm_bios_log_setup(dev_name(&chip->dev));
 
 	return 0;
 }
diff --git a/drivers/char/tpm/tpm.h b/drivers/char/tpm/tpm.h
index 1ce6547..31d9a8e 100644
--- a/drivers/char/tpm/tpm.h
+++ b/drivers/char/tpm/tpm.h
@@ -178,7 +178,6 @@ struct tpm_chip {
 	unsigned int flags;
 
 	int dev_num;		/* /dev/tpm# */
-	char devname[7];
 	unsigned long is_open;	/* only one allowed */
 	int time_expired;
 
diff --git a/drivers/char/tpm/tpm_eventlog.c b/drivers/char/tpm/tpm_eventlog.c
index bd72fb0..49e5097 100644
--- a/drivers/char/tpm/tpm_eventlog.c
+++ b/drivers/char/tpm/tpm_eventlog.c
@@ -397,7 +397,7 @@ static int is_bad(void *p)
 	return 0;
 }
 
-struct dentry **tpm_bios_log_setup(char *name)
+struct dentry **tpm_bios_log_setup(const char *name)
 {
 	struct dentry **ret = NULL, *tpm_dir, *bin_file, *ascii_file;
 
diff --git a/drivers/char/tpm/tpm_eventlog.h b/drivers/char/tpm/tpm_eventlog.h
index 267bfbd..cc9672f 100644
--- a/drivers/char/tpm/tpm_eventlog.h
+++ b/drivers/char/tpm/tpm_eventlog.h
@@ -77,7 +77,7 @@ int read_log(struct tpm_bios_log *log);
 
 #if defined(CONFIG_TCG_IBMVTPM) || defined(CONFIG_TCG_IBMVTPM_MODULE) || \
 	defined(CONFIG_ACPI)
-extern struct dentry **tpm_bios_log_setup(char *);
+extern struct dentry **tpm_bios_log_setup(const char *);
 extern void tpm_bios_log_teardown(struct dentry **);
 #else
 static inline struct dentry **tpm_bios_log_setup(char *name)
diff --git a/drivers/char/tpm/tpm_i2c_nuvoton.c b/drivers/char/tpm/tpm_i2c_nuvoton.c
index a1e1474..d61d43f 100644
--- a/drivers/char/tpm/tpm_i2c_nuvoton.c
+++ b/drivers/char/tpm/tpm_i2c_nuvoton.c
@@ -560,7 +560,7 @@ static int i2c_nuvoton_probe(struct i2c_client *client,
 		rc = devm_request_irq(dev, chip->vendor.irq,
 				      i2c_nuvoton_int_handler,
 				      IRQF_TRIGGER_LOW,
-				      chip->devname,
+				      dev_name(&chip->dev),
 				      chip);
 		if (rc) {
 			dev_err(dev, "%s() Unable to request irq: %d for use\n",
diff --git a/drivers/char/tpm/tpm_tis.c b/drivers/char/tpm/tpm_tis.c
index 0b5fc41..37f3d44 100644
--- a/drivers/char/tpm/tpm_tis.c
+++ b/drivers/char/tpm/tpm_tis.c
@@ -765,7 +765,7 @@ static int tpm_tis_init(struct device *dev, struct tpm_info *tpm_info,
 				 TPM_INT_VECTOR(chip->vendor.locality));
 			if (devm_request_irq
 			    (dev, i, tis_int_probe, IRQF_SHARED,
-			     chip->devname, chip) != 0) {
+			     dev_name(&chip->dev), chip) != 0) {
 				dev_info(&chip->dev,
 					 "Unable to request irq: %d for probe\n",
 					 i);
@@ -817,7 +817,7 @@ static int tpm_tis_init(struct device *dev, struct tpm_info *tpm_info,
 			 TPM_INT_VECTOR(chip->vendor.locality));
 		if (devm_request_irq
 		    (dev, chip->vendor.irq, tis_int_handler, IRQF_SHARED,
-		     chip->devname, chip) != 0) {
+		     dev_name(&chip->dev), chip) != 0) {
 			dev_info(&chip->dev,
 				 "Unable to request irq: %d for use\n",
 				 chip->vendor.irq);
-- 
2.4.3


------------------------------------------------------------------------------
Site24x7 APM Insight: Get Deep Visibility into Application Performance
APM + Mobile APM + RUM: Monitor 3 App instances at just $35/Month
Monitor end-to-end web transactions and take corrective actions now
Troubleshoot faster and improve end-user experience. Signup Now!
http://pubads.g.doubleclick.net/gampad/clk?id=272487151&iu=/4140

^ permalink raw reply related	[flat|nested] 60+ messages in thread

* [PATCH v3 04/11] tpm: Provide strong locking for device removal
       [not found] ` <1455885728-10315-1-git-send-email-stefanb-23VcF4HTsmIX0ybBhKVfKdBPR1lH4CV8@public.gmane.org>
  2016-02-19 12:41   ` [PATCH v3 02/11] tpm: Get rid of chip->pdev Stefan Berger
  2016-02-19 12:42   ` [PATCH v3 03/11] tpm: Get rid of devname Stefan Berger
@ 2016-02-19 12:42   ` Stefan Berger
       [not found]     ` <1455885728-10315-5-git-send-email-stefanb-23VcF4HTsmIX0ybBhKVfKdBPR1lH4CV8@public.gmane.org>
  2016-02-19 12:42   ` [PATCH v3 05/11] tpm: Get rid of module locking Stefan Berger
                     ` (7 subsequent siblings)
  10 siblings, 1 reply; 60+ messages in thread
From: Stefan Berger @ 2016-02-19 12:42 UTC (permalink / raw)
  To: tpmdd-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f

From: Jason Gunthorpe <jgunthorpe-ePGOBjL8dl3ta4EC/59zMFaTQe2KTcn/@public.gmane.org>

Add a read/write semaphore around the ops function pointers so
ops can be set to null when the driver un-registers.

Previously the tpm core expected module locking to be enough to
ensure that tpm_unregister could not be called during certain times,
however that hasn't been sufficient for a long time.

Introduce a read/write semaphore around 'ops' so the core can set
it to null when unregistering. This provides a strong fence around
the driver callbacks, guaranteeing to the driver that no callbacks
are running or will run again.

For now the ops_lock is placed very high in the call stack, it could
be pushed down and made more granular in future if necessary.

Signed-off-by: Jason Gunthorpe <jgunthorpe-ePGOBjL8dl3ta4EC/59zMFaTQe2KTcn/@public.gmane.org>
---
 drivers/char/tpm/tpm-chip.c      | 71 ++++++++++++++++++++++++++++++++++++----
 drivers/char/tpm/tpm-dev.c       | 11 ++++++-
 drivers/char/tpm/tpm-interface.c | 18 +++++-----
 drivers/char/tpm/tpm-sysfs.c     |  5 +++
 drivers/char/tpm/tpm.h           | 14 +++++---
 5 files changed, 98 insertions(+), 21 deletions(-)

diff --git a/drivers/char/tpm/tpm-chip.c b/drivers/char/tpm/tpm-chip.c
index 5df0149..0561400 100644
--- a/drivers/char/tpm/tpm-chip.c
+++ b/drivers/char/tpm/tpm-chip.c
@@ -36,10 +36,60 @@ static DEFINE_SPINLOCK(driver_lock);
 struct class *tpm_class;
 dev_t tpm_devt;
 
-/*
- * tpm_chip_find_get - return tpm_chip for a given chip number
- * @chip_num the device number for the chip
+/**
+ * tpm_try_get_ops() - Get a ref to the tpm_chip
+ * @chip: Chip to ref
+ *
+ * The caller must already have some kind of locking to ensure that chip is
+ * valid. This function will lock the chip so that the ops member can be
+ * accessed safely. The locking prevents tpm_chip_unregister from
+ * completing, so it should not be held for long periods.
+ *
+ * Returns -ERRNO if the chip could not be got.
  */
+int tpm_try_get_ops(struct tpm_chip *chip)
+{
+	int rc = -EIO;
+
+	get_device(&chip->dev);
+
+	down_read(&chip->ops_sem);
+	if (!chip->ops)
+		goto out_lock;
+
+	if (!try_module_get(chip->dev.parent->driver->owner))
+		goto out_lock;
+
+	return 0;
+out_lock:
+	up_read(&chip->ops_sem);
+	put_device(&chip->dev);
+	return rc;
+}
+EXPORT_SYMBOL_GPL(tpm_try_get_ops);
+
+/**
+ * tpm_put_ops() - Release a ref to the tpm_chip
+ * @chip: Chip to put
+ *
+ * This is the opposite pair to tpm_try_get_ops(). After this returns chip may
+ * be kfree'd.
+ */
+void tpm_put_ops(struct tpm_chip *chip)
+{
+	module_put(chip->dev.parent->driver->owner);
+	up_read(&chip->ops_sem);
+	put_device(&chip->dev);
+}
+EXPORT_SYMBOL_GPL(tpm_put_ops);
+
+/**
+ * tpm_chip_find_get() - return tpm_chip for a given chip number
+ * @chip_num: id to find
+ *
+ * The return'd chip has been tpm_try_get_ops'd and must be released via
+ * tpm_put_ops
+  */
 struct tpm_chip *tpm_chip_find_get(int chip_num)
 {
 	struct tpm_chip *pos, *chip = NULL;
@@ -49,10 +99,9 @@ struct tpm_chip *tpm_chip_find_get(int chip_num)
 		if (chip_num != TPM_ANY_NUM && chip_num != pos->dev_num)
 			continue;
 
-		if (try_module_get(pos->dev.parent->driver->owner)) {
+		if (!tpm_try_get_ops(pos))
 			chip = pos;
-			break;
-		}
+		break;
 	}
 	rcu_read_unlock();
 	return chip;
@@ -94,6 +143,7 @@ struct tpm_chip *tpmm_chip_alloc(struct device *dev,
 	if (chip == NULL)
 		return ERR_PTR(-ENOMEM);
 
+	init_rwsem(&chip->ops_sem);
 	mutex_init(&chip->tpm_mutex);
 	INIT_LIST_HEAD(&chip->list);
 
@@ -180,6 +230,12 @@ static int tpm_dev_add_device(struct tpm_chip *chip)
 static void tpm_dev_del_device(struct tpm_chip *chip)
 {
 	cdev_del(&chip->cdev);
+
+	/* Make the driver uncallable. */
+	down_write(&chip->ops_sem);
+	chip->ops = NULL;
+	up_write(&chip->ops_sem);
+
 	device_del(&chip->dev);
 }
 
@@ -218,6 +274,9 @@ static void tpm1_chip_unregister(struct tpm_chip *chip)
  * the device. As the last step this function adds the chip to the list of TPM
  * chips available for in-kernel use.
  *
+ * Once this function returns the driver call backs in 'op's will not be
+ * running and will no longer start.
+ *
  * This function should be only called after the chip initialization is
  * complete.
  */
diff --git a/drivers/char/tpm/tpm-dev.c b/drivers/char/tpm/tpm-dev.c
index 4009765..f5d4521 100644
--- a/drivers/char/tpm/tpm-dev.c
+++ b/drivers/char/tpm/tpm-dev.c
@@ -136,9 +136,18 @@ static ssize_t tpm_write(struct file *file, const char __user *buf,
 		return -EFAULT;
 	}
 
-	/* atomic tpm command send and result receive */
+	/* atomic tpm command send and result receive. We only hold the ops
+	 * lock during this period so that the tpm can be unregistered even if
+	 * the char dev is held open.
+	 */
+	if (tpm_try_get_ops(priv->chip)) {
+		mutex_unlock(&priv->buffer_mutex);
+		return -EPIPE;
+	}
 	out_size = tpm_transmit(priv->chip, priv->data_buffer,
 				sizeof(priv->data_buffer));
+
+	tpm_put_ops(priv->chip);
 	if (out_size < 0) {
 		mutex_unlock(&priv->buffer_mutex);
 		return out_size;
diff --git a/drivers/char/tpm/tpm-interface.c b/drivers/char/tpm/tpm-interface.c
index 65dc7fd..1dfe2ce 100644
--- a/drivers/char/tpm/tpm-interface.c
+++ b/drivers/char/tpm/tpm-interface.c
@@ -683,7 +683,7 @@ int tpm_is_tpm2(u32 chip_num)
 
 	rc = (chip->flags & TPM_CHIP_FLAG_TPM2) != 0;
 
-	tpm_chip_put(chip);
+	tpm_put_ops(chip);
 
 	return rc;
 }
@@ -712,7 +712,7 @@ int tpm_pcr_read(u32 chip_num, int pcr_idx, u8 *res_buf)
 		rc = tpm2_pcr_read(chip, pcr_idx, res_buf);
 	else
 		rc = tpm_pcr_read_dev(chip, pcr_idx, res_buf);
-	tpm_chip_put(chip);
+	tpm_put_ops(chip);
 	return rc;
 }
 EXPORT_SYMBOL_GPL(tpm_pcr_read);
@@ -747,7 +747,7 @@ int tpm_pcr_extend(u32 chip_num, int pcr_idx, const u8 *hash)
 
 	if (chip->flags & TPM_CHIP_FLAG_TPM2) {
 		rc = tpm2_pcr_extend(chip, pcr_idx, hash);
-		tpm_chip_put(chip);
+		tpm_put_ops(chip);
 		return rc;
 	}
 
@@ -757,7 +757,7 @@ int tpm_pcr_extend(u32 chip_num, int pcr_idx, const u8 *hash)
 	rc = tpm_transmit_cmd(chip, &cmd, EXTEND_PCR_RESULT_SIZE,
 			      "attempting extend a PCR value");
 
-	tpm_chip_put(chip);
+	tpm_put_ops(chip);
 	return rc;
 }
 EXPORT_SYMBOL_GPL(tpm_pcr_extend);
@@ -838,7 +838,7 @@ int tpm_send(u32 chip_num, void *cmd, size_t buflen)
 
 	rc = tpm_transmit_cmd(chip, cmd, buflen, "attempting tpm_cmd");
 
-	tpm_chip_put(chip);
+	tpm_put_ops(chip);
 	return rc;
 }
 EXPORT_SYMBOL_GPL(tpm_send);
@@ -1020,7 +1020,7 @@ int tpm_get_random(u32 chip_num, u8 *out, size_t max)
 
 	if (chip->flags & TPM_CHIP_FLAG_TPM2) {
 		err = tpm2_get_random(chip, out, max);
-		tpm_chip_put(chip);
+		tpm_put_ops(chip);
 		return err;
 	}
 
@@ -1042,7 +1042,7 @@ int tpm_get_random(u32 chip_num, u8 *out, size_t max)
 		num_bytes -= recd;
 	} while (retries-- && total < max);
 
-	tpm_chip_put(chip);
+	tpm_put_ops(chip);
 	return total ? total : -EIO;
 }
 EXPORT_SYMBOL_GPL(tpm_get_random);
@@ -1068,7 +1068,7 @@ int tpm_seal_trusted(u32 chip_num, struct trusted_key_payload *payload,
 
 	rc = tpm2_seal_trusted(chip, payload, options);
 
-	tpm_chip_put(chip);
+	tpm_put_ops(chip);
 	return rc;
 }
 EXPORT_SYMBOL_GPL(tpm_seal_trusted);
@@ -1094,7 +1094,7 @@ int tpm_unseal_trusted(u32 chip_num, struct trusted_key_payload *payload,
 
 	rc = tpm2_unseal_trusted(chip, payload, options);
 
-	tpm_chip_put(chip);
+	tpm_put_ops(chip);
 	return rc;
 }
 EXPORT_SYMBOL_GPL(tpm_unseal_trusted);
diff --git a/drivers/char/tpm/tpm-sysfs.c b/drivers/char/tpm/tpm-sysfs.c
index d93736a..34e7fc7 100644
--- a/drivers/char/tpm/tpm-sysfs.c
+++ b/drivers/char/tpm/tpm-sysfs.c
@@ -295,5 +295,10 @@ int tpm_sysfs_add_device(struct tpm_chip *chip)
 
 void tpm_sysfs_del_device(struct tpm_chip *chip)
 {
+	/* The sysfs routines rely on an implicit tpm_try_get_ops, this
+	 * function is called before ops is null'd and the sysfs core
+	 * synchronizes this removal so that no callbacks are running or can
+	 * run again
+	 */
 	sysfs_remove_group(&chip->dev.parent->kobj, &tpm_dev_group);
 }
diff --git a/drivers/char/tpm/tpm.h b/drivers/char/tpm/tpm.h
index 31d9a8e..2a8373e 100644
--- a/drivers/char/tpm/tpm.h
+++ b/drivers/char/tpm/tpm.h
@@ -174,7 +174,13 @@ struct tpm_chip {
 	struct device dev;
 	struct cdev cdev;
 
+	/* A driver callback under ops cannot be run unless ops_sem is held
+	 * (sometimes implicitly, eg for the sysfs code). ops becomes null
+	 * when the driver is unregistered, see tpm_try_get_ops.
+	 */
+	struct rw_semaphore ops_sem;
 	const struct tpm_class_ops *ops;
+
 	unsigned int flags;
 
 	int dev_num;		/* /dev/tpm# */
@@ -199,11 +205,6 @@ struct tpm_chip {
 
 #define to_tpm_chip(d) container_of(d, struct tpm_chip, dev)
 
-static inline void tpm_chip_put(struct tpm_chip *chip)
-{
-	module_put(chip->dev.parent->driver->owner);
-}
-
 static inline int tpm_read_index(int base, int index)
 {
 	outb(index, base);
@@ -511,6 +512,9 @@ extern int wait_for_tpm_stat(struct tpm_chip *, u8, unsigned long,
 			     wait_queue_head_t *, bool);
 
 struct tpm_chip *tpm_chip_find_get(int chip_num);
+__must_check int tpm_try_get_ops(struct tpm_chip *chip);
+void tpm_put_ops(struct tpm_chip *chip);
+
 extern struct tpm_chip *tpmm_chip_alloc(struct device *dev,
 				       const struct tpm_class_ops *ops);
 extern int tpm_chip_register(struct tpm_chip *chip);
-- 
2.4.3


------------------------------------------------------------------------------
Site24x7 APM Insight: Get Deep Visibility into Application Performance
APM + Mobile APM + RUM: Monitor 3 App instances at just $35/Month
Monitor end-to-end web transactions and take corrective actions now
Troubleshoot faster and improve end-user experience. Signup Now!
http://pubads.g.doubleclick.net/gampad/clk?id=272487151&iu=/4140

^ permalink raw reply related	[flat|nested] 60+ messages in thread

* [PATCH v3 05/11] tpm: Get rid of module locking
       [not found] ` <1455885728-10315-1-git-send-email-stefanb-23VcF4HTsmIX0ybBhKVfKdBPR1lH4CV8@public.gmane.org>
                     ` (2 preceding siblings ...)
  2016-02-19 12:42   ` [PATCH v3 04/11] tpm: Provide strong locking for device removal Stefan Berger
@ 2016-02-19 12:42   ` Stefan Berger
       [not found]     ` <1455885728-10315-6-git-send-email-stefanb-23VcF4HTsmIX0ybBhKVfKdBPR1lH4CV8@public.gmane.org>
  2016-02-19 12:42   ` [PATCH v3 06/11] tpm: Split out the devm stuff from tpmm_chip_alloc Stefan Berger
                     ` (6 subsequent siblings)
  10 siblings, 1 reply; 60+ messages in thread
From: Stefan Berger @ 2016-02-19 12:42 UTC (permalink / raw)
  To: tpmdd-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f

Get rid of the locking of the module

Signed-off-by: Stefan Berger <stefanb-23VcF4HTsmIX0ybBhKVfKdBPR1lH4CV8@public.gmane.org>
---
 drivers/char/tpm/tpm-chip.c | 4 ----
 1 file changed, 4 deletions(-)

diff --git a/drivers/char/tpm/tpm-chip.c b/drivers/char/tpm/tpm-chip.c
index 0561400..fe15637 100644
--- a/drivers/char/tpm/tpm-chip.c
+++ b/drivers/char/tpm/tpm-chip.c
@@ -57,9 +57,6 @@ int tpm_try_get_ops(struct tpm_chip *chip)
 	if (!chip->ops)
 		goto out_lock;
 
-	if (!try_module_get(chip->dev.parent->driver->owner))
-		goto out_lock;
-
 	return 0;
 out_lock:
 	up_read(&chip->ops_sem);
@@ -77,7 +74,6 @@ EXPORT_SYMBOL_GPL(tpm_try_get_ops);
  */
 void tpm_put_ops(struct tpm_chip *chip)
 {
-	module_put(chip->dev.parent->driver->owner);
 	up_read(&chip->ops_sem);
 	put_device(&chip->dev);
 }
-- 
2.4.3


------------------------------------------------------------------------------
Site24x7 APM Insight: Get Deep Visibility into Application Performance
APM + Mobile APM + RUM: Monitor 3 App instances at just $35/Month
Monitor end-to-end web transactions and take corrective actions now
Troubleshoot faster and improve end-user experience. Signup Now!
http://pubads.g.doubleclick.net/gampad/clk?id=272487151&iu=/4140

^ permalink raw reply related	[flat|nested] 60+ messages in thread

* [PATCH v3 06/11] tpm: Split out the devm stuff from tpmm_chip_alloc
       [not found] ` <1455885728-10315-1-git-send-email-stefanb-23VcF4HTsmIX0ybBhKVfKdBPR1lH4CV8@public.gmane.org>
                     ` (3 preceding siblings ...)
  2016-02-19 12:42   ` [PATCH v3 05/11] tpm: Get rid of module locking Stefan Berger
@ 2016-02-19 12:42   ` Stefan Berger
       [not found]     ` <1455885728-10315-7-git-send-email-stefanb-23VcF4HTsmIX0ybBhKVfKdBPR1lH4CV8@public.gmane.org>
  2016-02-19 12:42   ` [PATCH v3 07/11] tpm: Replace device number bitmap with IDR Stefan Berger
                     ` (5 subsequent siblings)
  10 siblings, 1 reply; 60+ messages in thread
From: Stefan Berger @ 2016-02-19 12:42 UTC (permalink / raw)
  To: tpmdd-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f

From: Jason Gunthorpe <jgunthorpe-ePGOBjL8dl3ta4EC/59zMFaTQe2KTcn/@public.gmane.org>

tpm_chip_alloc becomes a typical subsystem allocate call.

Signed-off-by: Jason Gunthorpe <jgunthorpe-ePGOBjL8dl3ta4EC/59zMFaTQe2KTcn/@public.gmane.org>
---
 drivers/char/tpm/tpm-chip.c | 57 +++++++++++++++++++++++++++++++--------------
 drivers/char/tpm/tpm.h      |  4 +++-
 2 files changed, 42 insertions(+), 19 deletions(-)

diff --git a/drivers/char/tpm/tpm-chip.c b/drivers/char/tpm/tpm-chip.c
index fe15637..2270e47 100644
--- a/drivers/char/tpm/tpm-chip.c
+++ b/drivers/char/tpm/tpm-chip.c
@@ -120,17 +120,17 @@ static void tpm_dev_release(struct device *dev)
 }
 
 /**
- * tpmm_chip_alloc() - allocate a new struct tpm_chip instance
- * @dev: device to which the chip is associated
+ * tpm_chip_alloc() - allocate a new struct tpm_chip instance
+ * @pdev: device to which the chip is associated
+ *        At this point pdev mst be initialized, but does not have to
+ *        be registered
  * @ops: struct tpm_class_ops instance
  *
  * Allocates a new struct tpm_chip instance and assigns a free
- * device number for it. Caller does not have to worry about
- * freeing the allocated resources. When the devices is removed
- * devres calls tpmm_chip_remove() to do the job.
+ * device number for it. Must be paired with put_device(&chip->dev).
  */
-struct tpm_chip *tpmm_chip_alloc(struct device *dev,
-				 const struct tpm_class_ops *ops)
+struct tpm_chip *tpm_chip_alloc(struct device *dev,
+				const struct tpm_class_ops *ops)
 {
 	struct tpm_chip *chip;
 	int err;
@@ -143,10 +143,10 @@ struct tpm_chip *tpmm_chip_alloc(struct device *dev,
 	mutex_init(&chip->tpm_mutex);
 	INIT_LIST_HEAD(&chip->list);
 
-	chip->ops = ops;
-
 	spin_lock(&driver_lock);
 	chip->dev_num = find_first_zero_bit(dev_mask, TPM_NUM_DEVICES);
+	if (chip->dev_num < TPM_NUM_DEVICES)
+		set_bit(chip->dev_num, dev_mask);
 	spin_unlock(&driver_lock);
 
 	if (chip->dev_num >= TPM_NUM_DEVICES) {
@@ -155,9 +155,9 @@ struct tpm_chip *tpmm_chip_alloc(struct device *dev,
 		return ERR_PTR(-ENOMEM);
 	}
 
-	set_bit(chip->dev_num, dev_mask);
+	chip->ops = ops;
 
-	dev_set_drvdata(dev, chip);
+	device_initialize(&chip->dev);
 
 	chip->dev.class = tpm_class;
 	chip->dev.release = tpm_dev_release;
@@ -175,23 +175,44 @@ struct tpm_chip *tpmm_chip_alloc(struct device *dev,
 	if (err)
 		goto out;
 
-	device_initialize(&chip->dev);
-
 	cdev_init(&chip->cdev, &tpm_fops);
 	chip->cdev.owner = dev->driver->owner;
 	chip->cdev.kobj.parent = &chip->dev.kobj;
 
-	err = devm_add_action(dev, (void (*)(void *)) put_device, &chip->dev);
+	return chip;
+
+out:
+	put_device(&chip->dev);
+	return ERR_PTR(err);
+}
+EXPORT_SYMBOL_GPL(tpm_chip_alloc);
+
+/**
+ * tpmm_chip_alloc() - allocate a new struct tpm_chip instance
+ * @pdev: parent device to which the chip is associated
+ * @ops: struct tpm_class_ops instance
+ *
+ * Same as tpm_chip_alloc except devm is used to do the put_device
+ */
+struct tpm_chip *tpmm_chip_alloc(struct device *pdev,
+				 const struct tpm_class_ops *ops)
+{
+	struct tpm_chip *chip;
+	int err;
+
+	chip = tpm_chip_alloc(pdev, ops);
+	if (IS_ERR(chip))
+		return chip;
+
+	err = devm_add_action(pdev, (void (*)(void *)) put_device, &chip->dev);
 	if (err) {
 		put_device(&chip->dev);
 		return ERR_PTR(err);
 	}
 
-	return chip;
+	dev_set_drvdata(pdev, chip);
 
-out:
-	put_device(&chip->dev);
-	return ERR_PTR(err);
+	return chip;
 }
 EXPORT_SYMBOL_GPL(tpmm_chip_alloc);
 
diff --git a/drivers/char/tpm/tpm.h b/drivers/char/tpm/tpm.h
index 2a8373e..25efe8f 100644
--- a/drivers/char/tpm/tpm.h
+++ b/drivers/char/tpm/tpm.h
@@ -515,7 +515,9 @@ struct tpm_chip *tpm_chip_find_get(int chip_num);
 __must_check int tpm_try_get_ops(struct tpm_chip *chip);
 void tpm_put_ops(struct tpm_chip *chip);
 
-extern struct tpm_chip *tpmm_chip_alloc(struct device *dev,
+extern struct tpm_chip *tpm_chip_alloc(struct device *dev,
+				       const struct tpm_class_ops *ops);
+extern struct tpm_chip *tpmm_chip_alloc(struct device *pdev,
 				       const struct tpm_class_ops *ops);
 extern int tpm_chip_register(struct tpm_chip *chip);
 extern void tpm_chip_unregister(struct tpm_chip *chip);
-- 
2.4.3


------------------------------------------------------------------------------
Site24x7 APM Insight: Get Deep Visibility into Application Performance
APM + Mobile APM + RUM: Monitor 3 App instances at just $35/Month
Monitor end-to-end web transactions and take corrective actions now
Troubleshoot faster and improve end-user experience. Signup Now!
http://pubads.g.doubleclick.net/gampad/clk?id=272487151&iu=/4140

^ permalink raw reply related	[flat|nested] 60+ messages in thread

* [PATCH v3 07/11] tpm: Replace device number bitmap with IDR
       [not found] ` <1455885728-10315-1-git-send-email-stefanb-23VcF4HTsmIX0ybBhKVfKdBPR1lH4CV8@public.gmane.org>
                     ` (4 preceding siblings ...)
  2016-02-19 12:42   ` [PATCH v3 06/11] tpm: Split out the devm stuff from tpmm_chip_alloc Stefan Berger
@ 2016-02-19 12:42   ` Stefan Berger
       [not found]     ` <1455885728-10315-8-git-send-email-stefanb-23VcF4HTsmIX0ybBhKVfKdBPR1lH4CV8@public.gmane.org>
  2016-02-19 12:42   ` [PATCH v3 08/11] tpm: Introduce TPM_CHIP_FLAG_VIRTUAL Stefan Berger
                     ` (4 subsequent siblings)
  10 siblings, 1 reply; 60+ messages in thread
From: Stefan Berger @ 2016-02-19 12:42 UTC (permalink / raw)
  To: tpmdd-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f

Replace the device number bitmap with IDR. Extend the number of devices we
can create to 64k.
Since an IDR allows us to associate a pointer with an ID, we use this now
to rewrite tpm_chip_find_get() to simply look up the chip pointer by the
given device ID.

Protect the IDR calls with a mutex.

Signed-off-by: Stefan Berger <stefanb-23VcF4HTsmIX0ybBhKVfKdBPR1lH4CV8@public.gmane.org>
---
 drivers/char/tpm/tpm-chip.c      | 81 +++++++++++++++++++++-------------------
 drivers/char/tpm/tpm-interface.c |  1 +
 drivers/char/tpm/tpm.h           |  5 +--
 3 files changed, 46 insertions(+), 41 deletions(-)

diff --git a/drivers/char/tpm/tpm-chip.c b/drivers/char/tpm/tpm-chip.c
index 2270e47..4fd36ba 100644
--- a/drivers/char/tpm/tpm-chip.c
+++ b/drivers/char/tpm/tpm-chip.c
@@ -29,9 +29,8 @@
 #include "tpm.h"
 #include "tpm_eventlog.h"
 
-static DECLARE_BITMAP(dev_mask, TPM_NUM_DEVICES);
-static LIST_HEAD(tpm_chip_list);
-static DEFINE_SPINLOCK(driver_lock);
+DEFINE_IDR(dev_nums_idr);
+static DEFINE_MUTEX(idr_lock);
 
 struct class *tpm_class;
 dev_t tpm_devt;
@@ -88,18 +87,27 @@ EXPORT_SYMBOL_GPL(tpm_put_ops);
   */
 struct tpm_chip *tpm_chip_find_get(int chip_num)
 {
-	struct tpm_chip *pos, *chip = NULL;
+	struct tpm_chip *chip;
+	int chip_next, chip_prev;
 
-	rcu_read_lock();
-	list_for_each_entry_rcu(pos, &tpm_chip_list, list) {
-		if (chip_num != TPM_ANY_NUM && chip_num != pos->dev_num)
-			continue;
+	if (chip_num == TPM_ANY_NUM)
+		chip_next = 0;
+
+	mutex_lock(&idr_lock);
+
+	do {
+		if (chip_num == TPM_ANY_NUM) {
+			chip_prev = chip_next;
+			chip = idr_get_next(&dev_nums_idr, &chip_next);
+		} else
+			chip = idr_find_slowpath(&dev_nums_idr, chip_num);
+
+		if (chip && !tpm_try_get_ops(chip))
+			break;
+	} while (chip_num == TPM_ANY_NUM && chip_prev != chip_next);
+
+	mutex_unlock(&idr_lock);
 
-		if (!tpm_try_get_ops(pos))
-			chip = pos;
-		break;
-	}
-	rcu_read_unlock();
 	return chip;
 }
 
@@ -113,9 +121,10 @@ static void tpm_dev_release(struct device *dev)
 {
 	struct tpm_chip *chip = container_of(dev, struct tpm_chip, dev);
 
-	spin_lock(&driver_lock);
-	clear_bit(chip->dev_num, dev_mask);
-	spin_unlock(&driver_lock);
+	mutex_lock(&idr_lock);
+	idr_remove(&dev_nums_idr, chip->dev_num);
+	mutex_unlock(&idr_lock);
+
 	kfree(chip);
 }
 
@@ -141,19 +150,16 @@ struct tpm_chip *tpm_chip_alloc(struct device *dev,
 
 	init_rwsem(&chip->ops_sem);
 	mutex_init(&chip->tpm_mutex);
-	INIT_LIST_HEAD(&chip->list);
-
-	spin_lock(&driver_lock);
-	chip->dev_num = find_first_zero_bit(dev_mask, TPM_NUM_DEVICES);
-	if (chip->dev_num < TPM_NUM_DEVICES)
-		set_bit(chip->dev_num, dev_mask);
-	spin_unlock(&driver_lock);
 
-	if (chip->dev_num >= TPM_NUM_DEVICES) {
+	mutex_lock(&idr_lock);
+	err = idr_alloc(&dev_nums_idr, NULL, 0, TPM_NUM_DEVICES, GFP_KERNEL);
+	mutex_unlock(&idr_lock);
+	if (err < 0) {
 		dev_err(dev, "No available tpm device numbers\n");
 		kfree(chip);
-		return ERR_PTR(-ENOMEM);
+		return ERR_PTR(err);
 	}
+	chip->dev_num = err;
 
 	chip->ops = ops;
 
@@ -247,12 +253,6 @@ static int tpm_dev_add_device(struct tpm_chip *chip)
 static void tpm_dev_del_device(struct tpm_chip *chip)
 {
 	cdev_del(&chip->cdev);
-
-	/* Make the driver uncallable. */
-	down_write(&chip->ops_sem);
-	chip->ops = NULL;
-	up_write(&chip->ops_sem);
-
 	device_del(&chip->dev);
 }
 
@@ -312,9 +312,9 @@ int tpm_chip_register(struct tpm_chip *chip)
 		goto out_err;
 
 	/* Make the chip available. */
-	spin_lock(&driver_lock);
-	list_add_tail_rcu(&chip->list, &tpm_chip_list);
-	spin_unlock(&driver_lock);
+	mutex_lock(&idr_lock);
+	idr_replace(&dev_nums_idr, chip, chip->dev_num);
+	mutex_unlock(&idr_lock);
 
 	chip->flags |= TPM_CHIP_FLAG_REGISTERED;
 
@@ -349,10 +349,15 @@ void tpm_chip_unregister(struct tpm_chip *chip)
 	if (!(chip->flags & TPM_CHIP_FLAG_REGISTERED))
 		return;
 
-	spin_lock(&driver_lock);
-	list_del_rcu(&chip->list);
-	spin_unlock(&driver_lock);
-	synchronize_rcu();
+	/* Make the driver uncallable. */
+	down_write(&chip->ops_sem);
+	chip->ops = NULL;
+	up_write(&chip->ops_sem);
+
+	/* hide the chip now */
+	mutex_lock(&idr_lock);
+	idr_replace(&dev_nums_idr, NULL, chip->dev_num);
+	mutex_unlock(&idr_lock);
 
 	if (!(chip->flags & TPM_CHIP_FLAG_TPM2))
 		sysfs_remove_link(&chip->dev.parent->kobj, "ppi");
diff --git a/drivers/char/tpm/tpm-interface.c b/drivers/char/tpm/tpm-interface.c
index 1dfe2ce..f2ae217 100644
--- a/drivers/char/tpm/tpm-interface.c
+++ b/drivers/char/tpm/tpm-interface.c
@@ -1121,6 +1121,7 @@ static int __init tpm_init(void)
 
 static void __exit tpm_exit(void)
 {
+	idr_destroy(&dev_nums_idr);
 	class_destroy(tpm_class);
 	unregister_chrdev_region(tpm_devt, TPM_NUM_DEVICES);
 }
diff --git a/drivers/char/tpm/tpm.h b/drivers/char/tpm/tpm.h
index 25efe8f..2ca5fb4 100644
--- a/drivers/char/tpm/tpm.h
+++ b/drivers/char/tpm/tpm.h
@@ -34,7 +34,7 @@
 enum tpm_const {
 	TPM_MINOR = 224,	/* officially assigned */
 	TPM_BUFSIZE = 4096,
-	TPM_NUM_DEVICES = 256,
+	TPM_NUM_DEVICES = 65536,
 	TPM_RETRY = 50,		/* 5 seconds */
 };
 
@@ -199,8 +199,6 @@ struct tpm_chip {
 	acpi_handle acpi_dev_handle;
 	char ppi_version[TPM_PPI_VERSION_LEN + 1];
 #endif /* CONFIG_ACPI */
-
-	struct list_head list;
 };
 
 #define to_tpm_chip(d) container_of(d, struct tpm_chip, dev)
@@ -496,6 +494,7 @@ static inline void tpm_buf_append_u32(struct tpm_buf *buf, const u32 value)
 extern struct class *tpm_class;
 extern dev_t tpm_devt;
 extern const struct file_operations tpm_fops;
+extern struct idr dev_nums_idr;
 
 ssize_t	tpm_getcap(struct device *, __be32, cap_t *, const char *);
 ssize_t tpm_transmit(struct tpm_chip *chip, const char *buf,
-- 
2.4.3


------------------------------------------------------------------------------
Site24x7 APM Insight: Get Deep Visibility into Application Performance
APM + Mobile APM + RUM: Monitor 3 App instances at just $35/Month
Monitor end-to-end web transactions and take corrective actions now
Troubleshoot faster and improve end-user experience. Signup Now!
http://pubads.g.doubleclick.net/gampad/clk?id=272487151&iu=/4140

^ permalink raw reply related	[flat|nested] 60+ messages in thread

* [PATCH v3 08/11] tpm: Introduce TPM_CHIP_FLAG_VIRTUAL
       [not found] ` <1455885728-10315-1-git-send-email-stefanb-23VcF4HTsmIX0ybBhKVfKdBPR1lH4CV8@public.gmane.org>
                     ` (5 preceding siblings ...)
  2016-02-19 12:42   ` [PATCH v3 07/11] tpm: Replace device number bitmap with IDR Stefan Berger
@ 2016-02-19 12:42   ` Stefan Berger
       [not found]     ` <1455885728-10315-9-git-send-email-stefanb-23VcF4HTsmIX0ybBhKVfKdBPR1lH4CV8@public.gmane.org>
  2016-02-19 12:42   ` [PATCH v3 09/11] tpm: Driver for supporting multiple emulated TPMs Stefan Berger
                     ` (3 subsequent siblings)
  10 siblings, 1 reply; 60+ messages in thread
From: Stefan Berger @ 2016-02-19 12:42 UTC (permalink / raw)
  To: tpmdd-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f

Introduce TPM_CHIP_FLAG_VIRTUAL to be used when the chip device has no parent
device. Also adapt tpm_chip_alloc so that it can be called with parent device
being NULL.

Signed-off-by: Stefan Berger <stefanb-23VcF4HTsmIX0ybBhKVfKdBPR1lH4CV8@public.gmane.org>
---
 drivers/char/tpm/tpm-chip.c  | 10 +++++-----
 drivers/char/tpm/tpm-sysfs.c | 13 +++++++++----
 drivers/char/tpm/tpm.h       |  5 +++--
 3 files changed, 17 insertions(+), 11 deletions(-)

diff --git a/drivers/char/tpm/tpm-chip.c b/drivers/char/tpm/tpm-chip.c
index 4fd36ba..2585f6a 100644
--- a/drivers/char/tpm/tpm-chip.c
+++ b/drivers/char/tpm/tpm-chip.c
@@ -168,9 +168,7 @@ struct tpm_chip *tpm_chip_alloc(struct device *dev,
 	chip->dev.class = tpm_class;
 	chip->dev.release = tpm_dev_release;
 	chip->dev.parent = dev;
-#ifdef CONFIG_ACPI
 	chip->dev.groups = chip->groups;
-#endif
 
 	if (chip->dev_num == 0)
 		chip->dev.devt = MKDEV(MISC_MAJOR, TPM_MINOR);
@@ -181,8 +179,10 @@ struct tpm_chip *tpm_chip_alloc(struct device *dev,
 	if (err)
 		goto out;
 
+	if (!dev)
+		chip->flags |= TPM_CHIP_FLAG_VIRTUAL;
+
 	cdev_init(&chip->cdev, &tpm_fops);
-	chip->cdev.owner = dev->driver->owner;
 	chip->cdev.kobj.parent = &chip->dev.kobj;
 
 	return chip;
@@ -318,7 +318,7 @@ int tpm_chip_register(struct tpm_chip *chip)
 
 	chip->flags |= TPM_CHIP_FLAG_REGISTERED;
 
-	if (!(chip->flags & TPM_CHIP_FLAG_TPM2)) {
+	if (!(chip->flags & (TPM_CHIP_FLAG_TPM2 | TPM_CHIP_FLAG_VIRTUAL))) {
 		rc = __compat_only_sysfs_link_entry_to_kobj(
 		    &chip->dev.parent->kobj, &chip->dev.kobj, "ppi");
 		if (rc && rc != -ENOENT) {
@@ -359,7 +359,7 @@ void tpm_chip_unregister(struct tpm_chip *chip)
 	idr_replace(&dev_nums_idr, NULL, chip->dev_num);
 	mutex_unlock(&idr_lock);
 
-	if (!(chip->flags & TPM_CHIP_FLAG_TPM2))
+	if (!(chip->flags & (TPM_CHIP_FLAG_TPM2 | TPM_CHIP_FLAG_VIRTUAL)))
 		sysfs_remove_link(&chip->dev.parent->kobj, "ppi");
 
 	tpm1_chip_unregister(chip);
diff --git a/drivers/char/tpm/tpm-sysfs.c b/drivers/char/tpm/tpm-sysfs.c
index 34e7fc7..127b0e5 100644
--- a/drivers/char/tpm/tpm-sysfs.c
+++ b/drivers/char/tpm/tpm-sysfs.c
@@ -283,9 +283,13 @@ static const struct attribute_group tpm_dev_group = {
 
 int tpm_sysfs_add_device(struct tpm_chip *chip)
 {
-	int err;
-	err = sysfs_create_group(&chip->dev.parent->kobj,
-				 &tpm_dev_group);
+	int err = 0;
+
+	if (!(chip->flags & TPM_CHIP_FLAG_VIRTUAL))
+		err = sysfs_create_group(&chip->dev.parent->kobj,
+					 &tpm_dev_group);
+	else
+		chip->groups[chip->groups_cnt++] = &tpm_dev_group;
 
 	if (err)
 		dev_err(&chip->dev,
@@ -300,5 +304,6 @@ void tpm_sysfs_del_device(struct tpm_chip *chip)
 	 * synchronizes this removal so that no callbacks are running or can
 	 * run again
 	 */
-	sysfs_remove_group(&chip->dev.parent->kobj, &tpm_dev_group);
+	if (!(chip->flags & TPM_CHIP_FLAG_VIRTUAL))
+		sysfs_remove_group(&chip->dev.parent->kobj, &tpm_dev_group);
 }
diff --git a/drivers/char/tpm/tpm.h b/drivers/char/tpm/tpm.h
index 2ca5fb4..dc50ca6 100644
--- a/drivers/char/tpm/tpm.h
+++ b/drivers/char/tpm/tpm.h
@@ -168,6 +168,7 @@ struct tpm_vendor_specific {
 enum tpm_chip_flags {
 	TPM_CHIP_FLAG_REGISTERED	= BIT(0),
 	TPM_CHIP_FLAG_TPM2		= BIT(1),
+	TPM_CHIP_FLAG_VIRTUAL		= BIT(2),
 };
 
 struct tpm_chip {
@@ -193,9 +194,9 @@ struct tpm_chip {
 
 	struct dentry **bios_dir;
 
-#ifdef CONFIG_ACPI
-	const struct attribute_group *groups[2];
+	const struct attribute_group *groups[3];
 	unsigned int groups_cnt;
+#ifdef CONFIG_ACPI
 	acpi_handle acpi_dev_handle;
 	char ppi_version[TPM_PPI_VERSION_LEN + 1];
 #endif /* CONFIG_ACPI */
-- 
2.4.3


------------------------------------------------------------------------------
Site24x7 APM Insight: Get Deep Visibility into Application Performance
APM + Mobile APM + RUM: Monitor 3 App instances at just $35/Month
Monitor end-to-end web transactions and take corrective actions now
Troubleshoot faster and improve end-user experience. Signup Now!
http://pubads.g.doubleclick.net/gampad/clk?id=272487151&iu=/4140

^ permalink raw reply related	[flat|nested] 60+ messages in thread

* [PATCH v3 09/11] tpm: Driver for supporting multiple emulated TPMs
       [not found] ` <1455885728-10315-1-git-send-email-stefanb-23VcF4HTsmIX0ybBhKVfKdBPR1lH4CV8@public.gmane.org>
                     ` (6 preceding siblings ...)
  2016-02-19 12:42   ` [PATCH v3 08/11] tpm: Introduce TPM_CHIP_FLAG_VIRTUAL Stefan Berger
@ 2016-02-19 12:42   ` Stefan Berger
       [not found]     ` <1455885728-10315-10-git-send-email-stefanb-23VcF4HTsmIX0ybBhKVfKdBPR1lH4CV8@public.gmane.org>
  2016-02-19 12:42   ` [PATCH v3 10/11] tpm: Initialize TPM and get durations and timeouts Stefan Berger
                     ` (2 subsequent siblings)
  10 siblings, 1 reply; 60+ messages in thread
From: Stefan Berger @ 2016-02-19 12:42 UTC (permalink / raw)
  To: tpmdd-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f

This patch implements a driver for supporting multiple emulated TPMs in a
system.

The driver implements a device /dev/vtpmx that is used to created
a client device pair /dev/tpmX (e.g., /dev/tpm10) and a server side that
is accessed using a file descriptor returned by an ioctl.
The device /dev/tpmX is the usual TPM device created by the core TPM
driver. Applications or kernel subsystems can send TPM commands to it
and the corresponding server-side file descriptor receives these
commands and delivers them to an emulated TPM.

Signed-off-by: Stefan Berger <stefanb-23VcF4HTsmIX0ybBhKVfKdBPR1lH4CV8@public.gmane.org>
---
 drivers/char/tpm/Kconfig    |  10 +
 drivers/char/tpm/Makefile   |   1 +
 drivers/char/tpm/tpm-vtpm.c | 543 ++++++++++++++++++++++++++++++++++++++++++++
 include/uapi/linux/Kbuild   |   1 +
 include/uapi/linux/vtpm.h   |  38 ++++
 5 files changed, 593 insertions(+)
 create mode 100644 drivers/char/tpm/tpm-vtpm.c
 create mode 100644 include/uapi/linux/vtpm.h

diff --git a/drivers/char/tpm/Kconfig b/drivers/char/tpm/Kconfig
index 3b84a8b..4c4e843 100644
--- a/drivers/char/tpm/Kconfig
+++ b/drivers/char/tpm/Kconfig
@@ -122,5 +122,15 @@ config TCG_CRB
 	  from within Linux.  To compile this driver as a module, choose
 	  M here; the module will be called tpm_crb.
 
+config TCG_VTPM
+	tristate "VTPM Interface"
+	depends on TCG_TPM
+	---help---
+	  This driver supports an emulated TPM (vTPM) running in userspace.
+	  A device /dev/vtpmx is provided that creates a device pair
+	  /dev/vtpmX and a server-side file descriptor on which the vTPM
+	  can receive commands.
+
+
 source "drivers/char/tpm/st33zp24/Kconfig"
 endif # TCG_TPM
diff --git a/drivers/char/tpm/Makefile b/drivers/char/tpm/Makefile
index 56e8f1f..d947db2 100644
--- a/drivers/char/tpm/Makefile
+++ b/drivers/char/tpm/Makefile
@@ -23,3 +23,4 @@ obj-$(CONFIG_TCG_IBMVTPM) += tpm_ibmvtpm.o
 obj-$(CONFIG_TCG_TIS_ST33ZP24) += st33zp24/
 obj-$(CONFIG_TCG_XEN) += xen-tpmfront.o
 obj-$(CONFIG_TCG_CRB) += tpm_crb.o
+obj-$(CONFIG_TCG_VTPM) += tpm-vtpm.o
diff --git a/drivers/char/tpm/tpm-vtpm.c b/drivers/char/tpm/tpm-vtpm.c
new file mode 100644
index 0000000..823c94a
--- /dev/null
+++ b/drivers/char/tpm/tpm-vtpm.c
@@ -0,0 +1,543 @@
+/*
+ * Copyright (C) 2015, 2016 IBM Corporation
+ *
+ * Author: Stefan Berger <stefanb-r/Jw6+rmf7HQT0dZR+AlfA@public.gmane.org>
+ *
+ * Maintained by: <tpmdd-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f@public.gmane.org>
+ *
+ * Device driver for vTPM.
+ *
+ * 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/types.h>
+#include <linux/spinlock.h>
+#include <linux/uaccess.h>
+#include <linux/wait.h>
+#include <linux/miscdevice.h>
+#include <linux/vtpm.h>
+#include <linux/file.h>
+#include <linux/anon_inodes.h>
+#include <linux/poll.h>
+#include <linux/compat.h>
+
+#include "tpm.h"
+
+#define VTPM_NUM_DEVICES TPM_NUM_DEVICES
+
+struct vtpm_dev {
+	struct tpm_chip *chip;
+
+	u32 flags;                   /* public API flags */
+
+	long state;
+#define STATE_OPENED_BIT        0
+#define STATE_WAIT_RESPONSE_BIT 1    /* waiting for emulator to give response */
+
+	spinlock_t buf_lock;         /* lock for buffers */
+
+	wait_queue_head_t wq;
+
+	size_t req_len;              /* length of queued TPM request */
+	size_t resp_len;             /* length of queued TPM response */
+	u8 buffer[TPM_BUFSIZE];      /* request/response buffer */
+};
+
+
+static void vtpm_delete_device_pair(struct vtpm_dev *vtpm_dev);
+
+/*
+ * Functions related to 'server side'
+ */
+
+/**
+ * vtpm_fops_read - Read TPM commands on 'server side'
+ *
+ * Return value:
+ *	Number of bytes read or negative error code
+ */
+static ssize_t vtpm_fops_read(struct file *filp, char __user *buf,
+			      size_t count, loff_t *off)
+{
+	struct vtpm_dev *vtpm_dev = filp->private_data;
+	size_t len;
+	int sig, rc;
+
+	sig = wait_event_interruptible(vtpm_dev->wq, vtpm_dev->req_len != 0);
+	if (sig)
+		return -EINTR;
+
+	spin_lock(&vtpm_dev->buf_lock);
+
+	len = vtpm_dev->req_len;
+
+	if (count < len) {
+		spin_unlock(&vtpm_dev->buf_lock);
+		pr_debug("Invalid size in recv: count=%zd, req_len=%zd\n",
+			 count, len);
+		return -EIO;
+	}
+
+	rc = copy_to_user(buf, vtpm_dev->buffer, len);
+	memset(vtpm_dev->buffer, 0, len);
+	vtpm_dev->req_len = 0;
+
+	spin_unlock(&vtpm_dev->buf_lock);
+
+	if (rc)
+		return -EFAULT;
+
+	set_bit(STATE_WAIT_RESPONSE_BIT, &vtpm_dev->state);
+
+	return len;
+}
+
+/**
+ * vtpm_fops_write - Write TPM responses on 'server side'
+ *
+ * Return value:
+ *	Number of bytes read or negative error value
+ */
+static ssize_t vtpm_fops_write(struct file *filp, const char __user *buf,
+			       size_t count, loff_t *off)
+{
+	struct vtpm_dev *vtpm_dev = filp->private_data;
+
+	if (count > sizeof(vtpm_dev->buffer) ||
+	    !test_bit(STATE_WAIT_RESPONSE_BIT, &vtpm_dev->state))
+		return -EIO;
+
+	clear_bit(STATE_WAIT_RESPONSE_BIT, &vtpm_dev->state);
+
+	spin_lock(&vtpm_dev->buf_lock);
+
+	vtpm_dev->req_len = 0;
+
+	if (copy_from_user(vtpm_dev->buffer, buf, count)) {
+		spin_unlock(&vtpm_dev->buf_lock);
+		return -EFAULT;
+	}
+
+	vtpm_dev->resp_len = count;
+
+	spin_unlock(&vtpm_dev->buf_lock);
+
+	wake_up_interruptible(&vtpm_dev->wq);
+
+	return count;
+}
+
+/*
+ * vtpm_fops_poll: Poll status on 'server side'
+ *
+ * Return value:
+ *      Poll flags
+ */
+static unsigned int vtpm_fops_poll(struct file *filp, poll_table *wait)
+{
+	struct vtpm_dev *vtpm_dev = filp->private_data;
+	unsigned ret;
+
+	poll_wait(filp, &vtpm_dev->wq, wait);
+
+	ret = POLLOUT;
+	if (vtpm_dev->req_len)
+		ret |= POLLIN | POLLRDNORM;
+
+	return ret;
+}
+
+/*
+ * vtpm_fops_open - Open vTPM device on 'server side'
+ *
+ * Called when setting up the anonymous file descriptor
+ */
+static void vtpm_fops_open(struct file *filp)
+{
+	struct vtpm_dev *vtpm_dev = filp->private_data;
+
+	set_bit(STATE_OPENED_BIT, &vtpm_dev->state);
+}
+
+/**
+ * vtpm_fops_undo_open - counter-part to vtpm_fops_open
+ *
+ * Call to undo vtpm_fops_open
+ */
+static void vtpm_fops_undo_open(struct vtpm_dev *vtpm_dev)
+{
+	clear_bit(STATE_OPENED_BIT, &vtpm_dev->state);
+
+	/* no more TPM responses -- wake up anyone waiting for them */
+	wake_up_interruptible(&vtpm_dev->wq);
+}
+
+/*
+ * vtpm_fops_release: Close 'server side'
+ *
+ * Return value:
+ *      Always returns 0.
+ */
+static int vtpm_fops_release(struct inode *inode, struct file *filp)
+{
+	struct vtpm_dev *vtpm_dev = filp->private_data;
+
+	filp->private_data = NULL;
+
+	vtpm_delete_device_pair(vtpm_dev);
+
+	return 0;
+}
+
+static const struct file_operations vtpm_fops = {
+	.owner = THIS_MODULE,
+	.llseek = no_llseek,
+	.read = vtpm_fops_read,
+	.write = vtpm_fops_write,
+	.poll = vtpm_fops_poll,
+	.release = vtpm_fops_release,
+};
+
+/*
+ * Functions invoked by the core TPM driver to send TPM commands to
+ * 'server side' and receive responses from there.
+ */
+
+/*
+ * Called when core TPM driver reads TPM responses from 'server side'
+ *
+ * Return value:
+ *      Number of TPM response bytes read, negative error value otherwise
+ */
+static int vtpm_tpm_op_recv(struct tpm_chip *chip, u8 *buf, size_t count)
+{
+	struct vtpm_dev *vtpm_dev = chip->vendor.priv;
+	int sig;
+	size_t len;
+
+	if (!vtpm_dev)
+		return -EIO;
+
+	/* wait for response or responder gone */
+	sig = wait_event_interruptible(vtpm_dev->wq,
+		(vtpm_dev->resp_len != 0
+		|| !test_bit(STATE_OPENED_BIT, &vtpm_dev->state)));
+
+	if (sig)
+		return -EINTR;
+
+	/* process gone ? */
+	if (!test_bit(STATE_OPENED_BIT, &vtpm_dev->state))
+		return -EPIPE;
+
+	spin_lock(&vtpm_dev->buf_lock);
+
+	len = vtpm_dev->resp_len;
+	if (count < len) {
+		dev_err(&chip->dev,
+			"Invalid size in recv: count=%zd, resp_len=%zd\n",
+			count, len);
+		len = -EIO;
+		goto out;
+	}
+
+	memcpy(buf, vtpm_dev->buffer, len);
+	vtpm_dev->resp_len = 0;
+
+out:
+	spin_unlock(&vtpm_dev->buf_lock);
+
+	return len;
+}
+
+/*
+ * Called when core TPM driver forwards TPM requests to 'server side'.
+ *
+ * Return value:
+ *      0 in case of success, negative error value otherwise.
+ */
+static int vtpm_tpm_op_send(struct tpm_chip *chip, u8 *buf, size_t count)
+{
+	struct vtpm_dev *vtpm_dev = chip->vendor.priv;
+	int rc = 0;
+
+	if (!vtpm_dev)
+		return -EIO;
+
+	if (!test_bit(STATE_OPENED_BIT, &vtpm_dev->state))
+		return -EPIPE;
+
+	if (count > sizeof(vtpm_dev->buffer)) {
+		dev_err(&chip->dev,
+			"Invalid size in send: count=%zd, buffer size=%zd\n",
+			count, sizeof(vtpm_dev->buffer));
+		return -EIO;
+	}
+
+	spin_lock(&vtpm_dev->buf_lock);
+
+	vtpm_dev->resp_len = 0;
+
+	vtpm_dev->req_len = count;
+	memcpy(vtpm_dev->buffer, buf, count);
+
+	spin_unlock(&vtpm_dev->buf_lock);
+
+	wake_up_interruptible(&vtpm_dev->wq);
+
+	clear_bit(STATE_WAIT_RESPONSE_BIT, &vtpm_dev->state);
+
+	return rc;
+}
+
+static void vtpm_tpm_op_cancel(struct tpm_chip *chip)
+{
+	/* not supported */
+}
+
+static u8 vtpm_tpm_op_status(struct tpm_chip *chip)
+{
+	return 0;
+}
+
+static bool vtpm_tpm_req_canceled(struct tpm_chip  *chip, u8 status)
+{
+	return (status == 0);
+}
+
+static const struct tpm_class_ops vtpm_tpm_ops = {
+	.recv = vtpm_tpm_op_recv,
+	.send = vtpm_tpm_op_send,
+	.cancel = vtpm_tpm_op_cancel,
+	.status = vtpm_tpm_op_status,
+	.req_complete_mask = 0,
+	.req_complete_val = 0,
+	.req_canceled = vtpm_tpm_req_canceled,
+};
+
+/*
+ * Code related to creation and deletion of device pairs
+ */
+static struct vtpm_dev *vtpm_create_vtpm_dev(void)
+{
+	struct vtpm_dev *vtpm_dev;
+	struct tpm_chip *chip;
+	int err;
+
+	vtpm_dev = kzalloc(sizeof(*vtpm_dev), GFP_KERNEL);
+	if (vtpm_dev == NULL)
+		return ERR_PTR(-ENOMEM);
+
+	init_waitqueue_head(&vtpm_dev->wq);
+	spin_lock_init(&vtpm_dev->buf_lock);
+
+	chip = tpm_chip_alloc(NULL, &vtpm_tpm_ops);
+	if (IS_ERR(chip)) {
+		err = PTR_ERR(chip);
+		goto err_vtpm_dev_free;
+	}
+	chip->vendor.priv = vtpm_dev;
+	chip->vendor.irq = 1;
+
+	vtpm_dev->chip = chip;
+
+	return vtpm_dev;
+
+err_vtpm_dev_free:
+	kfree(vtpm_dev);
+
+	return ERR_PTR(err);
+}
+
+/*
+ * Undo what has been done in vtpm_create_vtpm_dev
+ */
+static inline void vtpm_delete_vtpm_dev(struct vtpm_dev *vtpm_dev)
+{
+	put_device(&vtpm_dev->chip->dev); /* frees chip */
+	kfree(vtpm_dev);
+}
+
+/*
+ * Create a /dev/tpm%d and 'server side' file descriptor pair
+ *
+ * Return value:
+ *      Returns file pointer on success, an error value otherwise
+ */
+static struct file *vtpm_create_device_pair(
+				       struct vtpm_new_pair *vtpm_new_pair)
+{
+	struct vtpm_dev *vtpm_dev;
+	int rc, fd;
+	struct file *file;
+
+	vtpm_dev = vtpm_create_vtpm_dev();
+	if (IS_ERR(vtpm_dev))
+		return ERR_CAST(vtpm_dev);
+
+	vtpm_dev->flags = vtpm_new_pair->flags;
+
+	/* setup an anonymous file for the server-side */
+	fd = get_unused_fd_flags(O_RDWR);
+	if (fd < 0) {
+		rc = fd;
+		goto err_delete_vtpm_dev;
+	}
+
+	file = anon_inode_getfile("[vtpms]", &vtpm_fops, vtpm_dev, O_RDWR);
+	if (IS_ERR(file)) {
+		rc = PTR_ERR(file);
+		goto err_put_unused_fd;
+	}
+
+	/* from now on we can unwind with put_unused_fd() + fput() */
+	/* simulate an open() on the server side */
+	vtpm_fops_open(file);
+
+	if (vtpm_dev->flags & VTPM_FLAG_TPM2)
+		vtpm_dev->chip->flags |= TPM_CHIP_FLAG_TPM2;
+
+	rc = tpm_chip_register(vtpm_dev->chip);
+	if (rc)
+		goto err_vtpm_fput;
+
+	vtpm_new_pair->fd = fd;
+	vtpm_new_pair->major = MAJOR(vtpm_dev->chip->dev.devt);
+	vtpm_new_pair->minor = MINOR(vtpm_dev->chip->dev.devt);
+	vtpm_new_pair->tpm_dev_num = vtpm_dev->chip->dev_num;
+
+	return file;
+
+err_vtpm_fput:
+	put_unused_fd(fd);
+	fput(file);
+
+	return ERR_PTR(rc);
+
+err_put_unused_fd:
+	put_unused_fd(fd);
+
+err_delete_vtpm_dev:
+	vtpm_delete_vtpm_dev(vtpm_dev);
+
+	return ERR_PTR(rc);
+}
+
+/*
+ * Counter part to vtpm_create_device_pair.
+ */
+static void vtpm_delete_device_pair(struct vtpm_dev *vtpm_dev)
+{
+	tpm_chip_unregister(vtpm_dev->chip);
+
+	vtpm_fops_undo_open(vtpm_dev);
+
+	vtpm_delete_vtpm_dev(vtpm_dev);
+}
+
+/*
+ * Code related to the control device /dev/vtpmx
+ */
+
+/*
+ * vtpmx_fops_ioctl: ioctl on /dev/vtpmx
+ *
+ * Return value:
+ *      Returns 0 on success, a negative error code otherwise.
+ */
+static long vtpmx_fops_ioctl(struct file *f, unsigned int ioctl,
+			    unsigned long arg)
+{
+	void __user *argp = (void __user *)arg;
+	struct vtpm_new_pair *vtpm_new_pair_p;
+	struct vtpm_new_pair vtpm_new_pair;
+	struct file *file;
+
+	switch (ioctl) {
+	case VTPM_NEW_DEV:
+		if (!capable(CAP_SYS_ADMIN))
+			return -EPERM;
+		vtpm_new_pair_p = argp;
+		if (copy_from_user(&vtpm_new_pair, vtpm_new_pair_p,
+				   sizeof(vtpm_new_pair)))
+			return -EFAULT;
+		file = vtpm_create_device_pair(&vtpm_new_pair);
+		if (IS_ERR(file))
+			return PTR_ERR(file);
+		if (copy_to_user(vtpm_new_pair_p, &vtpm_new_pair,
+				 sizeof(vtpm_new_pair))) {
+			put_unused_fd(vtpm_new_pair.fd);
+			fput(file);
+			return -EFAULT;
+		}
+
+		fd_install(vtpm_new_pair.fd, file);
+		return 0;
+
+	default:
+		return -EINVAL;
+	}
+}
+
+#ifdef CONFIG_COMPAT
+static long vtpmx_fops_compat_ioctl(struct file *f, unsigned int ioctl,
+				    unsigned long arg)
+{
+	return vtpmx_fops_ioctl(f, ioctl, (unsigned long)compat_ptr(arg));
+}
+#endif
+
+static const struct file_operations vtpmx_fops = {
+	.owner = THIS_MODULE,
+	.unlocked_ioctl = vtpmx_fops_ioctl,
+#ifdef CONFIG_COMPAT
+	.compat_ioctl = vtpmx_fops_compat_ioctl,
+#endif
+	.llseek = noop_llseek,
+};
+
+static struct miscdevice vtpmx_miscdev = {
+	.minor = MISC_DYNAMIC_MINOR,
+	.name = "vtpmx",
+	.fops = &vtpmx_fops,
+};
+
+static int vtpmx_init(void)
+{
+	return misc_register(&vtpmx_miscdev);
+}
+
+static void vtpmx_cleanup(void)
+{
+	misc_deregister(&vtpmx_miscdev);
+}
+
+static int __init vtpm_module_init(void)
+{
+	int rc;
+
+	rc = vtpmx_init();
+	if (rc) {
+		pr_err("couldn't create vtpmx device\n");
+		return rc;
+	}
+
+	return 0;
+}
+
+static void __exit vtpm_module_exit(void)
+{
+	vtpmx_cleanup();
+}
+
+module_init(vtpm_module_init);
+module_exit(vtpm_module_exit);
+
+MODULE_AUTHOR("Stefan Berger (stefanb-r/Jw6+rmf7HQT0dZR+AlfA@public.gmane.org)");
+MODULE_DESCRIPTION("vTPM Driver");
+MODULE_VERSION("0.1");
+MODULE_LICENSE("GPL");
diff --git a/include/uapi/linux/Kbuild b/include/uapi/linux/Kbuild
index c2e5d6c..c194d61 100644
--- a/include/uapi/linux/Kbuild
+++ b/include/uapi/linux/Kbuild
@@ -449,6 +449,7 @@ header-y += virtio_scsi.h
 header-y += virtio_types.h
 header-y += vm_sockets.h
 header-y += vt.h
+header-y += vtpm.h
 header-y += wait.h
 header-y += wanrouter.h
 header-y += watchdog.h
diff --git a/include/uapi/linux/vtpm.h b/include/uapi/linux/vtpm.h
new file mode 100644
index 0000000..aef8733
--- /dev/null
+++ b/include/uapi/linux/vtpm.h
@@ -0,0 +1,38 @@
+/*
+ * Definitions for the VTPM interface
+ * Copyright (c) 2015, 2016, IBM Corporation
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ */
+
+#ifndef _UAPI_LINUX_VTPM_H
+#define _UAPI_LINUX_VTPM_H
+
+#include <linux/types.h>
+#include <linux/ioctl.h>
+
+/* ioctls */
+
+struct vtpm_new_pair {
+	__u32 flags;         /* input */
+	__u32 tpm_dev_num;   /* output */
+	__u32 fd;            /* output */
+	__u32 major;         /* output */
+	__u32 minor;         /* output */
+};
+
+/* above flags */
+#define VTPM_FLAG_TPM2           1  /* emulator is TPM 2 */
+
+#define VTPM_TPM 0xa0
+
+#define VTPM_NEW_DEV         _IOW(VTPM_TPM, 0x00, struct vtpm_new_pair)
+
+#endif /* _UAPI_LINUX_VTPM_H */
-- 
2.4.3


------------------------------------------------------------------------------
Site24x7 APM Insight: Get Deep Visibility into Application Performance
APM + Mobile APM + RUM: Monitor 3 App instances at just $35/Month
Monitor end-to-end web transactions and take corrective actions now
Troubleshoot faster and improve end-user experience. Signup Now!
http://pubads.g.doubleclick.net/gampad/clk?id=272487151&iu=/4140

^ permalink raw reply related	[flat|nested] 60+ messages in thread

* [PATCH v3 10/11] tpm: Initialize TPM and get durations and timeouts
       [not found] ` <1455885728-10315-1-git-send-email-stefanb-23VcF4HTsmIX0ybBhKVfKdBPR1lH4CV8@public.gmane.org>
                     ` (7 preceding siblings ...)
  2016-02-19 12:42   ` [PATCH v3 09/11] tpm: Driver for supporting multiple emulated TPMs Stefan Berger
@ 2016-02-19 12:42   ` Stefan Berger
  2016-02-19 12:42   ` [PATCH v3 11/11] A test program for vTPM device creation Stefan Berger
  2016-02-22 19:20   ` [PATCH v3 00/11] Multi-instance vTPM driver Jarkko Sakkinen
  10 siblings, 0 replies; 60+ messages in thread
From: Stefan Berger @ 2016-02-19 12:42 UTC (permalink / raw)
  To: tpmdd-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f

Add the retrieval of TPM 1.2 durations and timeouts. Since this requires
the startup of the TPM, do this for TPM 1.2 and TPM 2.

Signed-off-by: Stefan Berger <stefanb-23VcF4HTsmIX0ybBhKVfKdBPR1lH4CV8@public.gmane.org>
---
 drivers/char/tpm/tpm-vtpm.c | 85 ++++++++++++++++++++++++++++++++++++++++-----
 1 file changed, 76 insertions(+), 9 deletions(-)

diff --git a/drivers/char/tpm/tpm-vtpm.c b/drivers/char/tpm/tpm-vtpm.c
index 823c94a..fc2fe53 100644
--- a/drivers/char/tpm/tpm-vtpm.c
+++ b/drivers/char/tpm/tpm-vtpm.c
@@ -45,8 +45,11 @@ struct vtpm_dev {
 	size_t req_len;              /* length of queued TPM request */
 	size_t resp_len;             /* length of queued TPM response */
 	u8 buffer[TPM_BUFSIZE];      /* request/response buffer */
+
+	struct work_struct work;     /* task that retrieves TPM timeouts */
 };
 
+static struct workqueue_struct *workqueue;
 
 static void vtpm_delete_device_pair(struct vtpm_dev *vtpm_dev);
 
@@ -67,6 +70,9 @@ static ssize_t vtpm_fops_read(struct file *filp, char __user *buf,
 	size_t len;
 	int sig, rc;
 
+	if (!test_bit(STATE_OPENED_BIT, &vtpm_dev->state))
+		return -EPIPE;
+
 	sig = wait_event_interruptible(vtpm_dev->wq, vtpm_dev->req_len != 0);
 	if (sig)
 		return -EINTR;
@@ -107,6 +113,9 @@ static ssize_t vtpm_fops_write(struct file *filp, const char __user *buf,
 {
 	struct vtpm_dev *vtpm_dev = filp->private_data;
 
+	if (!test_bit(STATE_OPENED_BIT, &vtpm_dev->state))
+		return -EPIPE;
+
 	if (count > sizeof(vtpm_dev->buffer) ||
 	    !test_bit(STATE_WAIT_RESPONSE_BIT, &vtpm_dev->state))
 		return -EIO;
@@ -147,6 +156,8 @@ static unsigned int vtpm_fops_poll(struct file *filp, poll_table *wait)
 	ret = POLLOUT;
 	if (vtpm_dev->req_len)
 		ret |= POLLIN | POLLRDNORM;
+	if (!test_bit(STATE_OPENED_BIT, &vtpm_dev->state))
+		ret |= POLLHUP;
 
 	return ret;
 }
@@ -320,6 +331,54 @@ static const struct tpm_class_ops vtpm_tpm_ops = {
 };
 
 /*
+ * Code related to the startup of the TPM 2 and startup of TPM 1.2 +
+ * retrieval of timeouts and durations.
+ */
+
+static void vtpm_dev_work(struct work_struct *work)
+{
+	struct vtpm_dev *vtpm_dev = container_of(work, struct vtpm_dev, work);
+	int rc;
+
+	if (vtpm_dev->flags & VTPM_FLAG_TPM2)
+		rc = tpm2_startup(vtpm_dev->chip, TPM2_SU_CLEAR);
+	else
+		rc = tpm_get_timeouts(vtpm_dev->chip);
+
+	if (rc)
+		goto err;
+
+	rc = tpm_chip_register(vtpm_dev->chip);
+	if (rc)
+		goto err;
+
+	return;
+
+err:
+	vtpm_fops_undo_open(vtpm_dev);
+}
+
+/*
+ * vtpm_dev_work_stop: make sure the work has finished
+ *
+ * This function is useful when user space closed the fd
+ * while the driver still determines timeouts.
+ */
+static void vtpm_dev_work_stop(struct vtpm_dev *vtpm_dev)
+{
+	vtpm_fops_undo_open(vtpm_dev);
+	flush_work(&vtpm_dev->work);
+}
+
+/*
+ * vtpm_dev_work_start: Schedule the work for TPM 1.2 & 2 initialization
+ */
+static inline void vtpm_dev_work_start(struct vtpm_dev *vtpm_dev)
+{
+	queue_work(workqueue, &vtpm_dev->work);
+}
+
+/*
  * Code related to creation and deletion of device pairs
  */
 static struct vtpm_dev *vtpm_create_vtpm_dev(void)
@@ -334,6 +393,7 @@ static struct vtpm_dev *vtpm_create_vtpm_dev(void)
 
 	init_waitqueue_head(&vtpm_dev->wq);
 	spin_lock_init(&vtpm_dev->buf_lock);
+	INIT_WORK(&vtpm_dev->work, vtpm_dev_work);
 
 	chip = tpm_chip_alloc(NULL, &vtpm_tpm_ops);
 	if (IS_ERR(chip)) {
@@ -401,9 +461,7 @@ static struct file *vtpm_create_device_pair(
 	if (vtpm_dev->flags & VTPM_FLAG_TPM2)
 		vtpm_dev->chip->flags |= TPM_CHIP_FLAG_TPM2;
 
-	rc = tpm_chip_register(vtpm_dev->chip);
-	if (rc)
-		goto err_vtpm_fput;
+	vtpm_dev_work_start(vtpm_dev);
 
 	vtpm_new_pair->fd = fd;
 	vtpm_new_pair->major = MAJOR(vtpm_dev->chip->dev.devt);
@@ -412,12 +470,6 @@ static struct file *vtpm_create_device_pair(
 
 	return file;
 
-err_vtpm_fput:
-	put_unused_fd(fd);
-	fput(file);
-
-	return ERR_PTR(rc);
-
 err_put_unused_fd:
 	put_unused_fd(fd);
 
@@ -432,6 +484,8 @@ err_delete_vtpm_dev:
  */
 static void vtpm_delete_device_pair(struct vtpm_dev *vtpm_dev)
 {
+	vtpm_dev_work_stop(vtpm_dev);
+
 	tpm_chip_unregister(vtpm_dev->chip);
 
 	vtpm_fops_undo_open(vtpm_dev);
@@ -526,11 +580,24 @@ static int __init vtpm_module_init(void)
 		return rc;
 	}
 
+	workqueue = create_workqueue("tpm-vtpm");
+	if (!workqueue) {
+		pr_err("couldn't create workqueue\n");
+		rc = -ENOMEM;
+		goto err_vtpmx_cleanup;
+	}
+
 	return 0;
+
+err_vtpmx_cleanup:
+	vtpmx_cleanup();
+
+	return rc;
 }
 
 static void __exit vtpm_module_exit(void)
 {
+	destroy_workqueue(workqueue);
 	vtpmx_cleanup();
 }
 
-- 
2.4.3


------------------------------------------------------------------------------
Site24x7 APM Insight: Get Deep Visibility into Application Performance
APM + Mobile APM + RUM: Monitor 3 App instances at just $35/Month
Monitor end-to-end web transactions and take corrective actions now
Troubleshoot faster and improve end-user experience. Signup Now!
http://pubads.g.doubleclick.net/gampad/clk?id=272487151&iu=/4140

^ permalink raw reply related	[flat|nested] 60+ messages in thread

* [PATCH v3 11/11] A test program for vTPM device creation
       [not found] ` <1455885728-10315-1-git-send-email-stefanb-23VcF4HTsmIX0ybBhKVfKdBPR1lH4CV8@public.gmane.org>
                     ` (8 preceding siblings ...)
  2016-02-19 12:42   ` [PATCH v3 10/11] tpm: Initialize TPM and get durations and timeouts Stefan Berger
@ 2016-02-19 12:42   ` Stefan Berger
  2016-02-22 19:20   ` [PATCH v3 00/11] Multi-instance vTPM driver Jarkko Sakkinen
  10 siblings, 0 replies; 60+ messages in thread
From: Stefan Berger @ 2016-02-19 12:42 UTC (permalink / raw)
  To: tpmdd-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f

This patch provides a program that is for testing purposes only.

Build it using the following commands:

make headers_install ARCH=x86_64  INSTALL_HDR_PATH=/usr

gcc vtpmctrl.c -o vtpmctrl

To use it:

To create a device pair and have vtpmctrl listen for commands, display
them and respond with TPM success messages do:

#> ./vtpmctrl
Created TPM device /dev/tpm0; vTPM device has fd 4, major/minor = 10/224.

In another shell do

#> exec 100<>/dev/tpm0
#> /bin/echo -en '\x00\xc1\x00\x00\x00\x0a\x00\x00\x00\x00' >&100
#> od -t x1 <&100
00000000 00 c4 00 00 00 0a 00 00 00 00
00000012
#> exec 100>&-

Signed-off-by: Stefan Berger <stefanb-23VcF4HTsmIX0ybBhKVfKdBPR1lH4CV8@public.gmane.org>
---
 vtpmctrl.c | 163 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 163 insertions(+)
 create mode 100644 vtpmctrl.c

diff --git a/vtpmctrl.c b/vtpmctrl.c
new file mode 100644
index 0000000..6f3c860
--- /dev/null
+++ b/vtpmctrl.c
@@ -0,0 +1,163 @@
+/*
+ * vtpmctrl.c -- Linux vTPM driver control program
+ *
+ * (c) Copyright IBM Corporation 2015.
+ *
+ * Author: Stefan Berger <stefanb-r/Jw6+rmf7HQT0dZR+AlfA@public.gmane.org>
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * Neither the names of the IBM Corporation nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+#include <linux/vtpm.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/ioctl.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <string.h>
+#include <endian.h>
+#include <stdint.h>
+
+int vtpmctrl_create(void)
+{
+	int fd, n, option, li, serverfd, nn;
+	struct vtpm_new_pair vtpm_new_pair = {
+		.flags = 0,
+	};
+	char tpmdev[16];
+	unsigned char buffer[4096];
+	const unsigned char tpm_startup_resp[] = {
+		0x00, 0xc4, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00
+	};
+	const unsigned char timeout_req[] = {
+		0x00, 0xc1, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x65,
+		0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00,
+		0x01, 0x15
+	};
+	const unsigned char timeout_res[] = {
+		0x00, 0xc4, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00,
+		0x00, 0x01, 0x00, 0x00,
+		0x00, 0x02, 0x00, 0x00,
+		0x00, 0x03, 0x00, 0x00,
+		0x00, 0x04, 0x00, 0x00,
+	};
+	const unsigned char duration_req[] = {
+		0x00, 0xc1, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x65,
+		0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00,
+		0x01, 0x20
+	};
+	const unsigned char duration_res[] = {
+		0x00, 0xc4, 0x00, 0x00, 0x00, 0x1a, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00,
+		0x00, 0x01, 0x00, 0x00,
+		0x00, 0x02, 0x00, 0x00,
+		0x00, 0x03, 0x00, 0x00,
+	};
+	uint32_t ordinal;
+
+	fd = open("/dev/vtpmx", O_RDWR);
+	if (fd < 0) {
+		perror("Could not open /dev/vtpmx");
+		return 1;
+	}
+
+	n = ioctl(fd, VTPM_NEW_DEV, &vtpm_new_pair);
+	if (n != 0) {
+		perror("ioctl to create dev pair failed");
+		close(fd);
+		return 1;
+	}
+
+	snprintf(tpmdev, sizeof(tpmdev), "/dev/tpm%u",
+		 vtpm_new_pair.tpm_dev_num);
+
+	serverfd = vtpm_new_pair.fd;
+
+	printf("Created TPM device %s; vTPM device has fd %d, "
+	       "major/minor = %u/%u.\n",
+	       tpmdev, serverfd, vtpm_new_pair.major, vtpm_new_pair.minor);
+
+	close(fd);
+
+	while (1) {
+		n = read(serverfd, buffer, sizeof(buffer));
+		if (n > 0) {
+			printf("Request with %d bytes:\n", n);
+			nn = 0;
+			while (nn < n) {
+				printf("0x%02x ", buffer[nn]);
+				nn++;
+				if (nn % 16 == 0)
+					printf("\n");
+			}
+			printf("\n");
+			ordinal = be32toh(*(uint32_t *)&(buffer[6]));
+			switch (ordinal) {
+			case 0x99:
+				n = write(serverfd, tpm_startup_resp, sizeof(tpm_startup_resp));
+				break;
+			case 0x65:
+				if (!memcmp(timeout_req, buffer, sizeof(timeout_req))) {
+					n = write(serverfd, timeout_res, sizeof(timeout_res));
+
+				} else if (!memcmp(duration_req, buffer, sizeof(duration_req))) {
+					n = write(serverfd, duration_res, sizeof(duration_res));
+				} else {
+					n = write(serverfd, tpm_startup_resp, sizeof(tpm_startup_resp));
+				}
+				break;
+			default:
+				n = write(serverfd, tpm_startup_resp, sizeof(tpm_startup_resp));
+				break;
+			}
+			if (n < 0) {
+				printf("Error from writing the response: %s\n",
+				       strerror(errno));
+				break;
+			} else {
+				printf("Sent response with %d bytes.\n", n);
+			}
+		} else {
+			break;
+		}
+	}
+
+	return 0;
+}
+
+int main(int argc, char *argv[])
+{
+	return vtpmctrl_create();
+}
-- 
2.4.3


------------------------------------------------------------------------------
Site24x7 APM Insight: Get Deep Visibility into Application Performance
APM + Mobile APM + RUM: Monitor 3 App instances at just $35/Month
Monitor end-to-end web transactions and take corrective actions now
Troubleshoot faster and improve end-user experience. Signup Now!
http://pubads.g.doubleclick.net/gampad/clk?id=272487151&iu=/4140

^ permalink raw reply related	[flat|nested] 60+ messages in thread

* Re: [PATCH v3 03/11] tpm: Get rid of devname
       [not found]     ` <1455885728-10315-4-git-send-email-stefanb-23VcF4HTsmIX0ybBhKVfKdBPR1lH4CV8@public.gmane.org>
@ 2016-02-22 18:19       ` Jason Gunthorpe
       [not found]         ` <20160222181929.GB22088-ePGOBjL8dl3ta4EC/59zMFaTQe2KTcn/@public.gmane.org>
  0 siblings, 1 reply; 60+ messages in thread
From: Jason Gunthorpe @ 2016-02-22 18:19 UTC (permalink / raw)
  To: Stefan Berger; +Cc: tpmdd-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f

On Fri, Feb 19, 2016 at 07:42:00AM -0500, Stefan Berger wrote:
>  
> -	dev_set_name(&chip->dev, "%s", chip->devname);
> +	err = dev_set_name(&chip->dev, "tpm%d", chip->dev_num);
> +	if (err)
> +		goto out;
>  
>  	device_initialize(&chip->dev);
>  
> @@ -142,6 +142,10 @@ struct tpm_chip *tpmm_chip_alloc(struct device *dev,
>  	}
>  
>  	return chip;
> +
> +out:
> +	put_device(&chip->dev);
> +	return ERR_PTR(err);

Oops, something went wrong here in all the rebasing - dev_set_name has
to be after devince_initialize.

Jason

------------------------------------------------------------------------------
Site24x7 APM Insight: Get Deep Visibility into Application Performance
APM + Mobile APM + RUM: Monitor 3 App instances at just $35/Month
Monitor end-to-end web transactions and take corrective actions now
Troubleshoot faster and improve end-user experience. Signup Now!
http://pubads.g.doubleclick.net/gampad/clk?id=272487151&iu=/4140

^ permalink raw reply	[flat|nested] 60+ messages in thread

* Re: [PATCH v3 05/11] tpm: Get rid of module locking
       [not found]     ` <1455885728-10315-6-git-send-email-stefanb-23VcF4HTsmIX0ybBhKVfKdBPR1lH4CV8@public.gmane.org>
@ 2016-02-22 18:22       ` Jason Gunthorpe
       [not found]         ` <20160222182245.GC22088-ePGOBjL8dl3ta4EC/59zMFaTQe2KTcn/@public.gmane.org>
  2016-02-22 21:11       ` Jarkko Sakkinen
  1 sibling, 1 reply; 60+ messages in thread
From: Jason Gunthorpe @ 2016-02-22 18:22 UTC (permalink / raw)
  To: Stefan Berger; +Cc: tpmdd-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f

On Fri, Feb 19, 2016 at 07:42:02AM -0500, Stefan Berger wrote:
> Get rid of the locking of the module

Little more in the comment please..

  Now that the tpm core has strong locking around 'ops' it is possible
  to remove a TPM driver, module and all, even while user space still
  has things like /dev/tpmX open. For consistency and simplicity, drop
  the module locking entirely.

Jason

------------------------------------------------------------------------------
Site24x7 APM Insight: Get Deep Visibility into Application Performance
APM + Mobile APM + RUM: Monitor 3 App instances at just $35/Month
Monitor end-to-end web transactions and take corrective actions now
Troubleshoot faster and improve end-user experience. Signup Now!
http://pubads.g.doubleclick.net/gampad/clk?id=272487151&iu=/4140

^ permalink raw reply	[flat|nested] 60+ messages in thread

* Re: [PATCH v3 06/11] tpm: Split out the devm stuff from tpmm_chip_alloc
       [not found]     ` <1455885728-10315-7-git-send-email-stefanb-23VcF4HTsmIX0ybBhKVfKdBPR1lH4CV8@public.gmane.org>
@ 2016-02-22 18:24       ` Jason Gunthorpe
  2016-02-22 21:14       ` Jarkko Sakkinen
  1 sibling, 0 replies; 60+ messages in thread
From: Jason Gunthorpe @ 2016-02-22 18:24 UTC (permalink / raw)
  To: Stefan Berger; +Cc: tpmdd-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f

On Fri, Feb 19, 2016 at 07:42:03AM -0500, Stefan Berger wrote:
  
> -	dev_set_drvdata(dev, chip);
> +	device_initialize(&chip->dev);

Ah, there is the rebase mistake, this hunk needs to be shifted to the
dev_set_name patch.

Jason

------------------------------------------------------------------------------
Site24x7 APM Insight: Get Deep Visibility into Application Performance
APM + Mobile APM + RUM: Monitor 3 App instances at just $35/Month
Monitor end-to-end web transactions and take corrective actions now
Troubleshoot faster and improve end-user experience. Signup Now!
http://pubads.g.doubleclick.net/gampad/clk?id=272487151&iu=/4140

^ permalink raw reply	[flat|nested] 60+ messages in thread

* Re: [PATCH v3 07/11] tpm: Replace device number bitmap with IDR
       [not found]     ` <1455885728-10315-8-git-send-email-stefanb-23VcF4HTsmIX0ybBhKVfKdBPR1lH4CV8@public.gmane.org>
@ 2016-02-22 19:06       ` Jason Gunthorpe
       [not found]         ` <20160222190629.GE22088-ePGOBjL8dl3ta4EC/59zMFaTQe2KTcn/@public.gmane.org>
                           ` (2 more replies)
  0 siblings, 3 replies; 60+ messages in thread
From: Jason Gunthorpe @ 2016-02-22 19:06 UTC (permalink / raw)
  To: Stefan Berger; +Cc: tpmdd-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f

On Fri, Feb 19, 2016 at 07:42:04AM -0500, Stefan Berger wrote:
> +	if (chip_num == TPM_ANY_NUM)
> +		chip_next = 0;
> +
> +	mutex_lock(&idr_lock);
> +
> +	do {
> +		if (chip_num == TPM_ANY_NUM) {
> +			chip_prev = chip_next;
> +			chip = idr_get_next(&dev_nums_idr, &chip_next);
> +		} else
> +			chip = idr_find_slowpath(&dev_nums_idr, chip_num);
> +
> +		if (chip && !tpm_try_get_ops(chip))
> +			break;
> +	} while (chip_num == TPM_ANY_NUM && chip_prev != chip_next);

This while loop doesn't look very good if tpm_try_get_ops fails?

Maybe like this?

struct tpm_chip *tpm_chip_find_get(int chip_num)
{
	struct tpm_chip *res = NULL;

	mutex_lock(&idr_lock);

	if (chip_num == TPM_ANY_NUM) {
		struct tpm_chip *chip;

		chip_num = 0;
		do {
			chip = idr_get_next(&dev_nums_idr, &chip_num);
			if (res && !tpm_try_get_ops(chip)) {
				res = chip;
				break;
			}
		}
		while (chip);
	} else {
		res = idr_find_slowpath(&dev_nums_idr, chip_num);
		if (res && tpm_try_get_ops(chip))
			res = NULL;
	}

	mutex_unlock(&idr_lock);

	return res;
}

> +	if (err < 0) {
>  		dev_err(dev, "No available tpm device numbers\n");

I would drop the dev_err too

> @@ -247,12 +253,6 @@ static int tpm_dev_add_device(struct tpm_chip *chip)
>  static void tpm_dev_del_device(struct tpm_chip *chip)
>  {
>  	cdev_del(&chip->cdev);
> -
> -	/* Make the driver uncallable. */
> -	down_write(&chip->ops_sem);
> -	chip->ops = NULL;
> -	up_write(&chip->ops_sem);
> -
>  	device_del(&chip->dev);

Hum.. The ordering here is very important, I guess I got it slightly
wrong as well in my patch adding ops.

Lets go for this:

- Tear down /dev/tpmX, sysfs and all other user accessible entry
  points
- Do device_del (get rid of all the sysfs stuff)
- NULL the IDR (disables kAPI access and allow reuse of the ID)
- NULL the ops (flush in-progress access now that new access is impossible)
- put_device to kfree (via devm)

Jason

------------------------------------------------------------------------------
Site24x7 APM Insight: Get Deep Visibility into Application Performance
APM + Mobile APM + RUM: Monitor 3 App instances at just $35/Month
Monitor end-to-end web transactions and take corrective actions now
Troubleshoot faster and improve end-user experience. Signup Now!
http://pubads.g.doubleclick.net/gampad/clk?id=272487151&iu=/4140

^ permalink raw reply	[flat|nested] 60+ messages in thread

* Re: [PATCH v3 08/11] tpm: Introduce TPM_CHIP_FLAG_VIRTUAL
       [not found]     ` <1455885728-10315-9-git-send-email-stefanb-23VcF4HTsmIX0ybBhKVfKdBPR1lH4CV8@public.gmane.org>
@ 2016-02-22 19:19       ` Jason Gunthorpe
       [not found]         ` <20160222191922.GH22088-ePGOBjL8dl3ta4EC/59zMFaTQe2KTcn/@public.gmane.org>
                           ` (2 more replies)
  0 siblings, 3 replies; 60+ messages in thread
From: Jason Gunthorpe @ 2016-02-22 19:19 UTC (permalink / raw)
  To: Stefan Berger; +Cc: tpmdd-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f

On Fri, Feb 19, 2016 at 07:42:05AM -0500, Stefan Berger wrote:

>  	cdev_init(&chip->cdev, &tpm_fops);
> -	chip->cdev.owner = dev->driver->owner;

Shouldn't this be:

	chip->cdev.owner = THIS_MODULE;

?

Please drop this hunk into the 'tpm: Get rid of module locking' patch

> +
> +	if (!(chip->flags & TPM_CHIP_FLAG_VIRTUAL))
> +		err = sysfs_create_group(&chip->dev.parent->kobj,
> +					 &tpm_dev_group);
> +	else
> +		chip->groups[chip->groups_cnt++] = &tpm_dev_group;

For other reviewers: The intent here is to make another patch that
moves the main sysfs to only use groups with symlinks link ppi does
now.

Does sysfs work with vtpm? I am worried about dev_get_drvdata here
(and other places):

 static ssize_t durations_show(struct device *dev, struct device_attribute *attr,
                               char *buf)
 {
        struct tpm_chip *chip = dev_get_drvdata(dev);

There is only one dev_set_drvdata and it does not apply to chip->dev.

Ultimately this should change to container_of like ppi does.

Jason

------------------------------------------------------------------------------
Site24x7 APM Insight: Get Deep Visibility into Application Performance
APM + Mobile APM + RUM: Monitor 3 App instances at just $35/Month
Monitor end-to-end web transactions and take corrective actions now
Troubleshoot faster and improve end-user experience. Signup Now!
http://pubads.g.doubleclick.net/gampad/clk?id=272487151&iu=/4140

^ permalink raw reply	[flat|nested] 60+ messages in thread

* Re: [PATCH v3 00/11] Multi-instance vTPM driver
       [not found] ` <1455885728-10315-1-git-send-email-stefanb-23VcF4HTsmIX0ybBhKVfKdBPR1lH4CV8@public.gmane.org>
                     ` (9 preceding siblings ...)
  2016-02-19 12:42   ` [PATCH v3 11/11] A test program for vTPM device creation Stefan Berger
@ 2016-02-22 19:20   ` Jarkko Sakkinen
  10 siblings, 0 replies; 60+ messages in thread
From: Jarkko Sakkinen @ 2016-02-22 19:20 UTC (permalink / raw)
  To: Stefan Berger; +Cc: tpmdd-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f

On Fri, Feb 19, 2016 at 07:41:57AM -0500, Stefan Berger wrote:
> The following series of patches implements a multi-instance vTPM driver
> that can dynamically create TPM 'server' and client device pairs.
> 
> Using an ioctl on the provided /dev/vtpmx, a client-side vTPM device
> and a server side file descriptor is created. The file descriptor must
> be passed to a TPM emulator. The device driver will initialize the
> emulated TPM using TPM 1.2 or TPM 2 startup commands and it will read
> the command durations from the device in case of a TPM 1.2. The choice
> of emulated TPM device (1.2 or 2) must be provided with a flag in
> the ioctl.

I think it would be good to have something in Documentation/ (eventually).

/Jarkko

> The driver is based on Linux 4.4 and uses several recently posted patches
> from Jason and Jarkko. I may have adapted them to fit on top of Linux 4.4.
> 
>    Stefan
> 
> 
> Jarkko Sakkinen (1):
>   tpm: fix the cleanup of struct tpm_chip
> 
> Jason Gunthorpe (4):
>   tpm: Get rid of chip->pdev
>   tpm: Get rid of devname
>   tpm: Provide strong locking for device removal
>   tpm: Split out the devm stuff from tpmm_chip_alloc
> 
> Stefan Berger (6):
>   tpm: Get rid of module locking
>   tpm: Replace device number bitmap with IDR
>   tpm: Introduce TPM_CHIP_FLAG_VIRTUAL
>   tpm: Driver for supporting multiple emulated TPMs
>   tpm: Initialize TPM and get durations and timeouts
>   A test program for vTPM device creation
> 
>  drivers/char/tpm/Kconfig            |  10 +
>  drivers/char/tpm/Makefile           |   1 +
>  drivers/char/tpm/tpm-chip.c         | 217 +++++++++----
>  drivers/char/tpm/tpm-dev.c          |  15 +-
>  drivers/char/tpm/tpm-interface.c    |  49 +--
>  drivers/char/tpm/tpm-sysfs.c        |  20 +-
>  drivers/char/tpm/tpm-vtpm.c         | 610 ++++++++++++++++++++++++++++++++++++
>  drivers/char/tpm/tpm.h              |  30 +-
>  drivers/char/tpm/tpm2-cmd.c         |   8 +-
>  drivers/char/tpm/tpm_atmel.c        |  14 +-
>  drivers/char/tpm/tpm_eventlog.c     |   2 +-
>  drivers/char/tpm/tpm_eventlog.h     |   2 +-
>  drivers/char/tpm/tpm_i2c_atmel.c    |  16 +-
>  drivers/char/tpm/tpm_i2c_infineon.c |   6 +-
>  drivers/char/tpm/tpm_i2c_nuvoton.c  |  24 +-
>  drivers/char/tpm/tpm_infineon.c     |  22 +-
>  drivers/char/tpm/tpm_nsc.c          |  20 +-
>  drivers/char/tpm/tpm_tis.c          |  18 +-
>  include/uapi/linux/Kbuild           |   1 +
>  include/uapi/linux/vtpm.h           |  38 +++
>  vtpmctrl.c                          | 163 ++++++++++
>  21 files changed, 1111 insertions(+), 175 deletions(-)
>  create mode 100644 drivers/char/tpm/tpm-vtpm.c
>  create mode 100644 include/uapi/linux/vtpm.h
>  create mode 100644 vtpmctrl.c
> 
> -- 
> 2.4.3
> 

------------------------------------------------------------------------------
Site24x7 APM Insight: Get Deep Visibility into Application Performance
APM + Mobile APM + RUM: Monitor 3 App instances at just $35/Month
Monitor end-to-end web transactions and take corrective actions now
Troubleshoot faster and improve end-user experience. Signup Now!
http://pubads.g.doubleclick.net/gampad/clk?id=272487151&iu=/4140

^ permalink raw reply	[flat|nested] 60+ messages in thread

* Re: [PATCH v3 02/11] tpm: Get rid of chip->pdev
       [not found]     ` <1455885728-10315-3-git-send-email-stefanb-23VcF4HTsmIX0ybBhKVfKdBPR1lH4CV8@public.gmane.org>
@ 2016-02-22 19:25       ` Jarkko Sakkinen
  0 siblings, 0 replies; 60+ messages in thread
From: Jarkko Sakkinen @ 2016-02-22 19:25 UTC (permalink / raw)
  To: Stefan Berger; +Cc: tpmdd-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f

On Fri, Feb 19, 2016 at 07:41:59AM -0500, Stefan Berger wrote:
> From: Jason Gunthorpe <jgunthorpe-ePGOBjL8dl3ta4EC/59zMFaTQe2KTcn/@public.gmane.org>
> 
> This is a hold over from before the struct device conversion.
> 
> - All prints should be using &chip->dev, which is the Linux
>   standard. This changes prints to use tpm0 as the device name,
>   not the PnP/etc ID.
> - The few places involving sysfs/modules that really do need the
>   parent just use chip->dev.parent instead
> - We no longer need to get_device(pdev) in any places since it is no
>   longer used by any of the code. The kref on the parent is held
>   by the device core during device_add and dropped in device_del
> 
> Signed-off-by: Jason Gunthorpe <jgunthorpe-ePGOBjL8dl3ta4EC/59zMFaTQe2KTcn/@public.gmane.org>

Reviewed-by: Jarkko Sakkinen <jarkko.sakkinen-VuQAYsv1563Yd54FQh9/CA@public.gmane.org>

There was couple of places where I would adjust identation but that's
not really a major issue (and it passes checkpatch.pl anyway).

> ---
>  drivers/char/tpm/tpm-chip.c         | 15 ++++++---------
>  drivers/char/tpm/tpm-dev.c          |  4 +---
>  drivers/char/tpm/tpm-interface.c    | 30 ++++++++++++++++--------------
>  drivers/char/tpm/tpm-sysfs.c        |  6 +++---
>  drivers/char/tpm/tpm.h              |  3 +--
>  drivers/char/tpm/tpm2-cmd.c         |  8 ++++----
>  drivers/char/tpm/tpm_atmel.c        | 14 +++++++-------
>  drivers/char/tpm/tpm_i2c_atmel.c    | 16 ++++++++--------
>  drivers/char/tpm/tpm_i2c_infineon.c |  6 +++---
>  drivers/char/tpm/tpm_i2c_nuvoton.c  | 22 +++++++++++-----------
>  drivers/char/tpm/tpm_infineon.c     | 22 +++++++++++-----------
>  drivers/char/tpm/tpm_nsc.c          | 20 ++++++++++----------
>  drivers/char/tpm/tpm_tis.c          | 14 +++++++-------
>  13 files changed, 88 insertions(+), 92 deletions(-)
> 
> diff --git a/drivers/char/tpm/tpm-chip.c b/drivers/char/tpm/tpm-chip.c
> index ab32437..5ed9bed 100644
> --- a/drivers/char/tpm/tpm-chip.c
> +++ b/drivers/char/tpm/tpm-chip.c
> @@ -49,7 +49,7 @@ struct tpm_chip *tpm_chip_find_get(int chip_num)
>  		if (chip_num != TPM_ANY_NUM && chip_num != pos->dev_num)
>  			continue;
>  
> -		if (try_module_get(pos->pdev->driver->owner)) {
> +		if (try_module_get(pos->dev.parent->driver->owner)) {
>  			chip = pos;
>  			break;
>  		}
> @@ -113,13 +113,11 @@ struct tpm_chip *tpmm_chip_alloc(struct device *dev,
>  
>  	scnprintf(chip->devname, sizeof(chip->devname), "tpm%d", chip->dev_num);
>  
> -	chip->pdev = dev;
> -
>  	dev_set_drvdata(dev, chip);
>  
>  	chip->dev.class = tpm_class;
>  	chip->dev.release = tpm_dev_release;
> -	chip->dev.parent = chip->pdev;
> +	chip->dev.parent = dev;
>  #ifdef CONFIG_ACPI
>  	chip->dev.groups = chip->groups;
>  #endif
> @@ -134,7 +132,7 @@ struct tpm_chip *tpmm_chip_alloc(struct device *dev,
>  	device_initialize(&chip->dev);
>  
>  	cdev_init(&chip->cdev, &tpm_fops);
> -	chip->cdev.owner = chip->pdev->driver->owner;
> +	chip->cdev.owner = dev->driver->owner;
>  	chip->cdev.kobj.parent = &chip->dev.kobj;
>  
>  	err = devm_add_action(dev, (void (*)(void *)) put_device, &chip->dev);
> @@ -241,9 +239,8 @@ int tpm_chip_register(struct tpm_chip *chip)
>  	chip->flags |= TPM_CHIP_FLAG_REGISTERED;
>  
>  	if (!(chip->flags & TPM_CHIP_FLAG_TPM2)) {
> -		rc = __compat_only_sysfs_link_entry_to_kobj(&chip->pdev->kobj,
> -							    &chip->dev.kobj,
> -							    "ppi");
> +		rc = __compat_only_sysfs_link_entry_to_kobj(
> +		    &chip->dev.parent->kobj, &chip->dev.kobj, "ppi");
>  		if (rc && rc != -ENOENT) {
>  			tpm_chip_unregister(chip);
>  			return rc;
> @@ -278,7 +275,7 @@ void tpm_chip_unregister(struct tpm_chip *chip)
>  	synchronize_rcu();
>  
>  	if (!(chip->flags & TPM_CHIP_FLAG_TPM2))
> -		sysfs_remove_link(&chip->pdev->kobj, "ppi");
> +		sysfs_remove_link(&chip->dev.parent->kobj, "ppi");
>  
>  	tpm1_chip_unregister(chip);
>  	tpm_dev_del_device(chip);
> diff --git a/drivers/char/tpm/tpm-dev.c b/drivers/char/tpm/tpm-dev.c
> index de0337e..4009765 100644
> --- a/drivers/char/tpm/tpm-dev.c
> +++ b/drivers/char/tpm/tpm-dev.c
> @@ -61,7 +61,7 @@ static int tpm_open(struct inode *inode, struct file *file)
>  	 * 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->pdev, "Another process owns this TPM\n");
> +		dev_dbg(&chip->dev, "Another process owns this TPM\n");
>  		return -EBUSY;
>  	}
>  
> @@ -79,7 +79,6 @@ static int tpm_open(struct inode *inode, struct file *file)
>  	INIT_WORK(&priv->work, timeout_work);
>  
>  	file->private_data = priv;
> -	get_device(chip->pdev);
>  	return 0;
>  }
>  
> @@ -166,7 +165,6 @@ static int tpm_release(struct inode *inode, struct file *file)
>  	file->private_data = NULL;
>  	atomic_set(&priv->data_pending, 0);
>  	clear_bit(0, &priv->chip->is_open);
> -	put_device(priv->chip->pdev);
>  	kfree(priv);
>  	return 0;
>  }
> diff --git a/drivers/char/tpm/tpm-interface.c b/drivers/char/tpm/tpm-interface.c
> index c50637d..65dc7fd 100644
> --- a/drivers/char/tpm/tpm-interface.c
> +++ b/drivers/char/tpm/tpm-interface.c
> @@ -343,7 +343,7 @@ ssize_t tpm_transmit(struct tpm_chip *chip, const char *buf,
>  	if (count == 0)
>  		return -ENODATA;
>  	if (count > bufsiz) {
> -		dev_err(chip->pdev,
> +		dev_err(&chip->dev,
>  			"invalid count value %x %zx\n", count, bufsiz);
>  		return -E2BIG;
>  	}
> @@ -352,7 +352,7 @@ ssize_t tpm_transmit(struct tpm_chip *chip, const char *buf,
>  
>  	rc = chip->ops->send(chip, (u8 *) buf, count);
>  	if (rc < 0) {
> -		dev_err(chip->pdev,
> +		dev_err(&chip->dev,
>  			"tpm_transmit: tpm_send: error %zd\n", rc);
>  		goto out;
>  	}
> @@ -371,7 +371,7 @@ ssize_t tpm_transmit(struct tpm_chip *chip, const char *buf,
>  			goto out_recv;
>  
>  		if (chip->ops->req_canceled(chip, status)) {
> -			dev_err(chip->pdev, "Operation Canceled\n");
> +			dev_err(&chip->dev, "Operation Canceled\n");
>  			rc = -ECANCELED;
>  			goto out;
>  		}
> @@ -381,14 +381,14 @@ ssize_t tpm_transmit(struct tpm_chip *chip, const char *buf,
>  	} while (time_before(jiffies, stop));
>  
>  	chip->ops->cancel(chip);
> -	dev_err(chip->pdev, "Operation Timed out\n");
> +	dev_err(&chip->dev, "Operation Timed out\n");
>  	rc = -ETIME;
>  	goto out;
>  
>  out_recv:
>  	rc = chip->ops->recv(chip, (u8 *) buf, bufsiz);
>  	if (rc < 0)
> -		dev_err(chip->pdev,
> +		dev_err(&chip->dev,
>  			"tpm_transmit: tpm_recv: error %zd\n", rc);
>  out:
>  	mutex_unlock(&chip->tpm_mutex);
> @@ -414,7 +414,7 @@ ssize_t tpm_transmit_cmd(struct tpm_chip *chip, void *cmd,
>  
>  	err = be32_to_cpu(header->return_code);
>  	if (err != 0 && desc)
> -		dev_err(chip->pdev, "A TPM error (%d) occurred %s\n", err,
> +		dev_err(&chip->dev, "A TPM error (%d) occurred %s\n", err,
>  			desc);
>  
>  	return err;
> @@ -510,7 +510,7 @@ int tpm_get_timeouts(struct tpm_chip *chip)
>  	if (rc == TPM_ERR_INVALID_POSTINIT) {
>  		/* The TPM is not started, we are the first to talk to it.
>  		   Execute a startup command. */
> -		dev_info(chip->pdev, "Issuing TPM_STARTUP");
> +		dev_info(&chip->dev, "Issuing TPM_STARTUP");
>  		if (tpm_startup(chip, TPM_ST_CLEAR))
>  			return rc;
>  
> @@ -522,7 +522,7 @@ int tpm_get_timeouts(struct tpm_chip *chip)
>  				  NULL);
>  	}
>  	if (rc) {
> -		dev_err(chip->pdev,
> +		dev_err(&chip->dev,
>  			"A TPM error (%zd) occurred attempting to determine the timeouts\n",
>  			rc);
>  		goto duration;
> @@ -561,7 +561,7 @@ int tpm_get_timeouts(struct tpm_chip *chip)
>  
>  	/* Report adjusted timeouts */
>  	if (chip->vendor.timeout_adjusted) {
> -		dev_info(chip->pdev,
> +		dev_info(&chip->dev,
>  			 HW_ERR "Adjusting reported timeouts: A %lu->%luus B %lu->%luus C %lu->%luus D %lu->%luus\n",
>  			 old_timeout[0], new_timeout[0],
>  			 old_timeout[1], new_timeout[1],
> @@ -608,7 +608,7 @@ duration:
>  		chip->vendor.duration[TPM_MEDIUM] *= 1000;
>  		chip->vendor.duration[TPM_LONG] *= 1000;
>  		chip->vendor.duration_adjusted = true;
> -		dev_info(chip->pdev, "Adjusting TPM timeout parameters.");
> +		dev_info(&chip->dev, "Adjusting TPM timeout parameters.");
>  	}
>  	return 0;
>  }
> @@ -798,7 +798,9 @@ int tpm_do_selftest(struct tpm_chip *chip)
>  		 * around 300ms while the self test is ongoing, keep trying
>  		 * until the self test duration expires. */
>  		if (rc == -ETIME) {
> -			dev_info(chip->pdev, HW_ERR "TPM command timed out during continue self test");
> +			dev_info(
> +			    &chip->dev, HW_ERR
> +			    "TPM command timed out during continue self test");
>  			msleep(delay_msec);
>  			continue;
>  		}
> @@ -808,7 +810,7 @@ int tpm_do_selftest(struct tpm_chip *chip)
>  
>  		rc = be32_to_cpu(cmd.header.out.return_code);
>  		if (rc == TPM_ERR_DISABLED || rc == TPM_ERR_DEACTIVATED) {
> -			dev_info(chip->pdev,
> +			dev_info(&chip->dev,
>  				 "TPM is disabled/deactivated (0x%X)\n", rc);
>  			/* TPM is disabled and/or deactivated; driver can
>  			 * proceed and TPM does handle commands for
> @@ -961,10 +963,10 @@ int tpm_pm_suspend(struct device *dev)
>  	}
>  
>  	if (rc)
> -		dev_err(chip->pdev,
> +		dev_err(&chip->dev,
>  			"Error (%d) sending savestate before suspend\n", rc);
>  	else if (try > 0)
> -		dev_warn(chip->pdev, "TPM savestate took %dms\n",
> +		dev_warn(&chip->dev, "TPM savestate took %dms\n",
>  			 try * TPM_TIMEOUT_RETRY);
>  
>  	return rc;
> diff --git a/drivers/char/tpm/tpm-sysfs.c b/drivers/char/tpm/tpm-sysfs.c
> index ee66fd4..d93736a 100644
> --- a/drivers/char/tpm/tpm-sysfs.c
> +++ b/drivers/char/tpm/tpm-sysfs.c
> @@ -284,16 +284,16 @@ static const struct attribute_group tpm_dev_group = {
>  int tpm_sysfs_add_device(struct tpm_chip *chip)
>  {
>  	int err;
> -	err = sysfs_create_group(&chip->pdev->kobj,
> +	err = sysfs_create_group(&chip->dev.parent->kobj,
>  				 &tpm_dev_group);
>  
>  	if (err)
> -		dev_err(chip->pdev,
> +		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->pdev->kobj, &tpm_dev_group);
> +	sysfs_remove_group(&chip->dev.parent->kobj, &tpm_dev_group);
>  }
> diff --git a/drivers/char/tpm/tpm.h b/drivers/char/tpm/tpm.h
> index a4257a3..1ce6547 100644
> --- a/drivers/char/tpm/tpm.h
> +++ b/drivers/char/tpm/tpm.h
> @@ -171,7 +171,6 @@ enum tpm_chip_flags {
>  };
>  
>  struct tpm_chip {
> -	struct device *pdev;	/* Device stuff */
>  	struct device dev;
>  	struct cdev cdev;
>  
> @@ -203,7 +202,7 @@ struct tpm_chip {
>  
>  static inline void tpm_chip_put(struct tpm_chip *chip)
>  {
> -	module_put(chip->pdev->driver->owner);
> +	module_put(chip->dev.parent->driver->owner);
>  }
>  
>  static inline int tpm_read_index(int base, int index)
> diff --git a/drivers/char/tpm/tpm2-cmd.c b/drivers/char/tpm/tpm2-cmd.c
> index c121304..68508d4 100644
> --- a/drivers/char/tpm/tpm2-cmd.c
> +++ b/drivers/char/tpm/tpm2-cmd.c
> @@ -553,7 +553,7 @@ static void tpm2_flush_context(struct tpm_chip *chip, u32 handle)
>  
>  	rc = tpm_buf_init(&buf, TPM2_ST_NO_SESSIONS, TPM2_CC_FLUSH_CONTEXT);
>  	if (rc) {
> -		dev_warn(chip->pdev, "0x%08x was not flushed, out of memory\n",
> +		dev_warn(&chip->dev, "0x%08x was not flushed, out of memory\n",
>  			 handle);
>  		return;
>  	}
> @@ -562,7 +562,7 @@ static void tpm2_flush_context(struct tpm_chip *chip, u32 handle)
>  
>  	rc = tpm_transmit_cmd(chip, buf.data, PAGE_SIZE, "flushing context");
>  	if (rc)
> -		dev_warn(chip->pdev, "0x%08x was not flushed, rc=%d\n", handle,
> +		dev_warn(&chip->dev, "0x%08x was not flushed, rc=%d\n", handle,
>  			 rc);
>  
>  	tpm_buf_destroy(&buf);
> @@ -724,7 +724,7 @@ void tpm2_shutdown(struct tpm_chip *chip, u16 shutdown_type)
>  	 * except print the error code on a system failure.
>  	 */
>  	if (rc < 0)
> -		dev_warn(chip->pdev, "transmit returned %d while stopping the TPM",
> +		dev_warn(&chip->dev, "transmit returned %d while stopping the TPM",
>  			 rc);
>  }
>  EXPORT_SYMBOL_GPL(tpm2_shutdown);
> @@ -791,7 +791,7 @@ static int tpm2_start_selftest(struct tpm_chip *chip, bool full)
>  	 * immediately. This is a workaround for that.
>  	 */
>  	if (rc == TPM2_RC_TESTING) {
> -		dev_warn(chip->pdev, "Got RC_TESTING, ignoring\n");
> +		dev_warn(&chip->dev, "Got RC_TESTING, ignoring\n");
>  		rc = 0;
>  	}
>  
> diff --git a/drivers/char/tpm/tpm_atmel.c b/drivers/char/tpm/tpm_atmel.c
> index dfadad0..a48a878 100644
> --- a/drivers/char/tpm/tpm_atmel.c
> +++ b/drivers/char/tpm/tpm_atmel.c
> @@ -49,7 +49,7 @@ static int tpm_atml_recv(struct tpm_chip *chip, u8 *buf, size_t count)
>  	for (i = 0; i < 6; i++) {
>  		status = ioread8(chip->vendor.iobase + 1);
>  		if ((status & ATML_STATUS_DATA_AVAIL) == 0) {
> -			dev_err(chip->pdev, "error reading header\n");
> +			dev_err(&chip->dev, "error reading header\n");
>  			return -EIO;
>  		}
>  		*buf++ = ioread8(chip->vendor.iobase);
> @@ -60,12 +60,12 @@ static int tpm_atml_recv(struct tpm_chip *chip, u8 *buf, size_t count)
>  	size = be32_to_cpu(*native_size);
>  
>  	if (count < size) {
> -		dev_err(chip->pdev,
> +		dev_err(&chip->dev,
>  			"Recv size(%d) less than available space\n", size);
>  		for (; i < size; i++) {	/* clear the waiting data anyway */
>  			status = ioread8(chip->vendor.iobase + 1);
>  			if ((status & ATML_STATUS_DATA_AVAIL) == 0) {
> -				dev_err(chip->pdev, "error reading data\n");
> +				dev_err(&chip->dev, "error reading data\n");
>  				return -EIO;
>  			}
>  		}
> @@ -76,7 +76,7 @@ static int tpm_atml_recv(struct tpm_chip *chip, u8 *buf, size_t count)
>  	for (; i < size; i++) {
>  		status = ioread8(chip->vendor.iobase + 1);
>  		if ((status & ATML_STATUS_DATA_AVAIL) == 0) {
> -			dev_err(chip->pdev, "error reading data\n");
> +			dev_err(&chip->dev, "error reading data\n");
>  			return -EIO;
>  		}
>  		*buf++ = ioread8(chip->vendor.iobase);
> @@ -86,7 +86,7 @@ static int tpm_atml_recv(struct tpm_chip *chip, u8 *buf, size_t count)
>  	status = ioread8(chip->vendor.iobase + 1);
>  
>  	if (status & ATML_STATUS_DATA_AVAIL) {
> -		dev_err(chip->pdev, "data available is stuck\n");
> +		dev_err(&chip->dev, "data available is stuck\n");
>  		return -EIO;
>  	}
>  
> @@ -97,9 +97,9 @@ static int tpm_atml_send(struct tpm_chip *chip, u8 *buf, size_t count)
>  {
>  	int i;
>  
> -	dev_dbg(chip->pdev, "tpm_atml_send:\n");
> +	dev_dbg(&chip->dev, "tpm_atml_send:\n");
>  	for (i = 0; i < count; i++) {
> -		dev_dbg(chip->pdev, "%d 0x%x(%d)\n",  i, buf[i], buf[i]);
> +		dev_dbg(&chip->dev, "%d 0x%x(%d)\n",  i, buf[i], buf[i]);
>   		iowrite8(buf[i], chip->vendor.iobase);
>  	}
>  
> diff --git a/drivers/char/tpm/tpm_i2c_atmel.c b/drivers/char/tpm/tpm_i2c_atmel.c
> index 8dfb88b..dd8f0eb 100644
> --- a/drivers/char/tpm/tpm_i2c_atmel.c
> +++ b/drivers/char/tpm/tpm_i2c_atmel.c
> @@ -52,7 +52,7 @@ struct priv_data {
>  static int i2c_atmel_send(struct tpm_chip *chip, u8 *buf, size_t len)
>  {
>  	struct priv_data *priv = chip->vendor.priv;
> -	struct i2c_client *client = to_i2c_client(chip->pdev);
> +	struct i2c_client *client = to_i2c_client(chip->dev.parent);
>  	s32 status;
>  
>  	priv->len = 0;
> @@ -62,7 +62,7 @@ static int i2c_atmel_send(struct tpm_chip *chip, u8 *buf, size_t len)
>  
>  	status = i2c_master_send(client, buf, len);
>  
> -	dev_dbg(chip->pdev,
> +	dev_dbg(&chip->dev,
>  		"%s(buf=%*ph len=%0zx) -> sts=%d\n", __func__,
>  		(int)min_t(size_t, 64, len), buf, len, status);
>  	return status;
> @@ -71,7 +71,7 @@ static int i2c_atmel_send(struct tpm_chip *chip, u8 *buf, size_t len)
>  static int i2c_atmel_recv(struct tpm_chip *chip, u8 *buf, size_t count)
>  {
>  	struct priv_data *priv = chip->vendor.priv;
> -	struct i2c_client *client = to_i2c_client(chip->pdev);
> +	struct i2c_client *client = to_i2c_client(chip->dev.parent);
>  	struct tpm_output_header *hdr =
>  		(struct tpm_output_header *)priv->buffer;
>  	u32 expected_len;
> @@ -88,7 +88,7 @@ static int i2c_atmel_recv(struct tpm_chip *chip, u8 *buf, size_t count)
>  		return -ENOMEM;
>  
>  	if (priv->len >= expected_len) {
> -		dev_dbg(chip->pdev,
> +		dev_dbg(&chip->dev,
>  			"%s early(buf=%*ph count=%0zx) -> ret=%d\n", __func__,
>  			(int)min_t(size_t, 64, expected_len), buf, count,
>  			expected_len);
> @@ -97,7 +97,7 @@ static int i2c_atmel_recv(struct tpm_chip *chip, u8 *buf, size_t count)
>  	}
>  
>  	rc = i2c_master_recv(client, buf, expected_len);
> -	dev_dbg(chip->pdev,
> +	dev_dbg(&chip->dev,
>  		"%s reread(buf=%*ph count=%0zx) -> ret=%d\n", __func__,
>  		(int)min_t(size_t, 64, expected_len), buf, count,
>  		expected_len);
> @@ -106,13 +106,13 @@ static int i2c_atmel_recv(struct tpm_chip *chip, u8 *buf, size_t count)
>  
>  static void i2c_atmel_cancel(struct tpm_chip *chip)
>  {
> -	dev_err(chip->pdev, "TPM operation cancellation was requested, but is not supported");
> +	dev_err(&chip->dev, "TPM operation cancellation was requested, but is not supported");
>  }
>  
>  static u8 i2c_atmel_read_status(struct tpm_chip *chip)
>  {
>  	struct priv_data *priv = chip->vendor.priv;
> -	struct i2c_client *client = to_i2c_client(chip->pdev);
> +	struct i2c_client *client = to_i2c_client(chip->dev.parent);
>  	int rc;
>  
>  	/* The TPM fails the I2C read until it is ready, so we do the entire
> @@ -125,7 +125,7 @@ static u8 i2c_atmel_read_status(struct tpm_chip *chip)
>  	/* Once the TPM has completed the command the command remains readable
>  	 * until another command is issued. */
>  	rc = i2c_master_recv(client, priv->buffer, sizeof(priv->buffer));
> -	dev_dbg(chip->pdev,
> +	dev_dbg(&chip->dev,
>  		"%s: sts=%d", __func__, rc);
>  	if (rc <= 0)
>  		return 0;
> diff --git a/drivers/char/tpm/tpm_i2c_infineon.c b/drivers/char/tpm/tpm_i2c_infineon.c
> index 63d5d22..f2aa99e 100644
> --- a/drivers/char/tpm/tpm_i2c_infineon.c
> +++ b/drivers/char/tpm/tpm_i2c_infineon.c
> @@ -446,7 +446,7 @@ static int tpm_tis_i2c_recv(struct tpm_chip *chip, u8 *buf, size_t count)
>  	/* read first 10 bytes, including tag, paramsize, and result */
>  	size = recv_data(chip, buf, TPM_HEADER_SIZE);
>  	if (size < TPM_HEADER_SIZE) {
> -		dev_err(chip->pdev, "Unable to read header\n");
> +		dev_err(&chip->dev, "Unable to read header\n");
>  		goto out;
>  	}
>  
> @@ -459,14 +459,14 @@ static int tpm_tis_i2c_recv(struct tpm_chip *chip, u8 *buf, size_t count)
>  	size += recv_data(chip, &buf[TPM_HEADER_SIZE],
>  			  expected - TPM_HEADER_SIZE);
>  	if (size < expected) {
> -		dev_err(chip->pdev, "Unable to read remainder of result\n");
> +		dev_err(&chip->dev, "Unable to read remainder of result\n");
>  		size = -ETIME;
>  		goto out;
>  	}
>  
>  	wait_for_stat(chip, TPM_STS_VALID, chip->vendor.timeout_c, &status);
>  	if (status & TPM_STS_DATA_AVAIL) {	/* retry? */
> -		dev_err(chip->pdev, "Error left over data\n");
> +		dev_err(&chip->dev, "Error left over data\n");
>  		size = -EIO;
>  		goto out;
>  	}
> diff --git a/drivers/char/tpm/tpm_i2c_nuvoton.c b/drivers/char/tpm/tpm_i2c_nuvoton.c
> index 847f159..a1e1474 100644
> --- a/drivers/char/tpm/tpm_i2c_nuvoton.c
> +++ b/drivers/char/tpm/tpm_i2c_nuvoton.c
> @@ -96,13 +96,13 @@ static s32 i2c_nuvoton_write_buf(struct i2c_client *client, u8 offset, u8 size,
>  /* read TPM_STS register */
>  static u8 i2c_nuvoton_read_status(struct tpm_chip *chip)
>  {
> -	struct i2c_client *client = to_i2c_client(chip->pdev);
> +	struct i2c_client *client = to_i2c_client(chip->dev.parent);
>  	s32 status;
>  	u8 data;
>  
>  	status = i2c_nuvoton_read_buf(client, TPM_STS, 1, &data);
>  	if (status <= 0) {
> -		dev_err(chip->pdev, "%s() error return %d\n", __func__,
> +		dev_err(&chip->dev, "%s() error return %d\n", __func__,
>  			status);
>  		data = TPM_STS_ERR_VAL;
>  	}
> @@ -127,13 +127,13 @@ static s32 i2c_nuvoton_write_status(struct i2c_client *client, u8 data)
>  /* write commandReady to TPM_STS register */
>  static void i2c_nuvoton_ready(struct tpm_chip *chip)
>  {
> -	struct i2c_client *client = to_i2c_client(chip->pdev);
> +	struct i2c_client *client = to_i2c_client(chip->dev.parent);
>  	s32 status;
>  
>  	/* this causes the current command to be aborted */
>  	status = i2c_nuvoton_write_status(client, TPM_STS_COMMAND_READY);
>  	if (status < 0)
> -		dev_err(chip->pdev,
> +		dev_err(&chip->dev,
>  			"%s() fail to write TPM_STS.commandReady\n", __func__);
>  }
>  
> @@ -212,7 +212,7 @@ static int i2c_nuvoton_wait_for_stat(struct tpm_chip *chip, u8 mask, u8 value,
>  				return 0;
>  		} while (time_before(jiffies, stop));
>  	}
> -	dev_err(chip->pdev, "%s(%02x, %02x) -> timeout\n", __func__, mask,
> +	dev_err(&chip->dev, "%s(%02x, %02x) -> timeout\n", __func__, mask,
>  		value);
>  	return -ETIMEDOUT;
>  }
> @@ -240,7 +240,7 @@ static int i2c_nuvoton_recv_data(struct i2c_client *client,
>  					       &chip->vendor.read_queue) == 0) {
>  		burst_count = i2c_nuvoton_get_burstcount(client, chip);
>  		if (burst_count < 0) {
> -			dev_err(chip->pdev,
> +			dev_err(&chip->dev,
>  				"%s() fail to read burstCount=%d\n", __func__,
>  				burst_count);
>  			return -EIO;
> @@ -249,12 +249,12 @@ static int i2c_nuvoton_recv_data(struct i2c_client *client,
>  		rc = i2c_nuvoton_read_buf(client, TPM_DATA_FIFO_R,
>  					  bytes2read, &buf[size]);
>  		if (rc < 0) {
> -			dev_err(chip->pdev,
> +			dev_err(&chip->dev,
>  				"%s() fail on i2c_nuvoton_read_buf()=%d\n",
>  				__func__, rc);
>  			return -EIO;
>  		}
> -		dev_dbg(chip->pdev, "%s(%d):", __func__, bytes2read);
> +		dev_dbg(&chip->dev, "%s(%d):", __func__, bytes2read);
>  		size += bytes2read;
>  	}
>  
> @@ -264,7 +264,7 @@ static int i2c_nuvoton_recv_data(struct i2c_client *client,
>  /* Read TPM command results */
>  static int i2c_nuvoton_recv(struct tpm_chip *chip, u8 *buf, size_t count)
>  {
> -	struct device *dev = chip->pdev;
> +	struct device *dev = chip->dev.parent;
>  	struct i2c_client *client = to_i2c_client(dev);
>  	s32 rc;
>  	int expected, status, burst_count, retries, size = 0;
> @@ -334,7 +334,7 @@ static int i2c_nuvoton_recv(struct tpm_chip *chip, u8 *buf, size_t count)
>  		break;
>  	}
>  	i2c_nuvoton_ready(chip);
> -	dev_dbg(chip->pdev, "%s() -> %d\n", __func__, size);
> +	dev_dbg(&chip->dev, "%s() -> %d\n", __func__, size);
>  	return size;
>  }
>  
> @@ -347,7 +347,7 @@ static int i2c_nuvoton_recv(struct tpm_chip *chip, u8 *buf, size_t count)
>   */
>  static int i2c_nuvoton_send(struct tpm_chip *chip, u8 *buf, size_t len)
>  {
> -	struct device *dev = chip->pdev;
> +	struct device *dev = chip->dev.parent;
>  	struct i2c_client *client = to_i2c_client(dev);
>  	u32 ordinal;
>  	size_t count = 0;
> diff --git a/drivers/char/tpm/tpm_infineon.c b/drivers/char/tpm/tpm_infineon.c
> index 6c488e6..e3cf9f3 100644
> --- a/drivers/char/tpm/tpm_infineon.c
> +++ b/drivers/char/tpm/tpm_infineon.c
> @@ -195,9 +195,9 @@ static int wait(struct tpm_chip *chip, int wait_for_bit)
>  	}
>  	if (i == TPM_MAX_TRIES) {	/* timeout occurs */
>  		if (wait_for_bit == STAT_XFE)
> -			dev_err(chip->pdev, "Timeout in wait(STAT_XFE)\n");
> +			dev_err(&chip->dev, "Timeout in wait(STAT_XFE)\n");
>  		if (wait_for_bit == STAT_RDA)
> -			dev_err(chip->pdev, "Timeout in wait(STAT_RDA)\n");
> +			dev_err(&chip->dev, "Timeout in wait(STAT_RDA)\n");
>  		return -EIO;
>  	}
>  	return 0;
> @@ -220,7 +220,7 @@ static void wait_and_send(struct tpm_chip *chip, u8 sendbyte)
>  static void tpm_wtx(struct tpm_chip *chip)
>  {
>  	number_of_wtx++;
> -	dev_info(chip->pdev, "Granting WTX (%02d / %02d)\n",
> +	dev_info(&chip->dev, "Granting WTX (%02d / %02d)\n",
>  		 number_of_wtx, TPM_MAX_WTX_PACKAGES);
>  	wait_and_send(chip, TPM_VL_VER);
>  	wait_and_send(chip, TPM_CTRL_WTX);
> @@ -231,7 +231,7 @@ static void tpm_wtx(struct tpm_chip *chip)
>  
>  static void tpm_wtx_abort(struct tpm_chip *chip)
>  {
> -	dev_info(chip->pdev, "Aborting WTX\n");
> +	dev_info(&chip->dev, "Aborting WTX\n");
>  	wait_and_send(chip, TPM_VL_VER);
>  	wait_and_send(chip, TPM_CTRL_WTX_ABORT);
>  	wait_and_send(chip, 0x00);
> @@ -257,7 +257,7 @@ recv_begin:
>  	}
>  
>  	if (buf[0] != TPM_VL_VER) {
> -		dev_err(chip->pdev,
> +		dev_err(&chip->dev,
>  			"Wrong transport protocol implementation!\n");
>  		return -EIO;
>  	}
> @@ -272,7 +272,7 @@ recv_begin:
>  		}
>  
>  		if ((size == 0x6D00) && (buf[1] == 0x80)) {
> -			dev_err(chip->pdev, "Error handling on vendor layer!\n");
> +			dev_err(&chip->dev, "Error handling on vendor layer!\n");
>  			return -EIO;
>  		}
>  
> @@ -284,7 +284,7 @@ recv_begin:
>  	}
>  
>  	if (buf[1] == TPM_CTRL_WTX) {
> -		dev_info(chip->pdev, "WTX-package received\n");
> +		dev_info(&chip->dev, "WTX-package received\n");
>  		if (number_of_wtx < TPM_MAX_WTX_PACKAGES) {
>  			tpm_wtx(chip);
>  			goto recv_begin;
> @@ -295,14 +295,14 @@ recv_begin:
>  	}
>  
>  	if (buf[1] == TPM_CTRL_WTX_ABORT_ACK) {
> -		dev_info(chip->pdev, "WTX-abort acknowledged\n");
> +		dev_info(&chip->dev, "WTX-abort acknowledged\n");
>  		return size;
>  	}
>  
>  	if (buf[1] == TPM_CTRL_ERROR) {
> -		dev_err(chip->pdev, "ERROR-package received:\n");
> +		dev_err(&chip->dev, "ERROR-package received:\n");
>  		if (buf[4] == TPM_INF_NAK)
> -			dev_err(chip->pdev,
> +			dev_err(&chip->dev,
>  				"-> Negative acknowledgement"
>  				" - retransmit command!\n");
>  		return -EIO;
> @@ -321,7 +321,7 @@ static int tpm_inf_send(struct tpm_chip *chip, u8 * buf, size_t count)
>  
>  	ret = empty_fifo(chip, 1);
>  	if (ret) {
> -		dev_err(chip->pdev, "Timeout while clearing FIFO\n");
> +		dev_err(&chip->dev, "Timeout while clearing FIFO\n");
>  		return -EIO;
>  	}
>  
> diff --git a/drivers/char/tpm/tpm_nsc.c b/drivers/char/tpm/tpm_nsc.c
> index 289389e..766370b 100644
> --- a/drivers/char/tpm/tpm_nsc.c
> +++ b/drivers/char/tpm/tpm_nsc.c
> @@ -113,7 +113,7 @@ static int nsc_wait_for_ready(struct tpm_chip *chip)
>  	}
>  	while (time_before(jiffies, stop));
>  
> -	dev_info(chip->pdev, "wait for ready failed\n");
> +	dev_info(&chip->dev, "wait for ready failed\n");
>  	return -EBUSY;
>  }
>  
> @@ -129,12 +129,12 @@ static int tpm_nsc_recv(struct tpm_chip *chip, u8 * buf, size_t count)
>  		return -EIO;
>  
>  	if (wait_for_stat(chip, NSC_STATUS_F0, NSC_STATUS_F0, &data) < 0) {
> -		dev_err(chip->pdev, "F0 timeout\n");
> +		dev_err(&chip->dev, "F0 timeout\n");
>  		return -EIO;
>  	}
>  	if ((data =
>  	     inb(chip->vendor.base + NSC_DATA)) != NSC_COMMAND_NORMAL) {
> -		dev_err(chip->pdev, "not in normal mode (0x%x)\n",
> +		dev_err(&chip->dev, "not in normal mode (0x%x)\n",
>  			data);
>  		return -EIO;
>  	}
> @@ -143,7 +143,7 @@ static int tpm_nsc_recv(struct tpm_chip *chip, u8 * buf, size_t count)
>  	for (p = buffer; p < &buffer[count]; p++) {
>  		if (wait_for_stat
>  		    (chip, NSC_STATUS_OBF, NSC_STATUS_OBF, &data) < 0) {
> -			dev_err(chip->pdev,
> +			dev_err(&chip->dev,
>  				"OBF timeout (while reading data)\n");
>  			return -EIO;
>  		}
> @@ -154,11 +154,11 @@ static int tpm_nsc_recv(struct tpm_chip *chip, u8 * buf, size_t count)
>  
>  	if ((data & NSC_STATUS_F0) == 0 &&
>  	(wait_for_stat(chip, NSC_STATUS_F0, NSC_STATUS_F0, &data) < 0)) {
> -		dev_err(chip->pdev, "F0 not set\n");
> +		dev_err(&chip->dev, "F0 not set\n");
>  		return -EIO;
>  	}
>  	if ((data = inb(chip->vendor.base + NSC_DATA)) != NSC_COMMAND_EOC) {
> -		dev_err(chip->pdev,
> +		dev_err(&chip->dev,
>  			"expected end of command(0x%x)\n", data);
>  		return -EIO;
>  	}
> @@ -189,19 +189,19 @@ static int tpm_nsc_send(struct tpm_chip *chip, u8 * buf, size_t count)
>  		return -EIO;
>  
>  	if (wait_for_stat(chip, NSC_STATUS_IBF, 0, &data) < 0) {
> -		dev_err(chip->pdev, "IBF timeout\n");
> +		dev_err(&chip->dev, "IBF timeout\n");
>  		return -EIO;
>  	}
>  
>  	outb(NSC_COMMAND_NORMAL, chip->vendor.base + NSC_COMMAND);
>  	if (wait_for_stat(chip, NSC_STATUS_IBR, NSC_STATUS_IBR, &data) < 0) {
> -		dev_err(chip->pdev, "IBR timeout\n");
> +		dev_err(&chip->dev, "IBR timeout\n");
>  		return -EIO;
>  	}
>  
>  	for (i = 0; i < count; i++) {
>  		if (wait_for_stat(chip, NSC_STATUS_IBF, 0, &data) < 0) {
> -			dev_err(chip->pdev,
> +			dev_err(&chip->dev,
>  				"IBF timeout (while writing data)\n");
>  			return -EIO;
>  		}
> @@ -209,7 +209,7 @@ static int tpm_nsc_send(struct tpm_chip *chip, u8 * buf, size_t count)
>  	}
>  
>  	if (wait_for_stat(chip, NSC_STATUS_IBF, 0, &data) < 0) {
> -		dev_err(chip->pdev, "IBF timeout\n");
> +		dev_err(&chip->dev, "IBF timeout\n");
>  		return -EIO;
>  	}
>  	outb(NSC_COMMAND_EOC, chip->vendor.base + NSC_COMMAND);
> diff --git a/drivers/char/tpm/tpm_tis.c b/drivers/char/tpm/tpm_tis.c
> index 65f7eec..0b5fc41 100644
> --- a/drivers/char/tpm/tpm_tis.c
> +++ b/drivers/char/tpm/tpm_tis.c
> @@ -293,7 +293,7 @@ static int tpm_tis_recv(struct tpm_chip *chip, u8 *buf, size_t count)
>  	/* read first 10 bytes, including tag, paramsize, and result */
>  	if ((size =
>  	     recv_data(chip, buf, TPM_HEADER_SIZE)) < TPM_HEADER_SIZE) {
> -		dev_err(chip->pdev, "Unable to read header\n");
> +		dev_err(&chip->dev, "Unable to read header\n");
>  		goto out;
>  	}
>  
> @@ -306,7 +306,7 @@ static int tpm_tis_recv(struct tpm_chip *chip, u8 *buf, size_t count)
>  	if ((size +=
>  	     recv_data(chip, &buf[TPM_HEADER_SIZE],
>  		       expected - TPM_HEADER_SIZE)) < expected) {
> -		dev_err(chip->pdev, "Unable to read remainder of result\n");
> +		dev_err(&chip->dev, "Unable to read remainder of result\n");
>  		size = -ETIME;
>  		goto out;
>  	}
> @@ -315,7 +315,7 @@ static int tpm_tis_recv(struct tpm_chip *chip, u8 *buf, size_t count)
>  			  &chip->vendor.int_queue, false);
>  	status = tpm_tis_status(chip);
>  	if (status & TPM_STS_DATA_AVAIL) {	/* retry? */
> -		dev_err(chip->pdev, "Error left over data\n");
> +		dev_err(&chip->dev, "Error left over data\n");
>  		size = -EIO;
>  		goto out;
>  	}
> @@ -463,7 +463,7 @@ static int tpm_tis_send(struct tpm_chip *chip, u8 *buf, size_t len)
>  		msleep(1);
>  	if (!priv->irq_tested) {
>  		disable_interrupts(chip);
> -		dev_err(chip->pdev,
> +		dev_err(&chip->dev,
>  			FW_BUG "TPM interrupt not working, polling instead\n");
>  	}
>  	priv->irq_tested = true;
> @@ -533,7 +533,7 @@ static int probe_itpm(struct tpm_chip *chip)
>  
>  	rc = tpm_tis_send_data(chip, cmd_getticks, len);
>  	if (rc == 0) {
> -		dev_info(chip->pdev, "Detected an iTPM.\n");
> +		dev_info(&chip->dev, "Detected an iTPM.\n");
>  		rc = 1;
>  	} else
>  		rc = -EFAULT;
> @@ -766,7 +766,7 @@ static int tpm_tis_init(struct device *dev, struct tpm_info *tpm_info,
>  			if (devm_request_irq
>  			    (dev, i, tis_int_probe, IRQF_SHARED,
>  			     chip->devname, chip) != 0) {
> -				dev_info(chip->pdev,
> +				dev_info(&chip->dev,
>  					 "Unable to request irq: %d for probe\n",
>  					 i);
>  				continue;
> @@ -818,7 +818,7 @@ static int tpm_tis_init(struct device *dev, struct tpm_info *tpm_info,
>  		if (devm_request_irq
>  		    (dev, chip->vendor.irq, tis_int_handler, IRQF_SHARED,
>  		     chip->devname, chip) != 0) {
> -			dev_info(chip->pdev,
> +			dev_info(&chip->dev,
>  				 "Unable to request irq: %d for use\n",
>  				 chip->vendor.irq);
>  			chip->vendor.irq = 0;
> -- 
> 2.4.3
> 

------------------------------------------------------------------------------
Site24x7 APM Insight: Get Deep Visibility into Application Performance
APM + Mobile APM + RUM: Monitor 3 App instances at just $35/Month
Monitor end-to-end web transactions and take corrective actions now
Troubleshoot faster and improve end-user experience. Signup Now!
http://pubads.g.doubleclick.net/gampad/clk?id=272487151&iu=/4140

^ permalink raw reply	[flat|nested] 60+ messages in thread

* Re: [PATCH v3 09/11] tpm: Driver for supporting multiple emulated TPMs
       [not found]     ` <1455885728-10315-10-git-send-email-stefanb-23VcF4HTsmIX0ybBhKVfKdBPR1lH4CV8@public.gmane.org>
@ 2016-02-22 19:27       ` Jason Gunthorpe
       [not found]         ` <20160222192741.GI22088-ePGOBjL8dl3ta4EC/59zMFaTQe2KTcn/@public.gmane.org>
       [not found]         ` <201602230142.u1N1gSuF029481@d01av05.pok.ibm.com>
  2016-02-23 10:22       ` Jarkko Sakkinen
  1 sibling, 2 replies; 60+ messages in thread
From: Jason Gunthorpe @ 2016-02-22 19:27 UTC (permalink / raw)
  To: Stefan Berger; +Cc: tpmdd-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f

On Fri, Feb 19, 2016 at 07:42:06AM -0500, Stefan Berger wrote:

> +#define VTPM_NUM_DEVICES TPM_NUM_DEVICES

Never used

> +	rc = copy_to_user(buf, vtpm_dev->buffer, len);
> +	memset(vtpm_dev->buffer, 0, len);
> +	vtpm_dev->req_len = 0;
> +
> +	spin_unlock(&vtpm_dev->buf_lock);

No, do not call copy_to_user in a spin lock, (or copy_from_user)

> +	chip->vendor.irq = 1;

Do not set this, I am trying to remove it..

Overall, I think everything has turned out very nice indeed.

Jason

------------------------------------------------------------------------------
Site24x7 APM Insight: Get Deep Visibility into Application Performance
APM + Mobile APM + RUM: Monitor 3 App instances at just $35/Month
Monitor end-to-end web transactions and take corrective actions now
Troubleshoot faster and improve end-user experience. Signup Now!
http://pubads.g.doubleclick.net/gampad/clk?id=272487151&iu=/4140

^ permalink raw reply	[flat|nested] 60+ messages in thread

* Re: [PATCH v3 03/11] tpm: Get rid of devname
       [not found]         ` <20160222181929.GB22088-ePGOBjL8dl3ta4EC/59zMFaTQe2KTcn/@public.gmane.org>
@ 2016-02-22 19:42           ` Jarkko Sakkinen
       [not found]             ` <20160222194202.GC32667-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
  2016-02-23  0:22           ` Stefan Berger
  1 sibling, 1 reply; 60+ messages in thread
From: Jarkko Sakkinen @ 2016-02-22 19:42 UTC (permalink / raw)
  To: Jason Gunthorpe; +Cc: tpmdd-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f

On Mon, Feb 22, 2016 at 11:19:29AM -0700, Jason Gunthorpe wrote:
> On Fri, Feb 19, 2016 at 07:42:00AM -0500, Stefan Berger wrote:
> >  
> > -	dev_set_name(&chip->dev, "%s", chip->devname);
> > +	err = dev_set_name(&chip->dev, "tpm%d", chip->dev_num);
> > +	if (err)
> > +		goto out;
> >  
> >  	device_initialize(&chip->dev);
> >  
> > @@ -142,6 +142,10 @@ struct tpm_chip *tpmm_chip_alloc(struct device *dev,
> >  	}
> >  
> >  	return chip;
> > +
> > +out:
> > +	put_device(&chip->dev);
> > +	return ERR_PTR(err);
> 
> Oops, something went wrong here in all the rebasing - dev_set_name has
> to be after devince_initialize.

Why dev_set_name() cannot be called before device_initialize(). I see
many drivers call it before device_register() like RTC driver just as
an example:

http://lxr.free-electrons.com/source/drivers/rtc/class.c?v4.4#L226

If the call order is wrong, shouldn't fix for the call order be a
separate patch?

> Jason

/Jarkko

------------------------------------------------------------------------------
Site24x7 APM Insight: Get Deep Visibility into Application Performance
APM + Mobile APM + RUM: Monitor 3 App instances at just $35/Month
Monitor end-to-end web transactions and take corrective actions now
Troubleshoot faster and improve end-user experience. Signup Now!
http://pubads.g.doubleclick.net/gampad/clk?id=272487151&iu=/4140

^ permalink raw reply	[flat|nested] 60+ messages in thread

* Re: [PATCH v3 03/11] tpm: Get rid of devname
       [not found]             ` <20160222194202.GC32667-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
@ 2016-02-22 19:58               ` Jason Gunthorpe
       [not found]                 ` <20160222195816.GL22088-ePGOBjL8dl3ta4EC/59zMFaTQe2KTcn/@public.gmane.org>
  0 siblings, 1 reply; 60+ messages in thread
From: Jason Gunthorpe @ 2016-02-22 19:58 UTC (permalink / raw)
  To: Jarkko Sakkinen; +Cc: tpmdd-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f

On Mon, Feb 22, 2016 at 09:42:02PM +0200, Jarkko Sakkinen wrote:
> > Oops, something went wrong here in all the rebasing - dev_set_name has
> > to be after devince_initialize.
> 
> Why dev_set_name() cannot be called before device_initialize(). I see
> many drivers call it before device_register() like RTC driver just as
> an example:

Yep, you are right, it still looks nicer with the init earlier, but
the later patch does that anyhow.

Jason

------------------------------------------------------------------------------
Site24x7 APM Insight: Get Deep Visibility into Application Performance
APM + Mobile APM + RUM: Monitor 3 App instances at just $35/Month
Monitor end-to-end web transactions and take corrective actions now
Troubleshoot faster and improve end-user experience. Signup Now!
http://pubads.g.doubleclick.net/gampad/clk?id=272487151&iu=/4140

^ permalink raw reply	[flat|nested] 60+ messages in thread

* Re: [PATCH v3 03/11] tpm: Get rid of devname
       [not found]                 ` <20160222195816.GL22088-ePGOBjL8dl3ta4EC/59zMFaTQe2KTcn/@public.gmane.org>
@ 2016-02-22 20:34                   ` Jason Gunthorpe
  0 siblings, 0 replies; 60+ messages in thread
From: Jason Gunthorpe @ 2016-02-22 20:34 UTC (permalink / raw)
  To: Jarkko Sakkinen; +Cc: tpmdd-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f

On Mon, Feb 22, 2016 at 12:58:16PM -0700, Jason Gunthorpe wrote:
> On Mon, Feb 22, 2016 at 09:42:02PM +0200, Jarkko Sakkinen wrote:
> > > Oops, something went wrong here in all the rebasing - dev_set_name has
> > > to be after devince_initialize.
> > 
> > Why dev_set_name() cannot be called before device_initialize(). I see
> > many drivers call it before device_register() like RTC driver just as
> > an example:
> 
> Yep, you are right, it still looks nicer with the init earlier, but
> the later patch does that anyhow.

Sorry, to be clear, the dev_set_name is OK, but the error unwind for
it in this patch is not OK, it requires device_initialize to have been
called.

The change should still be made..

Jason

------------------------------------------------------------------------------
Site24x7 APM Insight: Get Deep Visibility into Application Performance
APM + Mobile APM + RUM: Monitor 3 App instances at just $35/Month
Monitor end-to-end web transactions and take corrective actions now
Troubleshoot faster and improve end-user experience. Signup Now!
http://pubads.g.doubleclick.net/gampad/clk?id=272487151&iu=/4140

^ permalink raw reply	[flat|nested] 60+ messages in thread

* Re: [PATCH v3 04/11] tpm: Provide strong locking for device removal
       [not found]     ` <1455885728-10315-5-git-send-email-stefanb-23VcF4HTsmIX0ybBhKVfKdBPR1lH4CV8@public.gmane.org>
@ 2016-02-22 21:08       ` Jarkko Sakkinen
       [not found]         ` <20160222210844.GA3310-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
  0 siblings, 1 reply; 60+ messages in thread
From: Jarkko Sakkinen @ 2016-02-22 21:08 UTC (permalink / raw)
  To: Stefan Berger; +Cc: tpmdd-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f

On Fri, Feb 19, 2016 at 07:42:01AM -0500, Stefan Berger wrote:
> From: Jason Gunthorpe <jgunthorpe-ePGOBjL8dl3ta4EC/59zMFaTQe2KTcn/@public.gmane.org>
> 
> Add a read/write semaphore around the ops function pointers so
> ops can be set to null when the driver un-registers.
> 
> Previously the tpm core expected module locking to be enough to
> ensure that tpm_unregister could not be called during certain times,
> however that hasn't been sufficient for a long time.

Could you be more concrete with the scenario? You could describe
a sequence of events where this could happen.

> Introduce a read/write semaphore around 'ops' so the core can set
> it to null when unregistering. This provides a strong fence around
> the driver callbacks, guaranteeing to the driver that no callbacks
> are running or will run again.
> 
> For now the ops_lock is placed very high in the call stack, it could
> be pushed down and made more granular in future if necessary.

Makes perfect sense. Fine-tuning performance is not a high priority goal
at this point of time.

> 
> Signed-off-by: Jason Gunthorpe <jgunthorpe-ePGOBjL8dl3ta4EC/59zMFaTQe2KTcn/@public.gmane.org>
> ---
>  drivers/char/tpm/tpm-chip.c      | 71 ++++++++++++++++++++++++++++++++++++----
>  drivers/char/tpm/tpm-dev.c       | 11 ++++++-
>  drivers/char/tpm/tpm-interface.c | 18 +++++-----
>  drivers/char/tpm/tpm-sysfs.c     |  5 +++
>  drivers/char/tpm/tpm.h           | 14 +++++---
>  5 files changed, 98 insertions(+), 21 deletions(-)
> 
> diff --git a/drivers/char/tpm/tpm-chip.c b/drivers/char/tpm/tpm-chip.c
> index 5df0149..0561400 100644
> --- a/drivers/char/tpm/tpm-chip.c
> +++ b/drivers/char/tpm/tpm-chip.c
> @@ -36,10 +36,60 @@ static DEFINE_SPINLOCK(driver_lock);
>  struct class *tpm_class;
>  dev_t tpm_devt;
>  
> -/*
> - * tpm_chip_find_get - return tpm_chip for a given chip number
> - * @chip_num the device number for the chip
> +/**
> + * tpm_try_get_ops() - Get a ref to the tpm_chip
> + * @chip: Chip to ref
> + *
> + * The caller must already have some kind of locking to ensure that chip is

What do you mean when you use the term "some kind of locking"?

> + * valid. This function will lock the chip so that the ops member can be
> + * accessed safely. The locking prevents tpm_chip_unregister from
> + * completing, so it should not be held for long periods.
> + *
> + * Returns -ERRNO if the chip could not be got.
>   */
> +int tpm_try_get_ops(struct tpm_chip *chip)
> +{
> +	int rc = -EIO;
> +
> +	get_device(&chip->dev);
> +
> +	down_read(&chip->ops_sem);
> +	if (!chip->ops)
> +		goto out_lock;
> +
> +	if (!try_module_get(chip->dev.parent->driver->owner))
> +		goto out_lock;
> +
> +	return 0;
> +out_lock:
> +	up_read(&chip->ops_sem);
> +	put_device(&chip->dev);
> +	return rc;
> +}
> +EXPORT_SYMBOL_GPL(tpm_try_get_ops);
> +
> +/**
> + * tpm_put_ops() - Release a ref to the tpm_chip
> + * @chip: Chip to put
> + *
> + * This is the opposite pair to tpm_try_get_ops(). After this returns chip may
> + * be kfree'd.
> + */
> +void tpm_put_ops(struct tpm_chip *chip)
> +{
> +	module_put(chip->dev.parent->driver->owner);
> +	up_read(&chip->ops_sem);
> +	put_device(&chip->dev);
> +}
> +EXPORT_SYMBOL_GPL(tpm_put_ops);

I'm just thinking is the try_module_get() and module_put() even
necessary after this change? You know that device is not unregistered
from chip->ops field, which is protected by that RW-semaphore.

> +
> +/**
> + * tpm_chip_find_get() - return tpm_chip for a given chip number
> + * @chip_num: id to find
> + *
> + * The return'd chip has been tpm_try_get_ops'd and must be released via
> + * tpm_put_ops
> +  */
>  struct tpm_chip *tpm_chip_find_get(int chip_num)
>  {
>  	struct tpm_chip *pos, *chip = NULL;
> @@ -49,10 +99,9 @@ struct tpm_chip *tpm_chip_find_get(int chip_num)
>  		if (chip_num != TPM_ANY_NUM && chip_num != pos->dev_num)
>  			continue;
>  
> -		if (try_module_get(pos->dev.parent->driver->owner)) {
> +		if (!tpm_try_get_ops(pos))
>  			chip = pos;
> -			break;
> -		}
> +		break;
>  	}
>  	rcu_read_unlock();
>  	return chip;
> @@ -94,6 +143,7 @@ struct tpm_chip *tpmm_chip_alloc(struct device *dev,
>  	if (chip == NULL)
>  		return ERR_PTR(-ENOMEM);
>  
> +	init_rwsem(&chip->ops_sem);
>  	mutex_init(&chip->tpm_mutex);
>  	INIT_LIST_HEAD(&chip->list);
>  
> @@ -180,6 +230,12 @@ static int tpm_dev_add_device(struct tpm_chip *chip)
>  static void tpm_dev_del_device(struct tpm_chip *chip)
>  {
>  	cdev_del(&chip->cdev);
> +
> +	/* Make the driver uncallable. */
> +	down_write(&chip->ops_sem);
> +	chip->ops = NULL;
> +	up_write(&chip->ops_sem);
> +
>  	device_del(&chip->dev);
>  }
>  
> @@ -218,6 +274,9 @@ static void tpm1_chip_unregister(struct tpm_chip *chip)
>   * the device. As the last step this function adds the chip to the list of TPM
>   * chips available for in-kernel use.
>   *
> + * Once this function returns the driver call backs in 'op's will not be
> + * running and will no longer start.
> + *
>   * This function should be only called after the chip initialization is
>   * complete.
>   */
> diff --git a/drivers/char/tpm/tpm-dev.c b/drivers/char/tpm/tpm-dev.c
> index 4009765..f5d4521 100644
> --- a/drivers/char/tpm/tpm-dev.c
> +++ b/drivers/char/tpm/tpm-dev.c
> @@ -136,9 +136,18 @@ static ssize_t tpm_write(struct file *file, const char __user *buf,
>  		return -EFAULT;
>  	}
>  
> -	/* atomic tpm command send and result receive */
> +	/* atomic tpm command send and result receive. We only hold the ops
> +	 * lock during this period so that the tpm can be unregistered even if
> +	 * the char dev is held open.
> +	 */
> +	if (tpm_try_get_ops(priv->chip)) {
> +		mutex_unlock(&priv->buffer_mutex);
> +		return -EPIPE;
> +	}
>  	out_size = tpm_transmit(priv->chip, priv->data_buffer,
>  				sizeof(priv->data_buffer));
> +
> +	tpm_put_ops(priv->chip);
>  	if (out_size < 0) {
>  		mutex_unlock(&priv->buffer_mutex);
>  		return out_size;
> diff --git a/drivers/char/tpm/tpm-interface.c b/drivers/char/tpm/tpm-interface.c
> index 65dc7fd..1dfe2ce 100644
> --- a/drivers/char/tpm/tpm-interface.c
> +++ b/drivers/char/tpm/tpm-interface.c
> @@ -683,7 +683,7 @@ int tpm_is_tpm2(u32 chip_num)
>  
>  	rc = (chip->flags & TPM_CHIP_FLAG_TPM2) != 0;
>  
> -	tpm_chip_put(chip);
> +	tpm_put_ops(chip);
>  
>  	return rc;
>  }
> @@ -712,7 +712,7 @@ int tpm_pcr_read(u32 chip_num, int pcr_idx, u8 *res_buf)
>  		rc = tpm2_pcr_read(chip, pcr_idx, res_buf);
>  	else
>  		rc = tpm_pcr_read_dev(chip, pcr_idx, res_buf);
> -	tpm_chip_put(chip);
> +	tpm_put_ops(chip);
>  	return rc;
>  }
>  EXPORT_SYMBOL_GPL(tpm_pcr_read);
> @@ -747,7 +747,7 @@ int tpm_pcr_extend(u32 chip_num, int pcr_idx, const u8 *hash)
>  
>  	if (chip->flags & TPM_CHIP_FLAG_TPM2) {
>  		rc = tpm2_pcr_extend(chip, pcr_idx, hash);
> -		tpm_chip_put(chip);
> +		tpm_put_ops(chip);
>  		return rc;
>  	}
>  
> @@ -757,7 +757,7 @@ int tpm_pcr_extend(u32 chip_num, int pcr_idx, const u8 *hash)
>  	rc = tpm_transmit_cmd(chip, &cmd, EXTEND_PCR_RESULT_SIZE,
>  			      "attempting extend a PCR value");
>  
> -	tpm_chip_put(chip);
> +	tpm_put_ops(chip);
>  	return rc;
>  }
>  EXPORT_SYMBOL_GPL(tpm_pcr_extend);
> @@ -838,7 +838,7 @@ int tpm_send(u32 chip_num, void *cmd, size_t buflen)
>  
>  	rc = tpm_transmit_cmd(chip, cmd, buflen, "attempting tpm_cmd");
>  
> -	tpm_chip_put(chip);
> +	tpm_put_ops(chip);
>  	return rc;
>  }
>  EXPORT_SYMBOL_GPL(tpm_send);
> @@ -1020,7 +1020,7 @@ int tpm_get_random(u32 chip_num, u8 *out, size_t max)
>  
>  	if (chip->flags & TPM_CHIP_FLAG_TPM2) {
>  		err = tpm2_get_random(chip, out, max);
> -		tpm_chip_put(chip);
> +		tpm_put_ops(chip);
>  		return err;
>  	}
>  
> @@ -1042,7 +1042,7 @@ int tpm_get_random(u32 chip_num, u8 *out, size_t max)
>  		num_bytes -= recd;
>  	} while (retries-- && total < max);
>  
> -	tpm_chip_put(chip);
> +	tpm_put_ops(chip);
>  	return total ? total : -EIO;
>  }
>  EXPORT_SYMBOL_GPL(tpm_get_random);
> @@ -1068,7 +1068,7 @@ int tpm_seal_trusted(u32 chip_num, struct trusted_key_payload *payload,
>  
>  	rc = tpm2_seal_trusted(chip, payload, options);
>  
> -	tpm_chip_put(chip);
> +	tpm_put_ops(chip);
>  	return rc;
>  }
>  EXPORT_SYMBOL_GPL(tpm_seal_trusted);
> @@ -1094,7 +1094,7 @@ int tpm_unseal_trusted(u32 chip_num, struct trusted_key_payload *payload,
>  
>  	rc = tpm2_unseal_trusted(chip, payload, options);
>  
> -	tpm_chip_put(chip);
> +	tpm_put_ops(chip);
>  	return rc;
>  }
>  EXPORT_SYMBOL_GPL(tpm_unseal_trusted);
> diff --git a/drivers/char/tpm/tpm-sysfs.c b/drivers/char/tpm/tpm-sysfs.c
> index d93736a..34e7fc7 100644
> --- a/drivers/char/tpm/tpm-sysfs.c
> +++ b/drivers/char/tpm/tpm-sysfs.c
> @@ -295,5 +295,10 @@ int tpm_sysfs_add_device(struct tpm_chip *chip)
>  
>  void tpm_sysfs_del_device(struct tpm_chip *chip)
>  {
> +	/* The sysfs routines rely on an implicit tpm_try_get_ops, this
> +	 * function is called before ops is null'd and the sysfs core
> +	 * synchronizes this removal so that no callbacks are running or can
> +	 * run again
> +	 */
>  	sysfs_remove_group(&chip->dev.parent->kobj, &tpm_dev_group);
>  }
> diff --git a/drivers/char/tpm/tpm.h b/drivers/char/tpm/tpm.h
> index 31d9a8e..2a8373e 100644
> --- a/drivers/char/tpm/tpm.h
> +++ b/drivers/char/tpm/tpm.h
> @@ -174,7 +174,13 @@ struct tpm_chip {
>  	struct device dev;
>  	struct cdev cdev;
>  
> +	/* A driver callback under ops cannot be run unless ops_sem is held
> +	 * (sometimes implicitly, eg for the sysfs code). ops becomes null
> +	 * when the driver is unregistered, see tpm_try_get_ops.
> +	 */
> +	struct rw_semaphore ops_sem;
>  	const struct tpm_class_ops *ops;
> +
>  	unsigned int flags;
>  
>  	int dev_num;		/* /dev/tpm# */
> @@ -199,11 +205,6 @@ struct tpm_chip {
>  
>  #define to_tpm_chip(d) container_of(d, struct tpm_chip, dev)
>  
> -static inline void tpm_chip_put(struct tpm_chip *chip)
> -{
> -	module_put(chip->dev.parent->driver->owner);
> -}
> -
>  static inline int tpm_read_index(int base, int index)
>  {
>  	outb(index, base);
> @@ -511,6 +512,9 @@ extern int wait_for_tpm_stat(struct tpm_chip *, u8, unsigned long,
>  			     wait_queue_head_t *, bool);
>  
>  struct tpm_chip *tpm_chip_find_get(int chip_num);
> +__must_check int tpm_try_get_ops(struct tpm_chip *chip);
> +void tpm_put_ops(struct tpm_chip *chip);
> +
>  extern struct tpm_chip *tpmm_chip_alloc(struct device *dev,
>  				       const struct tpm_class_ops *ops);
>  extern int tpm_chip_register(struct tpm_chip *chip);
> -- 
> 2.4.3
> 

/Jarkko

------------------------------------------------------------------------------
Site24x7 APM Insight: Get Deep Visibility into Application Performance
APM + Mobile APM + RUM: Monitor 3 App instances at just $35/Month
Monitor end-to-end web transactions and take corrective actions now
Troubleshoot faster and improve end-user experience. Signup Now!
http://pubads.g.doubleclick.net/gampad/clk?id=272487151&iu=/4140

^ permalink raw reply	[flat|nested] 60+ messages in thread

* Re: [PATCH v3 05/11] tpm: Get rid of module locking
       [not found]     ` <1455885728-10315-6-git-send-email-stefanb-23VcF4HTsmIX0ybBhKVfKdBPR1lH4CV8@public.gmane.org>
  2016-02-22 18:22       ` Jason Gunthorpe
@ 2016-02-22 21:11       ` Jarkko Sakkinen
       [not found]         ` <20160222211141.GB3310-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
  1 sibling, 1 reply; 60+ messages in thread
From: Jarkko Sakkinen @ 2016-02-22 21:11 UTC (permalink / raw)
  To: Stefan Berger; +Cc: tpmdd-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f

On Fri, Feb 19, 2016 at 07:42:02AM -0500, Stefan Berger wrote:
> Get rid of the locking of the module
> 
> Signed-off-by: Stefan Berger <stefanb-23VcF4HTsmIX0ybBhKVfKdBPR1lH4CV8@public.gmane.org>

I tend to think that this should have been part of the previous patch
with the description in the commit message why the RW-semaphore gives
the needed guarantees.

/Jarkko

> ---
>  drivers/char/tpm/tpm-chip.c | 4 ----
>  1 file changed, 4 deletions(-)
> 
> diff --git a/drivers/char/tpm/tpm-chip.c b/drivers/char/tpm/tpm-chip.c
> index 0561400..fe15637 100644
> --- a/drivers/char/tpm/tpm-chip.c
> +++ b/drivers/char/tpm/tpm-chip.c
> @@ -57,9 +57,6 @@ int tpm_try_get_ops(struct tpm_chip *chip)
>  	if (!chip->ops)
>  		goto out_lock;
>  
> -	if (!try_module_get(chip->dev.parent->driver->owner))
> -		goto out_lock;
> -
>  	return 0;
>  out_lock:
>  	up_read(&chip->ops_sem);
> @@ -77,7 +74,6 @@ EXPORT_SYMBOL_GPL(tpm_try_get_ops);
>   */
>  void tpm_put_ops(struct tpm_chip *chip)
>  {
> -	module_put(chip->dev.parent->driver->owner);
>  	up_read(&chip->ops_sem);
>  	put_device(&chip->dev);
>  }
> -- 
> 2.4.3
> 

------------------------------------------------------------------------------
Site24x7 APM Insight: Get Deep Visibility into Application Performance
APM + Mobile APM + RUM: Monitor 3 App instances at just $35/Month
Monitor end-to-end web transactions and take corrective actions now
Troubleshoot faster and improve end-user experience. Signup Now!
http://pubads.g.doubleclick.net/gampad/clk?id=272487151&iu=/4140

^ permalink raw reply	[flat|nested] 60+ messages in thread

* Re: [PATCH v3 06/11] tpm: Split out the devm stuff from tpmm_chip_alloc
       [not found]     ` <1455885728-10315-7-git-send-email-stefanb-23VcF4HTsmIX0ybBhKVfKdBPR1lH4CV8@public.gmane.org>
  2016-02-22 18:24       ` Jason Gunthorpe
@ 2016-02-22 21:14       ` Jarkko Sakkinen
       [not found]         ` <20160222211414.GC3310-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
  1 sibling, 1 reply; 60+ messages in thread
From: Jarkko Sakkinen @ 2016-02-22 21:14 UTC (permalink / raw)
  To: Stefan Berger; +Cc: tpmdd-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f

On Fri, Feb 19, 2016 at 07:42:03AM -0500, Stefan Berger wrote:
> From: Jason Gunthorpe <jgunthorpe-ePGOBjL8dl3ta4EC/59zMFaTQe2KTcn/@public.gmane.org>
> 
> tpm_chip_alloc becomes a typical subsystem allocate call.

Maybe a more verbose commit message?

> 
> Signed-off-by: Jason Gunthorpe <jgunthorpe-ePGOBjL8dl3ta4EC/59zMFaTQe2KTcn/@public.gmane.org>
> ---
>  drivers/char/tpm/tpm-chip.c | 57 +++++++++++++++++++++++++++++++--------------
>  drivers/char/tpm/tpm.h      |  4 +++-
>  2 files changed, 42 insertions(+), 19 deletions(-)
> 
> diff --git a/drivers/char/tpm/tpm-chip.c b/drivers/char/tpm/tpm-chip.c
> index fe15637..2270e47 100644
> --- a/drivers/char/tpm/tpm-chip.c
> +++ b/drivers/char/tpm/tpm-chip.c
> @@ -120,17 +120,17 @@ static void tpm_dev_release(struct device *dev)
>  }
>  
>  /**
> - * tpmm_chip_alloc() - allocate a new struct tpm_chip instance
> - * @dev: device to which the chip is associated
> + * tpm_chip_alloc() - allocate a new struct tpm_chip instance
> + * @pdev: device to which the chip is associated
> + *        At this point pdev mst be initialized, but does not have to
> + *        be registered
>   * @ops: struct tpm_class_ops instance
>   *
>   * Allocates a new struct tpm_chip instance and assigns a free
> - * device number for it. Caller does not have to worry about
> - * freeing the allocated resources. When the devices is removed
> - * devres calls tpmm_chip_remove() to do the job.
> + * device number for it. Must be paired with put_device(&chip->dev).
>   */
> -struct tpm_chip *tpmm_chip_alloc(struct device *dev,
> -				 const struct tpm_class_ops *ops)
> +struct tpm_chip *tpm_chip_alloc(struct device *dev,
> +				const struct tpm_class_ops *ops)
>  {
>  	struct tpm_chip *chip;
>  	int err;
> @@ -143,10 +143,10 @@ struct tpm_chip *tpmm_chip_alloc(struct device *dev,
>  	mutex_init(&chip->tpm_mutex);
>  	INIT_LIST_HEAD(&chip->list);
>  
> -	chip->ops = ops;
> -
>  	spin_lock(&driver_lock);
>  	chip->dev_num = find_first_zero_bit(dev_mask, TPM_NUM_DEVICES);
> +	if (chip->dev_num < TPM_NUM_DEVICES)
> +		set_bit(chip->dev_num, dev_mask);

I guess this change should a separate patch.

>  	spin_unlock(&driver_lock);
>  
>  	if (chip->dev_num >= TPM_NUM_DEVICES) {
> @@ -155,9 +155,9 @@ struct tpm_chip *tpmm_chip_alloc(struct device *dev,
>  		return ERR_PTR(-ENOMEM);
>  	}
>  
> -	set_bit(chip->dev_num, dev_mask);
> +	chip->ops = ops;
>  
> -	dev_set_drvdata(dev, chip);
> +	device_initialize(&chip->dev);
>  
>  	chip->dev.class = tpm_class;
>  	chip->dev.release = tpm_dev_release;
> @@ -175,23 +175,44 @@ struct tpm_chip *tpmm_chip_alloc(struct device *dev,
>  	if (err)
>  		goto out;
>  
> -	device_initialize(&chip->dev);
> -
>  	cdev_init(&chip->cdev, &tpm_fops);
>  	chip->cdev.owner = dev->driver->owner;
>  	chip->cdev.kobj.parent = &chip->dev.kobj;
>  
> -	err = devm_add_action(dev, (void (*)(void *)) put_device, &chip->dev);
> +	return chip;
> +
> +out:
> +	put_device(&chip->dev);
> +	return ERR_PTR(err);
> +}
> +EXPORT_SYMBOL_GPL(tpm_chip_alloc);
> +
> +/**
> + * tpmm_chip_alloc() - allocate a new struct tpm_chip instance
> + * @pdev: parent device to which the chip is associated
> + * @ops: struct tpm_class_ops instance
> + *
> + * Same as tpm_chip_alloc except devm is used to do the put_device
> + */
> +struct tpm_chip *tpmm_chip_alloc(struct device *pdev,
> +				 const struct tpm_class_ops *ops)
> +{
> +	struct tpm_chip *chip;
> +	int err;
> +
> +	chip = tpm_chip_alloc(pdev, ops);
> +	if (IS_ERR(chip))
> +		return chip;
> +
> +	err = devm_add_action(pdev, (void (*)(void *)) put_device, &chip->dev);
>  	if (err) {
>  		put_device(&chip->dev);
>  		return ERR_PTR(err);
>  	}
>  
> -	return chip;
> +	dev_set_drvdata(pdev, chip);
>  
> -out:
> -	put_device(&chip->dev);
> -	return ERR_PTR(err);
> +	return chip;
>  }
>  EXPORT_SYMBOL_GPL(tpmm_chip_alloc);
>  
> diff --git a/drivers/char/tpm/tpm.h b/drivers/char/tpm/tpm.h
> index 2a8373e..25efe8f 100644
> --- a/drivers/char/tpm/tpm.h
> +++ b/drivers/char/tpm/tpm.h
> @@ -515,7 +515,9 @@ struct tpm_chip *tpm_chip_find_get(int chip_num);
>  __must_check int tpm_try_get_ops(struct tpm_chip *chip);
>  void tpm_put_ops(struct tpm_chip *chip);
>  
> -extern struct tpm_chip *tpmm_chip_alloc(struct device *dev,
> +extern struct tpm_chip *tpm_chip_alloc(struct device *dev,
> +				       const struct tpm_class_ops *ops);
> +extern struct tpm_chip *tpmm_chip_alloc(struct device *pdev,
>  				       const struct tpm_class_ops *ops);
>  extern int tpm_chip_register(struct tpm_chip *chip);
>  extern void tpm_chip_unregister(struct tpm_chip *chip);
> -- 
> 2.4.3
> 

/Jarkko

------------------------------------------------------------------------------
Site24x7 APM Insight: Get Deep Visibility into Application Performance
APM + Mobile APM + RUM: Monitor 3 App instances at just $35/Month
Monitor end-to-end web transactions and take corrective actions now
Troubleshoot faster and improve end-user experience. Signup Now!
http://pubads.g.doubleclick.net/gampad/clk?id=272487151&iu=/4140

^ permalink raw reply	[flat|nested] 60+ messages in thread

* Re: [PATCH v3 06/11] tpm: Split out the devm stuff from tpmm_chip_alloc
       [not found]         ` <20160222211414.GC3310-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
@ 2016-02-22 22:13           ` Jason Gunthorpe
       [not found]             ` <20160222221328.GA27228-ePGOBjL8dl3ta4EC/59zMFaTQe2KTcn/@public.gmane.org>
  0 siblings, 1 reply; 60+ messages in thread
From: Jason Gunthorpe @ 2016-02-22 22:13 UTC (permalink / raw)
  To: Jarkko Sakkinen; +Cc: tpmdd-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f

On Mon, Feb 22, 2016 at 11:14:14PM +0200, Jarkko Sakkinen wrote:
> On Fri, Feb 19, 2016 at 07:42:03AM -0500, Stefan Berger wrote:
> > From: Jason Gunthorpe <jgunthorpe-ePGOBjL8dl3ta4EC/59zMFaTQe2KTcn/@public.gmane.org>
> > 
> > tpm_chip_alloc becomes a typical subsystem allocate call.
> 
> Maybe a more verbose commit message?

What more do you want to say?

> >  	spin_lock(&driver_lock);
> >  	chip->dev_num = find_first_zero_bit(dev_mask, TPM_NUM_DEVICES);
> > +	if (chip->dev_num < TPM_NUM_DEVICES)
> > +		set_bit(chip->dev_num, dev_mask);
> 
> I guess this change should a separate patch.

Hurm, Stefan? This was not in the patch I sent you? This hunk looks
incomplete to me, and replaced by the IDR stuff anyhow. Drop it?

You need to put your Signed-off-by on patches you make notable changes
to, this one would qualify

Jason

------------------------------------------------------------------------------
Site24x7 APM Insight: Get Deep Visibility into Application Performance
APM + Mobile APM + RUM: Monitor 3 App instances at just $35/Month
Monitor end-to-end web transactions and take corrective actions now
Troubleshoot faster and improve end-user experience. Signup Now!
http://pubads.g.doubleclick.net/gampad/clk?id=272487151&iu=/4140

^ permalink raw reply	[flat|nested] 60+ messages in thread

* Re: [PATCH v3 05/11] tpm: Get rid of module locking
       [not found]         ` <20160222211141.GB3310-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
@ 2016-02-22 22:15           ` Jason Gunthorpe
  0 siblings, 0 replies; 60+ messages in thread
From: Jason Gunthorpe @ 2016-02-22 22:15 UTC (permalink / raw)
  To: Jarkko Sakkinen; +Cc: tpmdd-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f

On Mon, Feb 22, 2016 at 11:11:41PM +0200, Jarkko Sakkinen wrote:
> On Fri, Feb 19, 2016 at 07:42:02AM -0500, Stefan Berger wrote:
> > Get rid of the locking of the module
> > 
> > Signed-off-by: Stefan Berger <stefanb-23VcF4HTsmIX0ybBhKVfKdBPR1lH4CV8@public.gmane.org>
> 
> I tend to think that this should have been part of the previous patch
> with the description in the commit message why the RW-semaphore gives
> the needed guarantees.

Module locking is user visible (no longer prevents rmmod), and Stefan
wrote this code so it deserves it's own patch. The ops changes are not
user visible.

Jason

------------------------------------------------------------------------------
Site24x7 APM Insight: Get Deep Visibility into Application Performance
APM + Mobile APM + RUM: Monitor 3 App instances at just $35/Month
Monitor end-to-end web transactions and take corrective actions now
Troubleshoot faster and improve end-user experience. Signup Now!
http://pubads.g.doubleclick.net/gampad/clk?id=272487151&iu=/4140

^ permalink raw reply	[flat|nested] 60+ messages in thread

* Re: [PATCH v3 04/11] tpm: Provide strong locking for device removal
       [not found]         ` <20160222210844.GA3310-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
@ 2016-02-22 22:20           ` Jason Gunthorpe
       [not found]             ` <20160222222017.GC27228-ePGOBjL8dl3ta4EC/59zMFaTQe2KTcn/@public.gmane.org>
  0 siblings, 1 reply; 60+ messages in thread
From: Jason Gunthorpe @ 2016-02-22 22:20 UTC (permalink / raw)
  To: Jarkko Sakkinen; +Cc: tpmdd-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f

On Mon, Feb 22, 2016 at 11:08:59PM +0200, Jarkko Sakkinen wrote:
> On Fri, Feb 19, 2016 at 07:42:01AM -0500, Stefan Berger wrote:
> > From: Jason Gunthorpe <jgunthorpe-ePGOBjL8dl3ta4EC/59zMFaTQe2KTcn/@public.gmane.org>
> > 
> > Add a read/write semaphore around the ops function pointers so
> > ops can be set to null when the driver un-registers.
> > 
> > Previously the tpm core expected module locking to be enough to
> > ensure that tpm_unregister could not be called during certain times,
> > however that hasn't been sufficient for a long time.
> 
> Could you be more concrete with the scenario? You could describe
> a sequence of events where this could happen.

echo 1 > /sys/.../remove

Is basically the same as a module unload without requiring module
unload. module locking cannot be relied upon for correctness like this
ever since hot remove was added to the kernel.

> > + * @chip: Chip to ref
> > + *
> > + * The caller must already have some kind of locking to ensure that chip is
> 
> What do you mean when you use the term "some kind of locking"?

Eg the IDR lookup code uses a idr specific mutex. The char device uses
a ref held by the cdev subsystem.

> > +void tpm_put_ops(struct tpm_chip *chip)
> > +{
> > +	module_put(chip->dev.parent->driver->owner);
> > +	up_read(&chip->ops_sem);
> > +	put_device(&chip->dev);
> > +}
> > +EXPORT_SYMBOL_GPL(tpm_put_ops);
> 
> I'm just thinking is the try_module_get() and module_put() even
> necessary after this change? You know that device is not unregistered
> from chip->ops field, which is protected by that RW-semaphore.

The module locking is not about correctness. Some subsystems will hold
the module lock on their driver specifically to prevent rmmod as a
hint to the user that the driver module is being used by an open
/dev/tpmX for instance. Eg rtc does that.

We need to decide if we want that for TPM or not. Orthogonal issue.

I'm OK with getting rid of the module lock, TPM has a long lived
user space daemon, rtc does not.

Jason

------------------------------------------------------------------------------
Site24x7 APM Insight: Get Deep Visibility into Application Performance
APM + Mobile APM + RUM: Monitor 3 App instances at just $35/Month
Monitor end-to-end web transactions and take corrective actions now
Troubleshoot faster and improve end-user experience. Signup Now!
http://pubads.g.doubleclick.net/gampad/clk?id=272487151&iu=/4140

^ permalink raw reply	[flat|nested] 60+ messages in thread

* Re: [PATCH v3 03/11] tpm: Get rid of devname
       [not found]         ` <20160222181929.GB22088-ePGOBjL8dl3ta4EC/59zMFaTQe2KTcn/@public.gmane.org>
  2016-02-22 19:42           ` Jarkko Sakkinen
@ 2016-02-23  0:22           ` Stefan Berger
  1 sibling, 0 replies; 60+ messages in thread
From: Stefan Berger @ 2016-02-23  0:22 UTC (permalink / raw)
  To: Jason Gunthorpe; +Cc: tpmdd-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f


[-- Attachment #1.1: Type: text/plain, Size: 1123 bytes --]

Jason Gunthorpe <jgunthorpe-ePGOBjL8dl3ta4EC/59zMFaTQe2KTcn/@public.gmane.org> wrote on 02/22/2016 
01:19:29 PM:

> From: Jason Gunthorpe <jgunthorpe-ePGOBjL8dl3ta4EC/59zMFaTQe2KTcn/@public.gmane.org>
> To: Stefan Berger <stefanb-23VcF4HTsmIX0ybBhKVfKdBPR1lH4CV8@public.gmane.org>
> Cc: tpmdd-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f@public.gmane.org
> Date: 02/22/2016 01:20 PM
> Subject: Re: [tpmdd-devel] [PATCH v3 03/11] tpm: Get rid of devname
> 
> On Fri, Feb 19, 2016 at 07:42:00AM -0500, Stefan Berger wrote:
> > 
> > -   dev_set_name(&chip->dev, "%s", chip->devname);
> > +   err = dev_set_name(&chip->dev, "tpm%d", chip->dev_num);
> > +   if (err)
> > +      goto out;
> > 
> >     device_initialize(&chip->dev);
> > 
> > @@ -142,6 +142,10 @@ struct tpm_chip *tpmm_chip_alloc(struct device 
*dev,
> >     }
> > 
> >     return chip;
> > +
> > +out:
> > +   put_device(&chip->dev);
> > +   return ERR_PTR(err);
> 
> Oops, something went wrong here in all the rebasing - dev_set_name has
> to be after devince_initialize.

dev_set_name is now after device_initialize.

   Stefan



[-- Attachment #1.2: Type: text/html, Size: 1722 bytes --]

[-- Attachment #2: Type: text/plain, Size: 413 bytes --]

------------------------------------------------------------------------------
Site24x7 APM Insight: Get Deep Visibility into Application Performance
APM + Mobile APM + RUM: Monitor 3 App instances at just $35/Month
Monitor end-to-end web transactions and take corrective actions now
Troubleshoot faster and improve end-user experience. Signup Now!
http://pubads.g.doubleclick.net/gampad/clk?id=272487151&iu=/4140

[-- Attachment #3: Type: text/plain, Size: 192 bytes --]

_______________________________________________
tpmdd-devel mailing list
tpmdd-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f@public.gmane.org
https://lists.sourceforge.net/lists/listinfo/tpmdd-devel

^ permalink raw reply	[flat|nested] 60+ messages in thread

* Re: [PATCH v3 05/11] tpm: Get rid of module locking
       [not found]         ` <20160222182245.GC22088-ePGOBjL8dl3ta4EC/59zMFaTQe2KTcn/@public.gmane.org>
@ 2016-02-23  0:26           ` Stefan Berger
  0 siblings, 0 replies; 60+ messages in thread
From: Stefan Berger @ 2016-02-23  0:26 UTC (permalink / raw)
  To: Jason Gunthorpe; +Cc: tpmdd-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f


[-- Attachment #1.1: Type: text/plain, Size: 659 bytes --]

Jason Gunthorpe <jgunthorpe-ePGOBjL8dl3ta4EC/59zMFaTQe2KTcn/@public.gmane.org> wrote on 02/22/2016 
01:22:45 PM:


> Subject: Re: [tpmdd-devel] [PATCH v3 05/11] tpm: Get rid of module 
locking
> 
> On Fri, Feb 19, 2016 at 07:42:02AM -0500, Stefan Berger wrote:
> > Get rid of the locking of the module
> 
> Little more in the comment please..
> 
>   Now that the tpm core has strong locking around 'ops' it is possible
>   to remove a TPM driver, module and all, even while user space still
>   has things like /dev/tpmX open. For consistency and simplicity, drop
>   the module locking entirely.


Took the text :-) Thanks.

   Stefan


[-- Attachment #1.2: Type: text/html, Size: 913 bytes --]

[-- Attachment #2: Type: text/plain, Size: 413 bytes --]

------------------------------------------------------------------------------
Site24x7 APM Insight: Get Deep Visibility into Application Performance
APM + Mobile APM + RUM: Monitor 3 App instances at just $35/Month
Monitor end-to-end web transactions and take corrective actions now
Troubleshoot faster and improve end-user experience. Signup Now!
http://pubads.g.doubleclick.net/gampad/clk?id=272487151&iu=/4140

[-- Attachment #3: Type: text/plain, Size: 192 bytes --]

_______________________________________________
tpmdd-devel mailing list
tpmdd-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f@public.gmane.org
https://lists.sourceforge.net/lists/listinfo/tpmdd-devel

^ permalink raw reply	[flat|nested] 60+ messages in thread

* Re: [PATCH v3 06/11] tpm: Split out the devm stuff from tpmm_chip_alloc
       [not found]             ` <20160222221328.GA27228-ePGOBjL8dl3ta4EC/59zMFaTQe2KTcn/@public.gmane.org>
@ 2016-02-23  0:45               ` Stefan Berger
  2016-02-23 11:31               ` Jarkko Sakkinen
  1 sibling, 0 replies; 60+ messages in thread
From: Stefan Berger @ 2016-02-23  0:45 UTC (permalink / raw)
  To: Jason Gunthorpe; +Cc: tpmdd-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f


[-- Attachment #1.1: Type: text/plain, Size: 948 bytes --]

Jason Gunthorpe <jgunthorpe-ePGOBjL8dl3ta4EC/59zMFaTQe2KTcn/@public.gmane.org> wrote on 02/22/2016 
05:13:28 PM:


> 
> On Mon, Feb 22, 2016 at 11:14:14PM +0200, Jarkko Sakkinen wrote:
> > On Fri, Feb 19, 2016 at 07:42:03AM -0500, Stefan Berger wrote:
> > > From: Jason Gunthorpe <jgunthorpe-ePGOBjL8dl3ta4EC/59zMFaTQe2KTcn/@public.gmane.org>
> > > 
> > > tpm_chip_alloc becomes a typical subsystem allocate call.
> > 
> > Maybe a more verbose commit message?
> 
> What more do you want to say?
> 
> > >     spin_lock(&driver_lock);
> > >     chip->dev_num = find_first_zero_bit(dev_mask, TPM_NUM_DEVICES);
> > > +   if (chip->dev_num < TPM_NUM_DEVICES)
> > > +      set_bit(chip->dev_num, dev_mask);
> > 
> > I guess this change should a separate patch.
> 
> Hurm, Stefan? This was not in the patch I sent you? This hunk looks
> incomplete to me, and replaced by the IDR stuff anyhow. Drop it?

Dropped.

   Stefan



[-- Attachment #1.2: Type: text/html, Size: 1284 bytes --]

[-- Attachment #2: Type: text/plain, Size: 413 bytes --]

------------------------------------------------------------------------------
Site24x7 APM Insight: Get Deep Visibility into Application Performance
APM + Mobile APM + RUM: Monitor 3 App instances at just $35/Month
Monitor end-to-end web transactions and take corrective actions now
Troubleshoot faster and improve end-user experience. Signup Now!
http://pubads.g.doubleclick.net/gampad/clk?id=272487151&iu=/4140

[-- Attachment #3: Type: text/plain, Size: 192 bytes --]

_______________________________________________
tpmdd-devel mailing list
tpmdd-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f@public.gmane.org
https://lists.sourceforge.net/lists/listinfo/tpmdd-devel

^ permalink raw reply	[flat|nested] 60+ messages in thread

* Re: [PATCH v3 07/11] tpm: Replace device number bitmap with IDR
       [not found]         ` <20160222190629.GE22088-ePGOBjL8dl3ta4EC/59zMFaTQe2KTcn/@public.gmane.org>
@ 2016-02-23  1:15           ` Stefan Berger
  2016-02-23  2:16           ` Stefan Berger
  1 sibling, 0 replies; 60+ messages in thread
From: Stefan Berger @ 2016-02-23  1:15 UTC (permalink / raw)
  To: Jason Gunthorpe; +Cc: tpmdd-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f


[-- Attachment #1.1: Type: text/plain, Size: 4166 bytes --]

Jason Gunthorpe <jgunthorpe-ePGOBjL8dl3ta4EC/59zMFaTQe2KTcn/@public.gmane.org> wrote on 02/22/2016 
02:06:29 PM:

> From: Jason Gunthorpe <jgunthorpe-ePGOBjL8dl3ta4EC/59zMFaTQe2KTcn/@public.gmane.org>
> To: Stefan Berger <stefanb-23VcF4HTsmIX0ybBhKVfKdBPR1lH4CV8@public.gmane.org>
> Cc: tpmdd-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f@public.gmane.org
> Date: 02/22/2016 02:06 PM
> Subject: Re: [tpmdd-devel] [PATCH v3 07/11] tpm: Replace device 
> number bitmap with IDR
> 
> On Fri, Feb 19, 2016 at 07:42:04AM -0500, Stefan Berger wrote:
> > +   if (chip_num == TPM_ANY_NUM)
> > +      chip_next = 0;
> > +
> > +   mutex_lock(&idr_lock);
> > +
> > +   do {
> > +      if (chip_num == TPM_ANY_NUM) {
> > +         chip_prev = chip_next;
> > +         chip = idr_get_next(&dev_nums_idr, &chip_next);
> > +      } else
> > +         chip = idr_find_slowpath(&dev_nums_idr, chip_num);
> > +
> > +      if (chip && !tpm_try_get_ops(chip))
> > +         break;
> > +   } while (chip_num == TPM_ANY_NUM && chip_prev != chip_next);
> 
> This while loop doesn't look very good if tpm_try_get_ops fails?
> 
> Maybe like this?
> 
> struct tpm_chip *tpm_chip_find_get(int chip_num)
> {
>    struct tpm_chip *res = NULL;
> 
>    mutex_lock(&idr_lock);
> 
>    if (chip_num == TPM_ANY_NUM) {
>       struct tpm_chip *chip;
> 
>       chip_num = 0;
>       do {
>          chip = idr_get_next(&dev_nums_idr, &chip_num);
>          if (res && !tpm_try_get_ops(chip)) {
>             res = chip;
>             break;
>          }
>       }
>       while (chip);
>    } else {
>       res = idr_find_slowpath(&dev_nums_idr, chip_num);
>       if (res && tpm_try_get_ops(chip))
>          res = NULL;
>    }
> 
>    mutex_unlock(&idr_lock);
> 
>    return res;
> }
> 
> > +   if (err < 0) {
> >        dev_err(dev, "No available tpm device numbers\n");
> 
> I would drop the dev_err too
> 
> > @@ -247,12 +253,6 @@ static int tpm_dev_add_device(struct tpm_chip 
*chip)
> >  static void tpm_dev_del_device(struct tpm_chip *chip)
> >  {
> >     cdev_del(&chip->cdev);
> > -
> > -   /* Make the driver uncallable. */
> > -   down_write(&chip->ops_sem);
> > -   chip->ops = NULL;
> > -   up_write(&chip->ops_sem);
> > -
> >     device_del(&chip->dev);
> 
> Hum.. The ordering here is very important, I guess I got it slightly
> wrong as well in my patch adding ops.
> 
> Lets go for this:
> 
> - Tear down /dev/tpmX, sysfs and all other user accessible entry
>   points
> - Do device_del (get rid of all the sysfs stuff)
> - NULL the IDR (disables kAPI access and allow reuse of the ID)
> - NULL the ops (flush in-progress access now that new access is 
impossible)

Why NULL the ops so late and allow access even after device_del? I'd do 
that at the beginning.

Also the IDR has a two-stages:
 one making the chip inaccessible on the idr : idr_replace(&dev_nums_idr, 
NULL, chip->dev_num)
 the other one by freeing the IDR for re-use : idr_remove(&dev_nums_ir, 
chip->dev_num)

> - put_device to kfree (via devm)


My propsal:

- Tear down /dev/tpmX
- NULL the IDR (disable kAPI access since chip cannot be found anymore)
- NULL the ops (flush in-progress access now that new access is 
impossible)
- Tear down sysfs and all other user accessible entry points
- put_device
- Free the chip's device number from the IDR (makes IDR re-usable; must 
happen after /dev/tpmX is released to avoid clashes

   Stefan

> 
> Jason
> 
> 
------------------------------------------------------------------------------
> Site24x7 APM Insight: Get Deep Visibility into Application Performance
> APM + Mobile APM + RUM: Monitor 3 App instances at just $35/Month
> Monitor end-to-end web transactions and take corrective actions now
> Troubleshoot faster and improve end-user experience. Signup Now!
> http://pubads.g.doubleclick.net/gampad/clk?id=272487151&iu=/4140
> _______________________________________________
> tpmdd-devel mailing list
> tpmdd-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f@public.gmane.org
> https://lists.sourceforge.net/lists/listinfo/tpmdd-devel
> 



[-- Attachment #1.2: Type: text/html, Size: 6410 bytes --]

[-- Attachment #2: Type: text/plain, Size: 413 bytes --]

------------------------------------------------------------------------------
Site24x7 APM Insight: Get Deep Visibility into Application Performance
APM + Mobile APM + RUM: Monitor 3 App instances at just $35/Month
Monitor end-to-end web transactions and take corrective actions now
Troubleshoot faster and improve end-user experience. Signup Now!
http://pubads.g.doubleclick.net/gampad/clk?id=272487151&iu=/4140

[-- Attachment #3: Type: text/plain, Size: 192 bytes --]

_______________________________________________
tpmdd-devel mailing list
tpmdd-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f@public.gmane.org
https://lists.sourceforge.net/lists/listinfo/tpmdd-devel

^ permalink raw reply	[flat|nested] 60+ messages in thread

* Re: [PATCH v3 08/11] tpm: IntroduceTPM_CHIP_FLAG_VIRTUAL
       [not found]         ` <20160222191922.GH22088-ePGOBjL8dl3ta4EC/59zMFaTQe2KTcn/@public.gmane.org>
@ 2016-02-23  1:20           ` Stefan Berger
  2016-02-23  1:21           ` Stefan Berger
  1 sibling, 0 replies; 60+ messages in thread
From: Stefan Berger @ 2016-02-23  1:20 UTC (permalink / raw)
  To: Jason Gunthorpe; +Cc: tpmdd-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f


[-- Attachment #1.1: Type: text/plain, Size: 2363 bytes --]

Jason Gunthorpe <jgunthorpe-ePGOBjL8dl3ta4EC/59zMFaTQe2KTcn/@public.gmane.org> wrote on 02/22/2016 
02:19:22 PM:

> From: Jason Gunthorpe <jgunthorpe-ePGOBjL8dl3ta4EC/59zMFaTQe2KTcn/@public.gmane.org>
> To: Stefan Berger <stefanb-23VcF4HTsmIX0ybBhKVfKdBPR1lH4CV8@public.gmane.org>
> Cc: tpmdd-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f@public.gmane.org
> Date: 02/22/2016 02:19 PM
> Subject: Re: [tpmdd-devel] [PATCH v3 08/11] tpm: Introduce 
> TPM_CHIP_FLAG_VIRTUAL
> 
> On Fri, Feb 19, 2016 at 07:42:05AM -0500, Stefan Berger wrote:
> 
> >     cdev_init(&chip->cdev, &tpm_fops);
> > -   chip->cdev.owner = dev->driver->owner;
> 
> Shouldn't this be:
> 
>    chip->cdev.owner = THIS_MODULE;
> 
> ?
> 
> Please drop this hunk into the 'tpm: Get rid of module locking' patch

Done.

> 
> > +
> > +   if (!(chip->flags & TPM_CHIP_FLAG_VIRTUAL))
> > +      err = sysfs_create_group(&chip->dev.parent->kobj,
> > +                &tpm_dev_group);
> > +   else
> > +      chip->groups[chip->groups_cnt++] = &tpm_dev_group;
> 
> For other reviewers: The intent here is to make another patch that
> moves the main sysfs to only use groups with symlinks link ppi does
> now.
> 
> Does sysfs work with vtpm? I am worried about dev_get_drvdata here
> (and other places):
> 
>  static ssize_t durations_show(struct device *dev, struct 
> device_attribute *attr,
>                                char *buf)
>  {
>         struct tpm_chip *chip = dev_get_drvdata(dev);
> 
> There is only one dev_set_drvdata and it does not apply to chip->dev.
> 
> Ultimately this should change to container_of like ppi does.


Fix in this patch or yet another one ?

   Stefan

> 
> Jason
> 
> 
------------------------------------------------------------------------------
> Site24x7 APM Insight: Get Deep Visibility into Application Performance
> APM + Mobile APM + RUM: Monitor 3 App instances at just $35/Month
> Monitor end-to-end web transactions and take corrective actions now
> Troubleshoot faster and improve end-user experience. Signup Now!
> http://pubads.g.doubleclick.net/gampad/clk?id=272487151&iu=/4140
> _______________________________________________
> tpmdd-devel mailing list
> tpmdd-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f@public.gmane.org
> https://lists.sourceforge.net/lists/listinfo/tpmdd-devel
> 



[-- Attachment #1.2: Type: text/html, Size: 3587 bytes --]

[-- Attachment #2: Type: text/plain, Size: 413 bytes --]

------------------------------------------------------------------------------
Site24x7 APM Insight: Get Deep Visibility into Application Performance
APM + Mobile APM + RUM: Monitor 3 App instances at just $35/Month
Monitor end-to-end web transactions and take corrective actions now
Troubleshoot faster and improve end-user experience. Signup Now!
http://pubads.g.doubleclick.net/gampad/clk?id=272487151&iu=/4140

[-- Attachment #3: Type: text/plain, Size: 192 bytes --]

_______________________________________________
tpmdd-devel mailing list
tpmdd-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f@public.gmane.org
https://lists.sourceforge.net/lists/listinfo/tpmdd-devel

^ permalink raw reply	[flat|nested] 60+ messages in thread

* Re: [PATCH v3 08/11] tpm: IntroduceTPM_CHIP_FLAG_VIRTUAL
       [not found]         ` <20160222191922.GH22088-ePGOBjL8dl3ta4EC/59zMFaTQe2KTcn/@public.gmane.org>
  2016-02-23  1:20           ` [PATCH v3 08/11] tpm: IntroduceTPM_CHIP_FLAG_VIRTUAL Stefan Berger
@ 2016-02-23  1:21           ` Stefan Berger
  1 sibling, 0 replies; 60+ messages in thread
From: Stefan Berger @ 2016-02-23  1:21 UTC (permalink / raw)
  To: Jason Gunthorpe; +Cc: tpmdd-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f


[-- Attachment #1.1: Type: text/plain, Size: 681 bytes --]

Jason Gunthorpe <jgunthorpe-ePGOBjL8dl3ta4EC/59zMFaTQe2KTcn/@public.gmane.org> wrote on 02/22/2016 
02:19:22 PM:


> > +
> > +   if (!(chip->flags & TPM_CHIP_FLAG_VIRTUAL))
> > +      err = sysfs_create_group(&chip->dev.parent->kobj,
> > +                &tpm_dev_group);
> > +   else
> > +      chip->groups[chip->groups_cnt++] = &tpm_dev_group;
> 
> For other reviewers: The intent here is to make another patch that
> moves the main sysfs to only use groups with symlinks link ppi does
> now.
> 
> Does sysfs work with vtpm? I am worried about dev_get_drvdata here
> (and other places):

Yes, works. I have a set_drv_data in the vtpm driver.

   Stefan



[-- Attachment #1.2: Type: text/html, Size: 1027 bytes --]

[-- Attachment #2: Type: text/plain, Size: 413 bytes --]

------------------------------------------------------------------------------
Site24x7 APM Insight: Get Deep Visibility into Application Performance
APM + Mobile APM + RUM: Monitor 3 App instances at just $35/Month
Monitor end-to-end web transactions and take corrective actions now
Troubleshoot faster and improve end-user experience. Signup Now!
http://pubads.g.doubleclick.net/gampad/clk?id=272487151&iu=/4140

[-- Attachment #3: Type: text/plain, Size: 192 bytes --]

_______________________________________________
tpmdd-devel mailing list
tpmdd-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f@public.gmane.org
https://lists.sourceforge.net/lists/listinfo/tpmdd-devel

^ permalink raw reply	[flat|nested] 60+ messages in thread

* Re: [PATCH v3 09/11] tpm: Driver for supporting multiple emulated TPMs
       [not found]         ` <20160222192741.GI22088-ePGOBjL8dl3ta4EC/59zMFaTQe2KTcn/@public.gmane.org>
@ 2016-02-23  1:45           ` Stefan Berger
  0 siblings, 0 replies; 60+ messages in thread
From: Stefan Berger @ 2016-02-23  1:45 UTC (permalink / raw)
  To: Jason Gunthorpe; +Cc: tpmdd-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f


[-- Attachment #1.1: Type: text/plain, Size: 1343 bytes --]

Jason Gunthorpe <jgunthorpe-ePGOBjL8dl3ta4EC/59zMFaTQe2KTcn/@public.gmane.org> wrote on 02/22/2016 
02:27:41 PM:


> Subject: Re: [tpmdd-devel] [PATCH v3 09/11] tpm: Driver for 
> supporting multiple emulated TPMs
> 
> On Fri, Feb 19, 2016 at 07:42:06AM -0500, Stefan Berger wrote:
> 
> > +#define VTPM_NUM_DEVICES TPM_NUM_DEVICES
> 
> Never used
> 

Dropped.

> > +   rc = copy_to_user(buf, vtpm_dev->buffer, len);
> > +   memset(vtpm_dev->buffer, 0, len);
> > +   vtpm_dev->req_len = 0;
> > +
> > +   spin_unlock(&vtpm_dev->buf_lock);
> 
> No, do not call copy_to_user in a spin lock, (or copy_from_user)

I suppose we don't copy into an intermediary buffer, right? Just copy 
without the protection then??


> 
> > +   chip->vendor.irq = 1;
> 
> Do not set this, I am trying to remove it..

dropped.

> 
> Overall, I think everything has turned out very nice indeed.

Thanks. I could not race it anymore with lots of concurrency, so a bit 
hesitant about the reordering of the IDR stuff.

Two things:
- the ioctl takes flags; should we return an error on flags that are not 
supported but set by userspace?
- the sysfs works but I wished we could give some control over whether it 
shows any entries. Can we have a flag in the ioctl on whether to show 
these files in sysfs?

  Stefan




[-- Attachment #1.2: Type: text/html, Size: 1974 bytes --]

[-- Attachment #2: Type: text/plain, Size: 413 bytes --]

------------------------------------------------------------------------------
Site24x7 APM Insight: Get Deep Visibility into Application Performance
APM + Mobile APM + RUM: Monitor 3 App instances at just $35/Month
Monitor end-to-end web transactions and take corrective actions now
Troubleshoot faster and improve end-user experience. Signup Now!
http://pubads.g.doubleclick.net/gampad/clk?id=272487151&iu=/4140

[-- Attachment #3: Type: text/plain, Size: 192 bytes --]

_______________________________________________
tpmdd-devel mailing list
tpmdd-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f@public.gmane.org
https://lists.sourceforge.net/lists/listinfo/tpmdd-devel

^ permalink raw reply	[flat|nested] 60+ messages in thread

* Re: [PATCH v3 08/11] tpm: IntroduceTPM_CHIP_FLAG_VIRTUAL
       [not found]           ` <201602230121.u1N1LYk2024786-4ZtxiNBBw+3ImUpY6SP3GEEOCMrvLtNR@public.gmane.org>
@ 2016-02-23  2:05             ` Jason Gunthorpe
       [not found]               ` <20160223020515.GA26177-ePGOBjL8dl3ta4EC/59zMFaTQe2KTcn/@public.gmane.org>
  0 siblings, 1 reply; 60+ messages in thread
From: Jason Gunthorpe @ 2016-02-23  2:05 UTC (permalink / raw)
  To: Stefan Berger; +Cc: tpmdd-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f

On Mon, Feb 22, 2016 at 08:21:09PM -0500, Stefan Berger wrote:
> 
> Jason Gunthorpe <jgunthorpe-ePGOBjL8dl3ta4EC/59zMFaTQe2KTcn/@public.gmane.org> wrote on 02/22/2016 02:19:22
> PM:
> 
> 
> > > +
> > > +   if (!(chip->flags & TPM_CHIP_FLAG_VIRTUAL))
> > > +      err = sysfs_create_group(&chip->dev.parent->kobj,
> > > +                &tpm_dev_group);
> > > +   else
> > > +      chip->groups[chip->groups_cnt++] = &tpm_dev_group;
> >
> > For other reviewers: The intent here is to make another patch that
> > moves the main sysfs to only use groups with symlinks link ppi does
> > now.
> >
> > Does sysfs work with vtpm? I am worried about dev_get_drvdata here
> > (and other places):
> 
> Yes, works. I have a set_drv_data in the vtpm driver.

?? I don't see that in the vtpm patch posted to the list? Can you
point me to it?

In any event, the core code should be self contained and not rely on
things in the drivers like this.

Jason

------------------------------------------------------------------------------
Site24x7 APM Insight: Get Deep Visibility into Application Performance
APM + Mobile APM + RUM: Monitor 3 App instances at just $35/Month
Monitor end-to-end web transactions and take corrective actions now
Troubleshoot faster and improve end-user experience. Signup Now!
http://pubads.g.doubleclick.net/gampad/clk?id=272487151&iu=/4140

^ permalink raw reply	[flat|nested] 60+ messages in thread

* Re: [PATCH v3 08/11] tpm: IntroduceTPM_CHIP_FLAG_VIRTUAL
       [not found]           ` <201602230116.u1N1Ghac006778-8DuMPbUlb4HImUpY6SP3GEEOCMrvLtNR@public.gmane.org>
@ 2016-02-23  2:06             ` Jason Gunthorpe
  0 siblings, 0 replies; 60+ messages in thread
From: Jason Gunthorpe @ 2016-02-23  2:06 UTC (permalink / raw)
  To: Stefan Berger; +Cc: tpmdd-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f

On Mon, Feb 22, 2016 at 08:20:03PM -0500, Stefan Berger wrote:
> > Ultimately this should change to container_of like ppi does.
> 
> Fix in this patch or yet another one ?

It would have to go with a future patch to change always use compat
symlinks for the parent.

Jason

------------------------------------------------------------------------------
Site24x7 APM Insight: Get Deep Visibility into Application Performance
APM + Mobile APM + RUM: Monitor 3 App instances at just $35/Month
Monitor end-to-end web transactions and take corrective actions now
Troubleshoot faster and improve end-user experience. Signup Now!
http://pubads.g.doubleclick.net/gampad/clk?id=272487151&iu=/4140

^ permalink raw reply	[flat|nested] 60+ messages in thread

* Re: [PATCH v3 07/11] tpm: Replace device number bitmap with IDR
       [not found]           ` <201602230116.u1N1G4iu012263-nNA/7dmquNI+UXBhvPuGgqsjOiXwFzmk@public.gmane.org>
@ 2016-02-23  2:16             ` Jason Gunthorpe
       [not found]               ` <20160223021606.GC26177-ePGOBjL8dl3ta4EC/59zMFaTQe2KTcn/@public.gmane.org>
       [not found]               ` <201602232305.u1NN521L020589@d03av01.boulder.ibm.com>
  0 siblings, 2 replies; 60+ messages in thread
From: Jason Gunthorpe @ 2016-02-23  2:16 UTC (permalink / raw)
  To: Stefan Berger; +Cc: tpmdd-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f

On Mon, Feb 22, 2016 at 08:15:38PM -0500, Stefan Berger wrote:
> > - Tear down /dev/tpmX, sysfs and all other user accessible entry
> >   points
> > - Do device_del (get rid of all the sysfs stuff)
> > - NULL the IDR (disables kAPI access and allow reuse of the ID)
> > - NULL the ops (flush in-progress access now that new access is impossible)
> 
> Why NULL the ops so late and allow access even after device_del? I'd do that at
> the beginning.

It absolutely has to be done as the very last thing.

None of the sysfs code checks ops, and thus can't fail on null ops
(see the comment I added in the ops patch in tpm-sysfs). All sysfs
must be rendered inaccessible and all in-progress accesses must be
completed before we attempt to drop ops.

Since we are moving to using chip->groups to register sysfs a full
device_del seems necessary to fully fence sysfs access.

> Also the IDR has a two-stages:
>  one making the chip inaccessible on the idr : idr_replace(&dev_nums_idr, NULL,
> chip->dev_num)
>  the other one by freeing the IDR for re-use : idr_remove(&dev_nums_ir, chip->
> dev_num)

Oh, I missed that, yes, that is the way to go for the IDR part,
do the idr_remove after device_del.

If you set to null I expect that means the while loop example I gave
will need adjusting.

> - Free the chip's device number from the IDR (makes IDR re-usable; must happen
> after /dev/tpmX is released to avoid clashes

With this new arrangment the idr_remove can happen directly after
device_del and we can avoid the intermediate state of a NULL'd entry,
which seems slightly simplifying. Before there was the problem because
vtpm was using a struct device, but that is gone now.

Jason

------------------------------------------------------------------------------
Site24x7 APM Insight: Get Deep Visibility into Application Performance
APM + Mobile APM + RUM: Monitor 3 App instances at just $35/Month
Monitor end-to-end web transactions and take corrective actions now
Troubleshoot faster and improve end-user experience. Signup Now!
http://pubads.g.doubleclick.net/gampad/clk?id=272487151&iu=/4140

^ permalink raw reply	[flat|nested] 60+ messages in thread

* Re: [PATCH v3 07/11] tpm: Replace device number bitmap with IDR
       [not found]         ` <20160222190629.GE22088-ePGOBjL8dl3ta4EC/59zMFaTQe2KTcn/@public.gmane.org>
  2016-02-23  1:15           ` Stefan Berger
@ 2016-02-23  2:16           ` Stefan Berger
  1 sibling, 0 replies; 60+ messages in thread
From: Stefan Berger @ 2016-02-23  2:16 UTC (permalink / raw)
  To: Jason Gunthorpe; +Cc: tpmdd-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f


[-- Attachment #1.1: Type: text/plain, Size: 2300 bytes --]

Jason Gunthorpe <jgunthorpe-ePGOBjL8dl3ta4EC/59zMFaTQe2KTcn/@public.gmane.org> wrote on 02/22/2016 
02:06:29 PM:


> 
> On Fri, Feb 19, 2016 at 07:42:04AM -0500, Stefan Berger wrote:
> > +   if (chip_num == TPM_ANY_NUM)
> > +      chip_next = 0;
> > +
> > +   mutex_lock(&idr_lock);
> > +
> > +   do {
> > +      if (chip_num == TPM_ANY_NUM) {
> > +         chip_prev = chip_next;
> > +         chip = idr_get_next(&dev_nums_idr, &chip_next);
> > +      } else
> > +         chip = idr_find_slowpath(&dev_nums_idr, chip_num);
> > +
> > +      if (chip && !tpm_try_get_ops(chip))
> > +         break;
> > +   } while (chip_num == TPM_ANY_NUM && chip_prev != chip_next);
> 
> This while loop doesn't look very good if tpm_try_get_ops fails?
> 
> Maybe like this?
> 
> struct tpm_chip *tpm_chip_find_get(int chip_num)
> {
>    struct tpm_chip *res = NULL;
> 
>    mutex_lock(&idr_lock);
> 
>    if (chip_num == TPM_ANY_NUM) {
>       struct tpm_chip *chip;
> 
>       chip_num = 0;
>       do {
>          chip = idr_get_next(&dev_nums_idr, &chip_num);
>          if (res && !tpm_try_get_ops(chip)) {
>             res = chip;
>             break;
>          }
>       }
>       while (chip);
>    } else {
>       res = idr_find_slowpath(&dev_nums_idr, chip_num);
>       if (res && tpm_try_get_ops(chip))
>          res = NULL;
>    }
> 
>    mutex_unlock(&idr_lock);
> 
>    return res;
> }

        mutex_lock(&idr_lock);

        if (chip_num == TPM_ANY_NUM) {
                chip_num = 0;
                do {
                        chip_prev = chip_num;
                        chip = idr_get_next(&dev_nums_idr, &chip_num);
                        if (chip && !tpm_try_get_ops(chip)) {
                                res = chip;
                                break;
                        }
                } while (chip_prev != chip_num);
        } else {
                chip = idr_find_slowpath(&dev_nums_idr, chip_num);
                if (chip && !tpm_try_get_ops(chip))
                        res = chip;
        }

        mutex_unlock(&idr_lock);



FYI: idr_get_next will return NULL for a chip->dev_num that has nothing 
(NULL) registered; we *may* find something after that again.

   Stefan



[-- Attachment #1.2: Type: text/html, Size: 5557 bytes --]

[-- Attachment #2: Type: text/plain, Size: 413 bytes --]

------------------------------------------------------------------------------
Site24x7 APM Insight: Get Deep Visibility into Application Performance
APM + Mobile APM + RUM: Monitor 3 App instances at just $35/Month
Monitor end-to-end web transactions and take corrective actions now
Troubleshoot faster and improve end-user experience. Signup Now!
http://pubads.g.doubleclick.net/gampad/clk?id=272487151&iu=/4140

[-- Attachment #3: Type: text/plain, Size: 192 bytes --]

_______________________________________________
tpmdd-devel mailing list
tpmdd-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f@public.gmane.org
https://lists.sourceforge.net/lists/listinfo/tpmdd-devel

^ permalink raw reply	[flat|nested] 60+ messages in thread

* Re: [PATCH v3 09/11] tpm: Driver for supporting multiple emulated TPMs
       [not found]           ` <201602230142.u1N1gSuF029481-8DuMPbUlb4HImUpY6SP3GEEOCMrvLtNR@public.gmane.org>
@ 2016-02-23  2:17             ` Jason Gunthorpe
       [not found]               ` <20160223021730.GD26177-ePGOBjL8dl3ta4EC/59zMFaTQe2KTcn/@public.gmane.org>
  0 siblings, 1 reply; 60+ messages in thread
From: Jason Gunthorpe @ 2016-02-23  2:17 UTC (permalink / raw)
  To: Stefan Berger; +Cc: tpmdd-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f

On Mon, Feb 22, 2016 at 08:45:51PM -0500, Stefan Berger wrote:

> Two things:
> - the ioctl takes flags; should we return an error on flags that are not
> supported but set by userspace?

Typically yes. Otherwise you cannot introduce new flags in
future.

> - the sysfs works but I wished we could give some control over whether it shows
> any entries. Can we have a flag in the ioctl on whether to show these files in
> sysfs?

That is something to address in the future namespace patch series I
expect you'll prepare..

Jason

------------------------------------------------------------------------------
Site24x7 APM Insight: Get Deep Visibility into Application Performance
APM + Mobile APM + RUM: Monitor 3 App instances at just $35/Month
Monitor end-to-end web transactions and take corrective actions now
Troubleshoot faster and improve end-user experience. Signup Now!
http://pubads.g.doubleclick.net/gampad/clk?id=272487151&iu=/4140

^ permalink raw reply	[flat|nested] 60+ messages in thread

* Re: [PATCH v3 07/11] tpm: Replace device number bitmap with IDR
       [not found]           ` <201602230217.u1N2HIJT003183-3MP/CPU4Muo+UXBhvPuGgqsjOiXwFzmk@public.gmane.org>
@ 2016-02-23  2:18             ` Jason Gunthorpe
  0 siblings, 0 replies; 60+ messages in thread
From: Jason Gunthorpe @ 2016-02-23  2:18 UTC (permalink / raw)
  To: Stefan Berger; +Cc: tpmdd-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f

On Mon, Feb 22, 2016 at 09:16:53PM -0500, Stefan Berger wrote:

> FYI: idr_get_next will return NULL for a chip->dev_num that has nothing (NULL)
> registered; we *may* find something after that again.

Yes, I see that now, if you decide to get rid of that then simplify
the search again, but your version looks nice either way.

Jason

------------------------------------------------------------------------------
Site24x7 APM Insight: Get Deep Visibility into Application Performance
APM + Mobile APM + RUM: Monitor 3 App instances at just $35/Month
Monitor end-to-end web transactions and take corrective actions now
Troubleshoot faster and improve end-user experience. Signup Now!
http://pubads.g.doubleclick.net/gampad/clk?id=272487151&iu=/4140

^ permalink raw reply	[flat|nested] 60+ messages in thread

* Re: [PATCH v3 08/11] tpm: IntroduceTPM_CHIP_FLAG_VIRTUAL
       [not found]               ` <20160223020515.GA26177-ePGOBjL8dl3ta4EC/59zMFaTQe2KTcn/@public.gmane.org>
@ 2016-02-23  3:40                 ` Stefan Berger
  0 siblings, 0 replies; 60+ messages in thread
From: Stefan Berger @ 2016-02-23  3:40 UTC (permalink / raw)
  To: Jason Gunthorpe; +Cc: tpmdd-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f


[-- Attachment #1.1: Type: text/plain, Size: 1442 bytes --]

Jason Gunthorpe <jgunthorpe-ePGOBjL8dl3ta4EC/59zMFaTQe2KTcn/@public.gmane.org> wrote on 02/22/2016 
09:05:15 PM:

> 
> On Mon, Feb 22, 2016 at 08:21:09PM -0500, Stefan Berger wrote:
> > 
> > Jason Gunthorpe <jgunthorpe-ePGOBjL8dl3ta4EC/59zMFaTQe2KTcn/@public.gmane.org> wrote on 02/22/
> 2016 02:19:22
> > PM:
> > 
> > 
> > > > +
> > > > +   if (!(chip->flags & TPM_CHIP_FLAG_VIRTUAL))
> > > > +      err = sysfs_create_group(&chip->dev.parent->kobj,
> > > > +                &tpm_dev_group);
> > > > +   else
> > > > +      chip->groups[chip->groups_cnt++] = &tpm_dev_group;
> > >
> > > For other reviewers: The intent here is to make another patch that
> > > moves the main sysfs to only use groups with symlinks link ppi does
> > > now.
> > >
> > > Does sysfs work with vtpm? I am worried about dev_get_drvdata here
> > > (and other places):
> > 
> > Yes, works. I have a set_drv_data in the vtpm driver.
> 
> ?? I don't see that in the vtpm patch posted to the list? Can you
> point me to it?

That was in the past that I had that call ... when there still was a 
device and when sysfs was still working.

I now converted the dev_get_drvdata in tpm-interface.c and tpm-sysfs.c to 
container_of to make sysfs work for vtpm. It has to be part of this patch.

  Stefan

> 
> In any event, the core code should be self contained and not rely on
> things in the drivers like this.
> 
> Jason
> 



[-- Attachment #1.2: Type: text/html, Size: 2045 bytes --]

[-- Attachment #2: Type: text/plain, Size: 413 bytes --]

------------------------------------------------------------------------------
Site24x7 APM Insight: Get Deep Visibility into Application Performance
APM + Mobile APM + RUM: Monitor 3 App instances at just $35/Month
Monitor end-to-end web transactions and take corrective actions now
Troubleshoot faster and improve end-user experience. Signup Now!
http://pubads.g.doubleclick.net/gampad/clk?id=272487151&iu=/4140

[-- Attachment #3: Type: text/plain, Size: 192 bytes --]

_______________________________________________
tpmdd-devel mailing list
tpmdd-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f@public.gmane.org
https://lists.sourceforge.net/lists/listinfo/tpmdd-devel

^ permalink raw reply	[flat|nested] 60+ messages in thread

* Re: [PATCH v3 09/11] tpm: Driver for supporting multiple emulated TPMs
       [not found]     ` <1455885728-10315-10-git-send-email-stefanb-23VcF4HTsmIX0ybBhKVfKdBPR1lH4CV8@public.gmane.org>
  2016-02-22 19:27       ` Jason Gunthorpe
@ 2016-02-23 10:22       ` Jarkko Sakkinen
       [not found]         ` <20160223102211.GA9474-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
       [not found]         ` <201602231210.u1NCAD6D017196@d01av03.pok.ibm.com>
  1 sibling, 2 replies; 60+ messages in thread
From: Jarkko Sakkinen @ 2016-02-23 10:22 UTC (permalink / raw)
  To: Stefan Berger; +Cc: tpmdd-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f

On Fri, Feb 19, 2016 at 07:42:06AM -0500, Stefan Berger wrote:
> This patch implements a driver for supporting multiple emulated TPMs in a
> system.
> 
> The driver implements a device /dev/vtpmx that is used to created
> a client device pair /dev/tpmX (e.g., /dev/tpm10) and a server side that
> is accessed using a file descriptor returned by an ioctl.
> The device /dev/tpmX is the usual TPM device created by the core TPM
> driver. Applications or kernel subsystems can send TPM commands to it
> and the corresponding server-side file descriptor receives these
> commands and delivers them to an emulated TPM.
> 
> Signed-off-by: Stefan Berger <stefanb-23VcF4HTsmIX0ybBhKVfKdBPR1lH4CV8@public.gmane.org>
> ---
>  drivers/char/tpm/Kconfig    |  10 +
>  drivers/char/tpm/Makefile   |   1 +
>  drivers/char/tpm/tpm-vtpm.c | 543 ++++++++++++++++++++++++++++++++++++++++++++
>  include/uapi/linux/Kbuild   |   1 +
>  include/uapi/linux/vtpm.h   |  38 ++++
>  5 files changed, 593 insertions(+)
>  create mode 100644 drivers/char/tpm/tpm-vtpm.c
>  create mode 100644 include/uapi/linux/vtpm.h
> 
> diff --git a/drivers/char/tpm/Kconfig b/drivers/char/tpm/Kconfig
> index 3b84a8b..4c4e843 100644
> --- a/drivers/char/tpm/Kconfig
> +++ b/drivers/char/tpm/Kconfig
> @@ -122,5 +122,15 @@ config TCG_CRB
>  	  from within Linux.  To compile this driver as a module, choose
>  	  M here; the module will be called tpm_crb.
>  
> +config TCG_VTPM
> +	tristate "VTPM Interface"
> +	depends on TCG_TPM
> +	---help---
> +	  This driver supports an emulated TPM (vTPM) running in userspace.
> +	  A device /dev/vtpmx is provided that creates a device pair
> +	  /dev/vtpmX and a server-side file descriptor on which the vTPM
> +	  can receive commands.
> +
> +
>  source "drivers/char/tpm/st33zp24/Kconfig"
>  endif # TCG_TPM
> diff --git a/drivers/char/tpm/Makefile b/drivers/char/tpm/Makefile
> index 56e8f1f..d947db2 100644
> --- a/drivers/char/tpm/Makefile
> +++ b/drivers/char/tpm/Makefile
> @@ -23,3 +23,4 @@ obj-$(CONFIG_TCG_IBMVTPM) += tpm_ibmvtpm.o
>  obj-$(CONFIG_TCG_TIS_ST33ZP24) += st33zp24/
>  obj-$(CONFIG_TCG_XEN) += xen-tpmfront.o
>  obj-$(CONFIG_TCG_CRB) += tpm_crb.o
> +obj-$(CONFIG_TCG_VTPM) += tpm-vtpm.o
> diff --git a/drivers/char/tpm/tpm-vtpm.c b/drivers/char/tpm/tpm-vtpm.c
> new file mode 100644
> index 0000000..823c94a
> --- /dev/null
> +++ b/drivers/char/tpm/tpm-vtpm.c
> @@ -0,0 +1,543 @@
> +/*
> + * Copyright (C) 2015, 2016 IBM Corporation
> + *
> + * Author: Stefan Berger <stefanb-r/Jw6+rmf7HQT0dZR+AlfA@public.gmane.org>
> + *
> + * Maintained by: <tpmdd-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f@public.gmane.org>
> + *
> + * Device driver for vTPM.
> + *
> + * 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/types.h>
> +#include <linux/spinlock.h>
> +#include <linux/uaccess.h>
> +#include <linux/wait.h>
> +#include <linux/miscdevice.h>
> +#include <linux/vtpm.h>
> +#include <linux/file.h>
> +#include <linux/anon_inodes.h>
> +#include <linux/poll.h>
> +#include <linux/compat.h>
> +
> +#include "tpm.h"
> +
> +#define VTPM_NUM_DEVICES TPM_NUM_DEVICES
> +
> +struct vtpm_dev {
> +	struct tpm_chip *chip;
> +
> +	u32 flags;                   /* public API flags */
> +
> +	long state;
> +#define STATE_OPENED_BIT        0
> +#define STATE_WAIT_RESPONSE_BIT 1    /* waiting for emulator to give response */

I'd prefer something like this before declaring the struct:

enum vtpm_dev_states {
	VTPM_DEV_OPENED			= BIT(0),
	VTPM_DEV_WAITING_FOR_RESPONSE	= BIT(1),
};

This whole use of set/clear_bit macros when you don't have variable
number of bits just makes code less transparent.

> +
> +	spinlock_t buf_lock;         /* lock for buffers */
> +
> +	wait_queue_head_t wq;
> +
> +	size_t req_len;              /* length of queued TPM request */
> +	size_t resp_len;             /* length of queued TPM response */
> +	u8 buffer[TPM_BUFSIZE];      /* request/response buffer */

I'd use alloc_page() with GFP_USERHIGH in order to be a better citizen
in 32-bit environments. You can kmap() it when you need it.

> +};
> +
> +
> +static void vtpm_delete_device_pair(struct vtpm_dev *vtpm_dev);
> +
> +/*
> + * Functions related to 'server side'
> + */
> +
> +/**
> + * vtpm_fops_read - Read TPM commands on 'server side'
> + *
> + * Return value:
> + *	Number of bytes read or negative error code
> + */
> +static ssize_t vtpm_fops_read(struct file *filp, char __user *buf,
> +			      size_t count, loff_t *off)
> +{
> +	struct vtpm_dev *vtpm_dev = filp->private_data;
> +	size_t len;
> +	int sig, rc;
> +
> +	sig = wait_event_interruptible(vtpm_dev->wq, vtpm_dev->req_len != 0);
> +	if (sig)
> +		return -EINTR;
> +
> +	spin_lock(&vtpm_dev->buf_lock);
> +
> +	len = vtpm_dev->req_len;
> +
> +	if (count < len) {
> +		spin_unlock(&vtpm_dev->buf_lock);
> +		pr_debug("Invalid size in recv: count=%zd, req_len=%zd\n",
> +			 count, len);
> +		return -EIO;
> +	}
> +
> +	rc = copy_to_user(buf, vtpm_dev->buffer, len);
> +	memset(vtpm_dev->buffer, 0, len);
> +	vtpm_dev->req_len = 0;

I saw already Jason's comment but maybe you could just use a mutex
instead of a spinlock?

> +
> +	spin_unlock(&vtpm_dev->buf_lock);
> +
> +	if (rc)
> +		return -EFAULT;
> +
> +	set_bit(STATE_WAIT_RESPONSE_BIT, &vtpm_dev->state);

vtpm_dev->state |= VTPM_DEV_WAIT_FOR_RESPONSE;

> +
> +	return len;
> +}
> +
> +/**
> + * vtpm_fops_write - Write TPM responses on 'server side'
> + *
> + * Return value:
> + *	Number of bytes read or negative error value
> + */
> +static ssize_t vtpm_fops_write(struct file *filp, const char __user *buf,
> +			       size_t count, loff_t *off)
> +{
> +	struct vtpm_dev *vtpm_dev = filp->private_data;
> +
> +	if (count > sizeof(vtpm_dev->buffer) ||
> +	    !test_bit(STATE_WAIT_RESPONSE_BIT, &vtpm_dev->state))
> +		return -EIO;
> +
> +	clear_bit(STATE_WAIT_RESPONSE_BIT, &vtpm_dev->state);

vtpm_dev->state &= ~VTPM_DEV_WAIT_FOR_RESPONSE;

> +
> +	spin_lock(&vtpm_dev->buf_lock);
> +
> +	vtpm_dev->req_len = 0;
> +
> +	if (copy_from_user(vtpm_dev->buffer, buf, count)) {
> +		spin_unlock(&vtpm_dev->buf_lock);
> +		return -EFAULT;
> +	}
> +
> +	vtpm_dev->resp_len = count;
> +
> +	spin_unlock(&vtpm_dev->buf_lock);
> +
> +	wake_up_interruptible(&vtpm_dev->wq);
> +
> +	return count;
> +}
> +
> +/*
> + * vtpm_fops_poll: Poll status on 'server side'
> + *
> + * Return value:
> + *      Poll flags
> + */
> +static unsigned int vtpm_fops_poll(struct file *filp, poll_table *wait)
> +{
> +	struct vtpm_dev *vtpm_dev = filp->private_data;
> +	unsigned ret;
> +
> +	poll_wait(filp, &vtpm_dev->wq, wait);
> +
> +	ret = POLLOUT;
> +	if (vtpm_dev->req_len)
> +		ret |= POLLIN | POLLRDNORM;
> +
> +	return ret;
> +}
> +
> +/*
> + * vtpm_fops_open - Open vTPM device on 'server side'
> + *
> + * Called when setting up the anonymous file descriptor
> + */
> +static void vtpm_fops_open(struct file *filp)
> +{
> +	struct vtpm_dev *vtpm_dev = filp->private_data;
> +
> +	set_bit(STATE_OPENED_BIT, &vtpm_dev->state);

vtpm_dev->state |= VTPM_DEV_OPENED;

> +}
> +
> +/**
> + * vtpm_fops_undo_open - counter-part to vtpm_fops_open
> + *
> + * Call to undo vtpm_fops_open
> + */
> +static void vtpm_fops_undo_open(struct vtpm_dev *vtpm_dev)
> +{
> +	clear_bit(STATE_OPENED_BIT, &vtpm_dev->state);


vtpm_dev->state &= ~VTPM_DEV_OPENED;

> +
> +	/* no more TPM responses -- wake up anyone waiting for them */
> +	wake_up_interruptible(&vtpm_dev->wq);
> +}
> +
> +/*
> + * vtpm_fops_release: Close 'server side'
> + *
> + * Return value:
> + *      Always returns 0.
> + */
> +static int vtpm_fops_release(struct inode *inode, struct file *filp)
> +{
> +	struct vtpm_dev *vtpm_dev = filp->private_data;
> +
> +	filp->private_data = NULL;
> +
> +	vtpm_delete_device_pair(vtpm_dev);
> +
> +	return 0;
> +}
> +
> +static const struct file_operations vtpm_fops = {
> +	.owner = THIS_MODULE,
> +	.llseek = no_llseek,
> +	.read = vtpm_fops_read,
> +	.write = vtpm_fops_write,
> +	.poll = vtpm_fops_poll,
> +	.release = vtpm_fops_release,
> +};
> +
> +/*
> + * Functions invoked by the core TPM driver to send TPM commands to
> + * 'server side' and receive responses from there.
> + */
> +
> +/*
> + * Called when core TPM driver reads TPM responses from 'server side'
> + *
> + * Return value:
> + *      Number of TPM response bytes read, negative error value otherwise
> + */
> +static int vtpm_tpm_op_recv(struct tpm_chip *chip, u8 *buf, size_t count)
> +{
> +	struct vtpm_dev *vtpm_dev = chip->vendor.priv;
> +	int sig;
> +	size_t len;
> +
> +	if (!vtpm_dev)
> +		return -EIO;
> +
> +	/* wait for response or responder gone */
> +	sig = wait_event_interruptible(vtpm_dev->wq,
> +		(vtpm_dev->resp_len != 0
> +		|| !test_bit(STATE_OPENED_BIT, &vtpm_dev->state)));
> +
> +	if (sig)
> +		return -EINTR;
> +
> +	/* process gone ? */
> +	if (!test_bit(STATE_OPENED_BIT, &vtpm_dev->state))
> +		return -EPIPE;
> +
> +	spin_lock(&vtpm_dev->buf_lock);
> +
> +	len = vtpm_dev->resp_len;
> +	if (count < len) {
> +		dev_err(&chip->dev,
> +			"Invalid size in recv: count=%zd, resp_len=%zd\n",
> +			count, len);
> +		len = -EIO;
> +		goto out;
> +	}
> +
> +	memcpy(buf, vtpm_dev->buffer, len);
> +	vtpm_dev->resp_len = 0;
> +
> +out:
> +	spin_unlock(&vtpm_dev->buf_lock);
> +
> +	return len;
> +}
> +
> +/*
> + * Called when core TPM driver forwards TPM requests to 'server side'.
> + *
> + * Return value:
> + *      0 in case of success, negative error value otherwise.
> + */
> +static int vtpm_tpm_op_send(struct tpm_chip *chip, u8 *buf, size_t count)
> +{
> +	struct vtpm_dev *vtpm_dev = chip->vendor.priv;
> +	int rc = 0;
> +
> +	if (!vtpm_dev)
> +		return -EIO;
> +
> +	if (!test_bit(STATE_OPENED_BIT, &vtpm_dev->state))
> +		return -EPIPE;
> +
> +	if (count > sizeof(vtpm_dev->buffer)) {
> +		dev_err(&chip->dev,
> +			"Invalid size in send: count=%zd, buffer size=%zd\n",
> +			count, sizeof(vtpm_dev->buffer));
> +		return -EIO;
> +	}
> +
> +	spin_lock(&vtpm_dev->buf_lock);
> +
> +	vtpm_dev->resp_len = 0;
> +
> +	vtpm_dev->req_len = count;
> +	memcpy(vtpm_dev->buffer, buf, count);
> +
> +	spin_unlock(&vtpm_dev->buf_lock);
> +
> +	wake_up_interruptible(&vtpm_dev->wq);
> +
> +	clear_bit(STATE_WAIT_RESPONSE_BIT, &vtpm_dev->state);

vtpm_dev->state &= ~VTPM_DEV_WAIT_FOR_RESPONSE;

> +
> +	return rc;
> +}
> +
> +static void vtpm_tpm_op_cancel(struct tpm_chip *chip)
> +{
> +	/* not supported */
> +}
> +
> +static u8 vtpm_tpm_op_status(struct tpm_chip *chip)
> +{
> +	return 0;
> +}
> +
> +static bool vtpm_tpm_req_canceled(struct tpm_chip  *chip, u8 status)
> +{
> +	return (status == 0);
> +}
> +
> +static const struct tpm_class_ops vtpm_tpm_ops = {
> +	.recv = vtpm_tpm_op_recv,
> +	.send = vtpm_tpm_op_send,
> +	.cancel = vtpm_tpm_op_cancel,
> +	.status = vtpm_tpm_op_status,
> +	.req_complete_mask = 0,
> +	.req_complete_val = 0,
> +	.req_canceled = vtpm_tpm_req_canceled,
> +};
> +
> +/*
> + * Code related to creation and deletion of device pairs
> + */
> +static struct vtpm_dev *vtpm_create_vtpm_dev(void)
> +{
> +	struct vtpm_dev *vtpm_dev;
> +	struct tpm_chip *chip;
> +	int err;
> +
> +	vtpm_dev = kzalloc(sizeof(*vtpm_dev), GFP_KERNEL);
> +	if (vtpm_dev == NULL)
> +		return ERR_PTR(-ENOMEM);
> +
> +	init_waitqueue_head(&vtpm_dev->wq);
> +	spin_lock_init(&vtpm_dev->buf_lock);
> +
> +	chip = tpm_chip_alloc(NULL, &vtpm_tpm_ops);
> +	if (IS_ERR(chip)) {
> +		err = PTR_ERR(chip);
> +		goto err_vtpm_dev_free;
> +	}
> +	chip->vendor.priv = vtpm_dev;
> +	chip->vendor.irq = 1;
> +
> +	vtpm_dev->chip = chip;
> +
> +	return vtpm_dev;
> +
> +err_vtpm_dev_free:
> +	kfree(vtpm_dev);
> +
> +	return ERR_PTR(err);
> +}
> +
> +/*
> + * Undo what has been done in vtpm_create_vtpm_dev
> + */
> +static inline void vtpm_delete_vtpm_dev(struct vtpm_dev *vtpm_dev)
> +{
> +	put_device(&vtpm_dev->chip->dev); /* frees chip */
> +	kfree(vtpm_dev);
> +}
> +
> +/*
> + * Create a /dev/tpm%d and 'server side' file descriptor pair
> + *
> + * Return value:
> + *      Returns file pointer on success, an error value otherwise
> + */
> +static struct file *vtpm_create_device_pair(
> +				       struct vtpm_new_pair *vtpm_new_pair)
> +{
> +	struct vtpm_dev *vtpm_dev;
> +	int rc, fd;
> +	struct file *file;
> +
> +	vtpm_dev = vtpm_create_vtpm_dev();
> +	if (IS_ERR(vtpm_dev))
> +		return ERR_CAST(vtpm_dev);
> +
> +	vtpm_dev->flags = vtpm_new_pair->flags;
> +
> +	/* setup an anonymous file for the server-side */
> +	fd = get_unused_fd_flags(O_RDWR);
> +	if (fd < 0) {
> +		rc = fd;
> +		goto err_delete_vtpm_dev;
> +	}
> +
> +	file = anon_inode_getfile("[vtpms]", &vtpm_fops, vtpm_dev, O_RDWR);
> +	if (IS_ERR(file)) {
> +		rc = PTR_ERR(file);
> +		goto err_put_unused_fd;
> +	}
> +
> +	/* from now on we can unwind with put_unused_fd() + fput() */
> +	/* simulate an open() on the server side */
> +	vtpm_fops_open(file);
> +
> +	if (vtpm_dev->flags & VTPM_FLAG_TPM2)
> +		vtpm_dev->chip->flags |= TPM_CHIP_FLAG_TPM2;
> +
> +	rc = tpm_chip_register(vtpm_dev->chip);
> +	if (rc)
> +		goto err_vtpm_fput;
> +
> +	vtpm_new_pair->fd = fd;
> +	vtpm_new_pair->major = MAJOR(vtpm_dev->chip->dev.devt);
> +	vtpm_new_pair->minor = MINOR(vtpm_dev->chip->dev.devt);
> +	vtpm_new_pair->tpm_dev_num = vtpm_dev->chip->dev_num;
> +
> +	return file;
> +
> +err_vtpm_fput:
> +	put_unused_fd(fd);
> +	fput(file);
> +
> +	return ERR_PTR(rc);
> +
> +err_put_unused_fd:
> +	put_unused_fd(fd);
> +
> +err_delete_vtpm_dev:
> +	vtpm_delete_vtpm_dev(vtpm_dev);
> +
> +	return ERR_PTR(rc);
> +}
> +
> +/*
> + * Counter part to vtpm_create_device_pair.
> + */
> +static void vtpm_delete_device_pair(struct vtpm_dev *vtpm_dev)
> +{
> +	tpm_chip_unregister(vtpm_dev->chip);
> +
> +	vtpm_fops_undo_open(vtpm_dev);
> +
> +	vtpm_delete_vtpm_dev(vtpm_dev);
> +}
> +
> +/*
> + * Code related to the control device /dev/vtpmx
> + */
> +
> +/*
> + * vtpmx_fops_ioctl: ioctl on /dev/vtpmx
> + *
> + * Return value:
> + *      Returns 0 on success, a negative error code otherwise.
> + */
> +static long vtpmx_fops_ioctl(struct file *f, unsigned int ioctl,
> +			    unsigned long arg)
> +{
> +	void __user *argp = (void __user *)arg;
> +	struct vtpm_new_pair *vtpm_new_pair_p;
> +	struct vtpm_new_pair vtpm_new_pair;
> +	struct file *file;
> +
> +	switch (ioctl) {
> +	case VTPM_NEW_DEV:
> +		if (!capable(CAP_SYS_ADMIN))
> +			return -EPERM;
> +		vtpm_new_pair_p = argp;
> +		if (copy_from_user(&vtpm_new_pair, vtpm_new_pair_p,
> +				   sizeof(vtpm_new_pair)))
> +			return -EFAULT;
> +		file = vtpm_create_device_pair(&vtpm_new_pair);
> +		if (IS_ERR(file))
> +			return PTR_ERR(file);
> +		if (copy_to_user(vtpm_new_pair_p, &vtpm_new_pair,
> +				 sizeof(vtpm_new_pair))) {
> +			put_unused_fd(vtpm_new_pair.fd);
> +			fput(file);
> +			return -EFAULT;
> +		}
> +
> +		fd_install(vtpm_new_pair.fd, file);
> +		return 0;
> +
> +	default:
> +		return -EINVAL;
> +	}
> +}
> +
> +#ifdef CONFIG_COMPAT
> +static long vtpmx_fops_compat_ioctl(struct file *f, unsigned int ioctl,
> +				    unsigned long arg)
> +{
> +	return vtpmx_fops_ioctl(f, ioctl, (unsigned long)compat_ptr(arg));
> +}
> +#endif
> +
> +static const struct file_operations vtpmx_fops = {
> +	.owner = THIS_MODULE,
> +	.unlocked_ioctl = vtpmx_fops_ioctl,
> +#ifdef CONFIG_COMPAT
> +	.compat_ioctl = vtpmx_fops_compat_ioctl,
> +#endif
> +	.llseek = noop_llseek,
> +};
> +
> +static struct miscdevice vtpmx_miscdev = {
> +	.minor = MISC_DYNAMIC_MINOR,
> +	.name = "vtpmx",
> +	.fops = &vtpmx_fops,
> +};
> +
> +static int vtpmx_init(void)
> +{
> +	return misc_register(&vtpmx_miscdev);
> +}
> +
> +static void vtpmx_cleanup(void)
> +{
> +	misc_deregister(&vtpmx_miscdev);
> +}
> +
> +static int __init vtpm_module_init(void)
> +{
> +	int rc;
> +
> +	rc = vtpmx_init();
> +	if (rc) {
> +		pr_err("couldn't create vtpmx device\n");
> +		return rc;
> +	}
> +
> +	return 0;
> +}
> +
> +static void __exit vtpm_module_exit(void)
> +{
> +	vtpmx_cleanup();
> +}
> +
> +module_init(vtpm_module_init);
> +module_exit(vtpm_module_exit);
> +
> +MODULE_AUTHOR("Stefan Berger (stefanb-r/Jw6+rmf7HQT0dZR+AlfA@public.gmane.org)");
> +MODULE_DESCRIPTION("vTPM Driver");
> +MODULE_VERSION("0.1");
> +MODULE_LICENSE("GPL");
> diff --git a/include/uapi/linux/Kbuild b/include/uapi/linux/Kbuild
> index c2e5d6c..c194d61 100644
> --- a/include/uapi/linux/Kbuild
> +++ b/include/uapi/linux/Kbuild
> @@ -449,6 +449,7 @@ header-y += virtio_scsi.h
>  header-y += virtio_types.h
>  header-y += vm_sockets.h
>  header-y += vt.h
> +header-y += vtpm.h
>  header-y += wait.h
>  header-y += wanrouter.h
>  header-y += watchdog.h
> diff --git a/include/uapi/linux/vtpm.h b/include/uapi/linux/vtpm.h
> new file mode 100644
> index 0000000..aef8733
> --- /dev/null
> +++ b/include/uapi/linux/vtpm.h
> @@ -0,0 +1,38 @@
> +/*
> + * Definitions for the VTPM interface
> + * Copyright (c) 2015, 2016, IBM Corporation
> + *
> + * This program is free software; you can redistribute it and/or modify it
> + * under the terms and conditions of the GNU General Public License,
> + * version 2, as published by the Free Software Foundation.
> + *
> + * This program is distributed in the hope it will be useful, but WITHOUT
> + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
> + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
> + * more details.
> + */
> +
> +#ifndef _UAPI_LINUX_VTPM_H
> +#define _UAPI_LINUX_VTPM_H
> +
> +#include <linux/types.h>
> +#include <linux/ioctl.h>
> +
> +/* ioctls */
> +
> +struct vtpm_new_pair {
> +	__u32 flags;         /* input */
> +	__u32 tpm_dev_num;   /* output */
> +	__u32 fd;            /* output */
> +	__u32 major;         /* output */
> +	__u32 minor;         /* output */
> +};
> +
> +/* above flags */
> +#define VTPM_FLAG_TPM2           1  /* emulator is TPM 2 */
> +
> +#define VTPM_TPM 0xa0
> +
> +#define VTPM_NEW_DEV         _IOW(VTPM_TPM, 0x00, struct vtpm_new_pair)
> +
> +#endif /* _UAPI_LINUX_VTPM_H */
> -- 
> 2.4.3
> 

/Jarkko

------------------------------------------------------------------------------
Site24x7 APM Insight: Get Deep Visibility into Application Performance
APM + Mobile APM + RUM: Monitor 3 App instances at just $35/Month
Monitor end-to-end web transactions and take corrective actions now
Troubleshoot faster and improve end-user experience. Signup Now!
http://pubads.g.doubleclick.net/gampad/clk?id=272487151&iu=/4140

^ permalink raw reply	[flat|nested] 60+ messages in thread

* Re: [PATCH v3 06/11] tpm: Split out the devm stuff from tpmm_chip_alloc
       [not found]             ` <20160222221328.GA27228-ePGOBjL8dl3ta4EC/59zMFaTQe2KTcn/@public.gmane.org>
  2016-02-23  0:45               ` Stefan Berger
@ 2016-02-23 11:31               ` Jarkko Sakkinen
  1 sibling, 0 replies; 60+ messages in thread
From: Jarkko Sakkinen @ 2016-02-23 11:31 UTC (permalink / raw)
  To: Jason Gunthorpe; +Cc: tpmdd-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f

On Mon, Feb 22, 2016 at 03:13:28PM -0700, Jason Gunthorpe wrote:
> On Mon, Feb 22, 2016 at 11:14:14PM +0200, Jarkko Sakkinen wrote:
> > On Fri, Feb 19, 2016 at 07:42:03AM -0500, Stefan Berger wrote:
> > > From: Jason Gunthorpe <jgunthorpe-ePGOBjL8dl3ta4EC/59zMFaTQe2KTcn/@public.gmane.org>
> > > 
> > > tpm_chip_alloc becomes a typical subsystem allocate call.
> > 
> > Maybe a more verbose commit message?
> 
> What more do you want to say?

I would just add that:

"This is needed for virtual devices because they are not associated to
any parent."

Of course when you read the patch set in reverse order it is clear but
this one sentence would make it easier to read it when you iterate it
from beginning :)

/Jarkko


> > >  	spin_lock(&driver_lock);
> > >  	chip->dev_num = find_first_zero_bit(dev_mask, TPM_NUM_DEVICES);
> > > +	if (chip->dev_num < TPM_NUM_DEVICES)
> > > +		set_bit(chip->dev_num, dev_mask);
> > 
> > I guess this change should a separate patch.
> 
> Hurm, Stefan? This was not in the patch I sent you? This hunk looks
> incomplete to me, and replaced by the IDR stuff anyhow. Drop it?
> 
> You need to put your Signed-off-by on patches you make notable changes
> to, this one would qualify
> 
> Jason

------------------------------------------------------------------------------
Site24x7 APM Insight: Get Deep Visibility into Application Performance
APM + Mobile APM + RUM: Monitor 3 App instances at just $35/Month
Monitor end-to-end web transactions and take corrective actions now
Troubleshoot faster and improve end-user experience. Signup Now!
http://pubads.g.doubleclick.net/gampad/clk?id=272487151&iu=/4140

^ permalink raw reply	[flat|nested] 60+ messages in thread

* Re: [PATCH v3 09/11] tpm: Driver for supporting multiple emulated TPMs
       [not found]         ` <20160223102211.GA9474-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
@ 2016-02-23 12:09           ` Stefan Berger
  0 siblings, 0 replies; 60+ messages in thread
From: Stefan Berger @ 2016-02-23 12:09 UTC (permalink / raw)
  To: Jarkko Sakkinen; +Cc: tpmdd-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f


[-- Attachment #1.1: Type: text/plain, Size: 6119 bytes --]

Jarkko Sakkinen <jarkko.sakkinen-VuQAYsv1563Yd54FQh9/CA@public.gmane.org> wrote on 02/23/2016 
05:22:11 AM:


> 
> On Fri, Feb 19, 2016 at 07:42:06AM -0500, Stefan Berger wrote:
> > This patch implements a driver for supporting multiple emulated TPMs 
in a
> > system.
> > 
> > The driver implements a device /dev/vtpmx that is used to created
> > a client device pair /dev/tpmX (e.g., /dev/tpm10) and a server side 
that
> > is accessed using a file descriptor returned by an ioctl.
> > The device /dev/tpmX is the usual TPM device created by the core TPM
> > driver. Applications or kernel subsystems can send TPM commands to it
> > and the corresponding server-side file descriptor receives these
> > commands and delivers them to an emulated TPM.
> > 
> > Signed-off-by: Stefan Berger <stefanb-23VcF4HTsmIX0ybBhKVfKdBPR1lH4CV8@public.gmane.org>
> > ---
> >  drivers/char/tpm/Kconfig    |  10 +
> >  drivers/char/tpm/Makefile   |   1 +
> >  drivers/char/tpm/tpm-vtpm.c | 543 +++++++++++++++++++++++++++++++
> +++++++++++++
> >  include/uapi/linux/Kbuild   |   1 +
> >  include/uapi/linux/vtpm.h   |  38 ++++
> >  5 files changed, 593 insertions(+)
> >  create mode 100644 drivers/char/tpm/tpm-vtpm.c
> >  create mode 100644 include/uapi/linux/vtpm.h
> > 
> > diff --git a/drivers/char/tpm/Kconfig b/drivers/char/tpm/Kconfig
> > index 3b84a8b..4c4e843 100644
> > --- a/drivers/char/tpm/Kconfig
> > +++ b/drivers/char/tpm/Kconfig
> > @@ -122,5 +122,15 @@ config TCG_CRB
> >       from within Linux.  To compile this driver as a module, choose
> >       M here; the module will be called tpm_crb.
> > 

> > +
> > +struct vtpm_dev {
> > +   struct tpm_chip *chip;
> > +
> > +   u32 flags;                   /* public API flags */
> > +
> > +   long state;
> > +#define STATE_OPENED_BIT        0
> > +#define STATE_WAIT_RESPONSE_BIT 1    /* waiting for emulator to 
> give response */
> 
> I'd prefer something like this before declaring the struct:
> 
> enum vtpm_dev_states {
>    VTPM_DEV_OPENED         = BIT(0),
>    VTPM_DEV_WAITING_FOR_RESPONSE   = BIT(1),
> };
> 
> This whole use of set/clear_bit macros when you don't have variable
> number of bits just makes code less transparent.

Though read-modify-writes with the bit ops are atomic and need no spinlock 
protection to avoid concurrency mess. Now we would need a spinlock for 
such ops.


> 
> > +
> > +   spinlock_t buf_lock;         /* lock for buffers */
> > +
> > +   wait_queue_head_t wq;
> > +
> > +   size_t req_len;              /* length of queued TPM request */
> > +   size_t resp_len;             /* length of queued TPM response */
> > +   u8 buffer[TPM_BUFSIZE];      /* request/response buffer */
> 
> I'd use alloc_page() with GFP_USERHIGH in order to be a better citizen
> in 32-bit environments. You can kmap() it when you need it.
> 
> > +};
> > +
> > +
> > +static void vtpm_delete_device_pair(struct vtpm_dev *vtpm_dev);
> > +
> > +/*
> > + * Functions related to 'server side'
> > + */
> > +
> > +/**
> > + * vtpm_fops_read - Read TPM commands on 'server side'
> > + *
> > + * Return value:
> > + *   Number of bytes read or negative error code
> > + */
> > +static ssize_t vtpm_fops_read(struct file *filp, char __user *buf,
> > +               size_t count, loff_t *off)
> > +{
> > +   struct vtpm_dev *vtpm_dev = filp->private_data;
> > +   size_t len;
> > +   int sig, rc;
> > +
> > +   sig = wait_event_interruptible(vtpm_dev->wq, vtpm_dev->req_len != 
0);
> > +   if (sig)
> > +      return -EINTR;
> > +
> > +   spin_lock(&vtpm_dev->buf_lock);
> > +
> > +   len = vtpm_dev->req_len;
> > +
> > +   if (count < len) {
> > +      spin_unlock(&vtpm_dev->buf_lock);
> > +      pr_debug("Invalid size in recv: count=%zd, req_len=%zd\n",
> > +          count, len);
> > +      return -EIO;
> > +   }
> > +
> > +   rc = copy_to_user(buf, vtpm_dev->buffer, len);
> > +   memset(vtpm_dev->buffer, 0, len);
> > +   vtpm_dev->req_len = 0;
> 
> I saw already Jason's comment but maybe you could just use a mutex
> instead of a spinlock?

I'll let Jason respond to it whether it's the difference between spinlock 
and mutex or just no locking at all. If no locking, I'd be inclined to 
work with two buffers, one for requests and one for responses.



> > +
> > +/*
> > + * Called when core TPM driver reads TPM responses from 'server side'
> > + *
> > + * Return value:
> > + *      Number of TPM response bytes read, negative error value 
otherwise
> > + */
> > +static int vtpm_tpm_op_recv(struct tpm_chip *chip, u8 *buf, size_t 
count)
> > +{
> > +   struct vtpm_dev *vtpm_dev = chip->vendor.priv;
> > +   int sig;
> > +   size_t len;
> > +
> > +   if (!vtpm_dev)
> > +      return -EIO;
> > +
> > +   /* wait for response or responder gone */
> > +   sig = wait_event_interruptible(vtpm_dev->wq,
> > +      (vtpm_dev->resp_len != 0
> > +      || !test_bit(STATE_OPENED_BIT, &vtpm_dev->state)));
> > +
> > +   if (sig)
> > +      return -EINTR;


With us not operating this driver in interrupt mode, we don't need the 
wait_event_interruptible if we make another change further below:


> > +
> > +static u8 vtpm_tpm_op_status(struct tpm_chip *chip)
> > +{
> > +   return 0;
> > +}


I modified this to 

static u8 vtpm_tpm_op_status(struct tpm_chip *chip)
{
        return (chip->resp_len) ? VTPM_REQ_COMPLETE_FLAG : 0;
}


> > +
> > +static bool vtpm_tpm_req_canceled(struct tpm_chip  *chip, u8 status)
> > +{
> > +   return (status == 0);
> > +}

This will have to remain like this.

> > +
> > +static const struct tpm_class_ops vtpm_tpm_ops = {
> > +   .recv = vtpm_tpm_op_recv,
> > +   .send = vtpm_tpm_op_send,
> > +   .cancel = vtpm_tpm_op_cancel,
> > +   .status = vtpm_tpm_op_status,
> > +   .req_complete_mask = 0,
> > +   .req_complete_val = 0,

        .req_complete_mask = VTPM_REQ_COMPLETE_FLAG,
        .req_complete_val = VTPM_REQ_COMPLETE_FLAG,

with

#define VTPM_REQ_COMPLETE_FLAG  BIT(0)


Agreed?

   Stefan



[-- Attachment #1.2: Type: text/html, Size: 9332 bytes --]

[-- Attachment #2: Type: text/plain, Size: 413 bytes --]

------------------------------------------------------------------------------
Site24x7 APM Insight: Get Deep Visibility into Application Performance
APM + Mobile APM + RUM: Monitor 3 App instances at just $35/Month
Monitor end-to-end web transactions and take corrective actions now
Troubleshoot faster and improve end-user experience. Signup Now!
http://pubads.g.doubleclick.net/gampad/clk?id=272487151&iu=/4140

[-- Attachment #3: Type: text/plain, Size: 192 bytes --]

_______________________________________________
tpmdd-devel mailing list
tpmdd-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f@public.gmane.org
https://lists.sourceforge.net/lists/listinfo/tpmdd-devel

^ permalink raw reply	[flat|nested] 60+ messages in thread

* Re: [PATCH v3 09/11] tpm: Driver for supporting multiple emulated TPMs
       [not found]           ` <201602231210.u1NCAD6D017196-CUdSWdNILC7ImUpY6SP3GEEOCMrvLtNR@public.gmane.org>
@ 2016-02-23 18:36             ` Jarkko Sakkinen
  0 siblings, 0 replies; 60+ messages in thread
From: Jarkko Sakkinen @ 2016-02-23 18:36 UTC (permalink / raw)
  To: Stefan Berger; +Cc: tpmdd-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f

On Tue, Feb 23, 2016 at 07:09:44AM -0500, Stefan Berger wrote:
>    Jarkko Sakkinen <jarkko.sakkinen-VuQAYsv1563Yd54FQh9/CA@public.gmane.org> wrote on 02/23/2016
>    05:22:11 AM:
>
>    > > +struct vtpm_dev {
>    > > +   struct tpm_chip *chip;
>    > > +
>    > > +   u32 flags;                   /* public API flags */
>    > > +
>    > > +   long state;
>    > > +#define STATE_OPENED_BIT        0
>    > > +#define STATE_WAIT_RESPONSE_BIT 1    /* waiting for emulator to
>    > give response */
>    >
>    > I'd prefer something like this before declaring the struct:
>    >
>    > enum vtpm_dev_states {
>    >    VTPM_DEV_OPENED         = BIT(0),
>    >    VTPM_DEV_WAITING_FOR_RESPONSE   = BIT(1),
>    > };
>    >
>    > This whole use of set/clear_bit macros when you don't have variable
>    > number of bits just makes code less transparent.
> 
>    Though read-modify-writes with the bit ops are atomic and need no spinlock
>    protection to avoid concurrency mess. Now we would need a spinlock for
>    such ops.

Sounds messy. You should refer to flags inside buf_lock like you
otherwise do.

>    I'll let Jason respond to it whether it's the difference between spinlock
>    and mutex or just no locking at all. If no locking, I'd be inclined to
>    work with two buffers, one for requests and one for responses.

You have to switch to mutex because copy_to_user and copy_from_user can
sleep. How would you handle mutual exclusion without any locking (two
concurrent read calls)?

/Jarkko

------------------------------------------------------------------------------
Site24x7 APM Insight: Get Deep Visibility into Application Performance
APM + Mobile APM + RUM: Monitor 3 App instances at just $35/Month
Monitor end-to-end web transactions and take corrective actions now
Troubleshoot faster and improve end-user experience. Signup Now!
http://pubads.g.doubleclick.net/gampad/clk?id=272487151&iu=/4140

^ permalink raw reply	[flat|nested] 60+ messages in thread

* Re: [PATCH v3 04/11] tpm: Provide strong locking for device removal
       [not found]             ` <20160222222017.GC27228-ePGOBjL8dl3ta4EC/59zMFaTQe2KTcn/@public.gmane.org>
@ 2016-02-23 19:40               ` Jarkko Sakkinen
       [not found]                 ` <20160223194014.GA5241-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
  2016-02-23 20:43               ` Jarkko Sakkinen
  1 sibling, 1 reply; 60+ messages in thread
From: Jarkko Sakkinen @ 2016-02-23 19:40 UTC (permalink / raw)
  To: Jason Gunthorpe; +Cc: tpmdd-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f

On Mon, Feb 22, 2016 at 03:20:17PM -0700, Jason Gunthorpe wrote:
> On Mon, Feb 22, 2016 at 11:08:59PM +0200, Jarkko Sakkinen wrote:
> > On Fri, Feb 19, 2016 at 07:42:01AM -0500, Stefan Berger wrote:
> > > From: Jason Gunthorpe <jgunthorpe-ePGOBjL8dl3ta4EC/59zMFaTQe2KTcn/@public.gmane.org>
> > > 
> > > Add a read/write semaphore around the ops function pointers so
> > > ops can be set to null when the driver un-registers.
> > > 
> > > Previously the tpm core expected module locking to be enough to
> > > ensure that tpm_unregister could not be called during certain times,
> > > however that hasn't been sufficient for a long time.
> > 
> > Could you be more concrete with the scenario? You could describe
> > a sequence of events where this could happen.
> 
> echo 1 > /sys/.../remove
> 
> Is basically the same as a module unload without requiring module
> unload. module locking cannot be relied upon for correctness like this
> ever since hot remove was added to the kernel.

The 'remove' file applies only to PCI devices AFAIK.

/Jarkko

------------------------------------------------------------------------------
Site24x7 APM Insight: Get Deep Visibility into Application Performance
APM + Mobile APM + RUM: Monitor 3 App instances at just $35/Month
Monitor end-to-end web transactions and take corrective actions now
Troubleshoot faster and improve end-user experience. Signup Now!
http://pubads.g.doubleclick.net/gampad/clk?id=272487151&iu=/4140

^ permalink raw reply	[flat|nested] 60+ messages in thread

* Re: [PATCH v3 04/11] tpm: Provide strong locking for device removal
       [not found]                 ` <20160223194014.GA5241-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
@ 2016-02-23 19:52                   ` Jason Gunthorpe
       [not found]                     ` <20160223195246.GC389-ePGOBjL8dl3ta4EC/59zMFaTQe2KTcn/@public.gmane.org>
  0 siblings, 1 reply; 60+ messages in thread
From: Jason Gunthorpe @ 2016-02-23 19:52 UTC (permalink / raw)
  To: Jarkko Sakkinen; +Cc: tpmdd-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f

On Tue, Feb 23, 2016 at 09:40:14PM +0200, Jarkko Sakkinen wrote:

> > echo 1 > /sys/.../remove
> > 
> > Is basically the same as a module unload without requiring module
> > unload. module locking cannot be relied upon for correctness like this
> > ever since hot remove was added to the kernel.
> 
> The 'remove' file applies only to PCI devices AFAIK.

Not only, PCI has remove but many other bus types do too, eg i2c, spi,
openfirmware, etc can all be hot-removed in various ways.

As a general subsystem core tpm cannot assume it's drivers are only
using non-hotplugable devices.

Jason

------------------------------------------------------------------------------
Site24x7 APM Insight: Get Deep Visibility into Application Performance
APM + Mobile APM + RUM: Monitor 3 App instances at just $35/Month
Monitor end-to-end web transactions and take corrective actions now
Troubleshoot faster and improve end-user experience. Signup Now!
http://pubads.g.doubleclick.net/gampad/clk?id=272487151&iu=/4140

^ permalink raw reply	[flat|nested] 60+ messages in thread

* Re: [PATCH v3 04/11] tpm: Provide strong locking for device removal
       [not found]                     ` <20160223195246.GC389-ePGOBjL8dl3ta4EC/59zMFaTQe2KTcn/@public.gmane.org>
@ 2016-02-23 20:36                       ` Jarkko Sakkinen
  0 siblings, 0 replies; 60+ messages in thread
From: Jarkko Sakkinen @ 2016-02-23 20:36 UTC (permalink / raw)
  To: Jason Gunthorpe; +Cc: tpmdd-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f

On Tue, Feb 23, 2016 at 12:52:46PM -0700, Jason Gunthorpe wrote:
> On Tue, Feb 23, 2016 at 09:40:14PM +0200, Jarkko Sakkinen wrote:
> 
> > > echo 1 > /sys/.../remove
> > > 
> > > Is basically the same as a module unload without requiring module
> > > unload. module locking cannot be relied upon for correctness like this
> > > ever since hot remove was added to the kernel.
> > 
> > The 'remove' file applies only to PCI devices AFAIK.
> 
> Not only, PCI has remove but many other bus types do too, eg i2c, spi,
> openfirmware, etc can all be hot-removed in various ways.
> 
> As a general subsystem core tpm cannot assume it's drivers are only
> using non-hotplugable devices.

Right, various ways, got confused from a concrete example :)

/Jarkko

------------------------------------------------------------------------------
Site24x7 APM Insight: Get Deep Visibility into Application Performance
APM + Mobile APM + RUM: Monitor 3 App instances at just $35/Month
Monitor end-to-end web transactions and take corrective actions now
Troubleshoot faster and improve end-user experience. Signup Now!
http://pubads.g.doubleclick.net/gampad/clk?id=272487151&iu=/4140

^ permalink raw reply	[flat|nested] 60+ messages in thread

* Re: [PATCH v3 04/11] tpm: Provide strong locking for device removal
       [not found]             ` <20160222222017.GC27228-ePGOBjL8dl3ta4EC/59zMFaTQe2KTcn/@public.gmane.org>
  2016-02-23 19:40               ` Jarkko Sakkinen
@ 2016-02-23 20:43               ` Jarkko Sakkinen
  1 sibling, 0 replies; 60+ messages in thread
From: Jarkko Sakkinen @ 2016-02-23 20:43 UTC (permalink / raw)
  To: Jason Gunthorpe; +Cc: tpmdd-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f

On Mon, Feb 22, 2016 at 03:20:17PM -0700, Jason Gunthorpe wrote:
> > I'm just thinking is the try_module_get() and module_put() even
> > necessary after this change? You know that device is not unregistered
> > from chip->ops field, which is protected by that RW-semaphore.
> 
> The module locking is not about correctness. Some subsystems will hold
> the module lock on their driver specifically to prevent rmmod as a
> hint to the user that the driver module is being used by an open
> /dev/tpmX for instance. Eg rtc does that.
> 
> We need to decide if we want that for TPM or not. Orthogonal issue.
> 
> I'm OK with getting rid of the module lock, TPM has a long lived
> user space daemon, rtc does not.

You might want to use TPM without a daemon on small embedded devices
but on the other hand in these use cases the environment is fairly
well controlled. I'm not sure which side to take.

> Jason

/Jarkko

------------------------------------------------------------------------------
Site24x7 APM Insight: Get Deep Visibility into Application Performance
APM + Mobile APM + RUM: Monitor 3 App instances at just $35/Month
Monitor end-to-end web transactions and take corrective actions now
Troubleshoot faster and improve end-user experience. Signup Now!
http://pubads.g.doubleclick.net/gampad/clk?id=272487151&iu=/4140

^ permalink raw reply	[flat|nested] 60+ messages in thread

* Re: [PATCH v3 07/11] tpm: Replace device number bitmap with IDR
       [not found]               ` <20160223021606.GC26177-ePGOBjL8dl3ta4EC/59zMFaTQe2KTcn/@public.gmane.org>
@ 2016-02-23 23:04                 ` Stefan Berger
  0 siblings, 0 replies; 60+ messages in thread
From: Stefan Berger @ 2016-02-23 23:04 UTC (permalink / raw)
  To: Jason Gunthorpe; +Cc: tpmdd-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f


[-- Attachment #1.1: Type: text/plain, Size: 1502 bytes --]

Jason Gunthorpe <jgunthorpe-ePGOBjL8dl3ta4EC/59zMFaTQe2KTcn/@public.gmane.org> wrote on 02/22/2016 
09:16:06 PM:

> 
> On Mon, Feb 22, 2016 at 08:15:38PM -0500, Stefan Berger wrote:
> > > - Tear down /dev/tpmX, sysfs and all other user accessible entry
> > >   points
> > > - Do device_del (get rid of all the sysfs stuff)
> > > - NULL the IDR (disables kAPI access and allow reuse of the ID)
> > > - NULL the ops (flush in-progress access now that new access is 
> impossible)
> > 

> 
> > - Free the chip's device number from the IDR (makes IDR re-usable;
> must happen
> > after /dev/tpmX is released to avoid clashes
> 
> With this new arrangment the idr_remove can happen directly after
> device_del and we can avoid the intermediate state of a NULL'd entry,
> which seems slightly simplifying. Before there was the problem because
> vtpm was using a struct device, but that is gone now.

Let's stay with the 2 stage removal unrolled in the functions that are the 
opposite where the do the staged adding.

I just ran into the problem that when tpm_chip_register wasn't called due 
to me killing the process while the driver task attempted to get the 
durations, the tpm_chip_unregister didn't get called either. So we lost 
ID's in the IDR. So we allocate the id in tpm_chip_alloc and free it 
before the kfree(chip) in tpm_dev_release. We put the chip on the IDR in 
tpm_dev_add_device and remove it in tpm_dev_del_device -- nice and 
symmetric.

  Stefan



[-- Attachment #1.2: Type: text/html, Size: 1776 bytes --]

[-- Attachment #2: Type: text/plain, Size: 413 bytes --]

------------------------------------------------------------------------------
Site24x7 APM Insight: Get Deep Visibility into Application Performance
APM + Mobile APM + RUM: Monitor 3 App instances at just $35/Month
Monitor end-to-end web transactions and take corrective actions now
Troubleshoot faster and improve end-user experience. Signup Now!
http://pubads.g.doubleclick.net/gampad/clk?id=272487151&iu=/4140

[-- Attachment #3: Type: text/plain, Size: 192 bytes --]

_______________________________________________
tpmdd-devel mailing list
tpmdd-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f@public.gmane.org
https://lists.sourceforge.net/lists/listinfo/tpmdd-devel

^ permalink raw reply	[flat|nested] 60+ messages in thread

* Re: [PATCH v3 07/11] tpm: Replace device number bitmap with IDR
       [not found]                 ` <201602232305.u1NN521L020589-Rn83F4s8Lwc+UXBhvPuGgqsjOiXwFzmk@public.gmane.org>
@ 2016-02-23 23:18                   ` Jason Gunthorpe
  0 siblings, 0 replies; 60+ messages in thread
From: Jason Gunthorpe @ 2016-02-23 23:18 UTC (permalink / raw)
  To: Stefan Berger; +Cc: tpmdd-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f

On Tue, Feb 23, 2016 at 06:04:38PM -0500, Stefan Berger wrote:

>    I just ran into the problem that when tpm_chip_register wasn't called
>    due to me killing the process while the driver task attempted to get
>    the durations, the tpm_chip_unregister didn't get called either.

Hmm. Okay. We can't move the idr alloc out of tpm_chip_alloc to combat
that, so we are stuck with the nulls.

Jason

------------------------------------------------------------------------------
Site24x7 APM Insight: Get Deep Visibility into Application Performance
APM + Mobile APM + RUM: Monitor 3 App instances at just $35/Month
Monitor end-to-end web transactions and take corrective actions now
Troubleshoot faster and improve end-user experience. Signup Now!
http://pubads.g.doubleclick.net/gampad/clk?id=272487151&iu=/4140

^ permalink raw reply	[flat|nested] 60+ messages in thread

* Re: [PATCH v3 09/11] tpm: Driver for supporting multiple emulated TPMs
       [not found]               ` <20160223021730.GD26177-ePGOBjL8dl3ta4EC/59zMFaTQe2KTcn/@public.gmane.org>
@ 2016-02-24 23:10                 ` Stefan Berger
       [not found]                   ` <201602242306.u1ON6qGP030251-8DuMPbUlb4HImUpY6SP3GEEOCMrvLtNR@public.gmane.org>
  0 siblings, 1 reply; 60+ messages in thread
From: Stefan Berger @ 2016-02-24 23:10 UTC (permalink / raw)
  To: Jason Gunthorpe; +Cc: tpmdd-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f


[-- Attachment #1.1: Type: text/plain, Size: 1967 bytes --]

Jason Gunthorpe <jgunthorpe-ePGOBjL8dl3ta4EC/59zMFaTQe2KTcn/@public.gmane.org> wrote on 02/22/2016 
09:17:30 PM:

> 
> On Mon, Feb 22, 2016 at 08:45:51PM -0500, Stefan Berger wrote:
> 
> > Two things:
> > - the ioctl takes flags; should we return an error on flags that are 
not
> > supported but set by userspace?
> 
> Typically yes. Otherwise you cannot introduce new flags in
> future.
> 
> > - the sysfs works but I wished we could give some control over 
> whether it shows
> > any entries. Can we have a flag in the ioctl on whether to show 
> these files in
> > sysfs?
> 
> That is something to address in the future namespace patch series I
> expect you'll prepare..

It may be a while until we get there ... nevertheless it may be worth some 
thought already.

So we have at least two choices for how to avoid data leakage via sysfs; 
the problem is that sysfs shows all vtpm devices in all containers; the 
good thing is that at least Docker (other mgmt. stacks probably also) 
mount sysfs read-only into 'normal' containers, so that writing (even only 
to cancel) isn't typically possible.

1) allow user space to set a flag whether the sysfs entries are to be 
registered; a typical container mgmt. stack would set the flag to avoid 
data leakage between containers; no vtpm device with that flag set would 
show anything via sysfs

2) we know in which (user) namespace a /dev/tpm%d device is moved into 
following an ioctl on the device where a process's PID is a parameter; we 
could associate the process's (user) namespace with the chip and compare 
the current_user_ns() with chip->user_ns and return an empty string if 
they don't match; here the vtpm device owned by a particular (user) 
namespace would then also show data in sysfs entries if accessed from the 
right namespace; which sysfs entry to look at could be inferred from the 
minor number on /dev/tpm0 inside the container


   Stefan



[-- Attachment #1.2: Type: text/html, Size: 2280 bytes --]

[-- Attachment #2: Type: text/plain, Size: 413 bytes --]

------------------------------------------------------------------------------
Site24x7 APM Insight: Get Deep Visibility into Application Performance
APM + Mobile APM + RUM: Monitor 3 App instances at just $35/Month
Monitor end-to-end web transactions and take corrective actions now
Troubleshoot faster and improve end-user experience. Signup Now!
http://pubads.g.doubleclick.net/gampad/clk?id=272487151&iu=/4140

[-- Attachment #3: Type: text/plain, Size: 192 bytes --]

_______________________________________________
tpmdd-devel mailing list
tpmdd-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f@public.gmane.org
https://lists.sourceforge.net/lists/listinfo/tpmdd-devel

^ permalink raw reply	[flat|nested] 60+ messages in thread

* Re: [PATCH v3 09/11] tpm: Driver for supporting multiple emulated TPMs
       [not found]                   ` <201602242306.u1ON6qGP030251-8DuMPbUlb4HImUpY6SP3GEEOCMrvLtNR@public.gmane.org>
@ 2016-02-25 13:17                     ` Jarkko Sakkinen
       [not found]                       ` <20160225131732.GA20860-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
       [not found]                       ` <201602251409.u1PE98LH012367@d01av05.pok.ibm.com>
  0 siblings, 2 replies; 60+ messages in thread
From: Jarkko Sakkinen @ 2016-02-25 13:17 UTC (permalink / raw)
  To: Stefan Berger; +Cc: tpmdd-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f

On Wed, Feb 24, 2016 at 06:10:42PM -0500, Stefan Berger wrote:
>    Jason Gunthorpe <jgunthorpe-ePGOBjL8dl3ta4EC/59zMFaTQe2KTcn/@public.gmane.org> wrote on 02/22/2016
>    09:17:30 PM:
> 
>    >
>    > On Mon, Feb 22, 2016 at 08:45:51PM -0500, Stefan Berger wrote:
>    >
>    > > Two things:
>    > > - the ioctl takes flags; should we return an error on flags that are
>    not
>    > > supported but set by userspace?
>    >
>    > Typically yes. Otherwise you cannot introduce new flags in
>    > future.
>    >
>    > > - the sysfs works but I wished we could give some control over
>    > whether it shows
>    > > any entries. Can we have a flag in the ioctl on whether to show
>    > these files in
>    > > sysfs?
>    >
>    > That is something to address in the future namespace patch series I
>    > expect you'll prepare..
> 
>    It may be a while until we get there ... nevertheless it may be worth some
>    thought already.
> 
>    So we have at least two choices for how to avoid data leakage via sysfs;
>    the problem is that sysfs shows all vtpm devices in all containers; the
>    good thing is that at least Docker (other mgmt. stacks probably also)
>    mount sysfs read-only into 'normal' containers, so that writing (even only
>    to cancel) isn't typically possible.
> 
>    1) allow user space to set a flag whether the sysfs entries are to be
>    registered; a typical container mgmt. stack would set the flag to avoid
>    data leakage between containers; no vtpm device with that flag set would
>    show anything via sysfs
> 
>    2) we know in which (user) namespace a /dev/tpm%d device is moved into
>    following an ioctl on the device where a process's PID is a parameter; we
>    could associate the process's (user) namespace with the chip and compare
>    the current_user_ns() with chip->user_ns and return an empty string if
>    they don't match; here the vtpm device owned by a particular (user)
>    namespace would then also show data in sysfs entries if accessed from the
>    right namespace; which sysfs entry to look at could be inferred from the
>    minor number on /dev/tpm0 inside the container

3) Do not show any existing sysfs attributes for containers. All but
   'ppi' are nonsense anyway or is there something that you couldn't read
   from /dev/tpm0? TPM 1.x user space tools could implement them by
   using the character device. It is not backwards compatibility break
   technically because existing code does not yet support vTPMs.

>       Stefan

How would you address measurement logs?

/Jarkko

------------------------------------------------------------------------------
Site24x7 APM Insight: Get Deep Visibility into Application Performance
APM + Mobile APM + RUM: Monitor 3 App instances at just $35/Month
Monitor end-to-end web transactions and take corrective actions now
Troubleshoot faster and improve end-user experience. Signup Now!
http://pubads.g.doubleclick.net/gampad/clk?id=272487151&iu=/4140

^ permalink raw reply	[flat|nested] 60+ messages in thread

* Re: [PATCH v3 09/11] tpm: Driver for supporting multiple emulated TPMs
       [not found]                       ` <20160225131732.GA20860-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
@ 2016-02-25 14:12                         ` Stefan Berger
  0 siblings, 0 replies; 60+ messages in thread
From: Stefan Berger @ 2016-02-25 14:12 UTC (permalink / raw)
  To: Jarkko Sakkinen; +Cc: tpmdd-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f


[-- Attachment #1.1: Type: text/plain, Size: 3398 bytes --]

Jarkko Sakkinen <jarkko.sakkinen-VuQAYsv1563Yd54FQh9/CA@public.gmane.org> wrote on 02/25/2016 
08:17:32 AM:

> 
> On Wed, Feb 24, 2016 at 06:10:42PM -0500, Stefan Berger wrote:
> >    Jason Gunthorpe <jgunthorpe-ePGOBjL8dl3ta4EC/59zMFaTQe2KTcn/@public.gmane.org> wrote on 
02/22/2016
> >    09:17:30 PM:
> > 
> >    >
> >    > On Mon, Feb 22, 2016 at 08:45:51PM -0500, Stefan Berger wrote:
> >    >
> >    > > Two things:
> >    > > - the ioctl takes flags; should we return an error on flags 
that are
> >    not
> >    > > supported but set by userspace?
> >    >
> >    > Typically yes. Otherwise you cannot introduce new flags in
> >    > future.
> >    >
> >    > > - the sysfs works but I wished we could give some control over
> >    > whether it shows
> >    > > any entries. Can we have a flag in the ioctl on whether to show
> >    > these files in
> >    > > sysfs?
> >    >
> >    > That is something to address in the future namespace patch series 
I
> >    > expect you'll prepare..
> > 
> >    It may be a while until we get there ... nevertheless it may 
beworth some
> >    thought already.
> > 
> >    So we have at least two choices for how to avoid data leakage via 
sysfs;
> >    the problem is that sysfs shows all vtpm devices in all containers; 
the
> >    good thing is that at least Docker (other mgmt. stacks probably 
also)
> >    mount sysfs read-only into 'normal' containers, so that 
writing(even only
> >    to cancel) isn't typically possible.
> > 
> >    1) allow user space to set a flag whether the sysfs entries are to 
be
> >    registered; a typical container mgmt. stack would set the flag to 
avoid
> >    data leakage between containers; no vtpm device with that flag set 
would
> >    show anything via sysfs
> > 
> >    2) we know in which (user) namespace a /dev/tpm%d device is moved 
into
> >    following an ioctl on the device where a process's PID is a 
parameter; we
> >    could associate the process's (user) namespace with the chip and 
compare
> >    the current_user_ns() with chip->user_ns and return an empty string 
if
> >    they don't match; here the vtpm device owned by a particular (user)
> >    namespace would then also show data in sysfs entries if accessed 
from the
> >    right namespace; which sysfs entry to look at could be inferred 
from the
> >    minor number on /dev/tpm0 inside the container

With clone() not necessarily setting the user namespace and setns() being 
able to do that after some fork()s, I think 2) doesn't work so well.

> 
> 3) Do not show any existing sysfs attributes for containers. All but

A separate sysfs tree isn't built for every container, so sysfs is more or 
less global showing pretty much the same in every container except for 
networking namespace seems to have a way of not doing that.

>    'ppi' are nonsense anyway or is there something that you couldn't 
read
>    from /dev/tpm0? TPM 1.x user space tools could implement them by
>    using the character device. It is not backwards compatibility break
>    technically because existing code does not yet support vTPMs.

Is this the same as 1) then ?

> 
> >       Stefan
> 
> How would you address measurement logs?

IMA would be namespaced and log separately for every IMA namespace / 
container.

   Stefan

> 
> /Jarkko
> 



[-- Attachment #1.2: Type: text/html, Size: 4696 bytes --]

[-- Attachment #2: Type: text/plain, Size: 413 bytes --]

------------------------------------------------------------------------------
Site24x7 APM Insight: Get Deep Visibility into Application Performance
APM + Mobile APM + RUM: Monitor 3 App instances at just $35/Month
Monitor end-to-end web transactions and take corrective actions now
Troubleshoot faster and improve end-user experience. Signup Now!
http://pubads.g.doubleclick.net/gampad/clk?id=272487151&iu=/4140

[-- Attachment #3: Type: text/plain, Size: 192 bytes --]

_______________________________________________
tpmdd-devel mailing list
tpmdd-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f@public.gmane.org
https://lists.sourceforge.net/lists/listinfo/tpmdd-devel

^ permalink raw reply	[flat|nested] 60+ messages in thread

* Re: [PATCH v3 09/11] tpm: Driver for supporting multiple emulated TPMs
       [not found]                         ` <201602251409.u1PE98LH012367-8DuMPbUlb4HImUpY6SP3GEEOCMrvLtNR@public.gmane.org>
@ 2016-02-25 17:39                           ` Jason Gunthorpe
       [not found]                             ` <20160225173956.GA1407-ePGOBjL8dl3ta4EC/59zMFaTQe2KTcn/@public.gmane.org>
       [not found]                             ` <201602251842.u1PIgEuL014249@d03av03.boulder.ibm.com>
  0 siblings, 2 replies; 60+ messages in thread
From: Jason Gunthorpe @ 2016-02-25 17:39 UTC (permalink / raw)
  To: Stefan Berger; +Cc: tpmdd-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f

On Thu, Feb 25, 2016 at 09:12:57AM -0500, Stefan Berger wrote:

>    > 3) Do not show any existing sysfs attributes for
>    > containers. All but

>    A separate sysfs tree isn't built for every container, so sysfs is more
>    or less global showing pretty much the same in every container except
>    for networking namespace seems to have a way of not doing that.

TPM should be able to use the same techniques as net, the syfs.*ns set
of APIs exists for this purpose. I've never looked at how to use them,
but something should be workable there.

Once you figure out how to define what TPMs are in a namespace it
should be doable to use the syfs_ns APIs to have sysfs follow that
restriction just like net does.

Jason

------------------------------------------------------------------------------
Site24x7 APM Insight: Get Deep Visibility into Application Performance
APM + Mobile APM + RUM: Monitor 3 App instances at just $35/Month
Monitor end-to-end web transactions and take corrective actions now
Troubleshoot faster and improve end-user experience. Signup Now!
http://pubads.g.doubleclick.net/gampad/clk?id=272487151&iu=/4140

^ permalink raw reply	[flat|nested] 60+ messages in thread

* Re: [PATCH v3 09/11] tpm: Driver for supporting multiple emulated TPMs
       [not found]                             ` <20160225173956.GA1407-ePGOBjL8dl3ta4EC/59zMFaTQe2KTcn/@public.gmane.org>
@ 2016-02-25 18:42                               ` Stefan Berger
  0 siblings, 0 replies; 60+ messages in thread
From: Stefan Berger @ 2016-02-25 18:42 UTC (permalink / raw)
  To: Jason Gunthorpe; +Cc: tpmdd-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f


[-- Attachment #1.1: Type: text/plain, Size: 2872 bytes --]

Jason Gunthorpe <jgunthorpe-ePGOBjL8dl3ta4EC/59zMFaTQe2KTcn/@public.gmane.org> wrote on 02/25/2016 
12:39:56 PM:


> 
> On Thu, Feb 25, 2016 at 09:12:57AM -0500, Stefan Berger wrote:
> 
> >    > 3) Do not show any existing sysfs attributes for
> >    > containers. All but
> 
> >    A separate sysfs tree isn't built for every container, so sysfs is 
more
> >    or less global showing pretty much the same in every container 
except
> >    for networking namespace seems to have a way of not doing that.
> 
> TPM should be able to use the same techniques as net, the syfs.*ns set
> of APIs exists for this purpose. I've never looked at how to use them,
> but something should be workable there.

It looks like they some are being used on the kobject level. 

> 
> Once you figure out how to define what TPMs are in a namespace it
> should be doable to use the syfs_ns APIs to have sysfs follow that
> restriction just like net does.

Networking has its own namespace and it looks like all devices get created 
while in that namespace. So the kobject can have its association with that 
namespace right from the beginning. In the case of vtpm we need to create 
the device on the host since we run the TPM emulator on the host out of 
reach of signals from the container. We would only associate the vtpm 
device with the namespace after the clone(), a long time after current 
registration with sysfs. Another difference is that we don't have a device 
namespace, so all our device names and major / minor numbers need to be 
unique and that's also reflected in sysfs.


I have been experimenting with an ioctl that passes along a file 
descriptor to a user namespace (/proc/pid/ns/user) for the purpose of 
associating the vtpm with that user namespace. This is similar to what 
setns() does, except the ioctl associates a vTPM with a namespace. This 
works (once the child is in its final namespace, which the parent needs to 
sync with) and following the proposed filtering on the TPM sysfs attribute 
level, only read()s issued from the user namespace that the vTPM is 
associated with get data. That we can have up to 64k TPM entries in sysfs 
certainly isn't nice.

This 1st ioctl can be called basically at any time and is called on the 
file descriptor returned by the vtpm driver.

Another ioctl is the one we have been discussing previously for 
associating the chip with an IMA namespace (which would be a compile time 
option). Here we need to ensure that the child gets the chip hooked to the 
IMA namespace before the execve() triggers measurements by IMA. Here I 
pass the process Id of that child to then determine IMA namespace to hook 
the chip to and user namespace for vTPM sysfs association. I prefer the 
child's process id over passing two file descriptors in this case...

   Stefan



[-- Attachment #1.2: Type: text/html, Size: 3317 bytes --]

[-- Attachment #2: Type: text/plain, Size: 413 bytes --]

------------------------------------------------------------------------------
Site24x7 APM Insight: Get Deep Visibility into Application Performance
APM + Mobile APM + RUM: Monitor 3 App instances at just $35/Month
Monitor end-to-end web transactions and take corrective actions now
Troubleshoot faster and improve end-user experience. Signup Now!
http://pubads.g.doubleclick.net/gampad/clk?id=272487151&iu=/4140

[-- Attachment #3: Type: text/plain, Size: 192 bytes --]

_______________________________________________
tpmdd-devel mailing list
tpmdd-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f@public.gmane.org
https://lists.sourceforge.net/lists/listinfo/tpmdd-devel

^ permalink raw reply	[flat|nested] 60+ messages in thread

* Re: [PATCH v3 09/11] tpm: Driver for supporting multiple emulated TPMs
       [not found]                               ` <201602251842.u1PIgEuL014249-MijUUJkLaQs+UXBhvPuGgqsjOiXwFzmk@public.gmane.org>
@ 2016-02-25 20:31                                 ` Jason Gunthorpe
       [not found]                                   ` <20160225203117.GA22984-ePGOBjL8dl3ta4EC/59zMFaTQe2KTcn/@public.gmane.org>
  0 siblings, 1 reply; 60+ messages in thread
From: Jason Gunthorpe @ 2016-02-25 20:31 UTC (permalink / raw)
  To: Stefan Berger; +Cc: tpmdd-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f

On Thu, Feb 25, 2016 at 01:42:10PM -0500, Stefan Berger wrote:

>    It looks like they some are being used on the kobject level.

Yes, struct devices are kobjects.

>    > Once you figure out how to define what TPMs are in a namespace it
>    > should be doable to use the syfs_ns APIs to have sysfs follow that
>    > restriction just like net does.

>    Networking has its own namespace and it looks like all devices get
>    created while in that namespace.

No, it is like tpm, a cannonical example is something like:

 ip netns add blue
 ip link add veth0 type veth peer name veth1
 ip link set veth1 netns blue

To move an interface, which presumably moves the sysfs stuff as
well. Seems exactly like a mode that could work for TPM.

>    clone(), a long time after current registration with sysfs. Another
>    difference is that we don't have a device namespace, so all our device
>    names and major / minor numbers need to be unique and that's also
>    reflected in sysfs.

major/minor numbers do not need to be unique, the mapping of TPM ID to
physical TPM is something a namespace should control, eg TPM ID 0 is
always major/minor 10:224, and can be routed to which ever tpm is
correct for the namespace of the accessing process.

Same for sysfs, within the namespace the vtpm should appear as tpm0.

>    I have been experimenting with an ioctl that passes along a file
>    descriptor to a user namespace (/proc/pid/ns/user) for the purpose of
>    associating the vtpm with that user namespace.

I would have thought you'd use the IMA namespace for this, seems more
natural?

Functionally it doesn't matter, which ever name space is used, migrate
the sysfs stuff similar to net and virtualize all the ID.

>    time option). Here we need to ensure that the child gets the chip
>    hooked to the IMA namespace before the execve() triggers measurements
>    by IMA. Here I pass the process Id of that child to then determine IMA
>    namespace to hook the chip to and user namespace for vTPM sysfs
>    association. I prefer the child's process id over passing two file
>    descriptors in this case...

I'm sure people familiar with namespaces/etc will have suggestions on
how to build the uapi side.

I still intensely dislike the use of an ioctl on vtpm because
namespaces will have to be a core tpm feature, an ioctl on the
/dev/tpmX fd would be more approriate.

Jason

------------------------------------------------------------------------------
Site24x7 APM Insight: Get Deep Visibility into Application Performance
APM + Mobile APM + RUM: Monitor 3 App instances at just $35/Month
Monitor end-to-end web transactions and take corrective actions now
Troubleshoot faster and improve end-user experience. Signup Now!
http://pubads.g.doubleclick.net/gampad/clk?id=272487151&iu=/4140

^ permalink raw reply	[flat|nested] 60+ messages in thread

* Re: [PATCH v3 09/11] tpm: Driver for supporting multiple emulated TPMs
       [not found]                                   ` <20160225203117.GA22984-ePGOBjL8dl3ta4EC/59zMFaTQe2KTcn/@public.gmane.org>
@ 2016-02-25 22:11                                     ` Stefan Berger
  0 siblings, 0 replies; 60+ messages in thread
From: Stefan Berger @ 2016-02-25 22:11 UTC (permalink / raw)
  To: Jason Gunthorpe; +Cc: tpmdd-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f


[-- Attachment #1.1: Type: text/plain, Size: 4330 bytes --]

Jason Gunthorpe <jgunthorpe-ePGOBjL8dl3ta4EC/59zMFaTQe2KTcn/@public.gmane.org> wrote on 02/25/2016 
03:31:17 PM:


> 
> On Thu, Feb 25, 2016 at 01:42:10PM -0500, Stefan Berger wrote:
> 
> >    It looks like they some are being used on the kobject level.
> 
> Yes, struct devices are kobjects.
> 
> >    > Once you figure out how to define what TPMs are in a namespace it
> >    > should be doable to use the syfs_ns APIs to have sysfs follow 
that
> >    > restriction just like net does.
> 
> >    Networking has its own namespace and it looks like all devices get
> >    created while in that namespace.
> 
> No, it is like tpm, a cannonical example is something like:
> 
>  ip netns add blue
>  ip link add veth0 type veth peer name veth1
>  ip link set veth1 netns blue

True.

> 
> To move an interface, which presumably moves the sysfs stuff as
> well. Seems exactly like a mode that could work for TPM.
> 
> >    clone(), a long time after current registration with sysfs. Another
> >    difference is that we don't have a device namespace, so all our 
device
> >    names and major / minor numbers need to be unique and that's also
> >    reflected in sysfs.
> 
> major/minor numbers do not need to be unique, the mapping of TPM ID to
> physical TPM is something a namespace should control, eg TPM ID 0 is
> always major/minor 10:224, and can be routed to which ever tpm is
> correct for the namespace of the accessing process.

Though you would agree that the device gets created in the host 
'namespace' first and then is moved into a namespace? We would then 
emulate the major/minor assignment (misc device oddity and so on) in the 
container management stack and assign the first 10:224 inside the 
container? Would the move make the device disappear on the host's main 
namespace? Like /dev/tpm2 now being moved into a namespace and it 
disappearing on the host?

Then in tpm_open() (as well as all the other functions) we would not get 
the chip the way we do now but by checking the user namespace to determine 
from where the open() is coming from and then search an ordered list of 
chips associated with that namespace and get the first entry? One would 
have to be able to conclude from the inode or file what major/minor number 
the device is associated with.

       struct tpm_chip *chip =
               container_of(inode->i_cdev, struct tpm_chip, cdev);

Well, I guess that part of this  would involve a level of indirection 
approximately like this:

struct tpm_file *tf = container_of(inode->i_cdev, struct tpm_file, cdev);

struct tpm_chip *chip = tpm_find_chip_by_namespace(current_user_ns(), 
tf->major, rf->minor);



> 
> Same for sysfs, within the namespace the vtpm should appear as tpm0.
> 
> >    I have been experimenting with an ioctl that passes along a file
> >    descriptor to a user namespace (/proc/pid/ns/user) for the purpose 
of
> >    associating the vtpm with that user namespace.
> 
> I would have thought you'd use the IMA namespace for this, seems more
> natural?

I am not yet sure. Maybe it's too early to talk about this ioctl. 

Can we upstream the current driver with patches 1 - 9?


> 
> Functionally it doesn't matter, which ever name space is used, migrate
> the sysfs stuff similar to net and virtualize all the ID.
> 
> >    time option). Here we need to ensure that the child gets the chip
> >    hooked to the IMA namespace before the execve() triggers 
measurements
> >    by IMA. Here I pass the process Id of that child to then determine 
IMA
> >    namespace to hook the chip to and user namespace for vTPM sysfs
> >    association. I prefer the child's process id over passing two file
> >    descriptors in this case...
> 
> I'm sure people familiar with namespaces/etc will have suggestions on
> how to build the uapi side.

Yes, not quite clear about which way is the best. 

> 
> I still intensely dislike the use of an ioctl on vtpm because
> namespaces will have to be a core tpm feature, an ioctl on the
> /dev/tpmX fd would be more approriate.

So that would be to move a hardware TPM into a container. If the 
namespacing implementation would need to be device-specific, it could call 
a function on the chip to do that.

   Stefan



[-- Attachment #1.2: Type: text/html, Size: 6381 bytes --]

[-- Attachment #2: Type: text/plain, Size: 413 bytes --]

------------------------------------------------------------------------------
Site24x7 APM Insight: Get Deep Visibility into Application Performance
APM + Mobile APM + RUM: Monitor 3 App instances at just $35/Month
Monitor end-to-end web transactions and take corrective actions now
Troubleshoot faster and improve end-user experience. Signup Now!
http://pubads.g.doubleclick.net/gampad/clk?id=272487151&iu=/4140

[-- Attachment #3: Type: text/plain, Size: 192 bytes --]

_______________________________________________
tpmdd-devel mailing list
tpmdd-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f@public.gmane.org
https://lists.sourceforge.net/lists/listinfo/tpmdd-devel

^ permalink raw reply	[flat|nested] 60+ messages in thread

end of thread, other threads:[~2016-02-25 22:11 UTC | newest]

Thread overview: 60+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-02-19 12:41 [PATCH v3 00/11] Multi-instance vTPM driver Stefan Berger
2016-02-19 12:41 ` [PATCH v3 01/11] tpm: fix the cleanup of struct tpm_chip Stefan Berger
     [not found] ` <1455885728-10315-1-git-send-email-stefanb-23VcF4HTsmIX0ybBhKVfKdBPR1lH4CV8@public.gmane.org>
2016-02-19 12:41   ` [PATCH v3 02/11] tpm: Get rid of chip->pdev Stefan Berger
     [not found]     ` <1455885728-10315-3-git-send-email-stefanb-23VcF4HTsmIX0ybBhKVfKdBPR1lH4CV8@public.gmane.org>
2016-02-22 19:25       ` Jarkko Sakkinen
2016-02-19 12:42   ` [PATCH v3 03/11] tpm: Get rid of devname Stefan Berger
     [not found]     ` <1455885728-10315-4-git-send-email-stefanb-23VcF4HTsmIX0ybBhKVfKdBPR1lH4CV8@public.gmane.org>
2016-02-22 18:19       ` Jason Gunthorpe
     [not found]         ` <20160222181929.GB22088-ePGOBjL8dl3ta4EC/59zMFaTQe2KTcn/@public.gmane.org>
2016-02-22 19:42           ` Jarkko Sakkinen
     [not found]             ` <20160222194202.GC32667-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
2016-02-22 19:58               ` Jason Gunthorpe
     [not found]                 ` <20160222195816.GL22088-ePGOBjL8dl3ta4EC/59zMFaTQe2KTcn/@public.gmane.org>
2016-02-22 20:34                   ` Jason Gunthorpe
2016-02-23  0:22           ` Stefan Berger
2016-02-19 12:42   ` [PATCH v3 04/11] tpm: Provide strong locking for device removal Stefan Berger
     [not found]     ` <1455885728-10315-5-git-send-email-stefanb-23VcF4HTsmIX0ybBhKVfKdBPR1lH4CV8@public.gmane.org>
2016-02-22 21:08       ` Jarkko Sakkinen
     [not found]         ` <20160222210844.GA3310-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
2016-02-22 22:20           ` Jason Gunthorpe
     [not found]             ` <20160222222017.GC27228-ePGOBjL8dl3ta4EC/59zMFaTQe2KTcn/@public.gmane.org>
2016-02-23 19:40               ` Jarkko Sakkinen
     [not found]                 ` <20160223194014.GA5241-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
2016-02-23 19:52                   ` Jason Gunthorpe
     [not found]                     ` <20160223195246.GC389-ePGOBjL8dl3ta4EC/59zMFaTQe2KTcn/@public.gmane.org>
2016-02-23 20:36                       ` Jarkko Sakkinen
2016-02-23 20:43               ` Jarkko Sakkinen
2016-02-19 12:42   ` [PATCH v3 05/11] tpm: Get rid of module locking Stefan Berger
     [not found]     ` <1455885728-10315-6-git-send-email-stefanb-23VcF4HTsmIX0ybBhKVfKdBPR1lH4CV8@public.gmane.org>
2016-02-22 18:22       ` Jason Gunthorpe
     [not found]         ` <20160222182245.GC22088-ePGOBjL8dl3ta4EC/59zMFaTQe2KTcn/@public.gmane.org>
2016-02-23  0:26           ` Stefan Berger
2016-02-22 21:11       ` Jarkko Sakkinen
     [not found]         ` <20160222211141.GB3310-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
2016-02-22 22:15           ` Jason Gunthorpe
2016-02-19 12:42   ` [PATCH v3 06/11] tpm: Split out the devm stuff from tpmm_chip_alloc Stefan Berger
     [not found]     ` <1455885728-10315-7-git-send-email-stefanb-23VcF4HTsmIX0ybBhKVfKdBPR1lH4CV8@public.gmane.org>
2016-02-22 18:24       ` Jason Gunthorpe
2016-02-22 21:14       ` Jarkko Sakkinen
     [not found]         ` <20160222211414.GC3310-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
2016-02-22 22:13           ` Jason Gunthorpe
     [not found]             ` <20160222221328.GA27228-ePGOBjL8dl3ta4EC/59zMFaTQe2KTcn/@public.gmane.org>
2016-02-23  0:45               ` Stefan Berger
2016-02-23 11:31               ` Jarkko Sakkinen
2016-02-19 12:42   ` [PATCH v3 07/11] tpm: Replace device number bitmap with IDR Stefan Berger
     [not found]     ` <1455885728-10315-8-git-send-email-stefanb-23VcF4HTsmIX0ybBhKVfKdBPR1lH4CV8@public.gmane.org>
2016-02-22 19:06       ` Jason Gunthorpe
     [not found]         ` <20160222190629.GE22088-ePGOBjL8dl3ta4EC/59zMFaTQe2KTcn/@public.gmane.org>
2016-02-23  1:15           ` Stefan Berger
2016-02-23  2:16           ` Stefan Berger
     [not found]         ` <201602230116.u1N1G4iu012263@d03av02.boulder.ibm.com>
     [not found]           ` <201602230116.u1N1G4iu012263-nNA/7dmquNI+UXBhvPuGgqsjOiXwFzmk@public.gmane.org>
2016-02-23  2:16             ` Jason Gunthorpe
     [not found]               ` <20160223021606.GC26177-ePGOBjL8dl3ta4EC/59zMFaTQe2KTcn/@public.gmane.org>
2016-02-23 23:04                 ` Stefan Berger
     [not found]               ` <201602232305.u1NN521L020589@d03av01.boulder.ibm.com>
     [not found]                 ` <201602232305.u1NN521L020589-Rn83F4s8Lwc+UXBhvPuGgqsjOiXwFzmk@public.gmane.org>
2016-02-23 23:18                   ` Jason Gunthorpe
     [not found]         ` <201602230217.u1N2HIJT003183@d03av05.boulder.ibm.com>
     [not found]           ` <201602230217.u1N2HIJT003183-3MP/CPU4Muo+UXBhvPuGgqsjOiXwFzmk@public.gmane.org>
2016-02-23  2:18             ` Jason Gunthorpe
2016-02-19 12:42   ` [PATCH v3 08/11] tpm: Introduce TPM_CHIP_FLAG_VIRTUAL Stefan Berger
     [not found]     ` <1455885728-10315-9-git-send-email-stefanb-23VcF4HTsmIX0ybBhKVfKdBPR1lH4CV8@public.gmane.org>
2016-02-22 19:19       ` Jason Gunthorpe
     [not found]         ` <20160222191922.GH22088-ePGOBjL8dl3ta4EC/59zMFaTQe2KTcn/@public.gmane.org>
2016-02-23  1:20           ` [PATCH v3 08/11] tpm: IntroduceTPM_CHIP_FLAG_VIRTUAL Stefan Berger
2016-02-23  1:21           ` Stefan Berger
     [not found]         ` <201602230121.u1N1LYk2024786@d01av01.pok.ibm.com>
     [not found]           ` <201602230121.u1N1LYk2024786-4ZtxiNBBw+3ImUpY6SP3GEEOCMrvLtNR@public.gmane.org>
2016-02-23  2:05             ` Jason Gunthorpe
     [not found]               ` <20160223020515.GA26177-ePGOBjL8dl3ta4EC/59zMFaTQe2KTcn/@public.gmane.org>
2016-02-23  3:40                 ` Stefan Berger
     [not found]         ` <201602230116.u1N1Ghac006778@d01av05.pok.ibm.com>
     [not found]           ` <201602230116.u1N1Ghac006778-8DuMPbUlb4HImUpY6SP3GEEOCMrvLtNR@public.gmane.org>
2016-02-23  2:06             ` Jason Gunthorpe
2016-02-19 12:42   ` [PATCH v3 09/11] tpm: Driver for supporting multiple emulated TPMs Stefan Berger
     [not found]     ` <1455885728-10315-10-git-send-email-stefanb-23VcF4HTsmIX0ybBhKVfKdBPR1lH4CV8@public.gmane.org>
2016-02-22 19:27       ` Jason Gunthorpe
     [not found]         ` <20160222192741.GI22088-ePGOBjL8dl3ta4EC/59zMFaTQe2KTcn/@public.gmane.org>
2016-02-23  1:45           ` Stefan Berger
     [not found]         ` <201602230142.u1N1gSuF029481@d01av05.pok.ibm.com>
     [not found]           ` <201602230142.u1N1gSuF029481-8DuMPbUlb4HImUpY6SP3GEEOCMrvLtNR@public.gmane.org>
2016-02-23  2:17             ` Jason Gunthorpe
     [not found]               ` <20160223021730.GD26177-ePGOBjL8dl3ta4EC/59zMFaTQe2KTcn/@public.gmane.org>
2016-02-24 23:10                 ` Stefan Berger
     [not found]                   ` <201602242306.u1ON6qGP030251-8DuMPbUlb4HImUpY6SP3GEEOCMrvLtNR@public.gmane.org>
2016-02-25 13:17                     ` Jarkko Sakkinen
     [not found]                       ` <20160225131732.GA20860-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
2016-02-25 14:12                         ` Stefan Berger
     [not found]                       ` <201602251409.u1PE98LH012367@d01av05.pok.ibm.com>
     [not found]                         ` <201602251409.u1PE98LH012367-8DuMPbUlb4HImUpY6SP3GEEOCMrvLtNR@public.gmane.org>
2016-02-25 17:39                           ` Jason Gunthorpe
     [not found]                             ` <20160225173956.GA1407-ePGOBjL8dl3ta4EC/59zMFaTQe2KTcn/@public.gmane.org>
2016-02-25 18:42                               ` Stefan Berger
     [not found]                             ` <201602251842.u1PIgEuL014249@d03av03.boulder.ibm.com>
     [not found]                               ` <201602251842.u1PIgEuL014249-MijUUJkLaQs+UXBhvPuGgqsjOiXwFzmk@public.gmane.org>
2016-02-25 20:31                                 ` Jason Gunthorpe
     [not found]                                   ` <20160225203117.GA22984-ePGOBjL8dl3ta4EC/59zMFaTQe2KTcn/@public.gmane.org>
2016-02-25 22:11                                     ` Stefan Berger
2016-02-23 10:22       ` Jarkko Sakkinen
     [not found]         ` <20160223102211.GA9474-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
2016-02-23 12:09           ` Stefan Berger
     [not found]         ` <201602231210.u1NCAD6D017196@d01av03.pok.ibm.com>
     [not found]           ` <201602231210.u1NCAD6D017196-CUdSWdNILC7ImUpY6SP3GEEOCMrvLtNR@public.gmane.org>
2016-02-23 18:36             ` Jarkko Sakkinen
2016-02-19 12:42   ` [PATCH v3 10/11] tpm: Initialize TPM and get durations and timeouts Stefan Berger
2016-02-19 12:42   ` [PATCH v3 11/11] A test program for vTPM device creation Stefan Berger
2016-02-22 19:20   ` [PATCH v3 00/11] Multi-instance vTPM driver Jarkko Sakkinen

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.