All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v4 00/10] Multi-instance vTPM driver
@ 2016-02-29 17:29 Stefan Berger
       [not found] ` <1456766996-9300-1-git-send-email-stefanb-23VcF4HTsmIX0ybBhKVfKdBPR1lH4CV8@public.gmane.org>
  0 siblings, 1 reply; 36+ messages in thread
From: Stefan Berger @ 2016-02-29 17:29 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 James Morris's 'next' branch and uses several
recently posted patches from Jason and Jarkko. Some of these patches
needed to rebased on top of this tree.

   Stefan


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         | 221 +++++++++----
 drivers/char/tpm/tpm-dev.c          |  15 +-
 drivers/char/tpm/tpm-interface.c    |  50 +--
 drivers/char/tpm/tpm-sysfs.c        |  22 +-
 drivers/char/tpm/tpm-vtpm.c         | 613 ++++++++++++++++++++++++++++++++++++
 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           |  41 +++
 vtpmctrl.c                          | 163 ++++++++++
 21 files changed, 1120 insertions(+), 179 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] 36+ messages in thread

* [PATCH v4 01/10] tpm: Get rid of chip->pdev
       [not found] ` <1456766996-9300-1-git-send-email-stefanb-23VcF4HTsmIX0ybBhKVfKdBPR1lH4CV8@public.gmane.org>
@ 2016-02-29 17:29   ` Stefan Berger
  2016-02-29 17:29   ` [PATCH v4 02/10] tpm: Get rid of devname Stefan Berger
                     ` (10 subsequent siblings)
  11 siblings, 0 replies; 36+ messages in thread
From: Stefan Berger @ 2016-02-29 17:29 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>
Signed-off-by: Stefan Berger <stefanb-23VcF4HTsmIX0ybBhKVfKdBPR1lH4CV8@public.gmane.org>
Tested-by: Stefan Berger <stefanb-23VcF4HTsmIX0ybBhKVfKdBPR1lH4CV8@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          | 16 ++++++++--------
 13 files changed, 89 insertions(+), 93 deletions(-)

diff --git a/drivers/char/tpm/tpm-chip.c b/drivers/char/tpm/tpm-chip.c
index 274dd01..12829dd 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;
 
 	rc = 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_del_char_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 e2fa89c..483f86f 100644
--- a/drivers/char/tpm/tpm-interface.c
+++ b/drivers/char/tpm/tpm-interface.c
@@ -345,7 +345,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;
 	}
@@ -354,7 +354,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;
 	}
@@ -373,7 +373,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;
 		}
@@ -383,14 +383,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);
@@ -416,7 +416,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;
@@ -527,7 +527,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;
 
@@ -539,7 +539,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;
@@ -578,7 +578,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],
@@ -625,7 +625,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;
 }
@@ -815,7 +815,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;
 		}
@@ -825,7 +827,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
@@ -978,10 +980,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 28b477e..9c9be6c 100644
--- a/drivers/char/tpm/tpm.h
+++ b/drivers/char/tpm/tpm.h
@@ -167,7 +167,6 @@ enum tpm_chip_flags {
 };
 
 struct tpm_chip {
-	struct device *pdev;	/* Device stuff */
 	struct device dev;
 	struct cdev cdev;
 
@@ -199,7 +198,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 b28e4da..5fc0e7c 100644
--- a/drivers/char/tpm/tpm2-cmd.c
+++ b/drivers/char/tpm/tpm2-cmd.c
@@ -597,7 +597,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;
 	}
@@ -606,7 +606,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);
@@ -770,7 +770,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);
@@ -837,7 +837,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 a507006..0a9aee9 100644
--- a/drivers/char/tpm/tpm_tis.c
+++ b/drivers/char/tpm/tpm_tis.c
@@ -260,7 +260,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;
 	}
 
@@ -273,7 +273,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;
 	}
@@ -282,7 +282,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;
 	}
@@ -368,7 +368,7 @@ static void disable_interrupts(struct tpm_chip *chip)
 	iowrite32(intmask,
 		  chip->vendor.iobase +
 		  TPM_INT_ENABLE(chip->vendor.locality));
-	devm_free_irq(chip->pdev, chip->vendor.irq, chip);
+	devm_free_irq(&chip->dev, chip->vendor.irq, chip);
 	chip->vendor.irq = 0;
 }
 
@@ -497,7 +497,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;
@@ -576,9 +576,9 @@ static int tpm_tis_probe_irq_single(struct tpm_chip *chip, u32 intmask,
 	struct priv_data *priv = chip->vendor.priv;
 	u8 original_int_vec;
 
-	if (devm_request_irq(chip->pdev, irq, tis_int_handler, flags,
+	if (devm_request_irq(&chip->dev, irq, tis_int_handler, flags,
 			     chip->devname, chip) != 0) {
-		dev_info(chip->pdev, "Unable to request irq: %d for probe\n",
+		dev_info(&chip->dev, "Unable to request irq: %d for probe\n",
 			 irq);
 		return -1;
 	}
@@ -779,7 +779,7 @@ static int tpm_tis_init(struct device *dev, struct tpm_info *tpm_info,
 			tpm_tis_probe_irq_single(chip, intmask, IRQF_SHARED,
 						 tpm_info->irq);
 			if (!chip->vendor.irq)
-				dev_err(chip->pdev, FW_BUG
+				dev_err(&chip->dev, FW_BUG
 					"TPM interrupt not working, polling instead\n");
 		} else
 			tpm_tis_probe_irq(chip, intmask);
-- 
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] 36+ messages in thread

* [PATCH v4 02/10] tpm: Get rid of devname
       [not found] ` <1456766996-9300-1-git-send-email-stefanb-23VcF4HTsmIX0ybBhKVfKdBPR1lH4CV8@public.gmane.org>
  2016-02-29 17:29   ` [PATCH v4 01/10] tpm: Get rid of chip->pdev Stefan Berger
@ 2016-02-29 17:29   ` Stefan Berger
  2016-02-29 17:29   ` [PATCH v4 03/10] tpm: Provide strong locking for device removal Stefan Berger
                     ` (9 subsequent siblings)
  11 siblings, 0 replies; 36+ messages in thread
From: Stefan Berger @ 2016-02-29 17:29 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>
Signed-off-by: Stefan Berger <stefanb-23VcF4HTsmIX0ybBhKVfKdBPR1lH4CV8@public.gmane.org>
---
 drivers/char/tpm/tpm-chip.c        | 18 +++++++++++-------
 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         |  2 +-
 6 files changed, 15 insertions(+), 12 deletions(-)

diff --git a/drivers/char/tpm/tpm-chip.c b/drivers/char/tpm/tpm-chip.c
index 12829dd..c21d81c 100644
--- a/drivers/char/tpm/tpm-chip.c
+++ b/drivers/char/tpm/tpm-chip.c
@@ -111,7 +111,7 @@ 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);
+	device_initialize(&chip->dev);
 
 	dev_set_drvdata(dev, chip);
 
@@ -127,9 +127,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);
-
-	device_initialize(&chip->dev);
+	rc = dev_set_name(&chip->dev, "tpm%d", chip->dev_num);
+	if (rc)
+		goto out;
 
 	cdev_init(&chip->cdev, &tpm_fops);
 	chip->cdev.owner = dev->driver->owner;
@@ -142,6 +142,10 @@ struct tpm_chip *tpmm_chip_alloc(struct device *dev,
 	}
 
 	return chip;
+
+out:
+	put_device(&chip->dev);
+	return ERR_PTR(rc);
 }
 EXPORT_SYMBOL_GPL(tpmm_chip_alloc);
 
@@ -153,7 +157,7 @@ static int tpm_add_char_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);
 
 		return rc;
@@ -163,7 +167,7 @@ static int tpm_add_char_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);
 
 		cdev_del(&chip->cdev);
@@ -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 9c9be6c..5d33ba5 100644
--- a/drivers/char/tpm/tpm.h
+++ b/drivers/char/tpm/tpm.h
@@ -174,7 +174,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 4e6940a..e722886 100644
--- a/drivers/char/tpm/tpm_eventlog.c
+++ b/drivers/char/tpm/tpm_eventlog.c
@@ -403,7 +403,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 0a9aee9..eed3bf5 100644
--- a/drivers/char/tpm/tpm_tis.c
+++ b/drivers/char/tpm/tpm_tis.c
@@ -577,7 +577,7 @@ static int tpm_tis_probe_irq_single(struct tpm_chip *chip, u32 intmask,
 	u8 original_int_vec;
 
 	if (devm_request_irq(&chip->dev, irq, tis_int_handler, flags,
-			     chip->devname, chip) != 0) {
+			     dev_name(&chip->dev), chip) != 0) {
 		dev_info(&chip->dev, "Unable to request irq: %d for probe\n",
 			 irq);
 		return -1;
-- 
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] 36+ messages in thread

* [PATCH v4 03/10] tpm: Provide strong locking for device removal
       [not found] ` <1456766996-9300-1-git-send-email-stefanb-23VcF4HTsmIX0ybBhKVfKdBPR1lH4CV8@public.gmane.org>
  2016-02-29 17:29   ` [PATCH v4 01/10] tpm: Get rid of chip->pdev Stefan Berger
  2016-02-29 17:29   ` [PATCH v4 02/10] tpm: Get rid of devname Stefan Berger
@ 2016-02-29 17:29   ` Stefan Berger
       [not found]     ` <1456766996-9300-4-git-send-email-stefanb-23VcF4HTsmIX0ybBhKVfKdBPR1lH4CV8@public.gmane.org>
  2016-02-29 17:29   ` [PATCH v4 04/10] tpm: Get rid of module locking Stefan Berger
                     ` (8 subsequent siblings)
  11 siblings, 1 reply; 36+ messages in thread
From: Stefan Berger @ 2016-02-29 17:29 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>
Reviewed-by: Stefan Berger <stefanb-23VcF4HTsmIX0ybBhKVfKdBPR1lH4CV8@public.gmane.org>
---
 drivers/char/tpm/tpm-chip.c      | 72 ++++++++++++++++++++++++++++++++++++----
 drivers/char/tpm/tpm-dev.c       | 11 +++++-
 drivers/char/tpm/tpm-interface.c | 19 ++++++-----
 drivers/char/tpm/tpm-sysfs.c     |  5 +++
 drivers/char/tpm/tpm.h           | 14 +++++---
 5 files changed, 100 insertions(+), 21 deletions(-)

diff --git a/drivers/char/tpm/tpm-chip.c b/drivers/char/tpm/tpm-chip.c
index c21d81c..1ae30f2 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,10 @@ 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)) {
+		/* rcu prevents chip from being free'd */
+		if (!tpm_try_get_ops(pos))
 			chip = pos;
-			break;
-		}
+		break;
 	}
 	rcu_read_unlock();
 	return chip;
@@ -95,6 +145,7 @@ struct tpm_chip *tpmm_chip_alloc(struct device *dev,
 		return ERR_PTR(-ENOMEM);
 
 	mutex_init(&chip->tpm_mutex);
+	init_rwsem(&chip->ops_sem);
 	INIT_LIST_HEAD(&chip->list);
 
 	chip->ops = ops;
@@ -180,6 +231,12 @@ static int tpm_add_char_device(struct tpm_chip *chip)
 static void tpm_del_char_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 +275,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 483f86f..5caf154 100644
--- a/drivers/char/tpm/tpm-interface.c
+++ b/drivers/char/tpm/tpm-interface.c
@@ -700,7 +700,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;
 }
@@ -729,7 +729,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);
@@ -764,7 +764,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;
 	}
 
@@ -774,7 +774,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);
@@ -855,7 +855,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);
@@ -1037,7 +1037,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;
 	}
 
@@ -1059,7 +1059,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);
@@ -1085,7 +1085,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);
@@ -1111,7 +1111,8 @@ 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 5d33ba5..c6376b1 100644
--- a/drivers/char/tpm/tpm.h
+++ b/drivers/char/tpm/tpm.h
@@ -170,7 +170,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# */
@@ -195,11 +201,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);
@@ -507,6 +508,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] 36+ messages in thread

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

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.

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

diff --git a/drivers/char/tpm/tpm-chip.c b/drivers/char/tpm/tpm-chip.c
index 1ae30f2..8f4b5f2 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);
 }
@@ -183,7 +179,7 @@ struct tpm_chip *tpmm_chip_alloc(struct device *dev,
 		goto out;
 
 	cdev_init(&chip->cdev, &tpm_fops);
-	chip->cdev.owner = dev->driver->owner;
+	chip->cdev.owner = THIS_MODULE;
 	chip->cdev.kobj.parent = &chip->dev.kobj;
 
 	rc = devm_add_action(dev, (void (*)(void *)) 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] 36+ messages in thread

* [PATCH v4 05/10] tpm: Split out the devm stuff from tpmm_chip_alloc
       [not found] ` <1456766996-9300-1-git-send-email-stefanb-23VcF4HTsmIX0ybBhKVfKdBPR1lH4CV8@public.gmane.org>
                     ` (3 preceding siblings ...)
  2016-02-29 17:29   ` [PATCH v4 04/10] tpm: Get rid of module locking Stefan Berger
@ 2016-02-29 17:29   ` Stefan Berger
  2016-02-29 17:29   ` [PATCH v4 06/10] tpm: Replace device number bitmap with IDR Stefan Berger
                     ` (6 subsequent siblings)
  11 siblings, 0 replies; 36+ messages in thread
From: Stefan Berger @ 2016-02-29 17:29 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>
Reviewed-by: Stefan Berger <stefanb-23VcF4HTsmIX0ybBhKVfKdBPR1lH4CV8@public.gmane.org>
Tested-by: Stefan Berger <stefanb-23VcF4HTsmIX0ybBhKVfKdBPR1lH4CV8@public.gmane.org>
---
 drivers/char/tpm/tpm-chip.c | 49 ++++++++++++++++++++++++++++++++-------------
 drivers/char/tpm/tpm.h      |  4 +++-
 2 files changed, 38 insertions(+), 15 deletions(-)

diff --git a/drivers/char/tpm/tpm-chip.c b/drivers/char/tpm/tpm-chip.c
index 8f4b5f2..b618a5d 100644
--- a/drivers/char/tpm/tpm-chip.c
+++ b/drivers/char/tpm/tpm-chip.c
@@ -121,17 +121,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 rc;
@@ -160,8 +160,6 @@ struct tpm_chip *tpmm_chip_alloc(struct device *dev,
 
 	device_initialize(&chip->dev);
 
-	dev_set_drvdata(dev, chip);
-
 	chip->dev.class = tpm_class;
 	chip->dev.release = tpm_dev_release;
 	chip->dev.parent = dev;
@@ -182,17 +180,40 @@ struct tpm_chip *tpmm_chip_alloc(struct device *dev,
 	chip->cdev.owner = THIS_MODULE;
 	chip->cdev.kobj.parent = &chip->dev.kobj;
 
-	rc = devm_add_action(dev, (void (*)(void *)) put_device, &chip->dev);
+	return chip;
+
+out:
+	put_device(&chip->dev);
+	return ERR_PTR(rc);
+}
+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 rc;
+
+	chip = tpm_chip_alloc(pdev, ops);
+	if (IS_ERR(chip))
+		return chip;
+
+	rc = devm_add_action(pdev, (void (*)(void *)) put_device, &chip->dev);
 	if (rc) {
 		put_device(&chip->dev);
 		return ERR_PTR(rc);
 	}
 
-	return chip;
+	dev_set_drvdata(pdev, chip);
 
-out:
-	put_device(&chip->dev);
-	return ERR_PTR(rc);
+	return chip;
 }
 EXPORT_SYMBOL_GPL(tpmm_chip_alloc);
 
diff --git a/drivers/char/tpm/tpm.h b/drivers/char/tpm/tpm.h
index c6376b1..5fcf788 100644
--- a/drivers/char/tpm/tpm.h
+++ b/drivers/char/tpm/tpm.h
@@ -511,7 +511,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] 36+ messages in thread

* [PATCH v4 06/10] tpm: Replace device number bitmap with IDR
       [not found] ` <1456766996-9300-1-git-send-email-stefanb-23VcF4HTsmIX0ybBhKVfKdBPR1lH4CV8@public.gmane.org>
                     ` (4 preceding siblings ...)
  2016-02-29 17:29   ` [PATCH v4 05/10] tpm: Split out the devm stuff from tpmm_chip_alloc Stefan Berger
@ 2016-02-29 17:29   ` Stefan Berger
       [not found]     ` <1456766996-9300-7-git-send-email-stefanb-23VcF4HTsmIX0ybBhKVfKdBPR1lH4CV8@public.gmane.org>
  2016-02-29 17:29   ` [PATCH v4 07/10] tpm: Introduce TPM_CHIP_FLAG_VIRTUAL Stefan Berger
                     ` (5 subsequent siblings)
  11 siblings, 1 reply; 36+ messages in thread
From: Stefan Berger @ 2016-02-29 17:29 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      | 84 +++++++++++++++++++++-------------------
 drivers/char/tpm/tpm-interface.c |  1 +
 drivers/char/tpm/tpm.h           |  5 +--
 3 files changed, 48 insertions(+), 42 deletions(-)

diff --git a/drivers/char/tpm/tpm-chip.c b/drivers/char/tpm/tpm-chip.c
index b618a5d..b5720c6 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,20 +87,30 @@ 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, *res = NULL;
+	int chip_prev;
+
+	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;
+	}
 
-	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;
+	mutex_unlock(&idr_lock);
 
-		/* rcu prevents chip from being free'd */
-		if (!tpm_try_get_ops(pos))
-			chip = pos;
-		break;
-	}
-	rcu_read_unlock();
-	return chip;
+	return res;
 }
 
 /**
@@ -114,9 +123,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);
 }
 
@@ -142,21 +152,18 @@ struct tpm_chip *tpm_chip_alloc(struct device *dev,
 
 	mutex_init(&chip->tpm_mutex);
 	init_rwsem(&chip->ops_sem);
-	INIT_LIST_HEAD(&chip->list);
 
 	chip->ops = ops;
 
-	spin_lock(&driver_lock);
-	chip->dev_num = find_first_zero_bit(dev_mask, TPM_NUM_DEVICES);
-	spin_unlock(&driver_lock);
-
-	if (chip->dev_num >= TPM_NUM_DEVICES) {
+	mutex_lock(&idr_lock);
+	rc = idr_alloc(&dev_nums_idr, NULL, 0, TPM_NUM_DEVICES, GFP_KERNEL);
+	mutex_unlock(&idr_lock);
+	if (rc < 0) {
 		dev_err(dev, "No available tpm device numbers\n");
 		kfree(chip);
-		return ERR_PTR(-ENOMEM);
+		return ERR_PTR(rc);
 	}
-
-	set_bit(chip->dev_num, dev_mask);
+	chip->dev_num = rc;
 
 	device_initialize(&chip->dev);
 
@@ -242,19 +249,28 @@ static int tpm_add_char_device(struct tpm_chip *chip)
 		return rc;
 	}
 
+	/* Make the chip available. */
+	mutex_lock(&idr_lock);
+	idr_replace(&dev_nums_idr, chip, chip->dev_num);
+	mutex_unlock(&idr_lock);
+
 	return rc;
 }
 
 static void tpm_del_char_device(struct tpm_chip *chip)
 {
 	cdev_del(&chip->cdev);
+	device_del(&chip->dev);
+
+	/* Make the chip unavailable. */
+	mutex_lock(&idr_lock);
+	idr_replace(&dev_nums_idr, NULL, chip->dev_num);
+	mutex_unlock(&idr_lock);
 
 	/* Make the driver uncallable. */
 	down_write(&chip->ops_sem);
 	chip->ops = NULL;
 	up_write(&chip->ops_sem);
-
-	device_del(&chip->dev);
 }
 
 static int tpm1_chip_register(struct tpm_chip *chip)
@@ -312,11 +328,6 @@ int tpm_chip_register(struct tpm_chip *chip)
 	if (rc)
 		goto out_err;
 
-	/* Make the chip available. */
-	spin_lock(&driver_lock);
-	list_add_tail_rcu(&chip->list, &tpm_chip_list);
-	spin_unlock(&driver_lock);
-
 	chip->flags |= TPM_CHIP_FLAG_REGISTERED;
 
 	if (!(chip->flags & TPM_CHIP_FLAG_TPM2)) {
@@ -350,11 +361,6 @@ 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();
-
 	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 5caf154..5397b64 100644
--- a/drivers/char/tpm/tpm-interface.c
+++ b/drivers/char/tpm/tpm-interface.c
@@ -1139,6 +1139,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 5fcf788..928b47f 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 */
 };
 
@@ -195,8 +195,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)
@@ -492,6 +490,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] 36+ messages in thread

* [PATCH v4 07/10] tpm: Introduce TPM_CHIP_FLAG_VIRTUAL
       [not found] ` <1456766996-9300-1-git-send-email-stefanb-23VcF4HTsmIX0ybBhKVfKdBPR1lH4CV8@public.gmane.org>
                     ` (5 preceding siblings ...)
  2016-02-29 17:29   ` [PATCH v4 06/10] tpm: Replace device number bitmap with IDR Stefan Berger
@ 2016-02-29 17:29   ` Stefan Berger
       [not found]     ` <1456766996-9300-8-git-send-email-stefanb-23VcF4HTsmIX0ybBhKVfKdBPR1lH4CV8@public.gmane.org>
  2016-02-29 17:29   ` [PATCH v4 08/10] tpm: Driver for supporting multiple emulated TPMs Stefan Berger
                     ` (4 subsequent siblings)
  11 siblings, 1 reply; 36+ messages in thread
From: Stefan Berger @ 2016-02-29 17:29 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  |  9 +++++----
 drivers/char/tpm/tpm-sysfs.c | 15 +++++++++++----
 drivers/char/tpm/tpm.h       |  5 +++--
 3 files changed, 19 insertions(+), 10 deletions(-)

diff --git a/drivers/char/tpm/tpm-chip.c b/drivers/char/tpm/tpm-chip.c
index b5720c6..2bcd8cd 100644
--- a/drivers/char/tpm/tpm-chip.c
+++ b/drivers/char/tpm/tpm-chip.c
@@ -170,9 +170,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);
@@ -183,6 +181,9 @@ struct tpm_chip *tpm_chip_alloc(struct device *dev,
 	if (rc)
 		goto out;
 
+	if (!dev)
+		chip->flags |= TPM_CHIP_FLAG_VIRTUAL;
+
 	cdev_init(&chip->cdev, &tpm_fops);
 	chip->cdev.owner = THIS_MODULE;
 	chip->cdev.kobj.parent = &chip->dev.kobj;
@@ -330,7 +331,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) {
@@ -361,7 +362,7 @@ void tpm_chip_unregister(struct tpm_chip *chip)
 	if (!(chip->flags & TPM_CHIP_FLAG_REGISTERED))
 		return;
 
-	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..9ee0f4d 100644
--- a/drivers/char/tpm/tpm-sysfs.c
+++ b/drivers/char/tpm/tpm-sysfs.c
@@ -283,9 +283,15 @@ 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 {
+		dev_set_drvdata(&chip->dev, chip);
+		chip->groups[chip->groups_cnt++] = &tpm_dev_group;
+	}
 
 	if (err)
 		dev_err(&chip->dev,
@@ -300,5 +306,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 928b47f..f197eef 100644
--- a/drivers/char/tpm/tpm.h
+++ b/drivers/char/tpm/tpm.h
@@ -164,6 +164,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 {
@@ -189,9 +190,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] 36+ messages in thread

* [PATCH v4 08/10] tpm: Driver for supporting multiple emulated TPMs
       [not found] ` <1456766996-9300-1-git-send-email-stefanb-23VcF4HTsmIX0ybBhKVfKdBPR1lH4CV8@public.gmane.org>
                     ` (6 preceding siblings ...)
  2016-02-29 17:29   ` [PATCH v4 07/10] tpm: Introduce TPM_CHIP_FLAG_VIRTUAL Stefan Berger
@ 2016-02-29 17:29   ` Stefan Berger
       [not found]     ` <1456766996-9300-9-git-send-email-stefanb-23VcF4HTsmIX0ybBhKVfKdBPR1lH4CV8@public.gmane.org>
  2016-02-29 17:29   ` [PATCH v4 09/10] tpm: Initialize TPM and get durations and timeouts Stefan Berger
                     ` (3 subsequent siblings)
  11 siblings, 1 reply; 36+ messages in thread
From: Stefan Berger @ 2016-02-29 17:29 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 | 546 ++++++++++++++++++++++++++++++++++++++++++++
 include/uapi/linux/Kbuild   |   1 +
 include/uapi/linux/vtpm.h   |  41 ++++
 5 files changed, 599 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..2c69363
--- /dev/null
+++ b/drivers/char/tpm/tpm-vtpm.c
@@ -0,0 +1,546 @@
+/*
+ * 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_REQ_COMPLETE_FLAG  BIT(0)
+
+struct vtpm_dev {
+	struct tpm_chip *chip;
+
+	u32 flags;                   /* public API flags */
+
+	wait_queue_head_t wq;
+
+	struct mutex buf_lock;       /* protect buffer and flag modifications */
+
+	long state;                  /* internal state */
+#define STATE_OPENED_FLAG        BIT(0)
+#define STATE_WAIT_RESPONSE_FLAG BIT(1)  /* waiting for emulator response */
+
+	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;
+
+	mutex_lock(&vtpm_dev->buf_lock);
+
+	len = vtpm_dev->req_len;
+
+	if (count < len) {
+		mutex_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;
+
+	if (!rc)
+		vtpm_dev->state |= STATE_WAIT_RESPONSE_FLAG;
+
+	mutex_unlock(&vtpm_dev->buf_lock);
+
+	if (rc)
+		return -EFAULT;
+
+	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) ||
+	    !(vtpm_dev->state & STATE_WAIT_RESPONSE_FLAG))
+		return -EIO;
+
+	mutex_lock(&vtpm_dev->buf_lock);
+
+	vtpm_dev->state &= ~STATE_WAIT_RESPONSE_FLAG;
+
+	vtpm_dev->req_len = 0;
+
+	if (copy_from_user(vtpm_dev->buffer, buf, count)) {
+		mutex_unlock(&vtpm_dev->buf_lock);
+		return -EFAULT;
+	}
+
+	vtpm_dev->resp_len = count;
+
+	mutex_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;
+
+	vtpm_dev->state |= STATE_OPENED_FLAG; /* locking not necessary */
+
+	mutex_unlock(&vtpm_dev->buf_lock);
+}
+
+/**
+ * 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)
+{
+	vtpm_dev->state &= ~STATE_OPENED_FLAG; /* locking not necessary */
+
+	/* 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;
+	size_t len;
+
+	if (!vtpm_dev)
+		return -EIO;
+
+	/* process gone ? */
+	if (!(vtpm_dev->state & STATE_OPENED_FLAG))
+		return -EPIPE;
+
+	mutex_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:
+	mutex_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 (!(vtpm_dev->state & STATE_OPENED_FLAG))
+		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;
+	}
+
+	mutex_lock(&vtpm_dev->buf_lock);
+
+	vtpm_dev->resp_len = 0;
+
+	vtpm_dev->req_len = count;
+	memcpy(vtpm_dev->buffer, buf, count);
+
+	vtpm_dev->state &= ~STATE_WAIT_RESPONSE_FLAG;
+
+	mutex_unlock(&vtpm_dev->buf_lock);
+
+	wake_up_interruptible(&vtpm_dev->wq);
+
+	return rc;
+}
+
+static void vtpm_tpm_op_cancel(struct tpm_chip *chip)
+{
+	/* not supported */
+}
+
+static u8 vtpm_tpm_op_status(struct tpm_chip *chip)
+{
+	struct vtpm_dev *vtpm_dev = chip->vendor.priv;
+
+	if (vtpm_dev->resp_len)
+		return VTPM_REQ_COMPLETE_FLAG;
+
+	return 0;
+}
+
+static bool vtpm_tpm_req_canceled(struct tpm_chip  *chip, u8 status)
+{
+	struct vtpm_dev *vtpm_dev = chip->vendor.priv;
+
+	return !(vtpm_dev->state & STATE_OPENED_FLAG);
+}
+
+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 = VTPM_REQ_COMPLETE_FLAG,
+	.req_complete_val = VTPM_REQ_COMPLETE_FLAG,
+	.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);
+	mutex_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;
+
+	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;
+
+	if (vtpm_new_pair->flags & ~VTPM_FLAGS_ALL)
+		return ERR_PTR(-EINVAL);
+
+	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 ebd10e6..3a602c9 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..978a849
--- /dev/null
+++ b/include/uapi/linux/vtpm.h
@@ -0,0 +1,41 @@
+/*
+ * 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 */
+
+/* all supported flags */
+#define VTPM_FLAGS_ALL  (VTPM_FLAG_TPM2)
+
+#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] 36+ messages in thread

* [PATCH v4 09/10] tpm: Initialize TPM and get durations and timeouts
       [not found] ` <1456766996-9300-1-git-send-email-stefanb-23VcF4HTsmIX0ybBhKVfKdBPR1lH4CV8@public.gmane.org>
                     ` (7 preceding siblings ...)
  2016-02-29 17:29   ` [PATCH v4 08/10] tpm: Driver for supporting multiple emulated TPMs Stefan Berger
@ 2016-02-29 17:29   ` Stefan Berger
  2016-02-29 17:29   ` [PATCH v4 10/10] A test program for vTPM device creation Stefan Berger
                     ` (2 subsequent siblings)
  11 siblings, 0 replies; 36+ messages in thread
From: Stefan Berger @ 2016-02-29 17:29 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 2c69363..d0df2b4 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 (!(vtpm_dev->state & STATE_OPENED_FLAG))
+		return -EPIPE;
+
 	sig = wait_event_interruptible(vtpm_dev->wq, vtpm_dev->req_len != 0);
 	if (sig)
 		return -EINTR;
@@ -108,6 +114,9 @@ static ssize_t vtpm_fops_write(struct file *filp, const char __user *buf,
 {
 	struct vtpm_dev *vtpm_dev = filp->private_data;
 
+	if (!(vtpm_dev->state & STATE_OPENED_FLAG))
+		return -EPIPE;
+
 	if (count > sizeof(vtpm_dev->buffer) ||
 	    !(vtpm_dev->state & STATE_WAIT_RESPONSE_FLAG))
 		return -EIO;
@@ -148,6 +157,8 @@ static unsigned int vtpm_fops_poll(struct file *filp, poll_table *wait)
 	ret = POLLOUT;
 	if (vtpm_dev->req_len)
 		ret |= POLLIN | POLLRDNORM;
+	if (!(vtpm_dev->state & STATE_OPENED_FLAG))
+		ret |= POLLHUP;
 
 	return ret;
 }
@@ -321,6 +332,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)
@@ -335,6 +394,7 @@ static struct vtpm_dev *vtpm_create_vtpm_dev(void)
 
 	init_waitqueue_head(&vtpm_dev->wq);
 	mutex_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)) {
@@ -404,9 +464,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);
@@ -415,12 +473,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);
 
@@ -435,6 +487,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);
@@ -529,11 +583,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] 36+ messages in thread

* [PATCH v4 10/10] A test program for vTPM device creation
       [not found] ` <1456766996-9300-1-git-send-email-stefanb-23VcF4HTsmIX0ybBhKVfKdBPR1lH4CV8@public.gmane.org>
                     ` (8 preceding siblings ...)
  2016-02-29 17:29   ` [PATCH v4 09/10] tpm: Initialize TPM and get durations and timeouts Stefan Berger
@ 2016-02-29 17:29   ` Stefan Berger
  2016-02-29 20:24   ` [PATCH v4 00/10] Multi-instance vTPM driver Jarkko Sakkinen
  2016-03-04 17:05   ` Jarkko Sakkinen
  11 siblings, 0 replies; 36+ messages in thread
From: Stefan Berger @ 2016-02-29 17:29 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] 36+ messages in thread

* Re: [PATCH v4 03/10] tpm: Provide strong locking for device removal
       [not found]     ` <1456766996-9300-4-git-send-email-stefanb-23VcF4HTsmIX0ybBhKVfKdBPR1lH4CV8@public.gmane.org>
@ 2016-02-29 19:25       ` Jason Gunthorpe
       [not found]         ` <20160229192532.GB15042-ePGOBjL8dl3ta4EC/59zMFaTQe2KTcn/@public.gmane.org>
       [not found]         ` <201602291949.u1TJn2Av025592@d03av03.boulder.ibm.com>
  0 siblings, 2 replies; 36+ messages in thread
From: Jason Gunthorpe @ 2016-02-29 19:25 UTC (permalink / raw)
  To: Stefan Berger; +Cc: tpmdd-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f

On Mon, Feb 29, 2016 at 12:29:49PM -0500, Stefan Berger wrote:
>   * 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.
>   */

Not sure what happened here, but this hunk belongs with
tpm_chip_unregister

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] 36+ messages in thread

* Re: [PATCH v4 04/10] tpm: Get rid of module locking
       [not found]     ` <1456766996-9300-5-git-send-email-stefanb-23VcF4HTsmIX0ybBhKVfKdBPR1lH4CV8@public.gmane.org>
@ 2016-02-29 19:25       ` Jason Gunthorpe
  2016-02-29 20:35       ` Jarkko Sakkinen
  1 sibling, 0 replies; 36+ messages in thread
From: Jason Gunthorpe @ 2016-02-29 19:25 UTC (permalink / raw)
  To: Stefan Berger; +Cc: tpmdd-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f

On Mon, Feb 29, 2016 at 12:29:50PM -0500, Stefan Berger wrote:
> 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.
> 
> Signed-off-by: Stefan Berger <stefanb-23VcF4HTsmIX0ybBhKVfKdBPR1lH4CV8@public.gmane.org>

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

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] 36+ messages in thread

* Re: [PATCH v4 06/10] tpm: Replace device number bitmap with IDR
       [not found]     ` <1456766996-9300-7-git-send-email-stefanb-23VcF4HTsmIX0ybBhKVfKdBPR1lH4CV8@public.gmane.org>
@ 2016-02-29 19:31       ` Jason Gunthorpe
       [not found]         ` <20160229193103.GD15042-ePGOBjL8dl3ta4EC/59zMFaTQe2KTcn/@public.gmane.org>
  0 siblings, 1 reply; 36+ messages in thread
From: Jason Gunthorpe @ 2016-02-29 19:31 UTC (permalink / raw)
  To: Stefan Berger; +Cc: tpmdd-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f

On Mon, Feb 29, 2016 at 12:29:52PM -0500, Stefan Berger wrote:
> 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>

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

 -	TPM_NUM_DEVICES = 256,
 +	TPM_NUM_DEVICES = 65536,
        rc = alloc_chrdev_region(&tpm_devt, 0, TPM_NUM_DEVICES, "tpm");

Although I do still wonder if passing such a large number to
alloc_chrdev_region is a good idea. Should it be MINORMASK instead or something?

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] 36+ messages in thread

* Re: [PATCH v4 07/10] tpm: Introduce TPM_CHIP_FLAG_VIRTUAL
       [not found]     ` <1456766996-9300-8-git-send-email-stefanb-23VcF4HTsmIX0ybBhKVfKdBPR1lH4CV8@public.gmane.org>
@ 2016-02-29 19:31       ` Jason Gunthorpe
  0 siblings, 0 replies; 36+ messages in thread
From: Jason Gunthorpe @ 2016-02-29 19:31 UTC (permalink / raw)
  To: Stefan Berger; +Cc: tpmdd-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f

On Mon, Feb 29, 2016 at 12:29:53PM -0500, Stefan Berger wrote:
> 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>

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

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] 36+ messages in thread

* Re: [PATCH v4 06/10] tpm: Replace device number bitmap with IDR
       [not found]         ` <20160229193103.GD15042-ePGOBjL8dl3ta4EC/59zMFaTQe2KTcn/@public.gmane.org>
@ 2016-02-29 19:36           ` Stefan Berger
  0 siblings, 0 replies; 36+ messages in thread
From: Stefan Berger @ 2016-02-29 19:36 UTC (permalink / raw)
  To: Jason Gunthorpe; +Cc: tpmdd-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f


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

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


> 
> On Mon, Feb 29, 2016 at 12:29:52PM -0500, Stefan Berger wrote:
> > 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>
> 
> Reviewed-by: Jason Gunthorpe <jgunthorpe-ePGOBjL8dl3ta4EC/59zMFaTQe2KTcn/@public.gmane.org>
> 
>  -   TPM_NUM_DEVICES = 256,
>  +   TPM_NUM_DEVICES = 65536,
>         rc = alloc_chrdev_region(&tpm_devt, 0, TPM_NUM_DEVICES, "tpm");
> 
> Although I do still wonder if passing such a large number to
> alloc_chrdev_region is a good idea. Should it be MINORMASK instead 
> or something?

Likely we would not use MINORMASK but we should use ( 1 << MINORBITS) 
instead, but that's 2^20 then.

   Stefan

> 
> Jason
> 



[-- Attachment #1.2: Type: text/html, Size: 1558 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] 36+ messages in thread

* Re: [PATCH v4 03/10] tpm: Provide strong locking for device removal
       [not found]         ` <20160229192532.GB15042-ePGOBjL8dl3ta4EC/59zMFaTQe2KTcn/@public.gmane.org>
@ 2016-02-29 19:48           ` Stefan Berger
  0 siblings, 0 replies; 36+ messages in thread
From: Stefan Berger @ 2016-02-29 19:48 UTC (permalink / raw)
  To: Jason Gunthorpe; +Cc: tpmdd-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f


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

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


> 
> On Mon, Feb 29, 2016 at 12:29:49PM -0500, Stefan Berger wrote:
> >   * 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.
> >   */
> 
> Not sure what happened here, but this hunk belongs with
> tpm_chip_unregister

That's where it is. The context 'tpm1_chip_unregister' the hunk shows is 
from the function 'above'.

   Stefan



[-- Attachment #1.2: Type: text/html, Size: 1056 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] 36+ messages in thread

* Re: [PATCH v4 03/10] tpm: Provide strong locking for device removal
       [not found]           ` <201602291949.u1TJn2Av025592-MijUUJkLaQs+UXBhvPuGgqsjOiXwFzmk@public.gmane.org>
@ 2016-02-29 19:54             ` Jason Gunthorpe
       [not found]               ` <20160229195400.GA32380-ePGOBjL8dl3ta4EC/59zMFaTQe2KTcn/@public.gmane.org>
  0 siblings, 1 reply; 36+ messages in thread
From: Jason Gunthorpe @ 2016-02-29 19:54 UTC (permalink / raw)
  To: Stefan Berger; +Cc: tpmdd-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f

On Mon, Feb 29, 2016 at 02:48:54PM -0500, Stefan Berger wrote:
>    Jason Gunthorpe <jgunthorpe-ePGOBjL8dl3ta4EC/59zMFaTQe2KTcn/@public.gmane.org> wrote on 02/29/2016
>    02:25:32 PM:
>    >
>    > On Mon, Feb 29, 2016 at 12:29:49PM -0500, Stefan Berger wrote:
>    > >   * 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.
>    > >   */
>    >
>    > Not sure what happened here, but this hunk belongs with
>    > tpm_chip_unregister
>    That's where it is. The context 'tpm1_chip_unregister' the hunk shows
>    is from the function 'above'.

Eh?

https://github.com/stefanberger/linux/blob/63f0cd1bae930167d31bbe5d5779d40a277e91c5/drivers/char/tpm/tpm-chip.c#L311

/*
 * tpm_chip_register() - create a character device for the TPM chip
 * @chip: TPM chip to use.
 *
 * Creates a character device for the TPM chip and adds sysfs attributes for
 * 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.
 */
int tpm_chip_register(struct tpm_chip *chip)
{

------------------------------------------------------------------------------
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] 36+ messages in thread

* Re: [PATCH v4 03/10] tpm: Provide strong locking for device removal
       [not found]               ` <20160229195400.GA32380-ePGOBjL8dl3ta4EC/59zMFaTQe2KTcn/@public.gmane.org>
@ 2016-02-29 20:04                 ` Stefan Berger
       [not found]                   ` <201602292004.u1TK4IDH023664-YREtIfBy6dDImUpY6SP3GEEOCMrvLtNR@public.gmane.org>
  0 siblings, 1 reply; 36+ messages in thread
From: Stefan Berger @ 2016-02-29 20:04 UTC (permalink / raw)
  To: Jason Gunthorpe; +Cc: tpmdd-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f


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

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

> 
> On Mon, Feb 29, 2016 at 02:48:54PM -0500, Stefan Berger wrote:
> >    Jason Gunthorpe <jgunthorpe-ePGOBjL8dl3ta4EC/59zMFaTQe2KTcn/@public.gmane.org> wrote on 
02/29/2016
> >    02:25:32 PM:
> >    >
> >    > On Mon, Feb 29, 2016 at 12:29:49PM -0500, Stefan Berger wrote:
> >    > >   * 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.
> >    > >   */
> >    >
> >    > Not sure what happened here, but this hunk belongs with
> >    > tpm_chip_unregister
> >    That's where it is. The context 'tpm1_chip_unregister' the hunk 
shows
> >    is from the function 'above'.
> 
> Eh?
> 
> https://github.com/stefanberger/linux/blob/
> 
63f0cd1bae930167d31bbe5d5779d40a277e91c5/drivers/char/tpm/tpm-chip.c#L311


Sorry. Fixed here : 
https://github.com/stefanberger/linux/commit/5808cd0b01b00e1a4e3b23d6970bac4efee69038

   Stefan



[-- Attachment #1.2: Type: text/html, Size: 2249 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] 36+ messages in thread

* Re: [PATCH v4 00/10] Multi-instance vTPM driver
       [not found] ` <1456766996-9300-1-git-send-email-stefanb-23VcF4HTsmIX0ybBhKVfKdBPR1lH4CV8@public.gmane.org>
                     ` (9 preceding siblings ...)
  2016-02-29 17:29   ` [PATCH v4 10/10] A test program for vTPM device creation Stefan Berger
@ 2016-02-29 20:24   ` Jarkko Sakkinen
       [not found]     ` <20160229202401.GA26296-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
       [not found]     ` <201602292030.u1TKUgSu010507@d01av03.pok.ibm.com>
  2016-03-04 17:05   ` Jarkko Sakkinen
  11 siblings, 2 replies; 36+ messages in thread
From: Jarkko Sakkinen @ 2016-02-29 20:24 UTC (permalink / raw)
  To: Stefan Berger; +Cc: tpmdd-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f

On Mon, Feb 29, 2016 at 12:29:46PM -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.
> 
> The driver is based on James Morris's 'next' branch and uses several
> recently posted patches from Jason and Jarkko. Some of these patches
> needed to rebased on top of this tree.

It is kind of hard to follow what has happend between patch set
versions if you don't have a changelog in the cover letter.

/Jarkko

> 
>    Stefan
> 
> 
> 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         | 221 +++++++++----
>  drivers/char/tpm/tpm-dev.c          |  15 +-
>  drivers/char/tpm/tpm-interface.c    |  50 +--
>  drivers/char/tpm/tpm-sysfs.c        |  22 +-
>  drivers/char/tpm/tpm-vtpm.c         | 613 ++++++++++++++++++++++++++++++++++++
>  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           |  41 +++
>  vtpmctrl.c                          | 163 ++++++++++
>  21 files changed, 1120 insertions(+), 179 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] 36+ messages in thread

* Re: [PATCH v4 00/10] Multi-instance vTPM driver
       [not found]     ` <20160229202401.GA26296-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
@ 2016-02-29 20:30       ` Stefan Berger
  0 siblings, 0 replies; 36+ messages in thread
From: Stefan Berger @ 2016-02-29 20:30 UTC (permalink / raw)
  To: Jarkko Sakkinen; +Cc: tpmdd-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f


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

Jarkko Sakkinen <jarkko.sakkinen-VuQAYsv1563Yd54FQh9/CA@public.gmane.org> wrote on 02/29/2016 
03:24:01 PM:


> 
> On Mon, Feb 29, 2016 at 12:29:46PM -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.
> > 
> > The driver is based on James Morris's 'next' branch and uses several
> > recently posted patches from Jason and Jarkko. Some of these patches
> > needed to rebased on top of this tree.
> 
> It is kind of hard to follow what has happend between patch set
> versions if you don't have a changelog in the cover letter.

Sorry for that. I followed your suggestion about the flags in the 
vtpm-driver but moved the ops related to flag modifications under the 
mutex lock.

    Stefan



[-- Attachment #1.2: Type: text/html, Size: 1592 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] 36+ messages in thread

* Re: [PATCH v4 04/10] tpm: Get rid of module locking
       [not found]     ` <1456766996-9300-5-git-send-email-stefanb-23VcF4HTsmIX0ybBhKVfKdBPR1lH4CV8@public.gmane.org>
  2016-02-29 19:25       ` Jason Gunthorpe
@ 2016-02-29 20:35       ` Jarkko Sakkinen
       [not found]         ` <20160229203550.GB26296-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
       [not found]         ` <201602292050.u1TKo2CC012799@d01av01.pok.ibm.com>
  1 sibling, 2 replies; 36+ messages in thread
From: Jarkko Sakkinen @ 2016-02-29 20:35 UTC (permalink / raw)
  To: Stefan Berger; +Cc: tpmdd-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f

On Mon, Feb 29, 2016 at 12:29:50PM -0500, Stefan Berger wrote:
> 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.

I don't understand why the user visible behavior of /dev/tpmX should
be changed if there are no life and death reasons to do it. Do you
think that this patch is absolutely crucial for the feature
implemented?

/Jarkko

> Signed-off-by: Stefan Berger <stefanb-23VcF4HTsmIX0ybBhKVfKdBPR1lH4CV8@public.gmane.org>
> ---
>  drivers/char/tpm/tpm-chip.c | 6 +-----
>  1 file changed, 1 insertion(+), 5 deletions(-)
> 
> diff --git a/drivers/char/tpm/tpm-chip.c b/drivers/char/tpm/tpm-chip.c
> index 1ae30f2..8f4b5f2 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);
>  }
> @@ -183,7 +179,7 @@ struct tpm_chip *tpmm_chip_alloc(struct device *dev,
>  		goto out;
>  
>  	cdev_init(&chip->cdev, &tpm_fops);
> -	chip->cdev.owner = dev->driver->owner;
> +	chip->cdev.owner = THIS_MODULE;
>  	chip->cdev.kobj.parent = &chip->dev.kobj;
>  
>  	rc = devm_add_action(dev, (void (*)(void *)) 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] 36+ messages in thread

* Re: [PATCH v4 00/10] Multi-instance vTPM driver
       [not found]       ` <201602292030.u1TKUgSu010507-CUdSWdNILC7ImUpY6SP3GEEOCMrvLtNR@public.gmane.org>
@ 2016-02-29 20:48         ` Jarkko Sakkinen
       [not found]           ` <20160229204846.GA27210-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
  0 siblings, 1 reply; 36+ messages in thread
From: Jarkko Sakkinen @ 2016-02-29 20:48 UTC (permalink / raw)
  To: Stefan Berger; +Cc: tpmdd-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f

On Mon, Feb 29, 2016 at 03:30:35PM -0500, Stefan Berger wrote:
>    Jarkko Sakkinen <jarkko.sakkinen-VuQAYsv1563Yd54FQh9/CA@public.gmane.org> wrote on 02/29/2016
>    03:24:01 PM:
> 
>    >
>    > On Mon, Feb 29, 2016 at 12:29:46PM -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.
>    > >
>    > > The driver is based on James Morris's 'next' branch and uses several
>    > > recently posted patches from Jason and Jarkko. Some of these patches
>    > > needed to rebased on top of this tree.
>    >
>    > It is kind of hard to follow what has happend between patch set
>    > versions if you don't have a changelog in the cover letter.
> 
>    Sorry for that. I followed your suggestion about the flags in the
>    vtpm-driver but moved the ops related to flag modifications under the
>    mutex lock.

Thanks and no worries.

>        Stefan

/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] 36+ messages in thread

* Re: [PATCH v4 04/10] tpm: Get rid of module locking
       [not found]         ` <20160229203550.GB26296-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
@ 2016-02-29 20:49           ` Stefan Berger
  2016-03-01  0:24           ` Jason Gunthorpe
  1 sibling, 0 replies; 36+ messages in thread
From: Stefan Berger @ 2016-02-29 20:49 UTC (permalink / raw)
  To: Jarkko Sakkinen, Jason Gunthorpe
  Cc: tpmdd-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f


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

Jarkko Sakkinen <jarkko.sakkinen-VuQAYsv1563Yd54FQh9/CA@public.gmane.org> wrote on 02/29/2016 
03:35:50 PM:


> On Mon, Feb 29, 2016 at 12:29:50PM -0500, Stefan Berger wrote:
> > 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.
> 
> I don't understand why the user visible behavior of /dev/tpmX should
> be changed if there are no life and death reasons to do it. Do you
> think that this patch is absolutely crucial for the feature
> implemented?

This changes the module counter on the hardware / backend driver and not 
other user visible behavior from what I can tell. It's certainly/hopefully 
not a life-and-death thing, though I am wondering whether it's be applied 
sooner or later anyway for cleanup reasons following the preceding patch 
providing 'strong locking'.

   Stefan

> 
> /Jarkko
> 
> > Signed-off-by: Stefan Berger <stefanb-23VcF4HTsmIX0ybBhKVfKdBPR1lH4CV8@public.gmane.org>
> > ---
> >  drivers/char/tpm/tpm-chip.c | 6 +-----
> >  1 file changed, 1 insertion(+), 5 deletions(-)
> > 
> > diff --git a/drivers/char/tpm/tpm-chip.c b/drivers/char/tpm/tpm-chip.c
> > index 1ae30f2..8f4b5f2 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);
> >  }
> > @@ -183,7 +179,7 @@ struct tpm_chip *tpmm_chip_alloc(struct device 
*dev,
> >        goto out;
> > 
> >     cdev_init(&chip->cdev, &tpm_fops);
> > -   chip->cdev.owner = dev->driver->owner;
> > +   chip->cdev.owner = THIS_MODULE;
> >     chip->cdev.kobj.parent = &chip->dev.kobj;
> > 
> >     rc = devm_add_action(dev, (void (*)(void *)) put_device, 
&chip->dev);
> > -- 
> > 2.4.3
> > 
> 



[-- Attachment #1.2: Type: text/html, Size: 3212 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] 36+ messages in thread

* Re: [PATCH v4 00/10] Multi-instance vTPM driver
       [not found]           ` <20160229204846.GA27210-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
@ 2016-02-29 20:57             ` Jarkko Sakkinen
  0 siblings, 0 replies; 36+ messages in thread
From: Jarkko Sakkinen @ 2016-02-29 20:57 UTC (permalink / raw)
  To: Stefan Berger; +Cc: tpmdd-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f

On Mon, Feb 29, 2016 at 10:48:46PM +0200, Jarkko Sakkinen wrote:
> On Mon, Feb 29, 2016 at 03:30:35PM -0500, Stefan Berger wrote:
> >    Jarkko Sakkinen <jarkko.sakkinen-VuQAYsv1563Yd54FQh9/CA@public.gmane.org> wrote on 02/29/2016
> >    03:24:01 PM:
> > 
> >    >
> >    > On Mon, Feb 29, 2016 at 12:29:46PM -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.
> >    > >
> >    > > The driver is based on James Morris's 'next' branch and uses several
> >    > > recently posted patches from Jason and Jarkko. Some of these patches
> >    > > needed to rebased on top of this tree.
> >    >
> >    > It is kind of hard to follow what has happend between patch set
> >    > versions if you don't have a changelog in the cover letter.
> > 
> >    Sorry for that. I followed your suggestion about the flags in the
> >    vtpm-driver but moved the ops related to flag modifications under the
> >    mutex lock.
> 
> Thanks and no worries.

I looked at the patches and I think this could be applied to master
very soon. I still have to look it with time though so this is not yet
a promise. In big picture this looks really good.

That does not mean of course that they will go to linux-next any time
soon but this way they would get more exposure.

Does not make sense to waste your time for rolling out new version of
the series if the problems are localized to few lines...

/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] 36+ messages in thread

* Re: [PATCH v4 04/10] tpm: Get rid of module locking
       [not found]         ` <20160229203550.GB26296-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
  2016-02-29 20:49           ` Stefan Berger
@ 2016-03-01  0:24           ` Jason Gunthorpe
  1 sibling, 0 replies; 36+ messages in thread
From: Jason Gunthorpe @ 2016-03-01  0:24 UTC (permalink / raw)
  To: Jarkko Sakkinen; +Cc: tpmdd-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f

On Mon, Feb 29, 2016 at 10:35:50PM +0200, Jarkko Sakkinen wrote:
> On Mon, Feb 29, 2016 at 12:29:50PM -0500, Stefan Berger wrote:
> > 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.
> 
> I don't understand why the user visible behavior of /dev/tpmX should
> be changed if there are no life and death reasons to do it. Do you
> think that this patch is absolutely crucial for the feature
> implemented?

Stefan is addressing it here because once NULL is a legal parent for
registration the chip->dev.parent->driver->owner expression becomes
useless for module locking.

If we want to keep module locking then Stefen has to add an 'owner'
field to tpm_class_ops and update all drivers. The ops->owner would
be used for the module locking instead of driver->owner

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] 36+ messages in thread

* Re: [PATCH v4 04/10] tpm: Get rid of module locking
       [not found]           ` <201602292050.u1TKo2CC012799-4ZtxiNBBw+3ImUpY6SP3GEEOCMrvLtNR@public.gmane.org>
@ 2016-03-01  5:18             ` Jarkko Sakkinen
  0 siblings, 0 replies; 36+ messages in thread
From: Jarkko Sakkinen @ 2016-03-01  5:18 UTC (permalink / raw)
  To: Stefan Berger; +Cc: tpmdd-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f

On Mon, Feb 29, 2016 at 03:49:55PM -0500, Stefan Berger wrote:
>    Jarkko Sakkinen <jarkko.sakkinen-VuQAYsv1563Yd54FQh9/CA@public.gmane.org> wrote on 02/29/2016
>    03:35:50 PM:
> 
>    > On Mon, Feb 29, 2016 at 12:29:50PM -0500, Stefan Berger wrote:
>    > > 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.
>    >
>    > I don't understand why the user visible behavior of /dev/tpmX should
>    > be changed if there are no life and death reasons to do it. Do you
>    > think that this patch is absolutely crucial for the feature
>    > implemented?
> 
>    This changes the module counter on the hardware / backend driver and not
>    other user visible behavior from what I can tell. It's certainly/hopefully
>    not a life-and-death thing, though I am wondering whether it's be applied
>    sooner or later anyway for cleanup reasons following the preceding patch
>    providing 'strong locking'.

OK, I just your and Jasons reply and will head soon to apply the series
to my master branch (being there still give space to move with locking
if needed).

/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] 36+ messages in thread

* Re: [PATCH v4 00/10] Multi-instance vTPM driver
       [not found] ` <1456766996-9300-1-git-send-email-stefanb-23VcF4HTsmIX0ybBhKVfKdBPR1lH4CV8@public.gmane.org>
                     ` (10 preceding siblings ...)
  2016-02-29 20:24   ` [PATCH v4 00/10] Multi-instance vTPM driver Jarkko Sakkinen
@ 2016-03-04 17:05   ` Jarkko Sakkinen
  11 siblings, 0 replies; 36+ messages in thread
From: Jarkko Sakkinen @ 2016-03-04 17:05 UTC (permalink / raw)
  To: Stefan Berger; +Cc: tpmdd-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f

On Mon, Feb 29, 2016 at 12:29:46PM -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.
> 
> The driver is based on James Morris's 'next' branch and uses several
> recently posted patches from Jason and Jarkko. Some of these patches
> needed to rebased on top of this tree.

I've now applied these patches to my master branch so that they
get more exposure:

git://git.infradead.org/users/jjs/linux-tpmdd.git

All patches are applied except the last one containing the test
program. Could you put a repository to somewhere for it?

Thanks for the good work!

/Jarkko

>    Stefan
> 
> 
> 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         | 221 +++++++++----
>  drivers/char/tpm/tpm-dev.c          |  15 +-
>  drivers/char/tpm/tpm-interface.c    |  50 +--
>  drivers/char/tpm/tpm-sysfs.c        |  22 +-
>  drivers/char/tpm/tpm-vtpm.c         | 613 ++++++++++++++++++++++++++++++++++++
>  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           |  41 +++
>  vtpmctrl.c                          | 163 ++++++++++
>  21 files changed, 1120 insertions(+), 179 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
> 

------------------------------------------------------------------------------

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

* Re: [PATCH v4 03/10] tpm: Provide strong locking for device removal
       [not found]                   ` <201602292004.u1TK4IDH023664-YREtIfBy6dDImUpY6SP3GEEOCMrvLtNR@public.gmane.org>
@ 2016-03-04 18:10                     ` Jarkko Sakkinen
       [not found]                       ` <20160304181038.GA24462-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
       [not found]                       ` <201603041908.u24J89Mv018643@d01av03.pok.ibm.com>
  0 siblings, 2 replies; 36+ messages in thread
From: Jarkko Sakkinen @ 2016-03-04 18:10 UTC (permalink / raw)
  To: Stefan Berger; +Cc: tpmdd-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f

On Mon, Feb 29, 2016 at 03:04:10PM -0500, Stefan Berger wrote:
>    Jason Gunthorpe <jgunthorpe-ePGOBjL8dl3ta4EC/59zMFaTQe2KTcn/@public.gmane.org> wrote on 02/29/2016
>    02:54:01 PM:
> 
>    >
>    > On Mon, Feb 29, 2016 at 02:48:54PM -0500, Stefan Berger wrote:
>    > >    Jason Gunthorpe <jgunthorpe-ePGOBjL8dl3ta4EC/59zMFaTQe2KTcn/@public.gmane.org> wrote on
>    02/29/2016
>    > >    02:25:32 PM:
>    > >    >
>    > >    > On Mon, Feb 29, 2016 at 12:29:49PM -0500, Stefan Berger wrote:
>    > >    > >   * 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.
>    > >    > >   */
>    > >    >
>    > >    > Not sure what happened here, but this hunk belongs with
>    > >    > tpm_chip_unregister
>    > >    That's where it is. The context 'tpm1_chip_unregister' the hunk
>    shows
>    > >    is from the function 'above'.
>    >
>    > Eh?
>    >
>    > https://github.com/stefanberger/linux/blob/
>    >
>    63f0cd1bae930167d31bbe5d5779d40a277e91c5/drivers/char/tpm/tpm-chip.c#L311
> 
>    Sorry. Fixed here :
>    https://github.com/stefanberger/linux/commit/5808cd0b01b00e1a4e3b23d6970bac4efee69038

Already applied v4. Could you send a fix for this to the list?
Thanks.

>       Stefan

/Jarkko

------------------------------------------------------------------------------

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

* Re: [PATCH v4 03/10] tpm: Provide strong locking for device removal
       [not found]                       ` <20160304181038.GA24462-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
@ 2016-03-04 19:06                         ` Stefan Berger
  0 siblings, 0 replies; 36+ messages in thread
From: Stefan Berger @ 2016-03-04 19:06 UTC (permalink / raw)
  To: Jarkko Sakkinen; +Cc: tpmdd-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f


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

Jarkko Sakkinen <jarkko.sakkinen-VuQAYsv1563Yd54FQh9/CA@public.gmane.org> wrote on 03/04/2016 
01:10:38 PM:

> 
> On Mon, Feb 29, 2016 at 03:04:10PM -0500, Stefan Berger wrote:
> >    Jason Gunthorpe <jgunthorpe-ePGOBjL8dl3ta4EC/59zMFaTQe2KTcn/@public.gmane.org> wrote on 
02/29/2016
> >    02:54:01 PM:
> > 
> >    >
> >    > On Mon, Feb 29, 2016 at 02:48:54PM -0500, Stefan Berger wrote:
> >    > >    Jason Gunthorpe <jgunthorpe-ePGOBjL8dl3ta4EC/59zMFaTQe2KTcn/@public.gmane.org> wrote on
> >    02/29/2016
> >    > >    02:25:32 PM:
> >    > >    >
> >    > >    > On Mon, Feb 29, 2016 at 12:29:49PM -0500, Stefan Berger 
wrote:
> >    > >    > >   * 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.
> >    > >    > >   */
> >    > >    >
> >    > >    > Not sure what happened here, but this hunk belongs with
> >    > >    > tpm_chip_unregister
> >    > >    That's where it is. The context 'tpm1_chip_unregister' the 
hunk
> >    shows
> >    > >    is from the function 'above'.
> >    >
> >    > Eh?
> >    >
> >    > https://github.com/stefanberger/linux/blob/
> >    >
> > 
63f0cd1bae930167d31bbe5d5779d40a277e91c5/drivers/char/tpm/tpm-chip.c#L311
> > 
> >    Sorry. Fixed here :
> >    https://github.com/stefanberger/linux/commit/
> 5808cd0b01b00e1a4e3b23d6970bac4efee69038
> 
> Already applied v4. Could you send a fix for this to the list?
> Thanks.

I can post v5 that also has the Reviewed-by's applied.

https://github.com/stefanberger/linux/commits/vtpm-driver.v5

  Stefan


> 
> >       Stefan
> 
> /Jarkko
> 



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

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

------------------------------------------------------------------------------

[-- 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] 36+ messages in thread

* Re: [PATCH v4 08/10] tpm: Driver for supporting multiple emulated TPMs
       [not found]     ` <1456766996-9300-9-git-send-email-stefanb-23VcF4HTsmIX0ybBhKVfKdBPR1lH4CV8@public.gmane.org>
@ 2016-03-04 20:29       ` Jarkko Sakkinen
       [not found]         ` <20160304202928.GA32617-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
       [not found]         ` <201603042112.u24LCT7q016369@d01av05.pok.ibm.com>
  0 siblings, 2 replies; 36+ messages in thread
From: Jarkko Sakkinen @ 2016-03-04 20:29 UTC (permalink / raw)
  To: Stefan Berger; +Cc: tpmdd-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f

Hi

I noticed some glitches.

On Mon, Feb 29, 2016 at 12:29:54PM -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.

Every other driver in the subsystem except xen-tpmfront uses
underscore instead of dash. For the sake of consistency this should be
renamed as tpm_vtpm.


> 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 | 546 ++++++++++++++++++++++++++++++++++++++++++++
>  include/uapi/linux/Kbuild   |   1 +
>  include/uapi/linux/vtpm.h   |  41 ++++
>  5 files changed, 599 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..2c69363
> --- /dev/null
> +++ b/drivers/char/tpm/tpm-vtpm.c
> @@ -0,0 +1,546 @@
> +/*
> + * 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_REQ_COMPLETE_FLAG  BIT(0)
> +
> +struct vtpm_dev {
> +	struct tpm_chip *chip;
> +
> +	u32 flags;                   /* public API flags */
> +
> +	wait_queue_head_t wq;
> +
> +	struct mutex buf_lock;       /* protect buffer and flag modifications */
> +
> +	long state;                  /* internal state */
> +#define STATE_OPENED_FLAG        BIT(0)
> +#define STATE_WAIT_RESPONSE_FLAG BIT(1)  /* waiting for emulator response */
> +
> +	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;
> +
> +	mutex_lock(&vtpm_dev->buf_lock);
> +
> +	len = vtpm_dev->req_len;
> +
> +	if (count < len) {
> +		mutex_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;
> +
> +	if (!rc)
> +		vtpm_dev->state |= STATE_WAIT_RESPONSE_FLAG;
> +
> +	mutex_unlock(&vtpm_dev->buf_lock);
> +
> +	if (rc)
> +		return -EFAULT;
> +
> +	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) ||
> +	    !(vtpm_dev->state & STATE_WAIT_RESPONSE_FLAG))
> +		return -EIO;

This is not atomic in any sense. You should move this statement after
taking buf_lock.

> +
> +	mutex_lock(&vtpm_dev->buf_lock);
> +
> +	vtpm_dev->state &= ~STATE_WAIT_RESPONSE_FLAG;
> +
> +	vtpm_dev->req_len = 0;
> +
> +	if (copy_from_user(vtpm_dev->buffer, buf, count)) {
> +		mutex_unlock(&vtpm_dev->buf_lock);
> +		return -EFAULT;
> +	}
> +
> +	vtpm_dev->resp_len = count;
> +
> +	mutex_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;


mutex_lock(&vtpm_dev->buf_lock);

> +
> +	vtpm_dev->state |= STATE_OPENED_FLAG; /* locking not necessary */
> +
> +	mutex_unlock(&vtpm_dev->buf_lock);
> +}
> +
> +/**
> + * 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)
> +{
> +	vtpm_dev->state &= ~STATE_OPENED_FLAG; /* locking not necessary */
> +
> +	/* 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;
> +	size_t len;
> +
> +	if (!vtpm_dev)
> +		return -EIO;
> +
> +	/* process gone ? */
> +	if (!(vtpm_dev->state & STATE_OPENED_FLAG))
> +		return -EPIPE;
> +
> +	mutex_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:
> +	mutex_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 (!(vtpm_dev->state & STATE_OPENED_FLAG))
> +		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;
> +	}
> +
> +	mutex_lock(&vtpm_dev->buf_lock);
> +
> +	vtpm_dev->resp_len = 0;
> +
> +	vtpm_dev->req_len = count;
> +	memcpy(vtpm_dev->buffer, buf, count);
> +
> +	vtpm_dev->state &= ~STATE_WAIT_RESPONSE_FLAG;
> +
> +	mutex_unlock(&vtpm_dev->buf_lock);
> +
> +	wake_up_interruptible(&vtpm_dev->wq);
> +
> +	return rc;
> +}
> +
> +static void vtpm_tpm_op_cancel(struct tpm_chip *chip)
> +{
> +	/* not supported */
> +}
> +
> +static u8 vtpm_tpm_op_status(struct tpm_chip *chip)
> +{
> +	struct vtpm_dev *vtpm_dev = chip->vendor.priv;
> +
> +	if (vtpm_dev->resp_len)
> +		return VTPM_REQ_COMPLETE_FLAG;
> +
> +	return 0;
> +}
> +
> +static bool vtpm_tpm_req_canceled(struct tpm_chip  *chip, u8 status)
> +{
> +	struct vtpm_dev *vtpm_dev = chip->vendor.priv;
> +
> +	return !(vtpm_dev->state & STATE_OPENED_FLAG);
> +}
> +
> +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 = VTPM_REQ_COMPLETE_FLAG,
> +	.req_complete_val = VTPM_REQ_COMPLETE_FLAG,
> +	.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);
> +	mutex_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;
> +
> +	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;
> +
> +	if (vtpm_new_pair->flags & ~VTPM_FLAGS_ALL)
> +		return ERR_PTR(-EINVAL);
> +
> +	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 ebd10e6..3a602c9 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..978a849
> --- /dev/null
> +++ b/include/uapi/linux/vtpm.h
> @@ -0,0 +1,41 @@
> +/*
> + * 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 */
> +
> +/* all supported flags */
> +#define VTPM_FLAGS_ALL  (VTPM_FLAG_TPM2)
> +
> +#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

------------------------------------------------------------------------------

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

* Re: [PATCH v4 08/10] tpm: Driver for supporting multiple emulated TPMs
       [not found]         ` <20160304202928.GA32617-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
@ 2016-03-04 21:16           ` Stefan Berger
  0 siblings, 0 replies; 36+ messages in thread
From: Stefan Berger @ 2016-03-04 21:16 UTC (permalink / raw)
  To: Jarkko Sakkinen; +Cc: tpmdd-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f


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

Jarkko Sakkinen <jarkko.sakkinen-VuQAYsv1563Yd54FQh9/CA@public.gmane.org> wrote on 03/04/2016 
03:29:28 PM:
> 
> Hi
> 
> I noticed some glitches.
> 
> On Mon, Feb 29, 2016 at 12:29:54PM -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.
> 
> Every other driver in the subsystem except xen-tpmfront uses
> underscore instead of dash. For the sake of consistency this should be
> renamed as tpm_vtpm.

fixed.


> 
> 
> > 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 | 546 +++++++++++++++++++++++++++++++
> +++++++++++++
> >  include/uapi/linux/Kbuild   |   1 +
> >  include/uapi/linux/vtpm.h   |  41 ++++
> >  5 files changed, 599 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..2c69363
> > --- /dev/null
> > +++ b/drivers/char/tpm/tpm-vtpm.c
> > @@ -0,0 +1,546 @@
> > +/*
> > + * 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_REQ_COMPLETE_FLAG  BIT(0)
> > +
> > +struct vtpm_dev {
> > +   struct tpm_chip *chip;
> > +
> > +   u32 flags;                   /* public API flags */
> > +
> > +   wait_queue_head_t wq;
> > +
> > +   struct mutex buf_lock;       /* protect buffer and flag 
modifications */
> > +
> > +   long state;                  /* internal state */
> > +#define STATE_OPENED_FLAG        BIT(0)
> > +#define STATE_WAIT_RESPONSE_FLAG BIT(1)  /* waiting for emulator 
> response */
> > +
> > +   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;
> > +
> > +   mutex_lock(&vtpm_dev->buf_lock);
> > +
> > +   len = vtpm_dev->req_len;
> > +
> > +   if (count < len) {
> > +      mutex_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;
> > +
> > +   if (!rc)
> > +      vtpm_dev->state |= STATE_WAIT_RESPONSE_FLAG;
> > +
> > +   mutex_unlock(&vtpm_dev->buf_lock);
> > +
> > +   if (rc)
> > +      return -EFAULT;
> > +
> > +   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) ||
> > +       !(vtpm_dev->state & STATE_WAIT_RESPONSE_FLAG))
> > +      return -EIO;
> 
> This is not atomic in any sense. You should move this statement after
> taking buf_lock.


set_bit and friends were all atomic. Now we need to put all of these into 
the mutex... ?

   Stefan




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

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

------------------------------------------------------------------------------

[-- 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] 36+ messages in thread

* Re: [PATCH v4 03/10] tpm: Provide strong locking for device removal
       [not found]                         ` <201603041908.u24J89Mv018643-CUdSWdNILC7ImUpY6SP3GEEOCMrvLtNR@public.gmane.org>
@ 2016-03-04 21:27                           ` Jarkko Sakkinen
       [not found]                             ` <20160304212716.GA9158-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
  0 siblings, 1 reply; 36+ messages in thread
From: Jarkko Sakkinen @ 2016-03-04 21:27 UTC (permalink / raw)
  To: Stefan Berger; +Cc: tpmdd-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f

On Fri, Mar 04, 2016 at 02:06:23PM -0500, Stefan Berger wrote:
>    Jarkko Sakkinen <jarkko.sakkinen-VuQAYsv1563Yd54FQh9/CA@public.gmane.org> wrote on 03/04/2016
>    01:10:38 PM:
>    >
>    > On Mon, Feb 29, 2016 at 03:04:10PM -0500, Stefan Berger wrote:
>    > >    Jason Gunthorpe <jgunthorpe-ePGOBjL8dl3ta4EC/59zMFaTQe2KTcn/@public.gmane.org> wrote on
>    02/29/2016
>    > >    02:54:01 PM:
>    > >
>    > >    >
>    > >    > On Mon, Feb 29, 2016 at 02:48:54PM -0500, Stefan Berger wrote:
>    > >    > >    Jason Gunthorpe <jgunthorpe-ePGOBjL8dl3ta4EC/59zMFaTQe2KTcn/@public.gmane.org> wrote on
>    > >    02/29/2016
>    > >    > >    02:25:32 PM:
>    > >    > >    >
>    > >    > >    > On Mon, Feb 29, 2016 at 12:29:49PM -0500, Stefan Berger
>    wrote:
>    > >    > >    > >   * 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.
>    > >    > >    > >   */
>    > >    > >    >
>    > >    > >    > Not sure what happened here, but this hunk belongs with
>    > >    > >    > tpm_chip_unregister
>    > >    > >    That's where it is. The context 'tpm1_chip_unregister' the
>    hunk
>    > >    shows
>    > >    > >    is from the function 'above'.
>    > >    >
>    > >    > Eh?
>    > >    >
>    > >    > https://github.com/stefanberger/linux/blob/
>    > >    >
>    > >  
>     63f0cd1bae930167d31bbe5d5779d40a277e91c5/drivers/char/tpm/tpm-chip.c#L311
>    > >
>    > >    Sorry. Fixed here :
>    > >    https://github.com/stefanberger/linux/commit/
>    > 5808cd0b01b00e1a4e3b23d6970bac4efee69038
>    >
>    > Already applied v4. Could you send a fix for this to the list?
>    > Thanks.
> 
>    I can post v5 that also has the Reviewed-by's applied.
> 
>    https://github.com/stefanberger/linux/commits/vtpm-driver.v5

That works too. I then just replace patches in my master with new ones.
BTW, before your post. Could you check my comment about the driver name.
I think it would be better if the name was tpm_vtpm for consistency
reasons.

>      Stefan

/Jarkko

------------------------------------------------------------------------------

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

* Re: [PATCH v4 03/10] tpm: Provide strong locking for device removal
       [not found]                             ` <20160304212716.GA9158-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
@ 2016-03-04 22:01                               ` Stefan Berger
  0 siblings, 0 replies; 36+ messages in thread
From: Stefan Berger @ 2016-03-04 22:01 UTC (permalink / raw)
  To: Jarkko Sakkinen; +Cc: tpmdd-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f


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

Jarkko Sakkinen <jarkko.sakkinen-VuQAYsv1563Yd54FQh9/CA@public.gmane.org> wrote on 03/04/2016 
04:27:16 PM:

> On Fri, Mar 04, 2016 at 02:06:23PM -0500, Stefan Berger wrote:
> >    Jarkko Sakkinen <jarkko.sakkinen-VuQAYsv1563Yd54FQh9/CA@public.gmane.org> wrote on 
03/04/2016
> >    01:10:38 PM:
> >    >
> >    > On Mon, Feb 29, 2016 at 03:04:10PM -0500, Stefan Berger wrote:
> >    > >    Jason Gunthorpe <jgunthorpe-ePGOBjL8dl3ta4EC/59zMFaTQe2KTcn/@public.gmane.org> wrote on
> >    02/29/2016
> >    > >    02:54:01 PM:
> >    > >
> >    > >    >
> >    > >    > On Mon, Feb 29, 2016 at 02:48:54PM -0500, Stefan Berger 
wrote:
> >    > >    > >    Jason Gunthorpe <jgunthorpe-ePGOBjL8dl3ta4EC/59zMFaTQe2KTcn/@public.gmane.org> 
wrote on
> >    > >    02/29/2016
> >    > >    > >    02:25:32 PM:
> >    > >    > >    >
> >    > >    > >    > On Mon, Feb 29, 2016 at 12:29:49PM -0500, Stefan 
Berger
> >    wrote:
> >    > >    > >    > >   * 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.
> >    > >    > >    > >   */
> >    > >    > >    >
> >    > >    > >    > Not sure what happened here, but this hunk belongs 
with
> >    > >    > >    > tpm_chip_unregister
> >    > >    > >    That's where it is. The context 
'tpm1_chip_unregister' the
> >    hunk
> >    > >    shows
> >    > >    > >    is from the function 'above'.
> >    > >    >
> >    > >    > Eh?
> >    > >    >
> >    > >    > https://github.com/stefanberger/linux/blob/
> >    > >    >
> >    > > 
> >     63f0cd1bae930167d31bbe5d5779d40a277e91c5/drivers/char/tpm/tpm-
> chip.c#L311
> >    > >
> >    > >    Sorry. Fixed here :
> >    > >    https://github.com/stefanberger/linux/commit/
> >    > 5808cd0b01b00e1a4e3b23d6970bac4efee69038
> >    >
> >    > Already applied v4. Could you send a fix for this to the list?
> >    > Thanks.
> > 
> >    I can post v5 that also has the Reviewed-by's applied.
> > 
> >    https://github.com/stefanberger/linux/commits/vtpm-driver.v5
> 
> That works too. I then just replace patches in my master with new ones.
> BTW, before your post. Could you check my comment about the driver name.
> I think it would be better if the name was tpm_vtpm for consistency
> reasons.
> 

I renamed the driver file to tpm_vtpm.c . I tested it a bit and it's 
available here now:

https://github.com/stefanberger/linux/commits/vtpm-driver.v5


   Stefan



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

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

------------------------------------------------------------------------------

[-- 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] 36+ messages in thread

* Re: [PATCH v4 08/10] tpm: Driver for supporting multiple emulated TPMs
       [not found]           ` <201603042112.u24LCT7q016369-8DuMPbUlb4HImUpY6SP3GEEOCMrvLtNR@public.gmane.org>
@ 2016-03-04 22:34             ` Jarkko Sakkinen
       [not found]               ` <20160304223410.GA12143-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
  0 siblings, 1 reply; 36+ messages in thread
From: Jarkko Sakkinen @ 2016-03-04 22:34 UTC (permalink / raw)
  To: Stefan Berger; +Cc: tpmdd-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f

On Fri, Mar 04, 2016 at 04:16:41PM -0500, Stefan Berger wrote:
>    > > +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) ||
>    > > +       !(vtpm_dev->state & STATE_WAIT_RESPONSE_FLAG))
>    > > +      return -EIO;
>    >
>    > This is not atomic in any sense. You should move this statement after
>    > taking buf_lock.
> 
>    set_bit and friends were all atomic. Now we need to put all of these into
>    the mutex... ?

Hmm... but you have other fields too in struct vtpm_dev so you anyway
need to use mutex for concurrent access to the file. In that statement
you are accessing two fields from that structure.

Lets say someone forks 100 processes that concurrently access this
same open file. How else you would keep the state of vtpm_dev coherent
than protecting with a mutex?

Maybe the problem is that you are only thinking a proper way to use
this infrastructure?

>       Stefan

/Jarkko

------------------------------------------------------------------------------

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

* Re: [PATCH v4 08/10] tpm: Driver for supporting multiple emulated TPMs
       [not found]               ` <20160304223410.GA12143-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
@ 2016-03-05 14:55                 ` Stefan Berger
  0 siblings, 0 replies; 36+ messages in thread
From: Stefan Berger @ 2016-03-05 14:55 UTC (permalink / raw)
  To: Jarkko Sakkinen; +Cc: tpmdd-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f


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

Jarkko Sakkinen <jarkko.sakkinen-VuQAYsv1563Yd54FQh9/CA@public.gmane.org> wrote on 03/04/2016 
05:34:10 PM:


> On Fri, Mar 04, 2016 at 04:16:41PM -0500, Stefan Berger wrote:
> >    > > +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) ||
> >    > > +       !(vtpm_dev->state & STATE_WAIT_RESPONSE_FLAG))
> >    > > +      return -EIO;
> >    >
> >    > This is not atomic in any sense. You should move this statement 
after
> >    > taking buf_lock.
> > 
> >    set_bit and friends were all atomic. Now we need to put all of 
these into
> >    the mutex... ?
> 
> Hmm... but you have other fields too in struct vtpm_dev so you anyway
> need to use mutex for concurrent access to the file. In that statement
> you are accessing two fields from that structure.
> 
> Lets say someone forks 100 processes that concurrently access this
> same open file. How else you would keep the state of vtpm_dev coherent
> than protecting with a mutex?

I moved the accesses to the flag now into the mutex where necessary, 
except for one place where it's done so early that there's no concurrency. 
The updated code is here:

https://github.com/stefanberger/linux/commits/vtpm-driver.v5

   Stefan



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

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

------------------------------------------------------------------------------

[-- 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] 36+ messages in thread

end of thread, other threads:[~2016-03-05 14:55 UTC | newest]

Thread overview: 36+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-02-29 17:29 [PATCH v4 00/10] Multi-instance vTPM driver Stefan Berger
     [not found] ` <1456766996-9300-1-git-send-email-stefanb-23VcF4HTsmIX0ybBhKVfKdBPR1lH4CV8@public.gmane.org>
2016-02-29 17:29   ` [PATCH v4 01/10] tpm: Get rid of chip->pdev Stefan Berger
2016-02-29 17:29   ` [PATCH v4 02/10] tpm: Get rid of devname Stefan Berger
2016-02-29 17:29   ` [PATCH v4 03/10] tpm: Provide strong locking for device removal Stefan Berger
     [not found]     ` <1456766996-9300-4-git-send-email-stefanb-23VcF4HTsmIX0ybBhKVfKdBPR1lH4CV8@public.gmane.org>
2016-02-29 19:25       ` Jason Gunthorpe
     [not found]         ` <20160229192532.GB15042-ePGOBjL8dl3ta4EC/59zMFaTQe2KTcn/@public.gmane.org>
2016-02-29 19:48           ` Stefan Berger
     [not found]         ` <201602291949.u1TJn2Av025592@d03av03.boulder.ibm.com>
     [not found]           ` <201602291949.u1TJn2Av025592-MijUUJkLaQs+UXBhvPuGgqsjOiXwFzmk@public.gmane.org>
2016-02-29 19:54             ` Jason Gunthorpe
     [not found]               ` <20160229195400.GA32380-ePGOBjL8dl3ta4EC/59zMFaTQe2KTcn/@public.gmane.org>
2016-02-29 20:04                 ` Stefan Berger
     [not found]                   ` <201602292004.u1TK4IDH023664-YREtIfBy6dDImUpY6SP3GEEOCMrvLtNR@public.gmane.org>
2016-03-04 18:10                     ` Jarkko Sakkinen
     [not found]                       ` <20160304181038.GA24462-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
2016-03-04 19:06                         ` Stefan Berger
     [not found]                       ` <201603041908.u24J89Mv018643@d01av03.pok.ibm.com>
     [not found]                         ` <201603041908.u24J89Mv018643-CUdSWdNILC7ImUpY6SP3GEEOCMrvLtNR@public.gmane.org>
2016-03-04 21:27                           ` Jarkko Sakkinen
     [not found]                             ` <20160304212716.GA9158-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
2016-03-04 22:01                               ` Stefan Berger
2016-02-29 17:29   ` [PATCH v4 04/10] tpm: Get rid of module locking Stefan Berger
     [not found]     ` <1456766996-9300-5-git-send-email-stefanb-23VcF4HTsmIX0ybBhKVfKdBPR1lH4CV8@public.gmane.org>
2016-02-29 19:25       ` Jason Gunthorpe
2016-02-29 20:35       ` Jarkko Sakkinen
     [not found]         ` <20160229203550.GB26296-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
2016-02-29 20:49           ` Stefan Berger
2016-03-01  0:24           ` Jason Gunthorpe
     [not found]         ` <201602292050.u1TKo2CC012799@d01av01.pok.ibm.com>
     [not found]           ` <201602292050.u1TKo2CC012799-4ZtxiNBBw+3ImUpY6SP3GEEOCMrvLtNR@public.gmane.org>
2016-03-01  5:18             ` Jarkko Sakkinen
2016-02-29 17:29   ` [PATCH v4 05/10] tpm: Split out the devm stuff from tpmm_chip_alloc Stefan Berger
2016-02-29 17:29   ` [PATCH v4 06/10] tpm: Replace device number bitmap with IDR Stefan Berger
     [not found]     ` <1456766996-9300-7-git-send-email-stefanb-23VcF4HTsmIX0ybBhKVfKdBPR1lH4CV8@public.gmane.org>
2016-02-29 19:31       ` Jason Gunthorpe
     [not found]         ` <20160229193103.GD15042-ePGOBjL8dl3ta4EC/59zMFaTQe2KTcn/@public.gmane.org>
2016-02-29 19:36           ` Stefan Berger
2016-02-29 17:29   ` [PATCH v4 07/10] tpm: Introduce TPM_CHIP_FLAG_VIRTUAL Stefan Berger
     [not found]     ` <1456766996-9300-8-git-send-email-stefanb-23VcF4HTsmIX0ybBhKVfKdBPR1lH4CV8@public.gmane.org>
2016-02-29 19:31       ` Jason Gunthorpe
2016-02-29 17:29   ` [PATCH v4 08/10] tpm: Driver for supporting multiple emulated TPMs Stefan Berger
     [not found]     ` <1456766996-9300-9-git-send-email-stefanb-23VcF4HTsmIX0ybBhKVfKdBPR1lH4CV8@public.gmane.org>
2016-03-04 20:29       ` Jarkko Sakkinen
     [not found]         ` <20160304202928.GA32617-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
2016-03-04 21:16           ` Stefan Berger
     [not found]         ` <201603042112.u24LCT7q016369@d01av05.pok.ibm.com>
     [not found]           ` <201603042112.u24LCT7q016369-8DuMPbUlb4HImUpY6SP3GEEOCMrvLtNR@public.gmane.org>
2016-03-04 22:34             ` Jarkko Sakkinen
     [not found]               ` <20160304223410.GA12143-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
2016-03-05 14:55                 ` Stefan Berger
2016-02-29 17:29   ` [PATCH v4 09/10] tpm: Initialize TPM and get durations and timeouts Stefan Berger
2016-02-29 17:29   ` [PATCH v4 10/10] A test program for vTPM device creation Stefan Berger
2016-02-29 20:24   ` [PATCH v4 00/10] Multi-instance vTPM driver Jarkko Sakkinen
     [not found]     ` <20160229202401.GA26296-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
2016-02-29 20:30       ` Stefan Berger
     [not found]     ` <201602292030.u1TKUgSu010507@d01av03.pok.ibm.com>
     [not found]       ` <201602292030.u1TKUgSu010507-CUdSWdNILC7ImUpY6SP3GEEOCMrvLtNR@public.gmane.org>
2016-02-29 20:48         ` Jarkko Sakkinen
     [not found]           ` <20160229204846.GA27210-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
2016-02-29 20:57             ` Jarkko Sakkinen
2016-03-04 17:05   ` 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.