]>
git.proxmox.com Git - mirror_ubuntu-jammy-kernel.git/blob - drivers/char/tpm/tpm-dev-common.c
2 * Copyright (C) 2004 IBM Corporation
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>
9 * Copyright (C) 2013 Obsidian Research Corp
10 * Jason Gunthorpe <jgunthorpe@obsidianresearch.com>
12 * Device file system interface to the TPM
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
20 #include <linux/poll.h>
21 #include <linux/slab.h>
22 #include <linux/uaccess.h>
23 #include <linux/workqueue.h>
27 static struct workqueue_struct
*tpm_dev_wq
;
28 static DEFINE_MUTEX(tpm_dev_wq_lock
);
30 static ssize_t
tpm_dev_transmit(struct tpm_chip
*chip
, struct tpm_space
*space
,
31 u8
*buf
, size_t bufsiz
)
33 struct tpm_header
*header
= (void *)buf
;
36 ret
= tpm2_prepare_space(chip
, space
, buf
, bufsiz
);
37 /* If the command is not implemented by the TPM, synthesize a
38 * response with a TPM2_RC_COMMAND_CODE return for user-space.
40 if (ret
== -EOPNOTSUPP
) {
41 header
->length
= cpu_to_be32(sizeof(*header
));
42 header
->tag
= cpu_to_be16(TPM2_ST_NO_SESSIONS
);
43 header
->return_code
= cpu_to_be32(TPM2_RC_COMMAND_CODE
|
44 TSS2_RESMGR_TPM_RC_LAYER
);
45 ret
= sizeof(*header
);
50 len
= tpm_transmit(chip
, buf
, bufsiz
);
55 ret
= tpm2_commit_space(chip
, space
, buf
, &len
);
58 return ret
? ret
: len
;
61 static void tpm_dev_async_work(struct work_struct
*work
)
63 struct file_priv
*priv
=
64 container_of(work
, struct file_priv
, async_work
);
67 mutex_lock(&priv
->buffer_mutex
);
68 priv
->command_enqueued
= false;
69 ret
= tpm_dev_transmit(priv
->chip
, priv
->space
, priv
->data_buffer
,
70 sizeof(priv
->data_buffer
));
71 tpm_put_ops(priv
->chip
);
73 priv
->response_length
= ret
;
74 mod_timer(&priv
->user_read_timer
, jiffies
+ (120 * HZ
));
76 mutex_unlock(&priv
->buffer_mutex
);
77 wake_up_interruptible(&priv
->async_wait
);
80 static void user_reader_timeout(struct timer_list
*t
)
82 struct file_priv
*priv
= from_timer(priv
, t
, user_read_timer
);
84 pr_warn("TPM user space timeout is deprecated (pid=%d)\n",
85 task_tgid_nr(current
));
87 schedule_work(&priv
->timeout_work
);
90 static void tpm_timeout_work(struct work_struct
*work
)
92 struct file_priv
*priv
= container_of(work
, struct file_priv
,
95 mutex_lock(&priv
->buffer_mutex
);
96 priv
->response_read
= true;
97 priv
->response_length
= 0;
98 memset(priv
->data_buffer
, 0, sizeof(priv
->data_buffer
));
99 mutex_unlock(&priv
->buffer_mutex
);
100 wake_up_interruptible(&priv
->async_wait
);
103 void tpm_common_open(struct file
*file
, struct tpm_chip
*chip
,
104 struct file_priv
*priv
, struct tpm_space
*space
)
108 priv
->response_read
= true;
110 mutex_init(&priv
->buffer_mutex
);
111 timer_setup(&priv
->user_read_timer
, user_reader_timeout
, 0);
112 INIT_WORK(&priv
->timeout_work
, tpm_timeout_work
);
113 INIT_WORK(&priv
->async_work
, tpm_dev_async_work
);
114 init_waitqueue_head(&priv
->async_wait
);
115 file
->private_data
= priv
;
118 ssize_t
tpm_common_read(struct file
*file
, char __user
*buf
,
119 size_t size
, loff_t
*off
)
121 struct file_priv
*priv
= file
->private_data
;
122 ssize_t ret_size
= 0;
125 mutex_lock(&priv
->buffer_mutex
);
127 if (priv
->response_length
) {
128 priv
->response_read
= true;
130 ret_size
= min_t(ssize_t
, size
, priv
->response_length
);
132 priv
->response_length
= 0;
136 rc
= copy_to_user(buf
, priv
->data_buffer
+ *off
, ret_size
);
138 memset(priv
->data_buffer
, 0, TPM_BUFSIZE
);
139 priv
->response_length
= 0;
142 memset(priv
->data_buffer
+ *off
, 0, ret_size
);
143 priv
->response_length
-= ret_size
;
149 if (!priv
->response_length
) {
151 del_singleshot_timer_sync(&priv
->user_read_timer
);
152 flush_work(&priv
->timeout_work
);
154 mutex_unlock(&priv
->buffer_mutex
);
158 ssize_t
tpm_common_write(struct file
*file
, const char __user
*buf
,
159 size_t size
, loff_t
*off
)
161 struct file_priv
*priv
= file
->private_data
;
164 if (size
> TPM_BUFSIZE
)
167 mutex_lock(&priv
->buffer_mutex
);
169 /* Cannot perform a write until the read has cleared either via
170 * tpm_read or a user_read_timer timeout. This also prevents split
171 * buffered writes from blocking here.
173 if ((!priv
->response_read
&& priv
->response_length
) ||
174 priv
->command_enqueued
) {
179 if (copy_from_user(priv
->data_buffer
, buf
, size
)) {
185 size
< be32_to_cpu(*((__be32
*)(priv
->data_buffer
+ 2)))) {
190 /* atomic tpm command send and result receive. We only hold the ops
191 * lock during this period so that the tpm can be unregistered even if
192 * the char dev is held open.
194 if (tpm_try_get_ops(priv
->chip
)) {
199 priv
->response_length
= 0;
200 priv
->response_read
= false;
204 * If in nonblocking mode schedule an async job to send
205 * the command return the size.
206 * In case of error the err code will be returned in
207 * the subsequent read call.
209 if (file
->f_flags
& O_NONBLOCK
) {
210 priv
->command_enqueued
= true;
211 queue_work(tpm_dev_wq
, &priv
->async_work
);
212 mutex_unlock(&priv
->buffer_mutex
);
216 ret
= tpm_dev_transmit(priv
->chip
, priv
->space
, priv
->data_buffer
,
217 sizeof(priv
->data_buffer
));
218 tpm_put_ops(priv
->chip
);
221 priv
->response_length
= ret
;
222 mod_timer(&priv
->user_read_timer
, jiffies
+ (120 * HZ
));
226 mutex_unlock(&priv
->buffer_mutex
);
230 __poll_t
tpm_common_poll(struct file
*file
, poll_table
*wait
)
232 struct file_priv
*priv
= file
->private_data
;
235 poll_wait(file
, &priv
->async_wait
, wait
);
236 mutex_lock(&priv
->buffer_mutex
);
239 * The response_length indicates if there is still response
240 * (or part of it) to be consumed. Partial reads decrease it
241 * by the number of bytes read, and write resets it the zero.
243 if (priv
->response_length
)
244 mask
= EPOLLIN
| EPOLLRDNORM
;
246 mask
= EPOLLOUT
| EPOLLWRNORM
;
248 mutex_unlock(&priv
->buffer_mutex
);
253 * Called on file close
255 void tpm_common_release(struct file
*file
, struct file_priv
*priv
)
257 flush_work(&priv
->async_work
);
258 del_singleshot_timer_sync(&priv
->user_read_timer
);
259 flush_work(&priv
->timeout_work
);
260 file
->private_data
= NULL
;
261 priv
->response_length
= 0;
264 int __init
tpm_dev_common_init(void)
266 tpm_dev_wq
= alloc_workqueue("tpm_dev_wq", WQ_MEM_RECLAIM
, 0);
268 return !tpm_dev_wq
? -ENOMEM
: 0;
271 void __exit
tpm_dev_common_exit(void)
274 destroy_workqueue(tpm_dev_wq
);