diff options
Diffstat (limited to 'lib')
| -rw-r--r-- | lib/Kconfig.debug | 28 | ||||
| -rw-r--r-- | lib/Kconfig.ubsan | 4 | ||||
| -rw-r--r-- | lib/atomic64_test.c | 2 | ||||
| -rw-r--r-- | lib/cpumask.c | 1 | ||||
| -rw-r--r-- | lib/devres.c | 2 | ||||
| -rw-r--r-- | lib/dump_stack.c | 7 | ||||
| -rw-r--r-- | lib/extable.c | 50 | ||||
| -rw-r--r-- | lib/klist.c | 6 | ||||
| -rw-r--r-- | lib/kobject.c | 1 | ||||
| -rw-r--r-- | lib/list_debug.c | 9 | ||||
| -rw-r--r-- | lib/mpi/longlong.h | 2 | ||||
| -rw-r--r-- | lib/mpi/mpi-inline.h | 2 | ||||
| -rw-r--r-- | lib/mpi/mpi-internal.h | 8 | ||||
| -rw-r--r-- | lib/mpi/mpicoder.c | 39 | ||||
| -rw-r--r-- | lib/radix-tree.c | 12 | ||||
| -rw-r--r-- | lib/scatterlist.c | 6 | ||||
| -rw-r--r-- | lib/test-string_helpers.c | 67 | ||||
| -rw-r--r-- | lib/test_printf.c | 53 | ||||
| -rw-r--r-- | lib/test_static_keys.c | 62 | ||||
| -rw-r--r-- | lib/ucs2_string.c | 62 | ||||
| -rw-r--r-- | lib/vsprintf.c | 101 |
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 | ||
| 1401 | endmenu # "RCU Debugging" | 1401 | endmenu # "RCU Debugging" |
| 1402 | 1402 | ||
| 1403 | config 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 | |||
| 1403 | config DEBUG_BLOCK_EXT_DEVT | 1418 | config 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 | ||
| 1445 | config 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 | |||
| 1430 | config NOTIFIER_ERROR_INJECTION | 1458 | config 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 | ||
| 22 | config UBSAN_ALIGNMENT | 24 | config 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 | } |
| 44 | EXPORT_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 | ||
| 237 | static void pcim_iomap_release(struct device *gendev, void *res) | 237 | static 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 | ||
| 26 | asmlinkage __visible void dump_stack(void) | 26 | asmlinkage __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 | |||
| 38 | retry: | 37 | retry: |
| 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 |
| 58 | asmlinkage __visible void dump_stack(void) | 59 | asmlinkage __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 | ||
| 20 | static 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 | ||
| 30 | static 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, | |||
| 48 | void trim_init_extable(struct module *m) | 78 | void 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 | } |
| 289 | EXPORT_SYMBOL_GPL(klist_iter_init_node); | 289 | EXPORT_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 | } |
| 864 | EXPORT_SYMBOL_GPL(kset_find_obj); | ||
| 864 | 865 | ||
| 865 | static void kset_release(struct kobject *kobj) | 866 | static 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 | ||
| 15 | static struct list_head force_poison; | ||
| 16 | void 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 | ||
| 36 | G10_MPI_INLINE_DECL mpi_limb_t | 36 | G10_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); | |||
| 168 | int mpi_lshift_limbs(MPI a, unsigned int count); | 168 | int mpi_lshift_limbs(MPI a, unsigned int count); |
| 169 | 169 | ||
| 170 | /*-- mpihelp-add.c --*/ | 170 | /*-- mpihelp-add.c --*/ |
| 171 | mpi_limb_t mpihelp_add_1(mpi_ptr_t res_ptr, mpi_ptr_t s1_ptr, | 171 | static 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); |
| 173 | mpi_limb_t mpihelp_add_n(mpi_ptr_t res_ptr, mpi_ptr_t s1_ptr, | 173 | mpi_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); |
| 175 | mpi_limb_t mpihelp_add(mpi_ptr_t res_ptr, mpi_ptr_t s1_ptr, mpi_size_t s1_size, | 175 | static 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 --*/ |
| 179 | mpi_limb_t mpihelp_sub_1(mpi_ptr_t res_ptr, mpi_ptr_t s1_ptr, | 179 | static 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); |
| 181 | mpi_limb_t mpihelp_sub_n(mpi_ptr_t res_ptr, mpi_ptr_t s1_ptr, | 181 | mpi_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); |
| 183 | mpi_limb_t mpihelp_sub(mpi_ptr_t res_ptr, mpi_ptr_t s1_ptr, mpi_size_t s1_size, | 183 | static 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 | } |
| 129 | EXPORT_SYMBOL_GPL(mpi_read_from_buffer); | 129 | EXPORT_SYMBOL_GPL(mpi_read_from_buffer); |
| 130 | 130 | ||
| 131 | static 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 | ||
| 338 | static __init void __test_string_get_size(const u64 size, const u64 blk_size, | 339 | static __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 | |||
| 356 | static __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 | ||
| 355 | static __init void test_string_get_size(void) | 373 | static __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 | ||
| 362 | static int __init test_string_helpers_init(void) | 393 | static 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 | ||
| 413 | static void __init | 416 | static void __init |
| 417 | flags(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 | |||
| 465 | static void __init | ||
| 414 | test_pointer(void) | 466 | test_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 | ||
| 433 | static int __init | 486 | static 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; }) | 50 | static bool key ## _ ## branch(void) \ |
| 51 | { \ | ||
| 52 | return branch(&key); \ | ||
| 53 | } | ||
| 51 | 54 | ||
| 52 | static void invert_key(struct static_key *key) | 55 | static 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 | ||
| 98 | test_key_func(old_true_key, static_key_true) | ||
| 99 | test_key_func(old_false_key, static_key_false) | ||
| 100 | test_key_func(true_key, static_branch_likely) | ||
| 101 | test_key_func(true_key, static_branch_unlikely) | ||
| 102 | test_key_func(false_key, static_branch_likely) | ||
| 103 | test_key_func(false_key, static_branch_unlikely) | ||
| 104 | test_key_func(base_old_true_key, static_key_true) | ||
| 105 | test_key_func(base_inv_old_true_key, static_key_true) | ||
| 106 | test_key_func(base_old_false_key, static_key_false) | ||
| 107 | test_key_func(base_inv_old_false_key, static_key_false) | ||
| 108 | test_key_func(base_true_key, static_branch_likely) | ||
| 109 | test_key_func(base_true_key, static_branch_unlikely) | ||
| 110 | test_key_func(base_inv_true_key, static_branch_likely) | ||
| 111 | test_key_func(base_inv_true_key, static_branch_unlikely) | ||
| 112 | test_key_func(base_false_key, static_branch_likely) | ||
| 113 | test_key_func(base_false_key, static_branch_unlikely) | ||
| 114 | test_key_func(base_inv_false_key, static_branch_likely) | ||
| 115 | test_key_func(base_inv_false_key, static_branch_unlikely) | ||
| 116 | |||
| 95 | static int __init test_static_key_init(void) | 117 | static 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 | } |
| 51 | EXPORT_SYMBOL(ucs2_strncmp); | 51 | EXPORT_SYMBOL(ucs2_strncmp); |
| 52 | |||
| 53 | unsigned long | ||
| 54 | ucs2_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 | } | ||
| 72 | EXPORT_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 | */ | ||
| 81 | unsigned long | ||
| 82 | ucs2_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 | } | ||
| 113 | EXPORT_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 | ||
| 1412 | static | ||
| 1413 | char *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 | |||
| 1449 | static noinline_for_stack | ||
| 1450 | char *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 | |||
| 1410 | int kptr_restrict __read_mostly; | 1478 | int 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) { |
