aboutsummaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/Kconfig.debug20
-rw-r--r--lib/audit.c2
-rw-r--r--lib/bitmap.c109
-rw-r--r--lib/flex_array.c26
-rw-r--r--lib/genalloc.c45
-rw-r--r--lib/kstrtox.c26
-rw-r--r--lib/lru_cache.c2
-rw-r--r--lib/show_mem.c2
-rw-r--r--lib/vsprintf.c2
9 files changed, 205 insertions, 29 deletions
diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug
index 0efcdca9751a..28afa4c5333c 100644
--- a/lib/Kconfig.debug
+++ b/lib/Kconfig.debug
@@ -670,6 +670,15 @@ config STACKTRACE
670 bool 670 bool
671 depends on STACKTRACE_SUPPORT 671 depends on STACKTRACE_SUPPORT
672 672
673config DEBUG_STACK_USAGE
674 bool "Stack utilization instrumentation"
675 depends on DEBUG_KERNEL
676 help
677 Enables the display of the minimum amount of free stack which each
678 task has ever had available in the sysrq-T and sysrq-P debug output.
679
680 This option will slow down process creation somewhat.
681
673config DEBUG_KOBJECT 682config DEBUG_KOBJECT
674 bool "kobject debugging" 683 bool "kobject debugging"
675 depends on DEBUG_KERNEL 684 depends on DEBUG_KERNEL
@@ -983,6 +992,17 @@ config DEBUG_FORCE_WEAK_PER_CPU
983 To ensure that generic code follows the above rules, this 992 To ensure that generic code follows the above rules, this
984 option forces all percpu variables to be defined as weak. 993 option forces all percpu variables to be defined as weak.
985 994
995config DEBUG_PER_CPU_MAPS
996 bool "Debug access to per_cpu maps"
997 depends on DEBUG_KERNEL
998 depends on SMP
999 help
1000 Say Y to verify that the per_cpu map being accessed has
1001 been set up. This adds a fair amount of code to kernel memory
1002 and decreases performance.
1003
1004 Say N if unsure.
1005
986config LKDTM 1006config LKDTM
987 tristate "Linux Kernel Dump Test Tool Module" 1007 tristate "Linux Kernel Dump Test Tool Module"
988 depends on DEBUG_FS 1008 depends on DEBUG_FS
diff --git a/lib/audit.c b/lib/audit.c
index 8e7dc1c63aa9..76bbed4a20e5 100644
--- a/lib/audit.c
+++ b/lib/audit.c
@@ -36,8 +36,10 @@ int audit_classify_arch(int arch)
36int audit_classify_syscall(int abi, unsigned syscall) 36int audit_classify_syscall(int abi, unsigned syscall)
37{ 37{
38 switch(syscall) { 38 switch(syscall) {
39#ifdef __NR_open
39 case __NR_open: 40 case __NR_open:
40 return 2; 41 return 2;
42#endif
41#ifdef __NR_openat 43#ifdef __NR_openat
42 case __NR_openat: 44 case __NR_openat:
43 return 3; 45 return 3;
diff --git a/lib/bitmap.c b/lib/bitmap.c
index 91e0ccfdb424..41baf02924e6 100644
--- a/lib/bitmap.c
+++ b/lib/bitmap.c
@@ -571,8 +571,11 @@ int bitmap_scnlistprintf(char *buf, unsigned int buflen,
571EXPORT_SYMBOL(bitmap_scnlistprintf); 571EXPORT_SYMBOL(bitmap_scnlistprintf);
572 572
573/** 573/**
574 * bitmap_parselist - convert list format ASCII string to bitmap 574 * __bitmap_parselist - convert list format ASCII string to bitmap
575 * @bp: read nul-terminated user string from this buffer 575 * @bp: read nul-terminated user string from this buffer
576 * @buflen: buffer size in bytes. If string is smaller than this
577 * then it must be terminated with a \0.
578 * @is_user: location of buffer, 0 indicates kernel space
576 * @maskp: write resulting mask here 579 * @maskp: write resulting mask here
577 * @nmaskbits: number of bits in mask to be written 580 * @nmaskbits: number of bits in mask to be written
578 * 581 *
@@ -587,20 +590,63 @@ EXPORT_SYMBOL(bitmap_scnlistprintf);
587 * %-EINVAL: invalid character in string 590 * %-EINVAL: invalid character in string
588 * %-ERANGE: bit number specified too large for mask 591 * %-ERANGE: bit number specified too large for mask
589 */ 592 */
590int bitmap_parselist(const char *bp, unsigned long *maskp, int nmaskbits) 593static int __bitmap_parselist(const char *buf, unsigned int buflen,
594 int is_user, unsigned long *maskp,
595 int nmaskbits)
591{ 596{
592 unsigned a, b; 597 unsigned a, b;
598 int c, old_c, totaldigits;
599 const char __user *ubuf = buf;
600 int exp_digit, in_range;
593 601
602 totaldigits = c = 0;
594 bitmap_zero(maskp, nmaskbits); 603 bitmap_zero(maskp, nmaskbits);
595 do { 604 do {
596 if (!isdigit(*bp)) 605 exp_digit = 1;
597 return -EINVAL; 606 in_range = 0;
598 b = a = simple_strtoul(bp, (char **)&bp, BASEDEC); 607 a = b = 0;
599 if (*bp == '-') { 608
600 bp++; 609 /* Get the next cpu# or a range of cpu#'s */
601 if (!isdigit(*bp)) 610 while (buflen) {
611 old_c = c;
612 if (is_user) {
613 if (__get_user(c, ubuf++))
614 return -EFAULT;
615 } else
616 c = *buf++;
617 buflen--;
618 if (isspace(c))
619 continue;
620
621 /*
622 * If the last character was a space and the current
623 * character isn't '\0', we've got embedded whitespace.
624 * This is a no-no, so throw an error.
625 */
626 if (totaldigits && c && isspace(old_c))
627 return -EINVAL;
628
629 /* A '\0' or a ',' signal the end of a cpu# or range */
630 if (c == '\0' || c == ',')
631 break;
632
633 if (c == '-') {
634 if (exp_digit || in_range)
635 return -EINVAL;
636 b = 0;
637 in_range = 1;
638 exp_digit = 1;
639 continue;
640 }
641
642 if (!isdigit(c))
602 return -EINVAL; 643 return -EINVAL;
603 b = simple_strtoul(bp, (char **)&bp, BASEDEC); 644
645 b = b * 10 + (c - '0');
646 if (!in_range)
647 a = b;
648 exp_digit = 0;
649 totaldigits++;
604 } 650 }
605 if (!(a <= b)) 651 if (!(a <= b))
606 return -EINVAL; 652 return -EINVAL;
@@ -610,13 +656,52 @@ int bitmap_parselist(const char *bp, unsigned long *maskp, int nmaskbits)
610 set_bit(a, maskp); 656 set_bit(a, maskp);
611 a++; 657 a++;
612 } 658 }
613 if (*bp == ',') 659 } while (buflen && c == ',');
614 bp++;
615 } while (*bp != '\0' && *bp != '\n');
616 return 0; 660 return 0;
617} 661}
662
663int bitmap_parselist(const char *bp, unsigned long *maskp, int nmaskbits)
664{
665 char *nl = strchr(bp, '\n');
666 int len;
667
668 if (nl)
669 len = nl - bp;
670 else
671 len = strlen(bp);
672
673 return __bitmap_parselist(bp, len, 0, maskp, nmaskbits);
674}
618EXPORT_SYMBOL(bitmap_parselist); 675EXPORT_SYMBOL(bitmap_parselist);
619 676
677
678/**
679 * bitmap_parselist_user()
680 *
681 * @ubuf: pointer to user buffer containing string.
682 * @ulen: buffer size in bytes. If string is smaller than this
683 * then it must be terminated with a \0.
684 * @maskp: pointer to bitmap array that will contain result.
685 * @nmaskbits: size of bitmap, in bits.
686 *
687 * Wrapper for bitmap_parselist(), providing it with user buffer.
688 *
689 * We cannot have this as an inline function in bitmap.h because it needs
690 * linux/uaccess.h to get the access_ok() declaration and this causes
691 * cyclic dependencies.
692 */
693int bitmap_parselist_user(const char __user *ubuf,
694 unsigned int ulen, unsigned long *maskp,
695 int nmaskbits)
696{
697 if (!access_ok(VERIFY_READ, ubuf, ulen))
698 return -EFAULT;
699 return __bitmap_parselist((const char *)ubuf,
700 ulen, 1, maskp, nmaskbits);
701}
702EXPORT_SYMBOL(bitmap_parselist_user);
703
704
620/** 705/**
621 * bitmap_pos_to_ord - find ordinal of set bit at given position in bitmap 706 * bitmap_pos_to_ord - find ordinal of set bit at given position in bitmap
622 * @buf: pointer to a bitmap 707 * @buf: pointer to a bitmap
diff --git a/lib/flex_array.c b/lib/flex_array.c
index 854b57bd7d9d..cab7621f98aa 100644
--- a/lib/flex_array.c
+++ b/lib/flex_array.c
@@ -88,8 +88,11 @@ struct flex_array *flex_array_alloc(int element_size, unsigned int total,
88 gfp_t flags) 88 gfp_t flags)
89{ 89{
90 struct flex_array *ret; 90 struct flex_array *ret;
91 int max_size = FLEX_ARRAY_NR_BASE_PTRS * 91 int max_size = 0;
92 FLEX_ARRAY_ELEMENTS_PER_PART(element_size); 92
93 if (element_size)
94 max_size = FLEX_ARRAY_NR_BASE_PTRS *
95 FLEX_ARRAY_ELEMENTS_PER_PART(element_size);
93 96
94 /* max_size will end up 0 if element_size > PAGE_SIZE */ 97 /* max_size will end up 0 if element_size > PAGE_SIZE */
95 if (total > max_size) 98 if (total > max_size)
@@ -183,15 +186,18 @@ __fa_get_part(struct flex_array *fa, int part_nr, gfp_t flags)
183int flex_array_put(struct flex_array *fa, unsigned int element_nr, void *src, 186int flex_array_put(struct flex_array *fa, unsigned int element_nr, void *src,
184 gfp_t flags) 187 gfp_t flags)
185{ 188{
186 int part_nr = fa_element_to_part_nr(fa, element_nr); 189 int part_nr;
187 struct flex_array_part *part; 190 struct flex_array_part *part;
188 void *dst; 191 void *dst;
189 192
190 if (element_nr >= fa->total_nr_elements) 193 if (element_nr >= fa->total_nr_elements)
191 return -ENOSPC; 194 return -ENOSPC;
195 if (!fa->element_size)
196 return 0;
192 if (elements_fit_in_base(fa)) 197 if (elements_fit_in_base(fa))
193 part = (struct flex_array_part *)&fa->parts[0]; 198 part = (struct flex_array_part *)&fa->parts[0];
194 else { 199 else {
200 part_nr = fa_element_to_part_nr(fa, element_nr);
195 part = __fa_get_part(fa, part_nr, flags); 201 part = __fa_get_part(fa, part_nr, flags);
196 if (!part) 202 if (!part)
197 return -ENOMEM; 203 return -ENOMEM;
@@ -211,15 +217,18 @@ EXPORT_SYMBOL(flex_array_put);
211 */ 217 */
212int flex_array_clear(struct flex_array *fa, unsigned int element_nr) 218int flex_array_clear(struct flex_array *fa, unsigned int element_nr)
213{ 219{
214 int part_nr = fa_element_to_part_nr(fa, element_nr); 220 int part_nr;
215 struct flex_array_part *part; 221 struct flex_array_part *part;
216 void *dst; 222 void *dst;
217 223
218 if (element_nr >= fa->total_nr_elements) 224 if (element_nr >= fa->total_nr_elements)
219 return -ENOSPC; 225 return -ENOSPC;
226 if (!fa->element_size)
227 return 0;
220 if (elements_fit_in_base(fa)) 228 if (elements_fit_in_base(fa))
221 part = (struct flex_array_part *)&fa->parts[0]; 229 part = (struct flex_array_part *)&fa->parts[0];
222 else { 230 else {
231 part_nr = fa_element_to_part_nr(fa, element_nr);
223 part = fa->parts[part_nr]; 232 part = fa->parts[part_nr];
224 if (!part) 233 if (!part)
225 return -EINVAL; 234 return -EINVAL;
@@ -264,6 +273,8 @@ int flex_array_prealloc(struct flex_array *fa, unsigned int start,
264 273
265 if (end >= fa->total_nr_elements) 274 if (end >= fa->total_nr_elements)
266 return -ENOSPC; 275 return -ENOSPC;
276 if (!fa->element_size)
277 return 0;
267 if (elements_fit_in_base(fa)) 278 if (elements_fit_in_base(fa))
268 return 0; 279 return 0;
269 start_part = fa_element_to_part_nr(fa, start); 280 start_part = fa_element_to_part_nr(fa, start);
@@ -291,14 +302,17 @@ EXPORT_SYMBOL(flex_array_prealloc);
291 */ 302 */
292void *flex_array_get(struct flex_array *fa, unsigned int element_nr) 303void *flex_array_get(struct flex_array *fa, unsigned int element_nr)
293{ 304{
294 int part_nr = fa_element_to_part_nr(fa, element_nr); 305 int part_nr;
295 struct flex_array_part *part; 306 struct flex_array_part *part;
296 307
308 if (!fa->element_size)
309 return NULL;
297 if (element_nr >= fa->total_nr_elements) 310 if (element_nr >= fa->total_nr_elements)
298 return NULL; 311 return NULL;
299 if (elements_fit_in_base(fa)) 312 if (elements_fit_in_base(fa))
300 part = (struct flex_array_part *)&fa->parts[0]; 313 part = (struct flex_array_part *)&fa->parts[0];
301 else { 314 else {
315 part_nr = fa_element_to_part_nr(fa, element_nr);
302 part = fa->parts[part_nr]; 316 part = fa->parts[part_nr];
303 if (!part) 317 if (!part)
304 return NULL; 318 return NULL;
@@ -353,7 +367,7 @@ int flex_array_shrink(struct flex_array *fa)
353 int part_nr; 367 int part_nr;
354 int ret = 0; 368 int ret = 0;
355 369
356 if (!fa->total_nr_elements) 370 if (!fa->total_nr_elements || !fa->element_size)
357 return 0; 371 return 0;
358 if (elements_fit_in_base(fa)) 372 if (elements_fit_in_base(fa))
359 return ret; 373 return ret;
diff --git a/lib/genalloc.c b/lib/genalloc.c
index 1923f1490e72..577ddf805975 100644
--- a/lib/genalloc.c
+++ b/lib/genalloc.c
@@ -39,17 +39,20 @@ struct gen_pool *gen_pool_create(int min_alloc_order, int nid)
39EXPORT_SYMBOL(gen_pool_create); 39EXPORT_SYMBOL(gen_pool_create);
40 40
41/** 41/**
42 * gen_pool_add - add a new chunk of special memory to the pool 42 * gen_pool_add_virt - add a new chunk of special memory to the pool
43 * @pool: pool to add new memory chunk to 43 * @pool: pool to add new memory chunk to
44 * @addr: starting address of memory chunk to add to pool 44 * @virt: virtual starting address of memory chunk to add to pool
45 * @phys: physical starting address of memory chunk to add to pool
45 * @size: size in bytes of the memory chunk to add to pool 46 * @size: size in bytes of the memory chunk to add to pool
46 * @nid: node id of the node the chunk structure and bitmap should be 47 * @nid: node id of the node the chunk structure and bitmap should be
47 * allocated on, or -1 48 * allocated on, or -1
48 * 49 *
49 * Add a new chunk of special memory to the specified pool. 50 * Add a new chunk of special memory to the specified pool.
51 *
52 * Returns 0 on success or a -ve errno on failure.
50 */ 53 */
51int gen_pool_add(struct gen_pool *pool, unsigned long addr, size_t size, 54int gen_pool_add_virt(struct gen_pool *pool, unsigned long virt, phys_addr_t phys,
52 int nid) 55 size_t size, int nid)
53{ 56{
54 struct gen_pool_chunk *chunk; 57 struct gen_pool_chunk *chunk;
55 int nbits = size >> pool->min_alloc_order; 58 int nbits = size >> pool->min_alloc_order;
@@ -58,11 +61,12 @@ int gen_pool_add(struct gen_pool *pool, unsigned long addr, size_t size,
58 61
59 chunk = kmalloc_node(nbytes, GFP_KERNEL | __GFP_ZERO, nid); 62 chunk = kmalloc_node(nbytes, GFP_KERNEL | __GFP_ZERO, nid);
60 if (unlikely(chunk == NULL)) 63 if (unlikely(chunk == NULL))
61 return -1; 64 return -ENOMEM;
62 65
63 spin_lock_init(&chunk->lock); 66 spin_lock_init(&chunk->lock);
64 chunk->start_addr = addr; 67 chunk->phys_addr = phys;
65 chunk->end_addr = addr + size; 68 chunk->start_addr = virt;
69 chunk->end_addr = virt + size;
66 70
67 write_lock(&pool->lock); 71 write_lock(&pool->lock);
68 list_add(&chunk->next_chunk, &pool->chunks); 72 list_add(&chunk->next_chunk, &pool->chunks);
@@ -70,7 +74,32 @@ int gen_pool_add(struct gen_pool *pool, unsigned long addr, size_t size,
70 74
71 return 0; 75 return 0;
72} 76}
73EXPORT_SYMBOL(gen_pool_add); 77EXPORT_SYMBOL(gen_pool_add_virt);
78
79/**
80 * gen_pool_virt_to_phys - return the physical address of memory
81 * @pool: pool to allocate from
82 * @addr: starting address of memory
83 *
84 * Returns the physical address on success, or -1 on error.
85 */
86phys_addr_t gen_pool_virt_to_phys(struct gen_pool *pool, unsigned long addr)
87{
88 struct list_head *_chunk;
89 struct gen_pool_chunk *chunk;
90
91 read_lock(&pool->lock);
92 list_for_each(_chunk, &pool->chunks) {
93 chunk = list_entry(_chunk, struct gen_pool_chunk, next_chunk);
94
95 if (addr >= chunk->start_addr && addr < chunk->end_addr)
96 return chunk->phys_addr + addr - chunk->start_addr;
97 }
98 read_unlock(&pool->lock);
99
100 return -1;
101}
102EXPORT_SYMBOL(gen_pool_virt_to_phys);
74 103
75/** 104/**
76 * gen_pool_destroy - destroy a special memory pool 105 * gen_pool_destroy - destroy a special memory pool
diff --git a/lib/kstrtox.c b/lib/kstrtox.c
index a235f3cc471c..2dbae88090ac 100644
--- a/lib/kstrtox.c
+++ b/lib/kstrtox.c
@@ -17,6 +17,7 @@
17#include <linux/math64.h> 17#include <linux/math64.h>
18#include <linux/module.h> 18#include <linux/module.h>
19#include <linux/types.h> 19#include <linux/types.h>
20#include <asm/uaccess.h>
20 21
21static inline char _tolower(const char c) 22static inline char _tolower(const char c)
22{ 23{
@@ -222,3 +223,28 @@ int kstrtos8(const char *s, unsigned int base, s8 *res)
222 return 0; 223 return 0;
223} 224}
224EXPORT_SYMBOL(kstrtos8); 225EXPORT_SYMBOL(kstrtos8);
226
227#define kstrto_from_user(f, g, type) \
228int f(const char __user *s, size_t count, unsigned int base, type *res) \
229{ \
230 /* sign, base 2 representation, newline, terminator */ \
231 char buf[1 + sizeof(type) * 8 + 1 + 1]; \
232 \
233 count = min(count, sizeof(buf) - 1); \
234 if (copy_from_user(buf, s, count)) \
235 return -EFAULT; \
236 buf[count] = '\0'; \
237 return g(buf, base, res); \
238} \
239EXPORT_SYMBOL(f)
240
241kstrto_from_user(kstrtoull_from_user, kstrtoull, unsigned long long);
242kstrto_from_user(kstrtoll_from_user, kstrtoll, long long);
243kstrto_from_user(kstrtoul_from_user, kstrtoul, unsigned long);
244kstrto_from_user(kstrtol_from_user, kstrtol, long);
245kstrto_from_user(kstrtouint_from_user, kstrtouint, unsigned int);
246kstrto_from_user(kstrtoint_from_user, kstrtoint, int);
247kstrto_from_user(kstrtou16_from_user, kstrtou16, u16);
248kstrto_from_user(kstrtos16_from_user, kstrtos16, s16);
249kstrto_from_user(kstrtou8_from_user, kstrtou8, u8);
250kstrto_from_user(kstrtos8_from_user, kstrtos8, s8);
diff --git a/lib/lru_cache.c b/lib/lru_cache.c
index 270de9d31b8c..a07e7268d7ed 100644
--- a/lib/lru_cache.c
+++ b/lib/lru_cache.c
@@ -84,7 +84,7 @@ struct lru_cache *lc_create(const char *name, struct kmem_cache *cache,
84 if (e_count > LC_MAX_ACTIVE) 84 if (e_count > LC_MAX_ACTIVE)
85 return NULL; 85 return NULL;
86 86
87 slot = kzalloc(e_count * sizeof(struct hlist_head*), GFP_KERNEL); 87 slot = kcalloc(e_count, sizeof(struct hlist_head), GFP_KERNEL);
88 if (!slot) 88 if (!slot)
89 goto out_fail; 89 goto out_fail;
90 element = kzalloc(e_count * sizeof(struct lc_element *), GFP_KERNEL); 90 element = kzalloc(e_count * sizeof(struct lc_element *), GFP_KERNEL);
diff --git a/lib/show_mem.c b/lib/show_mem.c
index 90cbe4bb5960..4407f8c9b1f7 100644
--- a/lib/show_mem.c
+++ b/lib/show_mem.c
@@ -16,7 +16,7 @@ void show_mem(unsigned int filter)
16 nonshared = 0, highmem = 0; 16 nonshared = 0, highmem = 0;
17 17
18 printk("Mem-Info:\n"); 18 printk("Mem-Info:\n");
19 __show_free_areas(filter); 19 show_free_areas(filter);
20 20
21 for_each_online_pgdat(pgdat) { 21 for_each_online_pgdat(pgdat) {
22 unsigned long i, flags; 22 unsigned long i, flags;
diff --git a/lib/vsprintf.c b/lib/vsprintf.c
index 1d659d7bb0f8..c11205688fb4 100644
--- a/lib/vsprintf.c
+++ b/lib/vsprintf.c
@@ -898,7 +898,7 @@ char *pointer(const char *fmt, char *buf, char *end, void *ptr,
898 case 'U': 898 case 'U':
899 return uuid_string(buf, end, ptr, spec, fmt); 899 return uuid_string(buf, end, ptr, spec, fmt);
900 case 'V': 900 case 'V':
901 return buf + vsnprintf(buf, end - buf, 901 return buf + vsnprintf(buf, end > buf ? end - buf : 0,
902 ((struct va_format *)ptr)->fmt, 902 ((struct va_format *)ptr)->fmt,
903 *(((struct va_format *)ptr)->va)); 903 *(((struct va_format *)ptr)->va));
904 case 'K': 904 case 'K':