aboutsummaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/Kconfig.debug28
-rw-r--r--lib/Kconfig.ubsan4
-rw-r--r--lib/atomic64_test.c2
-rw-r--r--lib/cpumask.c1
-rw-r--r--lib/devres.c2
-rw-r--r--lib/dump_stack.c7
-rw-r--r--lib/extable.c50
-rw-r--r--lib/klist.c6
-rw-r--r--lib/kobject.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/radix-tree.c12
-rw-r--r--lib/scatterlist.c6
-rw-r--r--lib/test-string_helpers.c67
-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.c101
21 files changed, 417 insertions, 107 deletions
diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug
index ecb9e75614bf..f28f7fad452f 100644
--- a/lib/Kconfig.debug
+++ b/lib/Kconfig.debug
@@ -1400,6 +1400,21 @@ config RCU_EQS_DEBUG
1400 1400
1401endmenu # "RCU Debugging" 1401endmenu # "RCU Debugging"
1402 1402
1403config DEBUG_WQ_FORCE_RR_CPU
1404 bool "Force round-robin CPU selection for unbound work items"
1405 depends on DEBUG_KERNEL
1406 default n
1407 help
1408 Workqueue used to implicitly guarantee that work items queued
1409 without explicit CPU specified are put on the local CPU. This
1410 guarantee is no longer true and while local CPU is still
1411 preferred work items may be put on foreign CPUs. Kernel
1412 parameter "workqueue.debug_force_rr_cpu" is added to force
1413 round-robin CPU selection to flush out usages which depend on the
1414 now broken guarantee. This config option enables the debug
1415 feature by default. When enabled, memory and cache locality will
1416 be impacted.
1417
1403config DEBUG_BLOCK_EXT_DEVT 1418config DEBUG_BLOCK_EXT_DEVT
1404 bool "Force extended block device numbers and spread them" 1419 bool "Force extended block device numbers and spread them"
1405 depends on DEBUG_KERNEL 1420 depends on DEBUG_KERNEL
@@ -1427,6 +1442,19 @@ config DEBUG_BLOCK_EXT_DEVT
1427 1442
1428 Say N if you are unsure. 1443 Say N if you are unsure.
1429 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
1430config NOTIFIER_ERROR_INJECTION 1458config NOTIFIER_ERROR_INJECTION
1431 tristate "Notifier error injection" 1459 tristate "Notifier error injection"
1432 depends on DEBUG_KERNEL 1460 depends on DEBUG_KERNEL
diff --git a/lib/Kconfig.ubsan b/lib/Kconfig.ubsan
index 49518fb48cab..e07c1ba9ba13 100644
--- a/lib/Kconfig.ubsan
+++ b/lib/Kconfig.ubsan
@@ -18,6 +18,8 @@ config UBSAN_SANITIZE_ALL
18 This option activates instrumentation for the entire kernel. 18 This option activates instrumentation for the entire kernel.
19 If you don't enable this option, you have to explicitly specify 19 If you don't enable this option, you have to explicitly specify
20 UBSAN_SANITIZE := y for the files/directories you want to check for UB. 20 UBSAN_SANITIZE := y for the files/directories you want to check for UB.
21 Enabling this option will get kernel image size increased
22 significantly.
21 23
22config UBSAN_ALIGNMENT 24config UBSAN_ALIGNMENT
23 bool "Enable checking of pointers alignment" 25 bool "Enable checking of pointers alignment"
@@ -25,5 +27,5 @@ config UBSAN_ALIGNMENT
25 default y if !HAVE_EFFICIENT_UNALIGNED_ACCESS 27 default y if !HAVE_EFFICIENT_UNALIGNED_ACCESS
26 help 28 help
27 This option enables detection of unaligned memory accesses. 29 This option enables detection of unaligned memory accesses.
28 Enabling this option on architectures that support unalligned 30 Enabling this option on architectures that support unaligned
29 accesses may produce a lot of false positives. 31 accesses may produce a lot of false positives.
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/devres.c b/lib/devres.c
index 8c85672639d3..cb1464c411a2 100644
--- a/lib/devres.c
+++ b/lib/devres.c
@@ -236,7 +236,7 @@ struct pcim_iomap_devres {
236 236
237static void pcim_iomap_release(struct device *gendev, void *res) 237static void pcim_iomap_release(struct device *gendev, void *res)
238{ 238{
239 struct pci_dev *dev = container_of(gendev, struct pci_dev, dev); 239 struct pci_dev *dev = to_pci_dev(gendev);
240 struct pcim_iomap_devres *this = res; 240 struct pcim_iomap_devres *this = res;
241 int i; 241 int i;
242 242
diff --git a/lib/dump_stack.c b/lib/dump_stack.c
index 6745c6230db3..c30d07e99dba 100644
--- a/lib/dump_stack.c
+++ b/lib/dump_stack.c
@@ -25,6 +25,7 @@ static atomic_t dump_lock = ATOMIC_INIT(-1);
25 25
26asmlinkage __visible void dump_stack(void) 26asmlinkage __visible void dump_stack(void)
27{ 27{
28 unsigned long flags;
28 int was_locked; 29 int was_locked;
29 int old; 30 int old;
30 int cpu; 31 int cpu;
@@ -33,9 +34,8 @@ asmlinkage __visible void dump_stack(void)
33 * Permit this cpu to perform nested stack dumps while serialising 34 * Permit this cpu to perform nested stack dumps while serialising
34 * against other CPUs 35 * against other CPUs
35 */ 36 */
36 preempt_disable();
37
38retry: 37retry:
38 local_irq_save(flags);
39 cpu = smp_processor_id(); 39 cpu = smp_processor_id();
40 old = atomic_cmpxchg(&dump_lock, -1, cpu); 40 old = atomic_cmpxchg(&dump_lock, -1, cpu);
41 if (old == -1) { 41 if (old == -1) {
@@ -43,6 +43,7 @@ retry:
43 } else if (old == cpu) { 43 } else if (old == cpu) {
44 was_locked = 1; 44 was_locked = 1;
45 } else { 45 } else {
46 local_irq_restore(flags);
46 cpu_relax(); 47 cpu_relax();
47 goto retry; 48 goto retry;
48 } 49 }
@@ -52,7 +53,7 @@ retry:
52 if (!was_locked) 53 if (!was_locked)
53 atomic_set(&dump_lock, -1); 54 atomic_set(&dump_lock, -1);
54 55
55 preempt_enable(); 56 local_irq_restore(flags);
56} 57}
57#else 58#else
58asmlinkage __visible void dump_stack(void) 59asmlinkage __visible void dump_stack(void)
diff --git a/lib/extable.c b/lib/extable.c
index 4cac81ec225e..0be02ad561e9 100644
--- a/lib/extable.c
+++ b/lib/extable.c
@@ -14,7 +14,37 @@
14#include <linux/sort.h> 14#include <linux/sort.h>
15#include <asm/uaccess.h> 15#include <asm/uaccess.h>
16 16
17#ifndef ARCH_HAS_RELATIVE_EXTABLE
18#define ex_to_insn(x) ((x)->insn)
19#else
20static inline unsigned long ex_to_insn(const struct exception_table_entry *x)
21{
22 return (unsigned long)&x->insn + x->insn;
23}
24#endif
25
17#ifndef ARCH_HAS_SORT_EXTABLE 26#ifndef ARCH_HAS_SORT_EXTABLE
27#ifndef ARCH_HAS_RELATIVE_EXTABLE
28#define swap_ex NULL
29#else
30static void swap_ex(void *a, void *b, int size)
31{
32 struct exception_table_entry *x = a, *y = b, tmp;
33 int delta = b - a;
34
35 tmp = *x;
36 x->insn = y->insn + delta;
37 y->insn = tmp.insn - delta;
38
39#ifdef swap_ex_entry_fixup
40 swap_ex_entry_fixup(x, y, tmp, delta);
41#else
42 x->fixup = y->fixup + delta;
43 y->fixup = tmp.fixup - delta;
44#endif
45}
46#endif /* ARCH_HAS_RELATIVE_EXTABLE */
47
18/* 48/*
19 * The exception table needs to be sorted so that the binary 49 * The exception table needs to be sorted so that the binary
20 * search that we use to find entries in it works properly. 50 * search that we use to find entries in it works properly.
@@ -26,9 +56,9 @@ static int cmp_ex(const void *a, const void *b)
26 const struct exception_table_entry *x = a, *y = b; 56 const struct exception_table_entry *x = a, *y = b;
27 57
28 /* avoid overflow */ 58 /* avoid overflow */
29 if (x->insn > y->insn) 59 if (ex_to_insn(x) > ex_to_insn(y))
30 return 1; 60 return 1;
31 if (x->insn < y->insn) 61 if (ex_to_insn(x) < ex_to_insn(y))
32 return -1; 62 return -1;
33 return 0; 63 return 0;
34} 64}
@@ -37,7 +67,7 @@ void sort_extable(struct exception_table_entry *start,
37 struct exception_table_entry *finish) 67 struct exception_table_entry *finish)
38{ 68{
39 sort(start, finish - start, sizeof(struct exception_table_entry), 69 sort(start, finish - start, sizeof(struct exception_table_entry),
40 cmp_ex, NULL); 70 cmp_ex, swap_ex);
41} 71}
42 72
43#ifdef CONFIG_MODULES 73#ifdef CONFIG_MODULES
@@ -48,13 +78,15 @@ void sort_extable(struct exception_table_entry *start,
48void trim_init_extable(struct module *m) 78void trim_init_extable(struct module *m)
49{ 79{
50 /*trim the beginning*/ 80 /*trim the beginning*/
51 while (m->num_exentries && within_module_init(m->extable[0].insn, m)) { 81 while (m->num_exentries &&
82 within_module_init(ex_to_insn(&m->extable[0]), m)) {
52 m->extable++; 83 m->extable++;
53 m->num_exentries--; 84 m->num_exentries--;
54 } 85 }
55 /*trim the end*/ 86 /*trim the end*/
56 while (m->num_exentries && 87 while (m->num_exentries &&
57 within_module_init(m->extable[m->num_exentries-1].insn, m)) 88 within_module_init(ex_to_insn(&m->extable[m->num_exentries - 1]),
89 m))
58 m->num_exentries--; 90 m->num_exentries--;
59} 91}
60#endif /* CONFIG_MODULES */ 92#endif /* CONFIG_MODULES */
@@ -81,13 +113,13 @@ search_extable(const struct exception_table_entry *first,
81 * careful, the distance between value and insn 113 * careful, the distance between value and insn
82 * can be larger than MAX_LONG: 114 * can be larger than MAX_LONG:
83 */ 115 */
84 if (mid->insn < value) 116 if (ex_to_insn(mid) < value)
85 first = mid + 1; 117 first = mid + 1;
86 else if (mid->insn > value) 118 else if (ex_to_insn(mid) > value)
87 last = mid - 1; 119 last = mid - 1;
88 else 120 else
89 return mid; 121 return mid;
90 } 122 }
91 return NULL; 123 return NULL;
92} 124}
93#endif 125#endif
diff --git a/lib/klist.c b/lib/klist.c
index d74cf7a29afd..0507fa5d84c5 100644
--- a/lib/klist.c
+++ b/lib/klist.c
@@ -282,9 +282,9 @@ void klist_iter_init_node(struct klist *k, struct klist_iter *i,
282 struct klist_node *n) 282 struct klist_node *n)
283{ 283{
284 i->i_klist = k; 284 i->i_klist = k;
285 i->i_cur = n; 285 i->i_cur = NULL;
286 if (n) 286 if (n && kref_get_unless_zero(&n->n_ref))
287 kref_get(&n->n_ref); 287 i->i_cur = n;
288} 288}
289EXPORT_SYMBOL_GPL(klist_iter_init_node); 289EXPORT_SYMBOL_GPL(klist_iter_init_node);
290 290
diff --git a/lib/kobject.c b/lib/kobject.c
index 7cbccd2b4c72..445dcaeb0f56 100644
--- a/lib/kobject.c
+++ b/lib/kobject.c
@@ -861,6 +861,7 @@ struct kobject *kset_find_obj(struct kset *kset, const char *name)
861 spin_unlock(&kset->list_lock); 861 spin_unlock(&kset->list_lock);
862 return ret; 862 return ret;
863} 863}
864EXPORT_SYMBOL_GPL(kset_find_obj);
864 865
865static void kset_release(struct kobject *kobj) 866static void kset_release(struct kobject *kobj)
866{ 867{
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/radix-tree.c b/lib/radix-tree.c
index fcf5d98574ce..6b79e9026e24 100644
--- a/lib/radix-tree.c
+++ b/lib/radix-tree.c
@@ -1019,9 +1019,13 @@ radix_tree_gang_lookup(struct radix_tree_root *root, void **results,
1019 return 0; 1019 return 0;
1020 1020
1021 radix_tree_for_each_slot(slot, root, &iter, first_index) { 1021 radix_tree_for_each_slot(slot, root, &iter, first_index) {
1022 results[ret] = indirect_to_ptr(rcu_dereference_raw(*slot)); 1022 results[ret] = rcu_dereference_raw(*slot);
1023 if (!results[ret]) 1023 if (!results[ret])
1024 continue; 1024 continue;
1025 if (radix_tree_is_indirect_ptr(results[ret])) {
1026 slot = radix_tree_iter_retry(&iter);
1027 continue;
1028 }
1025 if (++ret == max_items) 1029 if (++ret == max_items)
1026 break; 1030 break;
1027 } 1031 }
@@ -1098,9 +1102,13 @@ radix_tree_gang_lookup_tag(struct radix_tree_root *root, void **results,
1098 return 0; 1102 return 0;
1099 1103
1100 radix_tree_for_each_tagged(slot, root, &iter, first_index, tag) { 1104 radix_tree_for_each_tagged(slot, root, &iter, first_index, tag) {
1101 results[ret] = indirect_to_ptr(rcu_dereference_raw(*slot)); 1105 results[ret] = rcu_dereference_raw(*slot);
1102 if (!results[ret]) 1106 if (!results[ret])
1103 continue; 1107 continue;
1108 if (radix_tree_is_indirect_ptr(results[ret])) {
1109 slot = radix_tree_iter_retry(&iter);
1110 continue;
1111 }
1104 if (++ret == max_items) 1112 if (++ret == max_items)
1105 break; 1113 break;
1106 } 1114 }
diff --git a/lib/scatterlist.c b/lib/scatterlist.c
index bafa9933fa76..004fc70fc56a 100644
--- a/lib/scatterlist.c
+++ b/lib/scatterlist.c
@@ -598,9 +598,9 @@ EXPORT_SYMBOL(sg_miter_next);
598 * 598 *
599 * Description: 599 * Description:
600 * Stops mapping iterator @miter. @miter should have been started 600 * Stops mapping iterator @miter. @miter should have been started
601 * started using sg_miter_start(). A stopped iteration can be 601 * using sg_miter_start(). A stopped iteration can be resumed by
602 * resumed by calling sg_miter_next() on it. This is useful when 602 * calling sg_miter_next() on it. This is useful when resources (kmap)
603 * resources (kmap) need to be released during iteration. 603 * need to be released during iteration.
604 * 604 *
605 * Context: 605 * Context:
606 * Preemption disabled if the SG_MITER_ATOMIC is set. Don't care 606 * Preemption disabled if the SG_MITER_ATOMIC is set. Don't care
diff --git a/lib/test-string_helpers.c b/lib/test-string_helpers.c
index 98866a770770..25b5cbfb7615 100644
--- a/lib/test-string_helpers.c
+++ b/lib/test-string_helpers.c
@@ -327,36 +327,67 @@ out:
327} 327}
328 328
329#define string_get_size_maxbuf 16 329#define string_get_size_maxbuf 16
330#define test_string_get_size_one(size, blk_size, units, exp_result) \ 330#define test_string_get_size_one(size, blk_size, exp_result10, exp_result2) \
331 do { \ 331 do { \
332 BUILD_BUG_ON(sizeof(exp_result) >= string_get_size_maxbuf); \ 332 BUILD_BUG_ON(sizeof(exp_result10) >= string_get_size_maxbuf); \
333 __test_string_get_size((size), (blk_size), (units), \ 333 BUILD_BUG_ON(sizeof(exp_result2) >= string_get_size_maxbuf); \
334 (exp_result)); \ 334 __test_string_get_size((size), (blk_size), (exp_result10), \
335 (exp_result2)); \
335 } while (0) 336 } while (0)
336 337
337 338
338static __init void __test_string_get_size(const u64 size, const u64 blk_size, 339static __init void test_string_get_size_check(const char *units,
339 const enum string_size_units units, 340 const char *exp,
340 const char *exp_result) 341 char *res,
342 const u64 size,
343 const u64 blk_size)
341{ 344{
342 char buf[string_get_size_maxbuf]; 345 if (!memcmp(res, exp, strlen(exp) + 1))
343
344 string_get_size(size, blk_size, units, buf, sizeof(buf));
345 if (!memcmp(buf, exp_result, strlen(exp_result) + 1))
346 return; 346 return;
347 347
348 buf[sizeof(buf) - 1] = '\0'; 348 res[string_get_size_maxbuf - 1] = '\0';
349 pr_warn("Test 'test_string_get_size_one' failed!\n"); 349
350 pr_warn("string_get_size(size = %llu, blk_size = %llu, units = %d\n", 350 pr_warn("Test 'test_string_get_size' failed!\n");
351 pr_warn("string_get_size(size = %llu, blk_size = %llu, units = %s)\n",
351 size, blk_size, units); 352 size, blk_size, units);
352 pr_warn("expected: '%s', got '%s'\n", exp_result, buf); 353 pr_warn("expected: '%s', got '%s'\n", exp, res);
354}
355
356static __init void __test_string_get_size(const u64 size, const u64 blk_size,
357 const char *exp_result10,
358 const char *exp_result2)
359{
360 char buf10[string_get_size_maxbuf];
361 char buf2[string_get_size_maxbuf];
362
363 string_get_size(size, blk_size, STRING_UNITS_10, buf10, sizeof(buf10));
364 string_get_size(size, blk_size, STRING_UNITS_2, buf2, sizeof(buf2));
365
366 test_string_get_size_check("STRING_UNITS_10", exp_result10, buf10,
367 size, blk_size);
368
369 test_string_get_size_check("STRING_UNITS_2", exp_result2, buf2,
370 size, blk_size);
353} 371}
354 372
355static __init void test_string_get_size(void) 373static __init void test_string_get_size(void)
356{ 374{
357 test_string_get_size_one(16384, 512, STRING_UNITS_2, "8.00 MiB"); 375 /* small values */
358 test_string_get_size_one(8192, 4096, STRING_UNITS_10, "32.7 MB"); 376 test_string_get_size_one(0, 512, "0 B", "0 B");
359 test_string_get_size_one(1, 512, STRING_UNITS_10, "512 B"); 377 test_string_get_size_one(1, 512, "512 B", "512 B");
378 test_string_get_size_one(1100, 1, "1.10 kB", "1.07 KiB");
379
380 /* normal values */
381 test_string_get_size_one(16384, 512, "8.39 MB", "8.00 MiB");
382 test_string_get_size_one(500118192, 512, "256 GB", "238 GiB");
383 test_string_get_size_one(8192, 4096, "33.6 MB", "32.0 MiB");
384
385 /* weird block sizes */
386 test_string_get_size_one(3000, 1900, "5.70 MB", "5.44 MiB");
387
388 /* huge values */
389 test_string_get_size_one(U64_MAX, 4096, "75.6 ZB", "64.0 ZiB");
390 test_string_get_size_one(4096, U64_MAX, "75.6 ZB", "64.0 ZiB");
360} 391}
361 392
362static int __init test_string_helpers_init(void) 393static int __init test_string_helpers_init(void)
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 48ff9c36644d..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 *
@@ -1590,22 +1663,23 @@ char *pointer(const char *fmt, char *buf, char *end, void *ptr,
1590 return buf; 1663 return buf;
1591 } 1664 }
1592 case 'K': 1665 case 'K':
1593 /*
1594 * %pK cannot be used in IRQ context because its test
1595 * for CAP_SYSLOG would be meaningless.
1596 */
1597 if (kptr_restrict && (in_irq() || in_serving_softirq() ||
1598 in_nmi())) {
1599 if (spec.field_width == -1)
1600 spec.field_width = default_width;
1601 return string(buf, end, "pK-error", spec);
1602 }
1603
1604 switch (kptr_restrict) { 1666 switch (kptr_restrict) {
1605 case 0: 1667 case 0:
1606 /* Always print %pK values */ 1668 /* Always print %pK values */
1607 break; 1669 break;
1608 case 1: { 1670 case 1: {
1671 const struct cred *cred;
1672
1673 /*
1674 * kptr_restrict==1 cannot be used in IRQ context
1675 * because its test for CAP_SYSLOG would be meaningless.
1676 */
1677 if (in_irq() || in_serving_softirq() || in_nmi()) {
1678 if (spec.field_width == -1)
1679 spec.field_width = default_width;
1680 return string(buf, end, "pK-error", spec);
1681 }
1682
1609 /* 1683 /*
1610 * Only print the real pointer value if the current 1684 * Only print the real pointer value if the current
1611 * process has CAP_SYSLOG and is running with the 1685 * process has CAP_SYSLOG and is running with the
@@ -1615,8 +1689,7 @@ char *pointer(const char *fmt, char *buf, char *end, void *ptr,
1615 * leak pointer values if a binary opens a file using 1689 * leak pointer values if a binary opens a file using
1616 * %pK and then elevates privileges before reading it. 1690 * %pK and then elevates privileges before reading it.
1617 */ 1691 */
1618 const struct cred *cred = current_cred(); 1692 cred = current_cred();
1619
1620 if (!has_capability_noaudit(current, CAP_SYSLOG) || 1693 if (!has_capability_noaudit(current, CAP_SYSLOG) ||
1621 !uid_eq(cred->euid, cred->uid) || 1694 !uid_eq(cred->euid, cred->uid) ||
1622 !gid_eq(cred->egid, cred->gid)) 1695 !gid_eq(cred->egid, cred->gid))
@@ -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) {