1 // SPDX-License-Identifier: GPL-2.0-only
3 * Copyright (C) 2004 IBM Corporation
5 * Leendert van Doorn <leendert@watson.ibm.com>
6 * Dave Safford <safford@watson.ibm.com>
7 * Reiner Sailer <sailer@watson.ibm.com>
8 * Kylene Hall <kjhall@us.ibm.com>
10 * Copyright (C) 2013 Obsidian Research Corp
11 * Jason Gunthorpe <jgunthorpe@obsidianresearch.com>
13 * Device file system interface to the TPM
15 #include <linux/poll.h>
16 #include <linux/slab.h>
17 #include <linux/uaccess.h>
18 #include <linux/workqueue.h>
22 static struct workqueue_struct
*tpm_dev_wq
;
23 static DEFINE_MUTEX(tpm_dev_wq_lock
);
25 static ssize_t
tpm_dev_transmit(struct tpm_chip
*chip
, struct tpm_space
*space
,
26 u8
*buf
, size_t bufsiz
)
28 struct tpm_header
*header
= (void *)buf
;
31 ret
= tpm2_prepare_space(chip
, space
, buf
, bufsiz
);
32 /* If the command is not implemented by the TPM, synthesize a
33 * response with a TPM2_RC_COMMAND_CODE return for user-space.
35 if (ret
== -EOPNOTSUPP
) {
36 header
->length
= cpu_to_be32(sizeof(*header
));
37 header
->tag
= cpu_to_be16(TPM2_ST_NO_SESSIONS
);
38 header
->return_code
= cpu_to_be32(TPM2_RC_COMMAND_CODE
|
39 TSS2_RESMGR_TPM_RC_LAYER
);
40 ret
= sizeof(*header
);
45 len
= tpm_transmit(chip
, buf
, bufsiz
);
50 ret
= tpm2_commit_space(chip
, space
, buf
, &len
);
53 return ret
? ret
: len
;
56 static void tpm_dev_async_work(struct work_struct
*work
)
58 struct file_priv
*priv
=
59 container_of(work
, struct file_priv
, async_work
);
62 mutex_lock(&priv
->buffer_mutex
);
63 priv
->command_enqueued
= false;
64 ret
= tpm_try_get_ops(priv
->chip
);
66 priv
->response_length
= ret
;
70 ret
= tpm_dev_transmit(priv
->chip
, priv
->space
, priv
->data_buffer
,
71 sizeof(priv
->data_buffer
));
72 tpm_put_ops(priv
->chip
);
74 priv
->response_length
= ret
;
75 mod_timer(&priv
->user_read_timer
, jiffies
+ (120 * HZ
));
78 mutex_unlock(&priv
->buffer_mutex
);
79 wake_up_interruptible(&priv
->async_wait
);
82 static void user_reader_timeout(struct timer_list
*t
)
84 struct file_priv
*priv
= from_timer(priv
, t
, user_read_timer
);
86 pr_warn("TPM user space timeout is deprecated (pid=%d)\n",
87 task_tgid_nr(current
));
89 schedule_work(&priv
->timeout_work
);
92 static void tpm_timeout_work(struct work_struct
*work
)
94 struct file_priv
*priv
= container_of(work
, struct file_priv
,
97 mutex_lock(&priv
->buffer_mutex
);
98 priv
->response_read
= true;
99 priv
->response_length
= 0;
100 memset(priv
->data_buffer
, 0, sizeof(priv
->data_buffer
));
101 mutex_unlock(&priv
->buffer_mutex
);
102 wake_up_interruptible(&priv
->async_wait
);
105 void tpm_common_open(struct file
*file
, struct tpm_chip
*chip
,
106 struct file_priv
*priv
, struct tpm_space
*space
)
110 priv
->response_read
= true;
112 mutex_init(&priv
->buffer_mutex
);
113 timer_setup(&priv
->user_read_timer
, user_reader_timeout
, 0);
114 INIT_WORK(&priv
->timeout_work
, tpm_timeout_work
);
115 INIT_WORK(&priv
->async_work
, tpm_dev_async_work
);
116 init_waitqueue_head(&priv
->async_wait
);
117 file
->private_data
= priv
;
120 ssize_t
tpm_common_read(struct file
*file
, char __user
*buf
,
121 size_t size
, loff_t
*off
)
123 struct file_priv
*priv
= file
->private_data
;
124 ssize_t ret_size
= 0;
127 mutex_lock(&priv
->buffer_mutex
);
129 if (priv
->response_length
) {
130 priv
->response_read
= true;
132 ret_size
= min_t(ssize_t
, size
, priv
->response_length
);
134 priv
->response_length
= 0;
138 rc
= copy_to_user(buf
, priv
->data_buffer
+ *off
, ret_size
);
140 memset(priv
->data_buffer
, 0, TPM_BUFSIZE
);
141 priv
->response_length
= 0;
144 memset(priv
->data_buffer
+ *off
, 0, ret_size
);
145 priv
->response_length
-= ret_size
;
151 if (!priv
->response_length
) {
153 del_singleshot_timer_sync(&priv
->user_read_timer
);
154 flush_work(&priv
->timeout_work
);
156 mutex_unlock(&priv
->buffer_mutex
);
160 ssize_t
tpm_common_write(struct file
*file
, const char __user
*buf
,
161 size_t size
, loff_t
*off
)
163 struct file_priv
*priv
= file
->private_data
;
166 if (size
> TPM_BUFSIZE
)
169 mutex_lock(&priv
->buffer_mutex
);
171 /* Cannot perform a write until the read has cleared either via
172 * tpm_read or a user_read_timer timeout. This also prevents split
173 * buffered writes from blocking here.
175 if ((!priv
->response_read
&& priv
->response_length
) ||
176 priv
->command_enqueued
) {
181 if (copy_from_user(priv
->data_buffer
, buf
, size
)) {
187 size
< be32_to_cpu(*((__be32
*)(priv
->data_buffer
+ 2)))) {
192 priv
->response_length
= 0;
193 priv
->response_read
= false;
197 * If in nonblocking mode schedule an async job to send
198 * the command return the size.
199 * In case of error the err code will be returned in
200 * the subsequent read call.
202 if (file
->f_flags
& O_NONBLOCK
) {
203 priv
->command_enqueued
= true;
204 queue_work(tpm_dev_wq
, &priv
->async_work
);
205 mutex_unlock(&priv
->buffer_mutex
);
209 /* atomic tpm command send and result receive. We only hold the ops
210 * lock during this period so that the tpm can be unregistered even if
211 * the char dev is held open.
213 if (tpm_try_get_ops(priv
->chip
)) {
218 ret
= tpm_dev_transmit(priv
->chip
, priv
->space
, priv
->data_buffer
,
219 sizeof(priv
->data_buffer
));
220 tpm_put_ops(priv
->chip
);
223 priv
->response_length
= ret
;
224 mod_timer(&priv
->user_read_timer
, jiffies
+ (120 * HZ
));
228 mutex_unlock(&priv
->buffer_mutex
);
232 __poll_t
tpm_common_poll(struct file
*file
, poll_table
*wait
)
234 struct file_priv
*priv
= file
->private_data
;
237 poll_wait(file
, &priv
->async_wait
, wait
);
238 mutex_lock(&priv
->buffer_mutex
);
241 * The response_length indicates if there is still response
242 * (or part of it) to be consumed. Partial reads decrease it
243 * by the number of bytes read, and write resets it the zero.
245 if (priv
->response_length
)
246 mask
= EPOLLIN
| EPOLLRDNORM
;
248 mask
= EPOLLOUT
| EPOLLWRNORM
;
250 mutex_unlock(&priv
->buffer_mutex
);
255 * Called on file close
257 void tpm_common_release(struct file
*file
, struct file_priv
*priv
)
259 flush_work(&priv
->async_work
);
260 del_singleshot_timer_sync(&priv
->user_read_timer
);
261 flush_work(&priv
->timeout_work
);
262 file
->private_data
= NULL
;
263 priv
->response_length
= 0;
266 int __init
tpm_dev_common_init(void)
268 tpm_dev_wq
= alloc_workqueue("tpm_dev_wq", WQ_MEM_RECLAIM
, 0);
270 return !tpm_dev_wq
? -ENOMEM
: 0;
273 void __exit
tpm_dev_common_exit(void)
276 destroy_workqueue(tpm_dev_wq
);