1/* 2 * Copyright (C) 2004 IBM Corporation 3 * Authors: 4 * Leendert van Doorn <leendert@watson.ibm.com> 5 * Dave Safford <safford@watson.ibm.com> 6 * Reiner Sailer <sailer@watson.ibm.com> 7 * Kylene Hall <kjhall@us.ibm.com> 8 * 9 * Copyright (C) 2013 Obsidian Research Corp 10 * Jason Gunthorpe <jgunthorpe@obsidianresearch.com> 11 * 12 * Device file system interface to the TPM 13 * 14 * This program is free software; you can redistribute it and/or 15 * modify it under the terms of the GNU General Public License as 16 * published by the Free Software Foundation, version 2 of the 17 * License. 18 * 19 */ 20#include <linux/slab.h> 21#include <linux/uaccess.h> 22#include "tpm.h" 23 24struct file_priv { 25 struct tpm_chip *chip; 26 27 /* Data passed to and from the tpm via the read/write calls */ 28 atomic_t data_pending; 29 struct mutex buffer_mutex; 30 31 struct timer_list user_read_timer; /* user needs to claim result */ 32 struct work_struct work; 33 34 u8 data_buffer[TPM_BUFSIZE]; 35}; 36 37static void user_reader_timeout(unsigned long ptr) 38{ 39 struct file_priv *priv = (struct file_priv *)ptr; 40 41 schedule_work(&priv->work); 42} 43 44static void timeout_work(struct work_struct *work) 45{ 46 struct file_priv *priv = container_of(work, struct file_priv, work); 47 48 mutex_lock(&priv->buffer_mutex); 49 atomic_set(&priv->data_pending, 0); 50 memset(priv->data_buffer, 0, sizeof(priv->data_buffer)); 51 mutex_unlock(&priv->buffer_mutex); 52} 53 54static int tpm_open(struct inode *inode, struct file *file) 55{ 56 struct tpm_chip *chip = 57 container_of(inode->i_cdev, struct tpm_chip, cdev); 58 struct file_priv *priv; 59 60 /* It's assured that the chip will be opened just once, 61 * by the check of is_open variable, which is protected 62 * by driver_lock. */ 63 if (test_and_set_bit(0, &chip->is_open)) { 64 dev_dbg(chip->pdev, "Another process owns this TPM\n"); 65 return -EBUSY; 66 } 67 68 priv = kzalloc(sizeof(*priv), GFP_KERNEL); 69 if (priv == NULL) { 70 clear_bit(0, &chip->is_open); 71 return -ENOMEM; 72 } 73 74 priv->chip = chip; 75 atomic_set(&priv->data_pending, 0); 76 mutex_init(&priv->buffer_mutex); 77 setup_timer(&priv->user_read_timer, user_reader_timeout, 78 (unsigned long)priv); 79 INIT_WORK(&priv->work, timeout_work); 80 81 file->private_data = priv; 82 get_device(chip->pdev); 83 return 0; 84} 85 86static ssize_t tpm_read(struct file *file, char __user *buf, 87 size_t size, loff_t *off) 88{ 89 struct file_priv *priv = file->private_data; 90 ssize_t ret_size; 91 int rc; 92 93 del_singleshot_timer_sync(&priv->user_read_timer); 94 flush_work(&priv->work); 95 ret_size = atomic_read(&priv->data_pending); 96 if (ret_size > 0) { /* relay data */ 97 ssize_t orig_ret_size = ret_size; 98 if (size < ret_size) 99 ret_size = size; 100 101 mutex_lock(&priv->buffer_mutex); 102 rc = copy_to_user(buf, priv->data_buffer, ret_size); 103 memset(priv->data_buffer, 0, orig_ret_size); 104 if (rc) 105 ret_size = -EFAULT; 106 107 mutex_unlock(&priv->buffer_mutex); 108 } 109 110 atomic_set(&priv->data_pending, 0); 111 112 return ret_size; 113} 114 115static ssize_t tpm_write(struct file *file, const char __user *buf, 116 size_t size, loff_t *off) 117{ 118 struct file_priv *priv = file->private_data; 119 size_t in_size = size; 120 ssize_t out_size; 121 122 /* cannot perform a write until the read has cleared 123 either via tpm_read or a user_read_timer timeout. 124 This also prevents splitted buffered writes from blocking here. 125 */ 126 if (atomic_read(&priv->data_pending) != 0) 127 return -EBUSY; 128 129 if (in_size > TPM_BUFSIZE) 130 return -E2BIG; 131 132 mutex_lock(&priv->buffer_mutex); 133 134 if (copy_from_user 135 (priv->data_buffer, (void __user *) buf, in_size)) { 136 mutex_unlock(&priv->buffer_mutex); 137 return -EFAULT; 138 } 139 140 /* atomic tpm command send and result receive */ 141 out_size = tpm_transmit(priv->chip, priv->data_buffer, 142 sizeof(priv->data_buffer)); 143 if (out_size < 0) { 144 mutex_unlock(&priv->buffer_mutex); 145 return out_size; 146 } 147 148 atomic_set(&priv->data_pending, out_size); 149 mutex_unlock(&priv->buffer_mutex); 150 151 /* Set a timeout by which the reader must come claim the result */ 152 mod_timer(&priv->user_read_timer, jiffies + (60 * HZ)); 153 154 return in_size; 155} 156 157/* 158 * Called on file close 159 */ 160static int tpm_release(struct inode *inode, struct file *file) 161{ 162 struct file_priv *priv = file->private_data; 163 164 del_singleshot_timer_sync(&priv->user_read_timer); 165 flush_work(&priv->work); 166 file->private_data = NULL; 167 atomic_set(&priv->data_pending, 0); 168 clear_bit(0, &priv->chip->is_open); 169 put_device(priv->chip->pdev); 170 kfree(priv); 171 return 0; 172} 173 174const struct file_operations tpm_fops = { 175 .owner = THIS_MODULE, 176 .llseek = no_llseek, 177 .open = tpm_open, 178 .read = tpm_read, 179 .write = tpm_write, 180 .release = tpm_release, 181}; 182 183 184