Merge tag 'gpio-v4.1-1' of git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux...
[deliverable/linux.git] / drivers / char / hw_random / core.c
CommitLineData
844dd05f
MB
1/*
2 Added support for the AMD Geode LX RNG
3 (c) Copyright 2004-2005 Advanced Micro Devices, Inc.
4
5 derived from
6
7 Hardware driver for the Intel/AMD/VIA Random Number Generators (RNG)
8 (c) Copyright 2003 Red Hat Inc <jgarzik@redhat.com>
9
10 derived from
11
12 Hardware driver for the AMD 768 Random Number Generator (RNG)
13 (c) Copyright 2001 Red Hat Inc <alan@redhat.com>
14
15 derived from
16
17 Hardware driver for Intel i810 Random Number Generator (RNG)
18 Copyright 2000,2001 Jeff Garzik <jgarzik@pobox.com>
19 Copyright 2000,2001 Philipp Rumpf <prumpf@mandrakesoft.com>
20
21 Added generic RNG API
eb032b98 22 Copyright 2006 Michael Buesch <m@bues.ch>
844dd05f
MB
23 Copyright 2005 (c) MontaVista Software, Inc.
24
25 Please read Documentation/hw_random.txt for details on use.
26
27 ----------------------------------------------------------
28 This software may be used and distributed according to the terms
29 of the GNU General Public License, incorporated herein by reference.
30
31 */
32
33
34#include <linux/device.h>
35#include <linux/hw_random.h>
36#include <linux/module.h>
37#include <linux/kernel.h>
38#include <linux/fs.h>
914e2637 39#include <linux/sched.h>
844dd05f 40#include <linux/miscdevice.h>
be4000bc 41#include <linux/kthread.h>
844dd05f 42#include <linux/delay.h>
f7f154f1 43#include <linux/slab.h>
d9e79726 44#include <linux/random.h>
3a2c0ba5 45#include <linux/err.h>
844dd05f
MB
46#include <asm/uaccess.h>
47
48
49#define RNG_MODULE_NAME "hw_random"
50#define PFX RNG_MODULE_NAME ": "
51#define RNG_MISCDEV_MINOR 183 /* official */
52
53
54static struct hwrng *current_rng;
be4000bc 55static struct task_struct *hwrng_fill;
844dd05f 56static LIST_HEAD(rng_list);
9372b35e 57/* Protects rng_list and current_rng */
844dd05f 58static DEFINE_MUTEX(rng_mutex);
9372b35e
RR
59/* Protects rng read functions, data_avail, rng_buffer and rng_fillbuf */
60static DEFINE_MUTEX(reading_mutex);
9996508b 61static int data_avail;
be4000bc 62static u8 *rng_buffer, *rng_fillbuf;
0f734e6e
TD
63static unsigned short current_quality;
64static unsigned short default_quality; /* = 0; default to "off" */
be4000bc
TD
65
66module_param(current_quality, ushort, 0644);
67MODULE_PARM_DESC(current_quality,
68 "current hwrng entropy estimation per mill");
0f734e6e
TD
69module_param(default_quality, ushort, 0644);
70MODULE_PARM_DESC(default_quality,
71 "default entropy content of hwrng per mill");
be4000bc 72
ff77c150 73static void drop_current_rng(void);
90ac41bd 74static int hwrng_init(struct hwrng *rng);
be4000bc 75static void start_khwrngd(void);
f7f154f1 76
d3cc7996
AS
77static inline int rng_get_data(struct hwrng *rng, u8 *buffer, size_t size,
78 int wait);
79
f7f154f1
RR
80static size_t rng_buffer_size(void)
81{
82 return SMP_CACHE_BYTES < 32 ? 32 : SMP_CACHE_BYTES;
83}
844dd05f 84
d3cc7996
AS
85static void add_early_randomness(struct hwrng *rng)
86{
87 unsigned char bytes[16];
88 int bytes_read;
89
9372b35e 90 mutex_lock(&reading_mutex);
d3cc7996 91 bytes_read = rng_get_data(rng, bytes, sizeof(bytes), 1);
9372b35e 92 mutex_unlock(&reading_mutex);
d3cc7996
AS
93 if (bytes_read > 0)
94 add_device_randomness(bytes, bytes_read);
95}
96
3a2c0ba5
RR
97static inline void cleanup_rng(struct kref *kref)
98{
99 struct hwrng *rng = container_of(kref, struct hwrng, ref);
100
101 if (rng->cleanup)
102 rng->cleanup(rng);
a027f30d 103
77584ee5 104 complete(&rng->cleanup_done);
3a2c0ba5
RR
105}
106
90ac41bd 107static int set_current_rng(struct hwrng *rng)
3a2c0ba5 108{
90ac41bd
HX
109 int err;
110
3a2c0ba5 111 BUG_ON(!mutex_is_locked(&rng_mutex));
90ac41bd
HX
112
113 err = hwrng_init(rng);
114 if (err)
115 return err;
116
ff77c150 117 drop_current_rng();
3a2c0ba5 118 current_rng = rng;
90ac41bd
HX
119
120 return 0;
3a2c0ba5
RR
121}
122
123static void drop_current_rng(void)
124{
125 BUG_ON(!mutex_is_locked(&rng_mutex));
126 if (!current_rng)
127 return;
128
129 /* decrease last reference for triggering the cleanup */
130 kref_put(&current_rng->ref, cleanup_rng);
131 current_rng = NULL;
132}
133
134/* Returns ERR_PTR(), NULL or refcounted hwrng */
135static struct hwrng *get_current_rng(void)
136{
137 struct hwrng *rng;
138
139 if (mutex_lock_interruptible(&rng_mutex))
140 return ERR_PTR(-ERESTARTSYS);
141
142 rng = current_rng;
143 if (rng)
144 kref_get(&rng->ref);
145
146 mutex_unlock(&rng_mutex);
147 return rng;
148}
149
150static void put_rng(struct hwrng *rng)
151{
152 /*
153 * Hold rng_mutex here so we serialize in case they set_current_rng
154 * on rng again immediately.
155 */
156 mutex_lock(&rng_mutex);
157 if (rng)
158 kref_put(&rng->ref, cleanup_rng);
159 mutex_unlock(&rng_mutex);
160}
161
90ac41bd 162static int hwrng_init(struct hwrng *rng)
844dd05f 163{
15b66cd5
HX
164 if (kref_get_unless_zero(&rng->ref))
165 goto skip_init;
166
d3cc7996
AS
167 if (rng->init) {
168 int ret;
169
170 ret = rng->init(rng);
171 if (ret)
172 return ret;
173 }
15b66cd5
HX
174
175 kref_init(&rng->ref);
176 reinit_completion(&rng->cleanup_done);
177
178skip_init:
d3cc7996 179 add_early_randomness(rng);
be4000bc 180
0f734e6e 181 current_quality = rng->quality ? : default_quality;
506bf0c0
KP
182 if (current_quality > 1024)
183 current_quality = 1024;
0f734e6e
TD
184
185 if (current_quality == 0 && hwrng_fill)
186 kthread_stop(hwrng_fill);
be4000bc
TD
187 if (current_quality > 0 && !hwrng_fill)
188 start_khwrngd();
189
d3cc7996 190 return 0;
844dd05f
MB
191}
192
844dd05f
MB
193static int rng_dev_open(struct inode *inode, struct file *filp)
194{
195 /* enforce read-only access to this chrdev */
196 if ((filp->f_mode & FMODE_READ) == 0)
197 return -EINVAL;
198 if (filp->f_mode & FMODE_WRITE)
199 return -EINVAL;
200 return 0;
201}
202
9996508b
IM
203static inline int rng_get_data(struct hwrng *rng, u8 *buffer, size_t size,
204 int wait) {
205 int present;
206
9372b35e 207 BUG_ON(!mutex_is_locked(&reading_mutex));
9996508b
IM
208 if (rng->read)
209 return rng->read(rng, (void *)buffer, size, wait);
210
211 if (rng->data_present)
212 present = rng->data_present(rng, wait);
213 else
214 present = 1;
215
216 if (present)
217 return rng->data_read(rng, (u32 *)buffer);
218
219 return 0;
220}
221
844dd05f
MB
222static ssize_t rng_dev_read(struct file *filp, char __user *buf,
223 size_t size, loff_t *offp)
224{
844dd05f 225 ssize_t ret = 0;
984e976f 226 int err = 0;
9996508b 227 int bytes_read, len;
3a2c0ba5 228 struct hwrng *rng;
844dd05f
MB
229
230 while (size) {
3a2c0ba5
RR
231 rng = get_current_rng();
232 if (IS_ERR(rng)) {
233 err = PTR_ERR(rng);
844dd05f 234 goto out;
9996508b 235 }
3a2c0ba5 236 if (!rng) {
844dd05f 237 err = -ENODEV;
3a2c0ba5 238 goto out;
844dd05f 239 }
984e976f 240
9372b35e 241 mutex_lock(&reading_mutex);
9996508b 242 if (!data_avail) {
3a2c0ba5 243 bytes_read = rng_get_data(rng, rng_buffer,
f7f154f1 244 rng_buffer_size(),
9996508b
IM
245 !(filp->f_flags & O_NONBLOCK));
246 if (bytes_read < 0) {
247 err = bytes_read;
9372b35e 248 goto out_unlock_reading;
9996508b
IM
249 }
250 data_avail = bytes_read;
893f1128 251 }
844dd05f 252
9996508b
IM
253 if (!data_avail) {
254 if (filp->f_flags & O_NONBLOCK) {
255 err = -EAGAIN;
9372b35e 256 goto out_unlock_reading;
9996508b
IM
257 }
258 } else {
259 len = data_avail;
260 if (len > size)
261 len = size;
262
263 data_avail -= len;
264
265 if (copy_to_user(buf + ret, rng_buffer + data_avail,
266 len)) {
267 err = -EFAULT;
9372b35e 268 goto out_unlock_reading;
9996508b
IM
269 }
270
271 size -= len;
272 ret += len;
844dd05f
MB
273 }
274
9372b35e 275 mutex_unlock(&reading_mutex);
3a2c0ba5 276 put_rng(rng);
9996508b 277
844dd05f
MB
278 if (need_resched())
279 schedule_timeout_interruptible(1);
9996508b
IM
280
281 if (signal_pending(current)) {
282 err = -ERESTARTSYS;
844dd05f 283 goto out;
9996508b 284 }
844dd05f
MB
285 }
286out:
287 return ret ? : err;
3a2c0ba5 288
9372b35e
RR
289out_unlock_reading:
290 mutex_unlock(&reading_mutex);
3a2c0ba5
RR
291 put_rng(rng);
292 goto out;
844dd05f
MB
293}
294
295
62322d25 296static const struct file_operations rng_chrdev_ops = {
844dd05f
MB
297 .owner = THIS_MODULE,
298 .open = rng_dev_open,
299 .read = rng_dev_read,
6038f373 300 .llseek = noop_llseek,
844dd05f
MB
301};
302
303static struct miscdevice rng_miscdev = {
304 .minor = RNG_MISCDEV_MINOR,
305 .name = RNG_MODULE_NAME,
e454cea2 306 .nodename = "hwrng",
844dd05f
MB
307 .fops = &rng_chrdev_ops,
308};
309
310
94fbcded
GKH
311static ssize_t hwrng_attr_current_store(struct device *dev,
312 struct device_attribute *attr,
844dd05f
MB
313 const char *buf, size_t len)
314{
315 int err;
316 struct hwrng *rng;
317
318 err = mutex_lock_interruptible(&rng_mutex);
319 if (err)
320 return -ERESTARTSYS;
321 err = -ENODEV;
322 list_for_each_entry(rng, &rng_list, list) {
323 if (strcmp(rng->name, buf) == 0) {
844dd05f 324 err = 0;
90ac41bd
HX
325 if (rng != current_rng)
326 err = set_current_rng(rng);
844dd05f
MB
327 break;
328 }
329 }
330 mutex_unlock(&rng_mutex);
331
332 return err ? : len;
333}
334
94fbcded
GKH
335static ssize_t hwrng_attr_current_show(struct device *dev,
336 struct device_attribute *attr,
844dd05f
MB
337 char *buf)
338{
844dd05f 339 ssize_t ret;
3a2c0ba5 340 struct hwrng *rng;
844dd05f 341
3a2c0ba5
RR
342 rng = get_current_rng();
343 if (IS_ERR(rng))
344 return PTR_ERR(rng);
345
346 ret = snprintf(buf, PAGE_SIZE, "%s\n", rng ? rng->name : "none");
347 put_rng(rng);
844dd05f
MB
348
349 return ret;
350}
351
94fbcded
GKH
352static ssize_t hwrng_attr_available_show(struct device *dev,
353 struct device_attribute *attr,
844dd05f
MB
354 char *buf)
355{
356 int err;
844dd05f
MB
357 struct hwrng *rng;
358
359 err = mutex_lock_interruptible(&rng_mutex);
360 if (err)
361 return -ERESTARTSYS;
362 buf[0] = '\0';
363 list_for_each_entry(rng, &rng_list, list) {
61daf055
RS
364 strlcat(buf, rng->name, PAGE_SIZE);
365 strlcat(buf, " ", PAGE_SIZE);
844dd05f 366 }
61daf055 367 strlcat(buf, "\n", PAGE_SIZE);
844dd05f
MB
368 mutex_unlock(&rng_mutex);
369
61daf055 370 return strlen(buf);
844dd05f
MB
371}
372
94fbcded
GKH
373static DEVICE_ATTR(rng_current, S_IRUGO | S_IWUSR,
374 hwrng_attr_current_show,
375 hwrng_attr_current_store);
376static DEVICE_ATTR(rng_available, S_IRUGO,
377 hwrng_attr_available_show,
378 NULL);
844dd05f
MB
379
380
ac3a497f 381static void __exit unregister_miscdev(void)
844dd05f 382{
94fbcded
GKH
383 device_remove_file(rng_miscdev.this_device, &dev_attr_rng_available);
384 device_remove_file(rng_miscdev.this_device, &dev_attr_rng_current);
b844eba2 385 misc_deregister(&rng_miscdev);
844dd05f
MB
386}
387
ac3a497f 388static int __init register_miscdev(void)
844dd05f
MB
389{
390 int err;
391
392 err = misc_register(&rng_miscdev);
393 if (err)
394 goto out;
94fbcded
GKH
395 err = device_create_file(rng_miscdev.this_device,
396 &dev_attr_rng_current);
844dd05f
MB
397 if (err)
398 goto err_misc_dereg;
94fbcded
GKH
399 err = device_create_file(rng_miscdev.this_device,
400 &dev_attr_rng_available);
844dd05f
MB
401 if (err)
402 goto err_remove_current;
403out:
404 return err;
405
406err_remove_current:
94fbcded 407 device_remove_file(rng_miscdev.this_device, &dev_attr_rng_current);
844dd05f
MB
408err_misc_dereg:
409 misc_deregister(&rng_miscdev);
410 goto out;
411}
412
be4000bc
TD
413static int hwrng_fillfn(void *unused)
414{
415 long rc;
416
417 while (!kthread_should_stop()) {
3a2c0ba5
RR
418 struct hwrng *rng;
419
420 rng = get_current_rng();
421 if (IS_ERR(rng) || !rng)
be4000bc 422 break;
9372b35e 423 mutex_lock(&reading_mutex);
3a2c0ba5 424 rc = rng_get_data(rng, rng_fillbuf,
be4000bc 425 rng_buffer_size(), 1);
9372b35e 426 mutex_unlock(&reading_mutex);
3a2c0ba5 427 put_rng(rng);
be4000bc
TD
428 if (rc <= 0) {
429 pr_warn("hwrng: no data available\n");
430 msleep_interruptible(10000);
431 continue;
432 }
9372b35e 433 /* Outside lock, sure, but y'know: randomness. */
be4000bc 434 add_hwgenerator_randomness((void *)rng_fillbuf, rc,
e02b8765 435 rc * current_quality * 8 >> 10);
be4000bc 436 }
9dda727d 437 hwrng_fill = NULL;
be4000bc
TD
438 return 0;
439}
440
441static void start_khwrngd(void)
442{
443 hwrng_fill = kthread_run(hwrng_fillfn, NULL, "hwrng");
444 if (hwrng_fill == ERR_PTR(-ENOMEM)) {
445 pr_err("hwrng_fill thread creation failed");
446 hwrng_fill = NULL;
447 }
448}
449
844dd05f
MB
450int hwrng_register(struct hwrng *rng)
451{
844dd05f
MB
452 int err = -EINVAL;
453 struct hwrng *old_rng, *tmp;
454
455 if (rng->name == NULL ||
9996508b 456 (rng->data_read == NULL && rng->read == NULL))
844dd05f
MB
457 goto out;
458
459 mutex_lock(&rng_mutex);
460
f7f154f1
RR
461 /* kmalloc makes this safe for virt_to_page() in virtio_rng.c */
462 err = -ENOMEM;
463 if (!rng_buffer) {
464 rng_buffer = kmalloc(rng_buffer_size(), GFP_KERNEL);
465 if (!rng_buffer)
466 goto out_unlock;
467 }
be4000bc
TD
468 if (!rng_fillbuf) {
469 rng_fillbuf = kmalloc(rng_buffer_size(), GFP_KERNEL);
470 if (!rng_fillbuf) {
471 kfree(rng_buffer);
472 goto out_unlock;
473 }
474 }
f7f154f1 475
844dd05f
MB
476 /* Must not register two RNGs with the same name. */
477 err = -EEXIST;
478 list_for_each_entry(tmp, &rng_list, list) {
479 if (strcmp(tmp->name, rng->name) == 0)
480 goto out_unlock;
481 }
482
15b66cd5
HX
483 init_completion(&rng->cleanup_done);
484 complete(&rng->cleanup_done);
485
844dd05f 486 old_rng = current_rng;
ebbbfa24 487 err = 0;
844dd05f 488 if (!old_rng) {
90ac41bd 489 err = set_current_rng(rng);
844dd05f
MB
490 if (err)
491 goto out_unlock;
844dd05f 492 }
844dd05f 493 list_add_tail(&rng->list, &rng_list);
d9e79726 494
d3cc7996
AS
495 if (old_rng && !rng->init) {
496 /*
497 * Use a new device's input to add some randomness to
498 * the system. If this rng device isn't going to be
499 * used right away, its init function hasn't been
500 * called yet; so only use the randomness from devices
501 * that don't need an init callback.
502 */
503 add_early_randomness(rng);
504 }
505
844dd05f
MB
506out_unlock:
507 mutex_unlock(&rng_mutex);
508out:
509 return err;
510}
511EXPORT_SYMBOL_GPL(hwrng_register);
512
b844eba2 513void hwrng_unregister(struct hwrng *rng)
844dd05f 514{
844dd05f
MB
515 mutex_lock(&rng_mutex);
516
517 list_del(&rng->list);
518 if (current_rng == rng) {
3a2c0ba5
RR
519 drop_current_rng();
520 if (!list_empty(&rng_list)) {
521 struct hwrng *tail;
522
523 tail = list_entry(rng_list.prev, struct hwrng, list);
524
90ac41bd 525 set_current_rng(tail);
844dd05f
MB
526 }
527 }
3a2c0ba5 528
be4000bc 529 if (list_empty(&rng_list)) {
1dacb395 530 mutex_unlock(&rng_mutex);
be4000bc
TD
531 if (hwrng_fill)
532 kthread_stop(hwrng_fill);
1dacb395
AK
533 } else
534 mutex_unlock(&rng_mutex);
a027f30d 535
77584ee5 536 wait_for_completion(&rng->cleanup_done);
844dd05f 537}
b844eba2 538EXPORT_SYMBOL_GPL(hwrng_unregister);
844dd05f 539
4d9b519c
DT
540static void devm_hwrng_release(struct device *dev, void *res)
541{
542 hwrng_unregister(*(struct hwrng **)res);
543}
544
545static int devm_hwrng_match(struct device *dev, void *res, void *data)
546{
547 struct hwrng **r = res;
548
549 if (WARN_ON(!r || !*r))
550 return 0;
551
552 return *r == data;
553}
554
555int devm_hwrng_register(struct device *dev, struct hwrng *rng)
556{
557 struct hwrng **ptr;
558 int error;
559
560 ptr = devres_alloc(devm_hwrng_release, sizeof(*ptr), GFP_KERNEL);
561 if (!ptr)
562 return -ENOMEM;
563
564 error = hwrng_register(rng);
565 if (error) {
566 devres_free(ptr);
567 return error;
568 }
569
570 *ptr = rng;
571 devres_add(dev, ptr);
572 return 0;
573}
574EXPORT_SYMBOL_GPL(devm_hwrng_register);
575
576void devm_hwrng_unregister(struct device *dev, struct hwrng *rng)
577{
578 devres_release(dev, devm_hwrng_release, devm_hwrng_match, rng);
579}
580EXPORT_SYMBOL_GPL(devm_hwrng_unregister);
581
ac3a497f
HX
582static int __init hwrng_modinit(void)
583{
584 return register_miscdev();
585}
586
587static void __exit hwrng_modexit(void)
b7d44d94
ST
588{
589 mutex_lock(&rng_mutex);
590 BUG_ON(current_rng);
591 kfree(rng_buffer);
be4000bc 592 kfree(rng_fillbuf);
b7d44d94 593 mutex_unlock(&rng_mutex);
ac3a497f
HX
594
595 unregister_miscdev();
b7d44d94
ST
596}
597
ac3a497f
HX
598module_init(hwrng_modinit);
599module_exit(hwrng_modexit);
844dd05f
MB
600
601MODULE_DESCRIPTION("H/W Random Number Generator (RNG) driver");
602MODULE_LICENSE("GPL");
This page took 1.365929 seconds and 5 git commands to generate.