Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 2d06236a authored by James Morris's avatar James Morris
Browse files

Merge tag 'tpmdd-next-20180602' of git://git.infradead.org/users/jjs/linux-tpmdd into next-tpm

tpmdd fixes for Linux 4.17 (just missed 4.17)
parents 82e5b032 3ab2011e
Loading
Loading
Loading
Loading
+18 −22
Original line number Original line Diff line number Diff line
@@ -37,7 +37,7 @@ static void timeout_work(struct work_struct *work)
	struct file_priv *priv = container_of(work, struct file_priv, work);
	struct file_priv *priv = container_of(work, struct file_priv, work);


	mutex_lock(&priv->buffer_mutex);
	mutex_lock(&priv->buffer_mutex);
	atomic_set(&priv->data_pending, 0);
	priv->data_pending = 0;
	memset(priv->data_buffer, 0, sizeof(priv->data_buffer));
	memset(priv->data_buffer, 0, sizeof(priv->data_buffer));
	mutex_unlock(&priv->buffer_mutex);
	mutex_unlock(&priv->buffer_mutex);
}
}
@@ -46,7 +46,6 @@ void tpm_common_open(struct file *file, struct tpm_chip *chip,
		     struct file_priv *priv)
		     struct file_priv *priv)
{
{
	priv->chip = chip;
	priv->chip = chip;
	atomic_set(&priv->data_pending, 0);
	mutex_init(&priv->buffer_mutex);
	mutex_init(&priv->buffer_mutex);
	timer_setup(&priv->user_read_timer, user_reader_timeout, 0);
	timer_setup(&priv->user_read_timer, user_reader_timeout, 0);
	INIT_WORK(&priv->work, timeout_work);
	INIT_WORK(&priv->work, timeout_work);
@@ -58,29 +57,24 @@ ssize_t tpm_common_read(struct file *file, char __user *buf,
			size_t size, loff_t *off)
			size_t size, loff_t *off)
{
{
	struct file_priv *priv = file->private_data;
	struct file_priv *priv = file->private_data;
	ssize_t ret_size;
	ssize_t ret_size = 0;
	ssize_t orig_ret_size;
	int rc;
	int rc;


	del_singleshot_timer_sync(&priv->user_read_timer);
	del_singleshot_timer_sync(&priv->user_read_timer);
	flush_work(&priv->work);
	flush_work(&priv->work);
	ret_size = atomic_read(&priv->data_pending);
	if (ret_size > 0) {	/* relay data */
		orig_ret_size = ret_size;
		if (size < ret_size)
			ret_size = size;

	mutex_lock(&priv->buffer_mutex);
	mutex_lock(&priv->buffer_mutex);

	if (priv->data_pending) {
		ret_size = min_t(ssize_t, size, priv->data_pending);
		rc = copy_to_user(buf, priv->data_buffer, ret_size);
		rc = copy_to_user(buf, priv->data_buffer, ret_size);
		memset(priv->data_buffer, 0, orig_ret_size);
		memset(priv->data_buffer, 0, priv->data_pending);
		if (rc)
		if (rc)
			ret_size = -EFAULT;
			ret_size = -EFAULT;


		mutex_unlock(&priv->buffer_mutex);
		priv->data_pending = 0;
	}
	}


	atomic_set(&priv->data_pending, 0);
	mutex_unlock(&priv->buffer_mutex);

	return ret_size;
	return ret_size;
}
}


@@ -91,17 +85,19 @@ ssize_t tpm_common_write(struct file *file, const char __user *buf,
	size_t in_size = size;
	size_t in_size = size;
	ssize_t out_size;
	ssize_t out_size;


	if (in_size > TPM_BUFSIZE)
		return -E2BIG;

	mutex_lock(&priv->buffer_mutex);

	/* Cannot perform a write until the read has cleared either via
	/* Cannot perform a write until the read has cleared either via
	 * tpm_read or a user_read_timer timeout. This also prevents split
	 * tpm_read or a user_read_timer timeout. This also prevents split
	 * buffered writes from blocking here.
	 * buffered writes from blocking here.
	 */
	 */
	if (atomic_read(&priv->data_pending) != 0)
	if (priv->data_pending != 0) {
		mutex_unlock(&priv->buffer_mutex);
		return -EBUSY;
		return -EBUSY;

	}
	if (in_size > TPM_BUFSIZE)
		return -E2BIG;

	mutex_lock(&priv->buffer_mutex);


	if (copy_from_user
	if (copy_from_user
	    (priv->data_buffer, (void __user *) buf, in_size)) {
	    (priv->data_buffer, (void __user *) buf, in_size)) {
@@ -132,7 +128,7 @@ ssize_t tpm_common_write(struct file *file, const char __user *buf,
		return out_size;
		return out_size;
	}
	}


	atomic_set(&priv->data_pending, out_size);
	priv->data_pending = out_size;
	mutex_unlock(&priv->buffer_mutex);
	mutex_unlock(&priv->buffer_mutex);


	/* Set a timeout by which the reader must come claim the result */
	/* Set a timeout by which the reader must come claim the result */
@@ -149,5 +145,5 @@ void tpm_common_release(struct file *file, struct file_priv *priv)
	del_singleshot_timer_sync(&priv->user_read_timer);
	del_singleshot_timer_sync(&priv->user_read_timer);
	flush_work(&priv->work);
	flush_work(&priv->work);
	file->private_data = NULL;
	file->private_data = NULL;
	atomic_set(&priv->data_pending, 0);
	priv->data_pending = 0;
}
}
+1 −1
Original line number Original line Diff line number Diff line
@@ -8,7 +8,7 @@ struct file_priv {
	struct tpm_chip *chip;
	struct tpm_chip *chip;


	/* Data passed to and from the tpm via the read/write calls */
	/* Data passed to and from the tpm via the read/write calls */
	atomic_t data_pending;
	size_t data_pending;
	struct mutex buffer_mutex;
	struct mutex buffer_mutex;


	struct timer_list user_read_timer;      /* user needs to claim result */
	struct timer_list user_read_timer;      /* user needs to claim result */