aboutsummaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/Kconfig.debug16
-rw-r--r--lib/Makefile2
-rw-r--r--lib/bitmap.c54
-rw-r--r--lib/random32.c142
4 files changed, 201 insertions, 13 deletions
diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug
index 756a908c441d..77491e311791 100644
--- a/lib/Kconfig.debug
+++ b/lib/Kconfig.debug
@@ -71,7 +71,7 @@ config LOG_BUF_SHIFT
71 71
72config DETECT_SOFTLOCKUP 72config DETECT_SOFTLOCKUP
73 bool "Detect Soft Lockups" 73 bool "Detect Soft Lockups"
74 depends on DEBUG_KERNEL 74 depends on DEBUG_KERNEL && !S390
75 default y 75 default y
76 help 76 help
77 Say Y here to enable the kernel to detect "soft lockups", 77 Say Y here to enable the kernel to detect "soft lockups",
@@ -371,6 +371,20 @@ config FORCED_INLINING
371 become the default in the future, until then this option is there to 371 become the default in the future, until then this option is there to
372 test gcc for this. 372 test gcc for this.
373 373
374config HEADERS_CHECK
375 bool "Run 'make headers_check' when building vmlinux"
376 depends on !UML
377 help
378 This option will extract the user-visible kernel headers whenever
379 building the kernel, and will run basic sanity checks on them to
380 ensure that exported files do not attempt to include files which
381 were not exported, etc.
382
383 If you're making modifications to header files which are
384 relevant for userspace, say 'Y', and check the headers
385 exported to $(INSTALL_HDR_PATH) (usually 'usr/include' in
386 your build tree), to make sure they're suitable.
387
374config RCU_TORTURE_TEST 388config RCU_TORTURE_TEST
375 tristate "torture tests for RCU" 389 tristate "torture tests for RCU"
376 depends on DEBUG_KERNEL 390 depends on DEBUG_KERNEL
diff --git a/lib/Makefile b/lib/Makefile
index 8e6662bb9c37..cf98fabaa549 100644
--- a/lib/Makefile
+++ b/lib/Makefile
@@ -12,7 +12,7 @@ lib-$(CONFIG_SMP) += cpumask.o
12 12
13lib-y += kobject.o kref.o kobject_uevent.o klist.o 13lib-y += kobject.o kref.o kobject_uevent.o klist.o
14 14
15obj-y += sort.o parser.o halfmd4.o iomap_copy.o debug_locks.o 15obj-y += sort.o parser.o halfmd4.o iomap_copy.o debug_locks.o random32.o
16 16
17ifeq ($(CONFIG_DEBUG_KOBJECT),y) 17ifeq ($(CONFIG_DEBUG_KOBJECT),y)
18CFLAGS_kobject.o += -DDEBUG 18CFLAGS_kobject.o += -DDEBUG
diff --git a/lib/bitmap.c b/lib/bitmap.c
index d71e38c54ea5..037fa9aa2ed7 100644
--- a/lib/bitmap.c
+++ b/lib/bitmap.c
@@ -316,10 +316,11 @@ int bitmap_scnprintf(char *buf, unsigned int buflen,
316EXPORT_SYMBOL(bitmap_scnprintf); 316EXPORT_SYMBOL(bitmap_scnprintf);
317 317
318/** 318/**
319 * bitmap_parse - convert an ASCII hex string into a bitmap. 319 * __bitmap_parse - convert an ASCII hex string into a bitmap.
320 * @ubuf: pointer to buffer in user space containing string. 320 * @buf: pointer to buffer containing string.
321 * @ubuflen: buffer size in bytes. If string is smaller than this 321 * @buflen: buffer size in bytes. If string is smaller than this
322 * then it must be terminated with a \0. 322 * then it must be terminated with a \0.
323 * @is_user: location of buffer, 0 indicates kernel space
323 * @maskp: pointer to bitmap array that will contain result. 324 * @maskp: pointer to bitmap array that will contain result.
324 * @nmaskbits: size of bitmap, in bits. 325 * @nmaskbits: size of bitmap, in bits.
325 * 326 *
@@ -330,11 +331,13 @@ EXPORT_SYMBOL(bitmap_scnprintf);
330 * characters and for grouping errors such as "1,,5", ",44", "," and "". 331 * characters and for grouping errors such as "1,,5", ",44", "," and "".
331 * Leading and trailing whitespace accepted, but not embedded whitespace. 332 * Leading and trailing whitespace accepted, but not embedded whitespace.
332 */ 333 */
333int bitmap_parse(const char __user *ubuf, unsigned int ubuflen, 334int __bitmap_parse(const char *buf, unsigned int buflen,
334 unsigned long *maskp, int nmaskbits) 335 int is_user, unsigned long *maskp,
336 int nmaskbits)
335{ 337{
336 int c, old_c, totaldigits, ndigits, nchunks, nbits; 338 int c, old_c, totaldigits, ndigits, nchunks, nbits;
337 u32 chunk; 339 u32 chunk;
340 const char __user *ubuf = buf;
338 341
339 bitmap_zero(maskp, nmaskbits); 342 bitmap_zero(maskp, nmaskbits);
340 343
@@ -343,11 +346,15 @@ int bitmap_parse(const char __user *ubuf, unsigned int ubuflen,
343 chunk = ndigits = 0; 346 chunk = ndigits = 0;
344 347
345 /* Get the next chunk of the bitmap */ 348 /* Get the next chunk of the bitmap */
346 while (ubuflen) { 349 while (buflen) {
347 old_c = c; 350 old_c = c;
348 if (get_user(c, ubuf++)) 351 if (is_user) {
349 return -EFAULT; 352 if (__get_user(c, ubuf++))
350 ubuflen--; 353 return -EFAULT;
354 }
355 else
356 c = *buf++;
357 buflen--;
351 if (isspace(c)) 358 if (isspace(c))
352 continue; 359 continue;
353 360
@@ -388,11 +395,36 @@ int bitmap_parse(const char __user *ubuf, unsigned int ubuflen,
388 nbits += (nchunks == 1) ? nbits_to_hold_value(chunk) : CHUNKSZ; 395 nbits += (nchunks == 1) ? nbits_to_hold_value(chunk) : CHUNKSZ;
389 if (nbits > nmaskbits) 396 if (nbits > nmaskbits)
390 return -EOVERFLOW; 397 return -EOVERFLOW;
391 } while (ubuflen && c == ','); 398 } while (buflen && c == ',');
392 399
393 return 0; 400 return 0;
394} 401}
395EXPORT_SYMBOL(bitmap_parse); 402EXPORT_SYMBOL(__bitmap_parse);
403
404/**
405 * bitmap_parse_user()
406 *
407 * @ubuf: pointer to user buffer containing string.
408 * @ulen: buffer size in bytes. If string is smaller than this
409 * then it must be terminated with a \0.
410 * @maskp: pointer to bitmap array that will contain result.
411 * @nmaskbits: size of bitmap, in bits.
412 *
413 * Wrapper for __bitmap_parse(), providing it with user buffer.
414 *
415 * We cannot have this as an inline function in bitmap.h because it needs
416 * linux/uaccess.h to get the access_ok() declaration and this causes
417 * cyclic dependencies.
418 */
419int bitmap_parse_user(const char __user *ubuf,
420 unsigned int ulen, unsigned long *maskp,
421 int nmaskbits)
422{
423 if (!access_ok(VERIFY_READ, ubuf, ulen))
424 return -EFAULT;
425 return __bitmap_parse((const char *)ubuf, ulen, 1, maskp, nmaskbits);
426}
427EXPORT_SYMBOL(bitmap_parse_user);
396 428
397/* 429/*
398 * bscnl_emit(buf, buflen, rbot, rtop, bp) 430 * bscnl_emit(buf, buflen, rbot, rtop, bp)
diff --git a/lib/random32.c b/lib/random32.c
new file mode 100644
index 000000000000..4a15ce51cea7
--- /dev/null
+++ b/lib/random32.c
@@ -0,0 +1,142 @@
1/*
2 This is a maximally equidistributed combined Tausworthe generator
3 based on code from GNU Scientific Library 1.5 (30 Jun 2004)
4
5 x_n = (s1_n ^ s2_n ^ s3_n)
6
7 s1_{n+1} = (((s1_n & 4294967294) <<12) ^ (((s1_n <<13) ^ s1_n) >>19))
8 s2_{n+1} = (((s2_n & 4294967288) << 4) ^ (((s2_n << 2) ^ s2_n) >>25))
9 s3_{n+1} = (((s3_n & 4294967280) <<17) ^ (((s3_n << 3) ^ s3_n) >>11))
10
11 The period of this generator is about 2^88.
12
13 From: P. L'Ecuyer, "Maximally Equidistributed Combined Tausworthe
14 Generators", Mathematics of Computation, 65, 213 (1996), 203--213.
15
16 This is available on the net from L'Ecuyer's home page,
17
18 http://www.iro.umontreal.ca/~lecuyer/myftp/papers/tausme.ps
19 ftp://ftp.iro.umontreal.ca/pub/simulation/lecuyer/papers/tausme.ps
20
21 There is an erratum in the paper "Tables of Maximally
22 Equidistributed Combined LFSR Generators", Mathematics of
23 Computation, 68, 225 (1999), 261--269:
24 http://www.iro.umontreal.ca/~lecuyer/myftp/papers/tausme2.ps
25
26 ... the k_j most significant bits of z_j must be non-
27 zero, for each j. (Note: this restriction also applies to the
28 computer code given in [4], but was mistakenly not mentioned in
29 that paper.)
30
31 This affects the seeding procedure by imposing the requirement
32 s1 > 1, s2 > 7, s3 > 15.
33
34*/
35
36#include <linux/types.h>
37#include <linux/percpu.h>
38#include <linux/module.h>
39#include <linux/random.h>
40
41struct rnd_state {
42 u32 s1, s2, s3;
43};
44
45static DEFINE_PER_CPU(struct rnd_state, net_rand_state);
46
47static u32 __random32(struct rnd_state *state)
48{
49#define TAUSWORTHE(s,a,b,c,d) ((s&c)<<d) ^ (((s <<a) ^ s)>>b)
50
51 state->s1 = TAUSWORTHE(state->s1, 13, 19, 4294967294UL, 12);
52 state->s2 = TAUSWORTHE(state->s2, 2, 25, 4294967288UL, 4);
53 state->s3 = TAUSWORTHE(state->s3, 3, 11, 4294967280UL, 17);
54
55 return (state->s1 ^ state->s2 ^ state->s3);
56}
57
58static void __set_random32(struct rnd_state *state, unsigned long s)
59{
60 if (s == 0)
61 s = 1; /* default seed is 1 */
62
63#define LCG(n) (69069 * n)
64 state->s1 = LCG(s);
65 state->s2 = LCG(state->s1);
66 state->s3 = LCG(state->s2);
67
68 /* "warm it up" */
69 __random32(state);
70 __random32(state);
71 __random32(state);
72 __random32(state);
73 __random32(state);
74 __random32(state);
75}
76
77/**
78 * random32 - pseudo random number generator
79 *
80 * A 32 bit pseudo-random number is generated using a fast
81 * algorithm suitable for simulation. This algorithm is NOT
82 * considered safe for cryptographic use.
83 */
84u32 random32(void)
85{
86 unsigned long r;
87 struct rnd_state *state = &get_cpu_var(net_rand_state);
88 r = __random32(state);
89 put_cpu_var(state);
90 return r;
91}
92EXPORT_SYMBOL(random32);
93
94/**
95 * srandom32 - add entropy to pseudo random number generator
96 * @seed: seed value
97 *
98 * Add some additional seeding to the random32() pool.
99 * Note: this pool is per cpu so it only affects current CPU.
100 */
101void srandom32(u32 entropy)
102{
103 struct rnd_state *state = &get_cpu_var(net_rand_state);
104 __set_random32(state, state->s1 ^ entropy);
105 put_cpu_var(state);
106}
107EXPORT_SYMBOL(srandom32);
108
109/*
110 * Generate some initially weak seeding values to allow
111 * to start the random32() engine.
112 */
113static int __init random32_init(void)
114{
115 int i;
116
117 for_each_possible_cpu(i) {
118 struct rnd_state *state = &per_cpu(net_rand_state,i);
119 __set_random32(state, i + jiffies);
120 }
121 return 0;
122}
123core_initcall(random32_init);
124
125/*
126 * Generate better values after random number generator
127 * is fully initalized.
128 */
129static int __init random32_reseed(void)
130{
131 int i;
132 unsigned long seed;
133
134 for_each_possible_cpu(i) {
135 struct rnd_state *state = &per_cpu(net_rand_state,i);
136
137 get_random_bytes(&seed, sizeof(seed));
138 __set_random32(state, seed);
139 }
140 return 0;
141}
142late_initcall(random32_reseed);