summaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/Kconfig.debug13
-rw-r--r--lib/atomic64_test.c2
-rw-r--r--lib/cpumask.c1
-rw-r--r--lib/list_debug.c9
-rw-r--r--lib/mpi/longlong.h2
-rw-r--r--lib/mpi/mpi-inline.h2
-rw-r--r--lib/mpi/mpi-internal.h8
-rw-r--r--lib/mpi/mpicoder.c39
-rw-r--r--lib/test_printf.c53
-rw-r--r--lib/test_static_keys.c62
-rw-r--r--lib/ucs2_string.c62
-rw-r--r--lib/vsprintf.c75
12 files changed, 274 insertions, 54 deletions
diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug
index 8bfd1aca7a3d..f28f7fad452f 100644
--- a/lib/Kconfig.debug
+++ b/lib/Kconfig.debug
@@ -1442,6 +1442,19 @@ config DEBUG_BLOCK_EXT_DEVT
1442 1442
1443 Say N if you are unsure. 1443 Say N if you are unsure.
1444 1444
1445config CPU_HOTPLUG_STATE_CONTROL
1446 bool "Enable CPU hotplug state control"
1447 depends on DEBUG_KERNEL
1448 depends on HOTPLUG_CPU
1449 default n
1450 help
1451 Allows to write steps between "offline" and "online" to the CPUs
1452 sysfs target file so states can be stepped granular. This is a debug
1453 option for now as the hotplug machinery cannot be stopped and
1454 restarted at arbitrary points yet.
1455
1456 Say N if your are unsure.
1457
1445config NOTIFIER_ERROR_INJECTION 1458config NOTIFIER_ERROR_INJECTION
1446 tristate "Notifier error injection" 1459 tristate "Notifier error injection"
1447 depends on DEBUG_KERNEL 1460 depends on DEBUG_KERNEL
diff --git a/lib/atomic64_test.c b/lib/atomic64_test.c
index d62de8bf022d..123481814320 100644
--- a/lib/atomic64_test.c
+++ b/lib/atomic64_test.c
@@ -17,7 +17,7 @@
17#include <linux/atomic.h> 17#include <linux/atomic.h>
18 18
19#ifdef CONFIG_X86 19#ifdef CONFIG_X86
20#include <asm/processor.h> /* for boot_cpu_has below */ 20#include <asm/cpufeature.h> /* for boot_cpu_has below */
21#endif 21#endif
22 22
23#define TEST(bit, op, c_op, val) \ 23#define TEST(bit, op, c_op, val) \
diff --git a/lib/cpumask.c b/lib/cpumask.c
index 5a70f6196f57..81dedaab36cc 100644
--- a/lib/cpumask.c
+++ b/lib/cpumask.c
@@ -41,6 +41,7 @@ int cpumask_any_but(const struct cpumask *mask, unsigned int cpu)
41 break; 41 break;
42 return i; 42 return i;
43} 43}
44EXPORT_SYMBOL(cpumask_any_but);
44 45
45/* These are not inline because of header tangles. */ 46/* These are not inline because of header tangles. */
46#ifdef CONFIG_CPUMASK_OFFSTACK 47#ifdef CONFIG_CPUMASK_OFFSTACK
diff --git a/lib/list_debug.c b/lib/list_debug.c
index 3345a089ef7b..3859bf63561c 100644
--- a/lib/list_debug.c
+++ b/lib/list_debug.c
@@ -12,13 +12,6 @@
12#include <linux/kernel.h> 12#include <linux/kernel.h>
13#include <linux/rculist.h> 13#include <linux/rculist.h>
14 14
15static struct list_head force_poison;
16void list_force_poison(struct list_head *entry)
17{
18 entry->next = &force_poison;
19 entry->prev = &force_poison;
20}
21
22/* 15/*
23 * Insert a new entry between two known consecutive entries. 16 * Insert a new entry between two known consecutive entries.
24 * 17 *
@@ -30,8 +23,6 @@ void __list_add(struct list_head *new,
30 struct list_head *prev, 23 struct list_head *prev,
31 struct list_head *next) 24 struct list_head *next)
32{ 25{
33 WARN(new->next == &force_poison || new->prev == &force_poison,
34 "list_add attempted on force-poisoned entry\n");
35 WARN(next->prev != prev, 26 WARN(next->prev != prev,
36 "list_add corruption. next->prev should be " 27 "list_add corruption. next->prev should be "
37 "prev (%p), but was %p. (next=%p).\n", 28 "prev (%p), but was %p. (next=%p).\n",
diff --git a/lib/mpi/longlong.h b/lib/mpi/longlong.h
index b90e255c2a68..93336502af08 100644
--- a/lib/mpi/longlong.h
+++ b/lib/mpi/longlong.h
@@ -216,7 +216,7 @@ extern UDItype __udiv_qrnnd(UDItype *, UDItype, UDItype, UDItype);
216 __asm__ ("%@ Inlined umul_ppmm\n" \ 216 __asm__ ("%@ Inlined umul_ppmm\n" \
217 "umull %r1, %r0, %r2, %r3" \ 217 "umull %r1, %r0, %r2, %r3" \
218 : "=&r" ((USItype)(xh)), \ 218 : "=&r" ((USItype)(xh)), \
219 "=r" ((USItype)(xl)) \ 219 "=&r" ((USItype)(xl)) \
220 : "r" ((USItype)(a)), \ 220 : "r" ((USItype)(a)), \
221 "r" ((USItype)(b)) \ 221 "r" ((USItype)(b)) \
222 : "r0", "r1") 222 : "r0", "r1")
diff --git a/lib/mpi/mpi-inline.h b/lib/mpi/mpi-inline.h
index e2b39852b30a..c245ea31f785 100644
--- a/lib/mpi/mpi-inline.h
+++ b/lib/mpi/mpi-inline.h
@@ -30,7 +30,7 @@
30#define G10_MPI_INLINE_H 30#define G10_MPI_INLINE_H
31 31
32#ifndef G10_MPI_INLINE_DECL 32#ifndef G10_MPI_INLINE_DECL
33#define G10_MPI_INLINE_DECL extern inline 33#define G10_MPI_INLINE_DECL static inline
34#endif 34#endif
35 35
36G10_MPI_INLINE_DECL mpi_limb_t 36G10_MPI_INLINE_DECL mpi_limb_t
diff --git a/lib/mpi/mpi-internal.h b/lib/mpi/mpi-internal.h
index c65dd1bff45a..7eceeddb3fb8 100644
--- a/lib/mpi/mpi-internal.h
+++ b/lib/mpi/mpi-internal.h
@@ -168,19 +168,19 @@ void mpi_rshift_limbs(MPI a, unsigned int count);
168int mpi_lshift_limbs(MPI a, unsigned int count); 168int mpi_lshift_limbs(MPI a, unsigned int count);
169 169
170/*-- mpihelp-add.c --*/ 170/*-- mpihelp-add.c --*/
171mpi_limb_t mpihelp_add_1(mpi_ptr_t res_ptr, mpi_ptr_t s1_ptr, 171static inline mpi_limb_t mpihelp_add_1(mpi_ptr_t res_ptr, mpi_ptr_t s1_ptr,
172 mpi_size_t s1_size, mpi_limb_t s2_limb); 172 mpi_size_t s1_size, mpi_limb_t s2_limb);
173mpi_limb_t mpihelp_add_n(mpi_ptr_t res_ptr, mpi_ptr_t s1_ptr, 173mpi_limb_t mpihelp_add_n(mpi_ptr_t res_ptr, mpi_ptr_t s1_ptr,
174 mpi_ptr_t s2_ptr, mpi_size_t size); 174 mpi_ptr_t s2_ptr, mpi_size_t size);
175mpi_limb_t mpihelp_add(mpi_ptr_t res_ptr, mpi_ptr_t s1_ptr, mpi_size_t s1_size, 175static inline mpi_limb_t mpihelp_add(mpi_ptr_t res_ptr, mpi_ptr_t s1_ptr, mpi_size_t s1_size,
176 mpi_ptr_t s2_ptr, mpi_size_t s2_size); 176 mpi_ptr_t s2_ptr, mpi_size_t s2_size);
177 177
178/*-- mpihelp-sub.c --*/ 178/*-- mpihelp-sub.c --*/
179mpi_limb_t mpihelp_sub_1(mpi_ptr_t res_ptr, mpi_ptr_t s1_ptr, 179static inline mpi_limb_t mpihelp_sub_1(mpi_ptr_t res_ptr, mpi_ptr_t s1_ptr,
180 mpi_size_t s1_size, mpi_limb_t s2_limb); 180 mpi_size_t s1_size, mpi_limb_t s2_limb);
181mpi_limb_t mpihelp_sub_n(mpi_ptr_t res_ptr, mpi_ptr_t s1_ptr, 181mpi_limb_t mpihelp_sub_n(mpi_ptr_t res_ptr, mpi_ptr_t s1_ptr,
182 mpi_ptr_t s2_ptr, mpi_size_t size); 182 mpi_ptr_t s2_ptr, mpi_size_t size);
183mpi_limb_t mpihelp_sub(mpi_ptr_t res_ptr, mpi_ptr_t s1_ptr, mpi_size_t s1_size, 183static inline mpi_limb_t mpihelp_sub(mpi_ptr_t res_ptr, mpi_ptr_t s1_ptr, mpi_size_t s1_size,
184 mpi_ptr_t s2_ptr, mpi_size_t s2_size); 184 mpi_ptr_t s2_ptr, mpi_size_t s2_size);
185 185
186/*-- mpihelp-cmp.c --*/ 186/*-- mpihelp-cmp.c --*/
diff --git a/lib/mpi/mpicoder.c b/lib/mpi/mpicoder.c
index ec533a6c77b5..eb15e7dc7b65 100644
--- a/lib/mpi/mpicoder.c
+++ b/lib/mpi/mpicoder.c
@@ -128,6 +128,23 @@ leave:
128} 128}
129EXPORT_SYMBOL_GPL(mpi_read_from_buffer); 129EXPORT_SYMBOL_GPL(mpi_read_from_buffer);
130 130
131static int count_lzeros(MPI a)
132{
133 mpi_limb_t alimb;
134 int i, lzeros = 0;
135
136 for (i = a->nlimbs - 1; i >= 0; i--) {
137 alimb = a->d[i];
138 if (alimb == 0) {
139 lzeros += sizeof(mpi_limb_t);
140 } else {
141 lzeros += count_leading_zeros(alimb) / 8;
142 break;
143 }
144 }
145 return lzeros;
146}
147
131/** 148/**
132 * mpi_read_buffer() - read MPI to a bufer provided by user (msb first) 149 * mpi_read_buffer() - read MPI to a bufer provided by user (msb first)
133 * 150 *
@@ -148,7 +165,7 @@ int mpi_read_buffer(MPI a, uint8_t *buf, unsigned buf_len, unsigned *nbytes,
148 uint8_t *p; 165 uint8_t *p;
149 mpi_limb_t alimb; 166 mpi_limb_t alimb;
150 unsigned int n = mpi_get_size(a); 167 unsigned int n = mpi_get_size(a);
151 int i, lzeros = 0; 168 int i, lzeros;
152 169
153 if (!buf || !nbytes) 170 if (!buf || !nbytes)
154 return -EINVAL; 171 return -EINVAL;
@@ -156,14 +173,7 @@ int mpi_read_buffer(MPI a, uint8_t *buf, unsigned buf_len, unsigned *nbytes,
156 if (sign) 173 if (sign)
157 *sign = a->sign; 174 *sign = a->sign;
158 175
159 p = (void *)&a->d[a->nlimbs] - 1; 176 lzeros = count_lzeros(a);
160
161 for (i = a->nlimbs * sizeof(alimb) - 1; i >= 0; i--, p--) {
162 if (!*p)
163 lzeros++;
164 else
165 break;
166 }
167 177
168 if (buf_len < n - lzeros) { 178 if (buf_len < n - lzeros) {
169 *nbytes = n - lzeros; 179 *nbytes = n - lzeros;
@@ -351,7 +361,7 @@ int mpi_write_to_sgl(MPI a, struct scatterlist *sgl, unsigned *nbytes,
351 u8 *p, *p2; 361 u8 *p, *p2;
352 mpi_limb_t alimb, alimb2; 362 mpi_limb_t alimb, alimb2;
353 unsigned int n = mpi_get_size(a); 363 unsigned int n = mpi_get_size(a);
354 int i, x, y = 0, lzeros = 0, buf_len; 364 int i, x, y = 0, lzeros, buf_len;
355 365
356 if (!nbytes) 366 if (!nbytes)
357 return -EINVAL; 367 return -EINVAL;
@@ -359,14 +369,7 @@ int mpi_write_to_sgl(MPI a, struct scatterlist *sgl, unsigned *nbytes,
359 if (sign) 369 if (sign)
360 *sign = a->sign; 370 *sign = a->sign;
361 371
362 p = (void *)&a->d[a->nlimbs] - 1; 372 lzeros = count_lzeros(a);
363
364 for (i = a->nlimbs * sizeof(alimb) - 1; i >= 0; i--, p--) {
365 if (!*p)
366 lzeros++;
367 else
368 break;
369 }
370 373
371 if (*nbytes < n - lzeros) { 374 if (*nbytes < n - lzeros) {
372 *nbytes = n - lzeros; 375 *nbytes = n - lzeros;
diff --git a/lib/test_printf.c b/lib/test_printf.c
index 4f6ae60433bc..563f10e6876a 100644
--- a/lib/test_printf.c
+++ b/lib/test_printf.c
@@ -17,6 +17,9 @@
17#include <linux/socket.h> 17#include <linux/socket.h>
18#include <linux/in.h> 18#include <linux/in.h>
19 19
20#include <linux/gfp.h>
21#include <linux/mm.h>
22
20#define BUF_SIZE 256 23#define BUF_SIZE 256
21#define PAD_SIZE 16 24#define PAD_SIZE 16
22#define FILL_CHAR '$' 25#define FILL_CHAR '$'
@@ -411,6 +414,55 @@ netdev_features(void)
411} 414}
412 415
413static void __init 416static void __init
417flags(void)
418{
419 unsigned long flags;
420 gfp_t gfp;
421 char *cmp_buffer;
422
423 flags = 0;
424 test("", "%pGp", &flags);
425
426 /* Page flags should filter the zone id */
427 flags = 1UL << NR_PAGEFLAGS;
428 test("", "%pGp", &flags);
429
430 flags |= 1UL << PG_uptodate | 1UL << PG_dirty | 1UL << PG_lru
431 | 1UL << PG_active | 1UL << PG_swapbacked;
432 test("uptodate|dirty|lru|active|swapbacked", "%pGp", &flags);
433
434
435 flags = VM_READ | VM_EXEC | VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC
436 | VM_DENYWRITE;
437 test("read|exec|mayread|maywrite|mayexec|denywrite", "%pGv", &flags);
438
439 gfp = GFP_TRANSHUGE;
440 test("GFP_TRANSHUGE", "%pGg", &gfp);
441
442 gfp = GFP_ATOMIC|__GFP_DMA;
443 test("GFP_ATOMIC|GFP_DMA", "%pGg", &gfp);
444
445 gfp = __GFP_ATOMIC;
446 test("__GFP_ATOMIC", "%pGg", &gfp);
447
448 cmp_buffer = kmalloc(BUF_SIZE, GFP_KERNEL);
449 if (!cmp_buffer)
450 return;
451
452 /* Any flags not translated by the table should remain numeric */
453 gfp = ~__GFP_BITS_MASK;
454 snprintf(cmp_buffer, BUF_SIZE, "%#lx", (unsigned long) gfp);
455 test(cmp_buffer, "%pGg", &gfp);
456
457 snprintf(cmp_buffer, BUF_SIZE, "__GFP_ATOMIC|%#lx",
458 (unsigned long) gfp);
459 gfp |= __GFP_ATOMIC;
460 test(cmp_buffer, "%pGg", &gfp);
461
462 kfree(cmp_buffer);
463}
464
465static void __init
414test_pointer(void) 466test_pointer(void)
415{ 467{
416 plain(); 468 plain();
@@ -428,6 +480,7 @@ test_pointer(void)
428 struct_clk(); 480 struct_clk();
429 bitmap(); 481 bitmap();
430 netdev_features(); 482 netdev_features();
483 flags();
431} 484}
432 485
433static int __init 486static int __init
diff --git a/lib/test_static_keys.c b/lib/test_static_keys.c
index c61b299e367f..915d75df2086 100644
--- a/lib/test_static_keys.c
+++ b/lib/test_static_keys.c
@@ -46,8 +46,11 @@ struct test_key {
46 bool (*test_key)(void); 46 bool (*test_key)(void);
47}; 47};
48 48
49#define test_key_func(key, branch) \ 49#define test_key_func(key, branch) \
50 ({bool func(void) { return branch(key); } func; }) 50static bool key ## _ ## branch(void) \
51{ \
52 return branch(&key); \
53}
51 54
52static void invert_key(struct static_key *key) 55static void invert_key(struct static_key *key)
53{ 56{
@@ -92,6 +95,25 @@ static int verify_keys(struct test_key *keys, int size, bool invert)
92 return 0; 95 return 0;
93} 96}
94 97
98test_key_func(old_true_key, static_key_true)
99test_key_func(old_false_key, static_key_false)
100test_key_func(true_key, static_branch_likely)
101test_key_func(true_key, static_branch_unlikely)
102test_key_func(false_key, static_branch_likely)
103test_key_func(false_key, static_branch_unlikely)
104test_key_func(base_old_true_key, static_key_true)
105test_key_func(base_inv_old_true_key, static_key_true)
106test_key_func(base_old_false_key, static_key_false)
107test_key_func(base_inv_old_false_key, static_key_false)
108test_key_func(base_true_key, static_branch_likely)
109test_key_func(base_true_key, static_branch_unlikely)
110test_key_func(base_inv_true_key, static_branch_likely)
111test_key_func(base_inv_true_key, static_branch_unlikely)
112test_key_func(base_false_key, static_branch_likely)
113test_key_func(base_false_key, static_branch_unlikely)
114test_key_func(base_inv_false_key, static_branch_likely)
115test_key_func(base_inv_false_key, static_branch_unlikely)
116
95static int __init test_static_key_init(void) 117static int __init test_static_key_init(void)
96{ 118{
97 int ret; 119 int ret;
@@ -102,95 +124,95 @@ static int __init test_static_key_init(void)
102 { 124 {
103 .init_state = true, 125 .init_state = true,
104 .key = &old_true_key, 126 .key = &old_true_key,
105 .test_key = test_key_func(&old_true_key, static_key_true), 127 .test_key = &old_true_key_static_key_true,
106 }, 128 },
107 { 129 {
108 .init_state = false, 130 .init_state = false,
109 .key = &old_false_key, 131 .key = &old_false_key,
110 .test_key = test_key_func(&old_false_key, static_key_false), 132 .test_key = &old_false_key_static_key_false,
111 }, 133 },
112 /* internal keys - new keys */ 134 /* internal keys - new keys */
113 { 135 {
114 .init_state = true, 136 .init_state = true,
115 .key = &true_key.key, 137 .key = &true_key.key,
116 .test_key = test_key_func(&true_key, static_branch_likely), 138 .test_key = &true_key_static_branch_likely,
117 }, 139 },
118 { 140 {
119 .init_state = true, 141 .init_state = true,
120 .key = &true_key.key, 142 .key = &true_key.key,
121 .test_key = test_key_func(&true_key, static_branch_unlikely), 143 .test_key = &true_key_static_branch_unlikely,
122 }, 144 },
123 { 145 {
124 .init_state = false, 146 .init_state = false,
125 .key = &false_key.key, 147 .key = &false_key.key,
126 .test_key = test_key_func(&false_key, static_branch_likely), 148 .test_key = &false_key_static_branch_likely,
127 }, 149 },
128 { 150 {
129 .init_state = false, 151 .init_state = false,
130 .key = &false_key.key, 152 .key = &false_key.key,
131 .test_key = test_key_func(&false_key, static_branch_unlikely), 153 .test_key = &false_key_static_branch_unlikely,
132 }, 154 },
133 /* external keys - old keys */ 155 /* external keys - old keys */
134 { 156 {
135 .init_state = true, 157 .init_state = true,
136 .key = &base_old_true_key, 158 .key = &base_old_true_key,
137 .test_key = test_key_func(&base_old_true_key, static_key_true), 159 .test_key = &base_old_true_key_static_key_true,
138 }, 160 },
139 { 161 {
140 .init_state = false, 162 .init_state = false,
141 .key = &base_inv_old_true_key, 163 .key = &base_inv_old_true_key,
142 .test_key = test_key_func(&base_inv_old_true_key, static_key_true), 164 .test_key = &base_inv_old_true_key_static_key_true,
143 }, 165 },
144 { 166 {
145 .init_state = false, 167 .init_state = false,
146 .key = &base_old_false_key, 168 .key = &base_old_false_key,
147 .test_key = test_key_func(&base_old_false_key, static_key_false), 169 .test_key = &base_old_false_key_static_key_false,
148 }, 170 },
149 { 171 {
150 .init_state = true, 172 .init_state = true,
151 .key = &base_inv_old_false_key, 173 .key = &base_inv_old_false_key,
152 .test_key = test_key_func(&base_inv_old_false_key, static_key_false), 174 .test_key = &base_inv_old_false_key_static_key_false,
153 }, 175 },
154 /* external keys - new keys */ 176 /* external keys - new keys */
155 { 177 {
156 .init_state = true, 178 .init_state = true,
157 .key = &base_true_key.key, 179 .key = &base_true_key.key,
158 .test_key = test_key_func(&base_true_key, static_branch_likely), 180 .test_key = &base_true_key_static_branch_likely,
159 }, 181 },
160 { 182 {
161 .init_state = true, 183 .init_state = true,
162 .key = &base_true_key.key, 184 .key = &base_true_key.key,
163 .test_key = test_key_func(&base_true_key, static_branch_unlikely), 185 .test_key = &base_true_key_static_branch_unlikely,
164 }, 186 },
165 { 187 {
166 .init_state = false, 188 .init_state = false,
167 .key = &base_inv_true_key.key, 189 .key = &base_inv_true_key.key,
168 .test_key = test_key_func(&base_inv_true_key, static_branch_likely), 190 .test_key = &base_inv_true_key_static_branch_likely,
169 }, 191 },
170 { 192 {
171 .init_state = false, 193 .init_state = false,
172 .key = &base_inv_true_key.key, 194 .key = &base_inv_true_key.key,
173 .test_key = test_key_func(&base_inv_true_key, static_branch_unlikely), 195 .test_key = &base_inv_true_key_static_branch_unlikely,
174 }, 196 },
175 { 197 {
176 .init_state = false, 198 .init_state = false,
177 .key = &base_false_key.key, 199 .key = &base_false_key.key,
178 .test_key = test_key_func(&base_false_key, static_branch_likely), 200 .test_key = &base_false_key_static_branch_likely,
179 }, 201 },
180 { 202 {
181 .init_state = false, 203 .init_state = false,
182 .key = &base_false_key.key, 204 .key = &base_false_key.key,
183 .test_key = test_key_func(&base_false_key, static_branch_unlikely), 205 .test_key = &base_false_key_static_branch_unlikely,
184 }, 206 },
185 { 207 {
186 .init_state = true, 208 .init_state = true,
187 .key = &base_inv_false_key.key, 209 .key = &base_inv_false_key.key,
188 .test_key = test_key_func(&base_inv_false_key, static_branch_likely), 210 .test_key = &base_inv_false_key_static_branch_likely,
189 }, 211 },
190 { 212 {
191 .init_state = true, 213 .init_state = true,
192 .key = &base_inv_false_key.key, 214 .key = &base_inv_false_key.key,
193 .test_key = test_key_func(&base_inv_false_key, static_branch_unlikely), 215 .test_key = &base_inv_false_key_static_branch_unlikely,
194 }, 216 },
195 }; 217 };
196 218
diff --git a/lib/ucs2_string.c b/lib/ucs2_string.c
index 6f500ef2301d..f0b323abb4c6 100644
--- a/lib/ucs2_string.c
+++ b/lib/ucs2_string.c
@@ -49,3 +49,65 @@ ucs2_strncmp(const ucs2_char_t *a, const ucs2_char_t *b, size_t len)
49 } 49 }
50} 50}
51EXPORT_SYMBOL(ucs2_strncmp); 51EXPORT_SYMBOL(ucs2_strncmp);
52
53unsigned long
54ucs2_utf8size(const ucs2_char_t *src)
55{
56 unsigned long i;
57 unsigned long j = 0;
58
59 for (i = 0; i < ucs2_strlen(src); i++) {
60 u16 c = src[i];
61
62 if (c >= 0x800)
63 j += 3;
64 else if (c >= 0x80)
65 j += 2;
66 else
67 j += 1;
68 }
69
70 return j;
71}
72EXPORT_SYMBOL(ucs2_utf8size);
73
74/*
75 * copy at most maxlength bytes of whole utf8 characters to dest from the
76 * ucs2 string src.
77 *
78 * The return value is the number of characters copied, not including the
79 * final NUL character.
80 */
81unsigned long
82ucs2_as_utf8(u8 *dest, const ucs2_char_t *src, unsigned long maxlength)
83{
84 unsigned int i;
85 unsigned long j = 0;
86 unsigned long limit = ucs2_strnlen(src, maxlength);
87
88 for (i = 0; maxlength && i < limit; i++) {
89 u16 c = src[i];
90
91 if (c >= 0x800) {
92 if (maxlength < 3)
93 break;
94 maxlength -= 3;
95 dest[j++] = 0xe0 | (c & 0xf000) >> 12;
96 dest[j++] = 0x80 | (c & 0x0fc0) >> 6;
97 dest[j++] = 0x80 | (c & 0x003f);
98 } else if (c >= 0x80) {
99 if (maxlength < 2)
100 break;
101 maxlength -= 2;
102 dest[j++] = 0xc0 | (c & 0x7c0) >> 6;
103 dest[j++] = 0x80 | (c & 0x03f);
104 } else {
105 maxlength -= 1;
106 dest[j++] = c & 0x7f;
107 }
108 }
109 if (maxlength)
110 dest[j] = '\0';
111 return j;
112}
113EXPORT_SYMBOL(ucs2_as_utf8);
diff --git a/lib/vsprintf.c b/lib/vsprintf.c
index f44e178e6ede..525c8e19bda2 100644
--- a/lib/vsprintf.c
+++ b/lib/vsprintf.c
@@ -35,6 +35,8 @@
35#include <linux/blkdev.h> 35#include <linux/blkdev.h>
36#endif 36#endif
37 37
38#include "../mm/internal.h" /* For the trace_print_flags arrays */
39
38#include <asm/page.h> /* for PAGE_SIZE */ 40#include <asm/page.h> /* for PAGE_SIZE */
39#include <asm/sections.h> /* for dereference_function_descriptor() */ 41#include <asm/sections.h> /* for dereference_function_descriptor() */
40#include <asm/byteorder.h> /* cpu_to_le16 */ 42#include <asm/byteorder.h> /* cpu_to_le16 */
@@ -1407,6 +1409,72 @@ char *clock(char *buf, char *end, struct clk *clk, struct printf_spec spec,
1407 } 1409 }
1408} 1410}
1409 1411
1412static
1413char *format_flags(char *buf, char *end, unsigned long flags,
1414 const struct trace_print_flags *names)
1415{
1416 unsigned long mask;
1417 const struct printf_spec strspec = {
1418 .field_width = -1,
1419 .precision = -1,
1420 };
1421 const struct printf_spec numspec = {
1422 .flags = SPECIAL|SMALL,
1423 .field_width = -1,
1424 .precision = -1,
1425 .base = 16,
1426 };
1427
1428 for ( ; flags && names->name; names++) {
1429 mask = names->mask;
1430 if ((flags & mask) != mask)
1431 continue;
1432
1433 buf = string(buf, end, names->name, strspec);
1434
1435 flags &= ~mask;
1436 if (flags) {
1437 if (buf < end)
1438 *buf = '|';
1439 buf++;
1440 }
1441 }
1442
1443 if (flags)
1444 buf = number(buf, end, flags, numspec);
1445
1446 return buf;
1447}
1448
1449static noinline_for_stack
1450char *flags_string(char *buf, char *end, void *flags_ptr, const char *fmt)
1451{
1452 unsigned long flags;
1453 const struct trace_print_flags *names;
1454
1455 switch (fmt[1]) {
1456 case 'p':
1457 flags = *(unsigned long *)flags_ptr;
1458 /* Remove zone id */
1459 flags &= (1UL << NR_PAGEFLAGS) - 1;
1460 names = pageflag_names;
1461 break;
1462 case 'v':
1463 flags = *(unsigned long *)flags_ptr;
1464 names = vmaflag_names;
1465 break;
1466 case 'g':
1467 flags = *(gfp_t *)flags_ptr;
1468 names = gfpflag_names;
1469 break;
1470 default:
1471 WARN_ONCE(1, "Unsupported flags modifier: %c\n", fmt[1]);
1472 return buf;
1473 }
1474
1475 return format_flags(buf, end, flags, names);
1476}
1477
1410int kptr_restrict __read_mostly; 1478int kptr_restrict __read_mostly;
1411 1479
1412/* 1480/*
@@ -1495,6 +1563,11 @@ int kptr_restrict __read_mostly;
1495 * - 'Cn' For a clock, it prints the name (Common Clock Framework) or address 1563 * - 'Cn' For a clock, it prints the name (Common Clock Framework) or address
1496 * (legacy clock framework) of the clock 1564 * (legacy clock framework) of the clock
1497 * - 'Cr' For a clock, it prints the current rate of the clock 1565 * - 'Cr' For a clock, it prints the current rate of the clock
1566 * - 'G' For flags to be printed as a collection of symbolic strings that would
1567 * construct the specific value. Supported flags given by option:
1568 * p page flags (see struct page) given as pointer to unsigned long
1569 * g gfp flags (GFP_* and __GFP_*) given as pointer to gfp_t
1570 * v vma flags (VM_*) given as pointer to unsigned long
1498 * 1571 *
1499 * ** Please update also Documentation/printk-formats.txt when making changes ** 1572 * ** Please update also Documentation/printk-formats.txt when making changes **
1500 * 1573 *
@@ -1648,6 +1721,8 @@ char *pointer(const char *fmt, char *buf, char *end, void *ptr,
1648 return bdev_name(buf, end, ptr, spec, fmt); 1721 return bdev_name(buf, end, ptr, spec, fmt);
1649#endif 1722#endif
1650 1723
1724 case 'G':
1725 return flags_string(buf, end, ptr, fmt);
1651 } 1726 }
1652 spec.flags |= SMALL; 1727 spec.flags |= SMALL;
1653 if (spec.field_width == -1) { 1728 if (spec.field_width == -1) {