]>
Commit | Line | Data |
---|---|---|
716154c5 BB |
1 | /*****************************************************************************\ |
2 | * Copyright (C) 2007-2010 Lawrence Livermore National Security, LLC. | |
3 | * Copyright (C) 2007 The Regents of the University of California. | |
4 | * Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER). | |
5 | * Written by Brian Behlendorf <behlendorf1@llnl.gov>. | |
715f6251 | 6 | * UCRL-CODE-235197 |
7 | * | |
716154c5 | 8 | * This file is part of the SPL, Solaris Porting Layer. |
3d6af2dd | 9 | * For details, see <http://zfsonlinux.org/>. |
716154c5 BB |
10 | * |
11 | * The SPL is free software; you can redistribute it and/or modify it | |
12 | * under the terms of the GNU General Public License as published by the | |
13 | * Free Software Foundation; either version 2 of the License, or (at your | |
14 | * option) any later version. | |
715f6251 | 15 | * |
716154c5 | 16 | * The SPL is distributed in the hope that it will be useful, but WITHOUT |
715f6251 | 17 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
18 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
19 | * for more details. | |
20 | * | |
21 | * You should have received a copy of the GNU General Public License along | |
716154c5 BB |
22 | * with the SPL. If not, see <http://www.gnu.org/licenses/>. |
23 | ***************************************************************************** | |
24 | * Solaris Porting LAyer Tests (SPLAT) Random Number Generator Tests. | |
25 | \*****************************************************************************/ | |
715f6251 | 26 | |
df870a69 BB |
27 | #include <sys/random.h> |
28 | #include <sys/kmem.h> | |
7c50328b | 29 | #include "splat-internal.h" |
f1ca4da6 | 30 | |
7c50328b | 31 | #define SPLAT_KRNG_NAME "krng" |
32 | #define SPLAT_KRNG_DESC "Kernel Random Number Generator Tests" | |
f1ca4da6 | 33 | |
7c50328b | 34 | #define SPLAT_KRNG_TEST1_ID 0x0301 |
35 | #define SPLAT_KRNG_TEST1_NAME "freq" | |
36 | #define SPLAT_KRNG_TEST1_DESC "Frequency Test" | |
f1ca4da6 | 37 | |
38 | #define KRNG_NUM_BITS 1048576 | |
39 | #define KRNG_NUM_BYTES (KRNG_NUM_BITS >> 3) | |
40 | #define KRNG_NUM_BITS_DIV2 (KRNG_NUM_BITS >> 1) | |
41 | #define KRNG_ERROR_RANGE 2097 | |
42 | ||
43 | /* Random Number Generator Tests | |
44 | There can be meny more tests on quality of the | |
45 | random number generator. For now we are only | |
46 | testing the frequency of particular bits. | |
47 | We could also test consecutive sequences, | |
48 | randomness within a particular block, etc. | |
49 | but is probably not necessary for our purposes */ | |
50 | ||
51 | static int | |
7c50328b | 52 | splat_krng_test1(struct file *file, void *arg) |
f1ca4da6 | 53 | { |
54 | uint8_t *buf; | |
55 | int i, j, diff, num = 0, rc = 0; | |
56 | ||
57 | buf = kmalloc(sizeof(*buf) * KRNG_NUM_BYTES, GFP_KERNEL); | |
58 | if (buf == NULL) { | |
59 | rc = -ENOMEM; | |
60 | goto out; | |
61 | } | |
62 | ||
63 | memset(buf, 0, sizeof(*buf) * KRNG_NUM_BYTES); | |
64 | ||
65 | /* Always succeeds */ | |
66 | random_get_pseudo_bytes(buf, sizeof(uint8_t) * KRNG_NUM_BYTES); | |
67 | ||
68 | for (i = 0; i < KRNG_NUM_BYTES; i++) { | |
69 | uint8_t tmp = buf[i]; | |
70 | for (j = 0; j < 8; j++) { | |
71 | uint8_t tmp2 = ((tmp >> j) & 0x01); | |
72 | if (tmp2 == 1) { | |
73 | num++; | |
74 | } | |
75 | } | |
76 | } | |
77 | ||
78 | kfree(buf); | |
79 | ||
80 | diff = KRNG_NUM_BITS_DIV2 - num; | |
81 | if (diff < 0) | |
82 | diff *= -1; | |
83 | ||
7c50328b | 84 | splat_print(file, "Test 1 Number of ones: %d\n", num); |
85 | splat_print(file, "Test 1 Difference from expected: %d Allowed: %d\n", | |
f1ca4da6 | 86 | diff, KRNG_ERROR_RANGE); |
87 | ||
88 | if (diff > KRNG_ERROR_RANGE) | |
89 | rc = -ERANGE; | |
90 | out: | |
91 | return rc; | |
92 | } | |
93 | ||
7c50328b | 94 | splat_subsystem_t * |
95 | splat_krng_init(void) | |
f1ca4da6 | 96 | { |
7c50328b | 97 | splat_subsystem_t *sub; |
f1ca4da6 | 98 | |
99 | sub = kmalloc(sizeof(*sub), GFP_KERNEL); | |
100 | if (sub == NULL) | |
101 | return NULL; | |
102 | ||
103 | memset(sub, 0, sizeof(*sub)); | |
7c50328b | 104 | strncpy(sub->desc.name, SPLAT_KRNG_NAME, SPLAT_NAME_SIZE); |
105 | strncpy(sub->desc.desc, SPLAT_KRNG_DESC, SPLAT_DESC_SIZE); | |
f1ca4da6 | 106 | INIT_LIST_HEAD(&sub->subsystem_list); |
107 | INIT_LIST_HEAD(&sub->test_list); | |
108 | spin_lock_init(&sub->test_lock); | |
7c50328b | 109 | sub->desc.id = SPLAT_SUBSYSTEM_KRNG; |
f1ca4da6 | 110 | |
ec06701b | 111 | splat_test_init(sub, SPLAT_KRNG_TEST1_NAME, SPLAT_KRNG_TEST1_DESC, |
7c50328b | 112 | SPLAT_KRNG_TEST1_ID, splat_krng_test1); |
f1ca4da6 | 113 | |
114 | return sub; | |
115 | } | |
116 | ||
117 | void | |
7c50328b | 118 | splat_krng_fini(splat_subsystem_t *sub) |
f1ca4da6 | 119 | { |
120 | ASSERT(sub); | |
121 | ||
ec06701b | 122 | splat_test_fini(sub, SPLAT_KRNG_TEST1_ID); |
f1ca4da6 | 123 | |
124 | kfree(sub); | |
125 | } | |
126 | ||
127 | int | |
7c50328b | 128 | splat_krng_id(void) { |
129 | return SPLAT_SUBSYSTEM_KRNG; | |
f1ca4da6 | 130 | } |