aboutsummaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/Kconfig.debug24
-rw-r--r--lib/Makefile1
-rw-r--r--lib/cpu-notifier-error-inject.c84
-rw-r--r--lib/extable.c2
-rw-r--r--lib/iov_iter.c55
-rw-r--r--lib/kstrtox.c2
-rw-r--r--lib/timerqueue.c4
7 files changed, 30 insertions, 142 deletions
diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug
index cb66a4648840..b06848a104e6 100644
--- a/lib/Kconfig.debug
+++ b/lib/Kconfig.debug
@@ -1538,30 +1538,6 @@ config NOTIFIER_ERROR_INJECTION
1538 1538
1539 Say N if unsure. 1539 Say N if unsure.
1540 1540
1541config CPU_NOTIFIER_ERROR_INJECT
1542 tristate "CPU notifier error injection module"
1543 depends on HOTPLUG_CPU && NOTIFIER_ERROR_INJECTION
1544 help
1545 This option provides a kernel module that can be used to test
1546 the error handling of the cpu notifiers by injecting artificial
1547 errors to CPU notifier chain callbacks. It is controlled through
1548 debugfs interface under /sys/kernel/debug/notifier-error-inject/cpu
1549
1550 If the notifier call chain should be failed with some events
1551 notified, write the error code to "actions/<notifier event>/error".
1552
1553 Example: Inject CPU offline error (-1 == -EPERM)
1554
1555 # cd /sys/kernel/debug/notifier-error-inject/cpu
1556 # echo -1 > actions/CPU_DOWN_PREPARE/error
1557 # echo 0 > /sys/devices/system/cpu/cpu1/online
1558 bash: echo: write error: Operation not permitted
1559
1560 To compile this code as a module, choose M here: the module will
1561 be called cpu-notifier-error-inject.
1562
1563 If unsure, say N.
1564
1565config PM_NOTIFIER_ERROR_INJECT 1541config PM_NOTIFIER_ERROR_INJECT
1566 tristate "PM notifier error injection module" 1542 tristate "PM notifier error injection module"
1567 depends on PM && NOTIFIER_ERROR_INJECTION 1543 depends on PM && NOTIFIER_ERROR_INJECTION
diff --git a/lib/Makefile b/lib/Makefile
index 50144a3aeebd..bc4073a8cd08 100644
--- a/lib/Makefile
+++ b/lib/Makefile
@@ -128,7 +128,6 @@ obj-$(CONFIG_SWIOTLB) += swiotlb.o
128obj-$(CONFIG_IOMMU_HELPER) += iommu-helper.o iommu-common.o 128obj-$(CONFIG_IOMMU_HELPER) += iommu-helper.o iommu-common.o
129obj-$(CONFIG_FAULT_INJECTION) += fault-inject.o 129obj-$(CONFIG_FAULT_INJECTION) += fault-inject.o
130obj-$(CONFIG_NOTIFIER_ERROR_INJECTION) += notifier-error-inject.o 130obj-$(CONFIG_NOTIFIER_ERROR_INJECTION) += notifier-error-inject.o
131obj-$(CONFIG_CPU_NOTIFIER_ERROR_INJECT) += cpu-notifier-error-inject.o
132obj-$(CONFIG_PM_NOTIFIER_ERROR_INJECT) += pm-notifier-error-inject.o 131obj-$(CONFIG_PM_NOTIFIER_ERROR_INJECT) += pm-notifier-error-inject.o
133obj-$(CONFIG_NETDEV_NOTIFIER_ERROR_INJECT) += netdev-notifier-error-inject.o 132obj-$(CONFIG_NETDEV_NOTIFIER_ERROR_INJECT) += netdev-notifier-error-inject.o
134obj-$(CONFIG_MEMORY_NOTIFIER_ERROR_INJECT) += memory-notifier-error-inject.o 133obj-$(CONFIG_MEMORY_NOTIFIER_ERROR_INJECT) += memory-notifier-error-inject.o
diff --git a/lib/cpu-notifier-error-inject.c b/lib/cpu-notifier-error-inject.c
deleted file mode 100644
index 0e2c9a1e958a..000000000000
--- a/lib/cpu-notifier-error-inject.c
+++ /dev/null
@@ -1,84 +0,0 @@
1#include <linux/kernel.h>
2#include <linux/module.h>
3#include <linux/cpu.h>
4
5#include "notifier-error-inject.h"
6
7static int priority;
8module_param(priority, int, 0);
9MODULE_PARM_DESC(priority, "specify cpu notifier priority");
10
11#define UP_PREPARE 0
12#define UP_PREPARE_FROZEN 0
13#define DOWN_PREPARE 0
14#define DOWN_PREPARE_FROZEN 0
15
16static struct notifier_err_inject cpu_notifier_err_inject = {
17 .actions = {
18 { NOTIFIER_ERR_INJECT_ACTION(UP_PREPARE) },
19 { NOTIFIER_ERR_INJECT_ACTION(UP_PREPARE_FROZEN) },
20 { NOTIFIER_ERR_INJECT_ACTION(DOWN_PREPARE) },
21 { NOTIFIER_ERR_INJECT_ACTION(DOWN_PREPARE_FROZEN) },
22 {}
23 }
24};
25
26static int notf_err_handle(struct notifier_err_inject_action *action)
27{
28 int ret;
29
30 ret = action->error;
31 if (ret)
32 pr_info("Injecting error (%d) to %s\n", ret, action->name);
33 return ret;
34}
35
36static int notf_err_inj_up_prepare(unsigned int cpu)
37{
38 if (!cpuhp_tasks_frozen)
39 return notf_err_handle(&cpu_notifier_err_inject.actions[0]);
40 else
41 return notf_err_handle(&cpu_notifier_err_inject.actions[1]);
42}
43
44static int notf_err_inj_dead(unsigned int cpu)
45{
46 if (!cpuhp_tasks_frozen)
47 return notf_err_handle(&cpu_notifier_err_inject.actions[2]);
48 else
49 return notf_err_handle(&cpu_notifier_err_inject.actions[3]);
50}
51
52static struct dentry *dir;
53
54static int err_inject_init(void)
55{
56 int err;
57
58 dir = notifier_err_inject_init("cpu", notifier_err_inject_dir,
59 &cpu_notifier_err_inject, priority);
60 if (IS_ERR(dir))
61 return PTR_ERR(dir);
62
63 err = cpuhp_setup_state_nocalls(CPUHP_NOTF_ERR_INJ_PREPARE,
64 "cpu-err-notif:prepare",
65 notf_err_inj_up_prepare,
66 notf_err_inj_dead);
67 if (err)
68 debugfs_remove_recursive(dir);
69
70 return err;
71}
72
73static void err_inject_exit(void)
74{
75 cpuhp_remove_state_nocalls(CPUHP_NOTF_ERR_INJ_PREPARE);
76 debugfs_remove_recursive(dir);
77}
78
79module_init(err_inject_init);
80module_exit(err_inject_exit);
81
82MODULE_DESCRIPTION("CPU notifier error injection module");
83MODULE_LICENSE("GPL");
84MODULE_AUTHOR("Akinobu Mita <akinobu.mita@gmail.com>");
diff --git a/lib/extable.c b/lib/extable.c
index 0be02ad561e9..62968daa66a9 100644
--- a/lib/extable.c
+++ b/lib/extable.c
@@ -12,7 +12,7 @@
12#include <linux/module.h> 12#include <linux/module.h>
13#include <linux/init.h> 13#include <linux/init.h>
14#include <linux/sort.h> 14#include <linux/sort.h>
15#include <asm/uaccess.h> 15#include <linux/uaccess.h>
16 16
17#ifndef ARCH_HAS_RELATIVE_EXTABLE 17#ifndef ARCH_HAS_RELATIVE_EXTABLE
18#define ex_to_insn(x) ((x)->insn) 18#define ex_to_insn(x) ((x)->insn)
diff --git a/lib/iov_iter.c b/lib/iov_iter.c
index 228892dabba6..25f572303801 100644
--- a/lib/iov_iter.c
+++ b/lib/iov_iter.c
@@ -73,19 +73,21 @@
73} 73}
74 74
75#define iterate_all_kinds(i, n, v, I, B, K) { \ 75#define iterate_all_kinds(i, n, v, I, B, K) { \
76 size_t skip = i->iov_offset; \ 76 if (likely(n)) { \
77 if (unlikely(i->type & ITER_BVEC)) { \ 77 size_t skip = i->iov_offset; \
78 struct bio_vec v; \ 78 if (unlikely(i->type & ITER_BVEC)) { \
79 struct bvec_iter __bi; \ 79 struct bio_vec v; \
80 iterate_bvec(i, n, v, __bi, skip, (B)) \ 80 struct bvec_iter __bi; \
81 } else if (unlikely(i->type & ITER_KVEC)) { \ 81 iterate_bvec(i, n, v, __bi, skip, (B)) \
82 const struct kvec *kvec; \ 82 } else if (unlikely(i->type & ITER_KVEC)) { \
83 struct kvec v; \ 83 const struct kvec *kvec; \
84 iterate_kvec(i, n, v, kvec, skip, (K)) \ 84 struct kvec v; \
85 } else { \ 85 iterate_kvec(i, n, v, kvec, skip, (K)) \
86 const struct iovec *iov; \ 86 } else { \
87 struct iovec v; \ 87 const struct iovec *iov; \
88 iterate_iovec(i, n, v, iov, skip, (I)) \ 88 struct iovec v; \
89 iterate_iovec(i, n, v, iov, skip, (I)) \
90 } \
89 } \ 91 } \
90} 92}
91 93
@@ -576,7 +578,7 @@ bool copy_from_iter_full(void *addr, size_t bytes, struct iov_iter *i)
576 WARN_ON(1); 578 WARN_ON(1);
577 return false; 579 return false;
578 } 580 }
579 if (unlikely(i->count < bytes)) \ 581 if (unlikely(i->count < bytes))
580 return false; 582 return false;
581 583
582 iterate_all_kinds(i, bytes, v, ({ 584 iterate_all_kinds(i, bytes, v, ({
@@ -620,7 +622,7 @@ bool copy_from_iter_full_nocache(void *addr, size_t bytes, struct iov_iter *i)
620 WARN_ON(1); 622 WARN_ON(1);
621 return false; 623 return false;
622 } 624 }
623 if (unlikely(i->count < bytes)) \ 625 if (unlikely(i->count < bytes))
624 return false; 626 return false;
625 iterate_all_kinds(i, bytes, v, ({ 627 iterate_all_kinds(i, bytes, v, ({
626 if (__copy_from_user_nocache((to += v.iov_len) - v.iov_len, 628 if (__copy_from_user_nocache((to += v.iov_len) - v.iov_len,
@@ -837,11 +839,8 @@ unsigned long iov_iter_alignment(const struct iov_iter *i)
837 unsigned long res = 0; 839 unsigned long res = 0;
838 size_t size = i->count; 840 size_t size = i->count;
839 841
840 if (!size)
841 return 0;
842
843 if (unlikely(i->type & ITER_PIPE)) { 842 if (unlikely(i->type & ITER_PIPE)) {
844 if (i->iov_offset && allocated(&i->pipe->bufs[i->idx])) 843 if (size && i->iov_offset && allocated(&i->pipe->bufs[i->idx]))
845 return size | i->iov_offset; 844 return size | i->iov_offset;
846 return size; 845 return size;
847 } 846 }
@@ -856,10 +855,8 @@ EXPORT_SYMBOL(iov_iter_alignment);
856 855
857unsigned long iov_iter_gap_alignment(const struct iov_iter *i) 856unsigned long iov_iter_gap_alignment(const struct iov_iter *i)
858{ 857{
859 unsigned long res = 0; 858 unsigned long res = 0;
860 size_t size = i->count; 859 size_t size = i->count;
861 if (!size)
862 return 0;
863 860
864 if (unlikely(i->type & ITER_PIPE)) { 861 if (unlikely(i->type & ITER_PIPE)) {
865 WARN_ON(1); 862 WARN_ON(1);
@@ -874,7 +871,7 @@ unsigned long iov_iter_gap_alignment(const struct iov_iter *i)
874 (res |= (!res ? 0 : (unsigned long)v.iov_base) | 871 (res |= (!res ? 0 : (unsigned long)v.iov_base) |
875 (size != v.iov_len ? size : 0)) 872 (size != v.iov_len ? size : 0))
876 ); 873 );
877 return res; 874 return res;
878} 875}
879EXPORT_SYMBOL(iov_iter_gap_alignment); 876EXPORT_SYMBOL(iov_iter_gap_alignment);
880 877
@@ -908,6 +905,9 @@ static ssize_t pipe_get_pages(struct iov_iter *i,
908 size_t capacity; 905 size_t capacity;
909 int idx; 906 int idx;
910 907
908 if (!maxsize)
909 return 0;
910
911 if (!sanity(i)) 911 if (!sanity(i))
912 return -EFAULT; 912 return -EFAULT;
913 913
@@ -926,9 +926,6 @@ ssize_t iov_iter_get_pages(struct iov_iter *i,
926 if (maxsize > i->count) 926 if (maxsize > i->count)
927 maxsize = i->count; 927 maxsize = i->count;
928 928
929 if (!maxsize)
930 return 0;
931
932 if (unlikely(i->type & ITER_PIPE)) 929 if (unlikely(i->type & ITER_PIPE))
933 return pipe_get_pages(i, pages, maxsize, maxpages, start); 930 return pipe_get_pages(i, pages, maxsize, maxpages, start);
934 iterate_all_kinds(i, maxsize, v, ({ 931 iterate_all_kinds(i, maxsize, v, ({
@@ -975,6 +972,9 @@ static ssize_t pipe_get_pages_alloc(struct iov_iter *i,
975 int idx; 972 int idx;
976 int npages; 973 int npages;
977 974
975 if (!maxsize)
976 return 0;
977
978 if (!sanity(i)) 978 if (!sanity(i))
979 return -EFAULT; 979 return -EFAULT;
980 980
@@ -1006,9 +1006,6 @@ ssize_t iov_iter_get_pages_alloc(struct iov_iter *i,
1006 if (maxsize > i->count) 1006 if (maxsize > i->count)
1007 maxsize = i->count; 1007 maxsize = i->count;
1008 1008
1009 if (!maxsize)
1010 return 0;
1011
1012 if (unlikely(i->type & ITER_PIPE)) 1009 if (unlikely(i->type & ITER_PIPE))
1013 return pipe_get_pages_alloc(i, pages, maxsize, start); 1010 return pipe_get_pages_alloc(i, pages, maxsize, start);
1014 iterate_all_kinds(i, maxsize, v, ({ 1011 iterate_all_kinds(i, maxsize, v, ({
diff --git a/lib/kstrtox.c b/lib/kstrtox.c
index b8e2080c1a47..bf85e05ce858 100644
--- a/lib/kstrtox.c
+++ b/lib/kstrtox.c
@@ -17,7 +17,7 @@
17#include <linux/math64.h> 17#include <linux/math64.h>
18#include <linux/export.h> 18#include <linux/export.h>
19#include <linux/types.h> 19#include <linux/types.h>
20#include <asm/uaccess.h> 20#include <linux/uaccess.h>
21#include "kstrtox.h" 21#include "kstrtox.h"
22 22
23const char *_parse_integer_fixup_radix(const char *s, unsigned int *base) 23const char *_parse_integer_fixup_radix(const char *s, unsigned int *base)
diff --git a/lib/timerqueue.c b/lib/timerqueue.c
index 782ae8ca2c06..adc6ee0a5126 100644
--- a/lib/timerqueue.c
+++ b/lib/timerqueue.c
@@ -48,7 +48,7 @@ bool timerqueue_add(struct timerqueue_head *head, struct timerqueue_node *node)
48 while (*p) { 48 while (*p) {
49 parent = *p; 49 parent = *p;
50 ptr = rb_entry(parent, struct timerqueue_node, node); 50 ptr = rb_entry(parent, struct timerqueue_node, node);
51 if (node->expires.tv64 < ptr->expires.tv64) 51 if (node->expires < ptr->expires)
52 p = &(*p)->rb_left; 52 p = &(*p)->rb_left;
53 else 53 else
54 p = &(*p)->rb_right; 54 p = &(*p)->rb_right;
@@ -56,7 +56,7 @@ bool timerqueue_add(struct timerqueue_head *head, struct timerqueue_node *node)
56 rb_link_node(&node->node, parent, p); 56 rb_link_node(&node->node, parent, p);
57 rb_insert_color(&node->node, &head->head); 57 rb_insert_color(&node->node, &head->head);
58 58
59 if (!head->next || node->expires.tv64 < head->next->expires.tv64) { 59 if (!head->next || node->expires < head->next->expires) {
60 head->next = node; 60 head->next = node;
61 return true; 61 return true;
62 } 62 }