diff options
Diffstat (limited to 'lib')
| -rw-r--r-- | lib/Kconfig.debug | 24 | ||||
| -rw-r--r-- | lib/Makefile | 1 | ||||
| -rw-r--r-- | lib/cpu-notifier-error-inject.c | 84 | ||||
| -rw-r--r-- | lib/extable.c | 2 | ||||
| -rw-r--r-- | lib/iov_iter.c | 55 | ||||
| -rw-r--r-- | lib/kstrtox.c | 2 | ||||
| -rw-r--r-- | lib/timerqueue.c | 4 |
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 | ||
| 1541 | config 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 | |||
| 1565 | config PM_NOTIFIER_ERROR_INJECT | 1541 | config 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 | |||
| 128 | obj-$(CONFIG_IOMMU_HELPER) += iommu-helper.o iommu-common.o | 128 | obj-$(CONFIG_IOMMU_HELPER) += iommu-helper.o iommu-common.o |
| 129 | obj-$(CONFIG_FAULT_INJECTION) += fault-inject.o | 129 | obj-$(CONFIG_FAULT_INJECTION) += fault-inject.o |
| 130 | obj-$(CONFIG_NOTIFIER_ERROR_INJECTION) += notifier-error-inject.o | 130 | obj-$(CONFIG_NOTIFIER_ERROR_INJECTION) += notifier-error-inject.o |
| 131 | obj-$(CONFIG_CPU_NOTIFIER_ERROR_INJECT) += cpu-notifier-error-inject.o | ||
| 132 | obj-$(CONFIG_PM_NOTIFIER_ERROR_INJECT) += pm-notifier-error-inject.o | 131 | obj-$(CONFIG_PM_NOTIFIER_ERROR_INJECT) += pm-notifier-error-inject.o |
| 133 | obj-$(CONFIG_NETDEV_NOTIFIER_ERROR_INJECT) += netdev-notifier-error-inject.o | 132 | obj-$(CONFIG_NETDEV_NOTIFIER_ERROR_INJECT) += netdev-notifier-error-inject.o |
| 134 | obj-$(CONFIG_MEMORY_NOTIFIER_ERROR_INJECT) += memory-notifier-error-inject.o | 133 | obj-$(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 | |||
| 7 | static int priority; | ||
| 8 | module_param(priority, int, 0); | ||
| 9 | MODULE_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 | |||
| 16 | static 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 | |||
| 26 | static 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 | |||
| 36 | static 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 | |||
| 44 | static 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 | |||
| 52 | static struct dentry *dir; | ||
| 53 | |||
| 54 | static 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 | |||
| 73 | static void err_inject_exit(void) | ||
| 74 | { | ||
| 75 | cpuhp_remove_state_nocalls(CPUHP_NOTF_ERR_INJ_PREPARE); | ||
| 76 | debugfs_remove_recursive(dir); | ||
| 77 | } | ||
| 78 | |||
| 79 | module_init(err_inject_init); | ||
| 80 | module_exit(err_inject_exit); | ||
| 81 | |||
| 82 | MODULE_DESCRIPTION("CPU notifier error injection module"); | ||
| 83 | MODULE_LICENSE("GPL"); | ||
| 84 | MODULE_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 | ||
| 857 | unsigned long iov_iter_gap_alignment(const struct iov_iter *i) | 856 | unsigned 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 | } |
| 879 | EXPORT_SYMBOL(iov_iter_gap_alignment); | 876 | EXPORT_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 | ||
| 23 | const char *_parse_integer_fixup_radix(const char *s, unsigned int *base) | 23 | const 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 | } |
