diff options
author | David S. Miller <davem@davemloft.net> | 2016-05-04 00:52:29 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2016-05-04 00:52:29 -0400 |
commit | cba653210056cf47cc1969f831f05ddfb99ee2bd (patch) | |
tree | 92d93a3eee5b12d77af3696b9da8026e71df5752 /kernel | |
parent | 26879da58711aa604a1b866cbeedd7e0f78f90ad (diff) | |
parent | 7391daf2ffc780679d6ab3fad1db2619e5dd2c2a (diff) |
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net
Conflicts:
net/ipv4/ip_gre.c
Minor conflicts between tunnel bug fixes in net and
ipv6 tunnel cleanups in net-next.
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'kernel')
-rw-r--r-- | kernel/bpf/inode.c | 7 | ||||
-rw-r--r-- | kernel/bpf/syscall.c | 24 | ||||
-rw-r--r-- | kernel/bpf/verifier.c | 76 | ||||
-rw-r--r-- | kernel/cgroup.c | 7 | ||||
-rw-r--r-- | kernel/cpuset.c | 4 | ||||
-rw-r--r-- | kernel/events/core.c | 55 | ||||
-rw-r--r-- | kernel/kcov.c | 3 | ||||
-rw-r--r-- | kernel/kexec_core.c | 7 | ||||
-rw-r--r-- | kernel/locking/lockdep.c | 37 | ||||
-rw-r--r-- | kernel/locking/lockdep_proc.c | 2 | ||||
-rw-r--r-- | kernel/workqueue.c | 29 |
11 files changed, 188 insertions, 63 deletions
diff --git a/kernel/bpf/inode.c b/kernel/bpf/inode.c index f2ece3c174a5..8f94ca1860cf 100644 --- a/kernel/bpf/inode.c +++ b/kernel/bpf/inode.c | |||
@@ -31,10 +31,10 @@ static void *bpf_any_get(void *raw, enum bpf_type type) | |||
31 | { | 31 | { |
32 | switch (type) { | 32 | switch (type) { |
33 | case BPF_TYPE_PROG: | 33 | case BPF_TYPE_PROG: |
34 | atomic_inc(&((struct bpf_prog *)raw)->aux->refcnt); | 34 | raw = bpf_prog_inc(raw); |
35 | break; | 35 | break; |
36 | case BPF_TYPE_MAP: | 36 | case BPF_TYPE_MAP: |
37 | bpf_map_inc(raw, true); | 37 | raw = bpf_map_inc(raw, true); |
38 | break; | 38 | break; |
39 | default: | 39 | default: |
40 | WARN_ON_ONCE(1); | 40 | WARN_ON_ONCE(1); |
@@ -297,7 +297,8 @@ static void *bpf_obj_do_get(const struct filename *pathname, | |||
297 | goto out; | 297 | goto out; |
298 | 298 | ||
299 | raw = bpf_any_get(inode->i_private, *type); | 299 | raw = bpf_any_get(inode->i_private, *type); |
300 | touch_atime(&path); | 300 | if (!IS_ERR(raw)) |
301 | touch_atime(&path); | ||
301 | 302 | ||
302 | path_put(&path); | 303 | path_put(&path); |
303 | return raw; | 304 | return raw; |
diff --git a/kernel/bpf/syscall.c b/kernel/bpf/syscall.c index adc5e4bd74f8..cf5e9f7ad13a 100644 --- a/kernel/bpf/syscall.c +++ b/kernel/bpf/syscall.c | |||
@@ -218,11 +218,18 @@ struct bpf_map *__bpf_map_get(struct fd f) | |||
218 | return f.file->private_data; | 218 | return f.file->private_data; |
219 | } | 219 | } |
220 | 220 | ||
221 | void bpf_map_inc(struct bpf_map *map, bool uref) | 221 | /* prog's and map's refcnt limit */ |
222 | #define BPF_MAX_REFCNT 32768 | ||
223 | |||
224 | struct bpf_map *bpf_map_inc(struct bpf_map *map, bool uref) | ||
222 | { | 225 | { |
223 | atomic_inc(&map->refcnt); | 226 | if (atomic_inc_return(&map->refcnt) > BPF_MAX_REFCNT) { |
227 | atomic_dec(&map->refcnt); | ||
228 | return ERR_PTR(-EBUSY); | ||
229 | } | ||
224 | if (uref) | 230 | if (uref) |
225 | atomic_inc(&map->usercnt); | 231 | atomic_inc(&map->usercnt); |
232 | return map; | ||
226 | } | 233 | } |
227 | 234 | ||
228 | struct bpf_map *bpf_map_get_with_uref(u32 ufd) | 235 | struct bpf_map *bpf_map_get_with_uref(u32 ufd) |
@@ -234,7 +241,7 @@ struct bpf_map *bpf_map_get_with_uref(u32 ufd) | |||
234 | if (IS_ERR(map)) | 241 | if (IS_ERR(map)) |
235 | return map; | 242 | return map; |
236 | 243 | ||
237 | bpf_map_inc(map, true); | 244 | map = bpf_map_inc(map, true); |
238 | fdput(f); | 245 | fdput(f); |
239 | 246 | ||
240 | return map; | 247 | return map; |
@@ -658,6 +665,15 @@ static struct bpf_prog *__bpf_prog_get(struct fd f) | |||
658 | return f.file->private_data; | 665 | return f.file->private_data; |
659 | } | 666 | } |
660 | 667 | ||
668 | struct bpf_prog *bpf_prog_inc(struct bpf_prog *prog) | ||
669 | { | ||
670 | if (atomic_inc_return(&prog->aux->refcnt) > BPF_MAX_REFCNT) { | ||
671 | atomic_dec(&prog->aux->refcnt); | ||
672 | return ERR_PTR(-EBUSY); | ||
673 | } | ||
674 | return prog; | ||
675 | } | ||
676 | |||
661 | /* called by sockets/tracing/seccomp before attaching program to an event | 677 | /* called by sockets/tracing/seccomp before attaching program to an event |
662 | * pairs with bpf_prog_put() | 678 | * pairs with bpf_prog_put() |
663 | */ | 679 | */ |
@@ -670,7 +686,7 @@ struct bpf_prog *bpf_prog_get(u32 ufd) | |||
670 | if (IS_ERR(prog)) | 686 | if (IS_ERR(prog)) |
671 | return prog; | 687 | return prog; |
672 | 688 | ||
673 | atomic_inc(&prog->aux->refcnt); | 689 | prog = bpf_prog_inc(prog); |
674 | fdput(f); | 690 | fdput(f); |
675 | 691 | ||
676 | return prog; | 692 | return prog; |
diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c index 56f18068b52b..63554b6d4e25 100644 --- a/kernel/bpf/verifier.c +++ b/kernel/bpf/verifier.c | |||
@@ -249,16 +249,6 @@ static const char * const reg_type_str[] = { | |||
249 | [CONST_IMM] = "imm", | 249 | [CONST_IMM] = "imm", |
250 | }; | 250 | }; |
251 | 251 | ||
252 | static const struct { | ||
253 | int map_type; | ||
254 | int func_id; | ||
255 | } func_limit[] = { | ||
256 | {BPF_MAP_TYPE_PROG_ARRAY, BPF_FUNC_tail_call}, | ||
257 | {BPF_MAP_TYPE_PERF_EVENT_ARRAY, BPF_FUNC_perf_event_read}, | ||
258 | {BPF_MAP_TYPE_PERF_EVENT_ARRAY, BPF_FUNC_perf_event_output}, | ||
259 | {BPF_MAP_TYPE_STACK_TRACE, BPF_FUNC_get_stackid}, | ||
260 | }; | ||
261 | |||
262 | static void print_verifier_state(struct verifier_env *env) | 252 | static void print_verifier_state(struct verifier_env *env) |
263 | { | 253 | { |
264 | enum bpf_reg_type t; | 254 | enum bpf_reg_type t; |
@@ -943,27 +933,52 @@ static int check_func_arg(struct verifier_env *env, u32 regno, | |||
943 | 933 | ||
944 | static int check_map_func_compatibility(struct bpf_map *map, int func_id) | 934 | static int check_map_func_compatibility(struct bpf_map *map, int func_id) |
945 | { | 935 | { |
946 | bool bool_map, bool_func; | ||
947 | int i; | ||
948 | |||
949 | if (!map) | 936 | if (!map) |
950 | return 0; | 937 | return 0; |
951 | 938 | ||
952 | for (i = 0; i < ARRAY_SIZE(func_limit); i++) { | 939 | /* We need a two way check, first is from map perspective ... */ |
953 | bool_map = (map->map_type == func_limit[i].map_type); | 940 | switch (map->map_type) { |
954 | bool_func = (func_id == func_limit[i].func_id); | 941 | case BPF_MAP_TYPE_PROG_ARRAY: |
955 | /* only when map & func pair match it can continue. | 942 | if (func_id != BPF_FUNC_tail_call) |
956 | * don't allow any other map type to be passed into | 943 | goto error; |
957 | * the special func; | 944 | break; |
958 | */ | 945 | case BPF_MAP_TYPE_PERF_EVENT_ARRAY: |
959 | if (bool_func && bool_map != bool_func) { | 946 | if (func_id != BPF_FUNC_perf_event_read && |
960 | verbose("cannot pass map_type %d into func %d\n", | 947 | func_id != BPF_FUNC_perf_event_output) |
961 | map->map_type, func_id); | 948 | goto error; |
962 | return -EINVAL; | 949 | break; |
963 | } | 950 | case BPF_MAP_TYPE_STACK_TRACE: |
951 | if (func_id != BPF_FUNC_get_stackid) | ||
952 | goto error; | ||
953 | break; | ||
954 | default: | ||
955 | break; | ||
956 | } | ||
957 | |||
958 | /* ... and second from the function itself. */ | ||
959 | switch (func_id) { | ||
960 | case BPF_FUNC_tail_call: | ||
961 | if (map->map_type != BPF_MAP_TYPE_PROG_ARRAY) | ||
962 | goto error; | ||
963 | break; | ||
964 | case BPF_FUNC_perf_event_read: | ||
965 | case BPF_FUNC_perf_event_output: | ||
966 | if (map->map_type != BPF_MAP_TYPE_PERF_EVENT_ARRAY) | ||
967 | goto error; | ||
968 | break; | ||
969 | case BPF_FUNC_get_stackid: | ||
970 | if (map->map_type != BPF_MAP_TYPE_STACK_TRACE) | ||
971 | goto error; | ||
972 | break; | ||
973 | default: | ||
974 | break; | ||
964 | } | 975 | } |
965 | 976 | ||
966 | return 0; | 977 | return 0; |
978 | error: | ||
979 | verbose("cannot pass map_type %d into func %d\n", | ||
980 | map->map_type, func_id); | ||
981 | return -EINVAL; | ||
967 | } | 982 | } |
968 | 983 | ||
969 | static int check_raw_mode(const struct bpf_func_proto *fn) | 984 | static int check_raw_mode(const struct bpf_func_proto *fn) |
@@ -2111,15 +2126,18 @@ static int replace_map_fd_with_map_ptr(struct verifier_env *env) | |||
2111 | return -E2BIG; | 2126 | return -E2BIG; |
2112 | } | 2127 | } |
2113 | 2128 | ||
2114 | /* remember this map */ | ||
2115 | env->used_maps[env->used_map_cnt++] = map; | ||
2116 | |||
2117 | /* hold the map. If the program is rejected by verifier, | 2129 | /* hold the map. If the program is rejected by verifier, |
2118 | * the map will be released by release_maps() or it | 2130 | * the map will be released by release_maps() or it |
2119 | * will be used by the valid program until it's unloaded | 2131 | * will be used by the valid program until it's unloaded |
2120 | * and all maps are released in free_bpf_prog_info() | 2132 | * and all maps are released in free_bpf_prog_info() |
2121 | */ | 2133 | */ |
2122 | bpf_map_inc(map, false); | 2134 | map = bpf_map_inc(map, false); |
2135 | if (IS_ERR(map)) { | ||
2136 | fdput(f); | ||
2137 | return PTR_ERR(map); | ||
2138 | } | ||
2139 | env->used_maps[env->used_map_cnt++] = map; | ||
2140 | |||
2123 | fdput(f); | 2141 | fdput(f); |
2124 | next_insn: | 2142 | next_insn: |
2125 | insn++; | 2143 | insn++; |
diff --git a/kernel/cgroup.c b/kernel/cgroup.c index 671dc05c0b0f..909a7d31ffd3 100644 --- a/kernel/cgroup.c +++ b/kernel/cgroup.c | |||
@@ -2825,9 +2825,10 @@ static ssize_t __cgroup_procs_write(struct kernfs_open_file *of, char *buf, | |||
2825 | size_t nbytes, loff_t off, bool threadgroup) | 2825 | size_t nbytes, loff_t off, bool threadgroup) |
2826 | { | 2826 | { |
2827 | struct task_struct *tsk; | 2827 | struct task_struct *tsk; |
2828 | struct cgroup_subsys *ss; | ||
2828 | struct cgroup *cgrp; | 2829 | struct cgroup *cgrp; |
2829 | pid_t pid; | 2830 | pid_t pid; |
2830 | int ret; | 2831 | int ssid, ret; |
2831 | 2832 | ||
2832 | if (kstrtoint(strstrip(buf), 0, &pid) || pid < 0) | 2833 | if (kstrtoint(strstrip(buf), 0, &pid) || pid < 0) |
2833 | return -EINVAL; | 2834 | return -EINVAL; |
@@ -2875,8 +2876,10 @@ out_unlock_rcu: | |||
2875 | rcu_read_unlock(); | 2876 | rcu_read_unlock(); |
2876 | out_unlock_threadgroup: | 2877 | out_unlock_threadgroup: |
2877 | percpu_up_write(&cgroup_threadgroup_rwsem); | 2878 | percpu_up_write(&cgroup_threadgroup_rwsem); |
2879 | for_each_subsys(ss, ssid) | ||
2880 | if (ss->post_attach) | ||
2881 | ss->post_attach(); | ||
2878 | cgroup_kn_unlock(of->kn); | 2882 | cgroup_kn_unlock(of->kn); |
2879 | cpuset_post_attach_flush(); | ||
2880 | return ret ?: nbytes; | 2883 | return ret ?: nbytes; |
2881 | } | 2884 | } |
2882 | 2885 | ||
diff --git a/kernel/cpuset.c b/kernel/cpuset.c index 00ab5c2b7c5b..1902956baba1 100644 --- a/kernel/cpuset.c +++ b/kernel/cpuset.c | |||
@@ -58,7 +58,6 @@ | |||
58 | #include <asm/uaccess.h> | 58 | #include <asm/uaccess.h> |
59 | #include <linux/atomic.h> | 59 | #include <linux/atomic.h> |
60 | #include <linux/mutex.h> | 60 | #include <linux/mutex.h> |
61 | #include <linux/workqueue.h> | ||
62 | #include <linux/cgroup.h> | 61 | #include <linux/cgroup.h> |
63 | #include <linux/wait.h> | 62 | #include <linux/wait.h> |
64 | 63 | ||
@@ -1016,7 +1015,7 @@ static void cpuset_migrate_mm(struct mm_struct *mm, const nodemask_t *from, | |||
1016 | } | 1015 | } |
1017 | } | 1016 | } |
1018 | 1017 | ||
1019 | void cpuset_post_attach_flush(void) | 1018 | static void cpuset_post_attach(void) |
1020 | { | 1019 | { |
1021 | flush_workqueue(cpuset_migrate_mm_wq); | 1020 | flush_workqueue(cpuset_migrate_mm_wq); |
1022 | } | 1021 | } |
@@ -2087,6 +2086,7 @@ struct cgroup_subsys cpuset_cgrp_subsys = { | |||
2087 | .can_attach = cpuset_can_attach, | 2086 | .can_attach = cpuset_can_attach, |
2088 | .cancel_attach = cpuset_cancel_attach, | 2087 | .cancel_attach = cpuset_cancel_attach, |
2089 | .attach = cpuset_attach, | 2088 | .attach = cpuset_attach, |
2089 | .post_attach = cpuset_post_attach, | ||
2090 | .bind = cpuset_bind, | 2090 | .bind = cpuset_bind, |
2091 | .legacy_cftypes = files, | 2091 | .legacy_cftypes = files, |
2092 | .early_init = true, | 2092 | .early_init = true, |
diff --git a/kernel/events/core.c b/kernel/events/core.c index 9eb23dc27462..0bdc6e7d4908 100644 --- a/kernel/events/core.c +++ b/kernel/events/core.c | |||
@@ -412,7 +412,8 @@ int perf_cpu_time_max_percent_handler(struct ctl_table *table, int write, | |||
412 | if (ret || !write) | 412 | if (ret || !write) |
413 | return ret; | 413 | return ret; |
414 | 414 | ||
415 | if (sysctl_perf_cpu_time_max_percent == 100) { | 415 | if (sysctl_perf_cpu_time_max_percent == 100 || |
416 | sysctl_perf_cpu_time_max_percent == 0) { | ||
416 | printk(KERN_WARNING | 417 | printk(KERN_WARNING |
417 | "perf: Dynamic interrupt throttling disabled, can hang your system!\n"); | 418 | "perf: Dynamic interrupt throttling disabled, can hang your system!\n"); |
418 | WRITE_ONCE(perf_sample_allowed_ns, 0); | 419 | WRITE_ONCE(perf_sample_allowed_ns, 0); |
@@ -1105,6 +1106,7 @@ static void put_ctx(struct perf_event_context *ctx) | |||
1105 | * function. | 1106 | * function. |
1106 | * | 1107 | * |
1107 | * Lock order: | 1108 | * Lock order: |
1109 | * cred_guard_mutex | ||
1108 | * task_struct::perf_event_mutex | 1110 | * task_struct::perf_event_mutex |
1109 | * perf_event_context::mutex | 1111 | * perf_event_context::mutex |
1110 | * perf_event::child_mutex; | 1112 | * perf_event::child_mutex; |
@@ -3420,7 +3422,6 @@ static struct task_struct * | |||
3420 | find_lively_task_by_vpid(pid_t vpid) | 3422 | find_lively_task_by_vpid(pid_t vpid) |
3421 | { | 3423 | { |
3422 | struct task_struct *task; | 3424 | struct task_struct *task; |
3423 | int err; | ||
3424 | 3425 | ||
3425 | rcu_read_lock(); | 3426 | rcu_read_lock(); |
3426 | if (!vpid) | 3427 | if (!vpid) |
@@ -3434,16 +3435,7 @@ find_lively_task_by_vpid(pid_t vpid) | |||
3434 | if (!task) | 3435 | if (!task) |
3435 | return ERR_PTR(-ESRCH); | 3436 | return ERR_PTR(-ESRCH); |
3436 | 3437 | ||
3437 | /* Reuse ptrace permission checks for now. */ | ||
3438 | err = -EACCES; | ||
3439 | if (!ptrace_may_access(task, PTRACE_MODE_READ_REALCREDS)) | ||
3440 | goto errout; | ||
3441 | |||
3442 | return task; | 3438 | return task; |
3443 | errout: | ||
3444 | put_task_struct(task); | ||
3445 | return ERR_PTR(err); | ||
3446 | |||
3447 | } | 3439 | } |
3448 | 3440 | ||
3449 | /* | 3441 | /* |
@@ -8446,6 +8438,24 @@ SYSCALL_DEFINE5(perf_event_open, | |||
8446 | 8438 | ||
8447 | get_online_cpus(); | 8439 | get_online_cpus(); |
8448 | 8440 | ||
8441 | if (task) { | ||
8442 | err = mutex_lock_interruptible(&task->signal->cred_guard_mutex); | ||
8443 | if (err) | ||
8444 | goto err_cpus; | ||
8445 | |||
8446 | /* | ||
8447 | * Reuse ptrace permission checks for now. | ||
8448 | * | ||
8449 | * We must hold cred_guard_mutex across this and any potential | ||
8450 | * perf_install_in_context() call for this new event to | ||
8451 | * serialize against exec() altering our credentials (and the | ||
8452 | * perf_event_exit_task() that could imply). | ||
8453 | */ | ||
8454 | err = -EACCES; | ||
8455 | if (!ptrace_may_access(task, PTRACE_MODE_READ_REALCREDS)) | ||
8456 | goto err_cred; | ||
8457 | } | ||
8458 | |||
8449 | if (flags & PERF_FLAG_PID_CGROUP) | 8459 | if (flags & PERF_FLAG_PID_CGROUP) |
8450 | cgroup_fd = pid; | 8460 | cgroup_fd = pid; |
8451 | 8461 | ||
@@ -8453,7 +8463,7 @@ SYSCALL_DEFINE5(perf_event_open, | |||
8453 | NULL, NULL, cgroup_fd); | 8463 | NULL, NULL, cgroup_fd); |
8454 | if (IS_ERR(event)) { | 8464 | if (IS_ERR(event)) { |
8455 | err = PTR_ERR(event); | 8465 | err = PTR_ERR(event); |
8456 | goto err_cpus; | 8466 | goto err_cred; |
8457 | } | 8467 | } |
8458 | 8468 | ||
8459 | if (is_sampling_event(event)) { | 8469 | if (is_sampling_event(event)) { |
@@ -8512,11 +8522,6 @@ SYSCALL_DEFINE5(perf_event_open, | |||
8512 | goto err_context; | 8522 | goto err_context; |
8513 | } | 8523 | } |
8514 | 8524 | ||
8515 | if (task) { | ||
8516 | put_task_struct(task); | ||
8517 | task = NULL; | ||
8518 | } | ||
8519 | |||
8520 | /* | 8525 | /* |
8521 | * Look up the group leader (we will attach this event to it): | 8526 | * Look up the group leader (we will attach this event to it): |
8522 | */ | 8527 | */ |
@@ -8614,6 +8619,11 @@ SYSCALL_DEFINE5(perf_event_open, | |||
8614 | 8619 | ||
8615 | WARN_ON_ONCE(ctx->parent_ctx); | 8620 | WARN_ON_ONCE(ctx->parent_ctx); |
8616 | 8621 | ||
8622 | /* | ||
8623 | * This is the point on no return; we cannot fail hereafter. This is | ||
8624 | * where we start modifying current state. | ||
8625 | */ | ||
8626 | |||
8617 | if (move_group) { | 8627 | if (move_group) { |
8618 | /* | 8628 | /* |
8619 | * See perf_event_ctx_lock() for comments on the details | 8629 | * See perf_event_ctx_lock() for comments on the details |
@@ -8685,6 +8695,11 @@ SYSCALL_DEFINE5(perf_event_open, | |||
8685 | mutex_unlock(&gctx->mutex); | 8695 | mutex_unlock(&gctx->mutex); |
8686 | mutex_unlock(&ctx->mutex); | 8696 | mutex_unlock(&ctx->mutex); |
8687 | 8697 | ||
8698 | if (task) { | ||
8699 | mutex_unlock(&task->signal->cred_guard_mutex); | ||
8700 | put_task_struct(task); | ||
8701 | } | ||
8702 | |||
8688 | put_online_cpus(); | 8703 | put_online_cpus(); |
8689 | 8704 | ||
8690 | mutex_lock(¤t->perf_event_mutex); | 8705 | mutex_lock(¤t->perf_event_mutex); |
@@ -8717,6 +8732,9 @@ err_alloc: | |||
8717 | */ | 8732 | */ |
8718 | if (!event_file) | 8733 | if (!event_file) |
8719 | free_event(event); | 8734 | free_event(event); |
8735 | err_cred: | ||
8736 | if (task) | ||
8737 | mutex_unlock(&task->signal->cred_guard_mutex); | ||
8720 | err_cpus: | 8738 | err_cpus: |
8721 | put_online_cpus(); | 8739 | put_online_cpus(); |
8722 | err_task: | 8740 | err_task: |
@@ -9001,6 +9019,9 @@ static void perf_event_exit_task_context(struct task_struct *child, int ctxn) | |||
9001 | 9019 | ||
9002 | /* | 9020 | /* |
9003 | * When a child task exits, feed back event values to parent events. | 9021 | * When a child task exits, feed back event values to parent events. |
9022 | * | ||
9023 | * Can be called with cred_guard_mutex held when called from | ||
9024 | * install_exec_creds(). | ||
9004 | */ | 9025 | */ |
9005 | void perf_event_exit_task(struct task_struct *child) | 9026 | void perf_event_exit_task(struct task_struct *child) |
9006 | { | 9027 | { |
diff --git a/kernel/kcov.c b/kernel/kcov.c index 3efbee0834a8..a02f2dddd1d7 100644 --- a/kernel/kcov.c +++ b/kernel/kcov.c | |||
@@ -1,5 +1,6 @@ | |||
1 | #define pr_fmt(fmt) "kcov: " fmt | 1 | #define pr_fmt(fmt) "kcov: " fmt |
2 | 2 | ||
3 | #define DISABLE_BRANCH_PROFILING | ||
3 | #include <linux/compiler.h> | 4 | #include <linux/compiler.h> |
4 | #include <linux/types.h> | 5 | #include <linux/types.h> |
5 | #include <linux/file.h> | 6 | #include <linux/file.h> |
@@ -43,7 +44,7 @@ struct kcov { | |||
43 | * Entry point from instrumented code. | 44 | * Entry point from instrumented code. |
44 | * This is called once per basic-block/edge. | 45 | * This is called once per basic-block/edge. |
45 | */ | 46 | */ |
46 | void __sanitizer_cov_trace_pc(void) | 47 | void notrace __sanitizer_cov_trace_pc(void) |
47 | { | 48 | { |
48 | struct task_struct *t; | 49 | struct task_struct *t; |
49 | enum kcov_mode mode; | 50 | enum kcov_mode mode; |
diff --git a/kernel/kexec_core.c b/kernel/kexec_core.c index 8d34308ea449..1391d3ee3b86 100644 --- a/kernel/kexec_core.c +++ b/kernel/kexec_core.c | |||
@@ -1415,6 +1415,9 @@ static int __init crash_save_vmcoreinfo_init(void) | |||
1415 | VMCOREINFO_OFFSET(page, lru); | 1415 | VMCOREINFO_OFFSET(page, lru); |
1416 | VMCOREINFO_OFFSET(page, _mapcount); | 1416 | VMCOREINFO_OFFSET(page, _mapcount); |
1417 | VMCOREINFO_OFFSET(page, private); | 1417 | VMCOREINFO_OFFSET(page, private); |
1418 | VMCOREINFO_OFFSET(page, compound_dtor); | ||
1419 | VMCOREINFO_OFFSET(page, compound_order); | ||
1420 | VMCOREINFO_OFFSET(page, compound_head); | ||
1418 | VMCOREINFO_OFFSET(pglist_data, node_zones); | 1421 | VMCOREINFO_OFFSET(pglist_data, node_zones); |
1419 | VMCOREINFO_OFFSET(pglist_data, nr_zones); | 1422 | VMCOREINFO_OFFSET(pglist_data, nr_zones); |
1420 | #ifdef CONFIG_FLAT_NODE_MEM_MAP | 1423 | #ifdef CONFIG_FLAT_NODE_MEM_MAP |
@@ -1447,8 +1450,8 @@ static int __init crash_save_vmcoreinfo_init(void) | |||
1447 | #ifdef CONFIG_X86 | 1450 | #ifdef CONFIG_X86 |
1448 | VMCOREINFO_NUMBER(KERNEL_IMAGE_SIZE); | 1451 | VMCOREINFO_NUMBER(KERNEL_IMAGE_SIZE); |
1449 | #endif | 1452 | #endif |
1450 | #ifdef CONFIG_HUGETLBFS | 1453 | #ifdef CONFIG_HUGETLB_PAGE |
1451 | VMCOREINFO_SYMBOL(free_huge_page); | 1454 | VMCOREINFO_NUMBER(HUGETLB_PAGE_DTOR); |
1452 | #endif | 1455 | #endif |
1453 | 1456 | ||
1454 | arch_crash_save_vmcoreinfo(); | 1457 | arch_crash_save_vmcoreinfo(); |
diff --git a/kernel/locking/lockdep.c b/kernel/locking/lockdep.c index ed9410936a22..78c1c0ee6dc1 100644 --- a/kernel/locking/lockdep.c +++ b/kernel/locking/lockdep.c | |||
@@ -2176,15 +2176,37 @@ cache_hit: | |||
2176 | chain->irq_context = hlock->irq_context; | 2176 | chain->irq_context = hlock->irq_context; |
2177 | i = get_first_held_lock(curr, hlock); | 2177 | i = get_first_held_lock(curr, hlock); |
2178 | chain->depth = curr->lockdep_depth + 1 - i; | 2178 | chain->depth = curr->lockdep_depth + 1 - i; |
2179 | |||
2180 | BUILD_BUG_ON((1UL << 24) <= ARRAY_SIZE(chain_hlocks)); | ||
2181 | BUILD_BUG_ON((1UL << 6) <= ARRAY_SIZE(curr->held_locks)); | ||
2182 | BUILD_BUG_ON((1UL << 8*sizeof(chain_hlocks[0])) <= ARRAY_SIZE(lock_classes)); | ||
2183 | |||
2179 | if (likely(nr_chain_hlocks + chain->depth <= MAX_LOCKDEP_CHAIN_HLOCKS)) { | 2184 | if (likely(nr_chain_hlocks + chain->depth <= MAX_LOCKDEP_CHAIN_HLOCKS)) { |
2180 | chain->base = nr_chain_hlocks; | 2185 | chain->base = nr_chain_hlocks; |
2181 | nr_chain_hlocks += chain->depth; | ||
2182 | for (j = 0; j < chain->depth - 1; j++, i++) { | 2186 | for (j = 0; j < chain->depth - 1; j++, i++) { |
2183 | int lock_id = curr->held_locks[i].class_idx - 1; | 2187 | int lock_id = curr->held_locks[i].class_idx - 1; |
2184 | chain_hlocks[chain->base + j] = lock_id; | 2188 | chain_hlocks[chain->base + j] = lock_id; |
2185 | } | 2189 | } |
2186 | chain_hlocks[chain->base + j] = class - lock_classes; | 2190 | chain_hlocks[chain->base + j] = class - lock_classes; |
2187 | } | 2191 | } |
2192 | |||
2193 | if (nr_chain_hlocks < MAX_LOCKDEP_CHAIN_HLOCKS) | ||
2194 | nr_chain_hlocks += chain->depth; | ||
2195 | |||
2196 | #ifdef CONFIG_DEBUG_LOCKDEP | ||
2197 | /* | ||
2198 | * Important for check_no_collision(). | ||
2199 | */ | ||
2200 | if (unlikely(nr_chain_hlocks > MAX_LOCKDEP_CHAIN_HLOCKS)) { | ||
2201 | if (debug_locks_off_graph_unlock()) | ||
2202 | return 0; | ||
2203 | |||
2204 | print_lockdep_off("BUG: MAX_LOCKDEP_CHAIN_HLOCKS too low!"); | ||
2205 | dump_stack(); | ||
2206 | return 0; | ||
2207 | } | ||
2208 | #endif | ||
2209 | |||
2188 | hlist_add_head_rcu(&chain->entry, hash_head); | 2210 | hlist_add_head_rcu(&chain->entry, hash_head); |
2189 | debug_atomic_inc(chain_lookup_misses); | 2211 | debug_atomic_inc(chain_lookup_misses); |
2190 | inc_chains(); | 2212 | inc_chains(); |
@@ -2932,6 +2954,11 @@ static int mark_irqflags(struct task_struct *curr, struct held_lock *hlock) | |||
2932 | return 1; | 2954 | return 1; |
2933 | } | 2955 | } |
2934 | 2956 | ||
2957 | static inline unsigned int task_irq_context(struct task_struct *task) | ||
2958 | { | ||
2959 | return 2 * !!task->hardirq_context + !!task->softirq_context; | ||
2960 | } | ||
2961 | |||
2935 | static int separate_irq_context(struct task_struct *curr, | 2962 | static int separate_irq_context(struct task_struct *curr, |
2936 | struct held_lock *hlock) | 2963 | struct held_lock *hlock) |
2937 | { | 2964 | { |
@@ -2940,8 +2967,6 @@ static int separate_irq_context(struct task_struct *curr, | |||
2940 | /* | 2967 | /* |
2941 | * Keep track of points where we cross into an interrupt context: | 2968 | * Keep track of points where we cross into an interrupt context: |
2942 | */ | 2969 | */ |
2943 | hlock->irq_context = 2*(curr->hardirq_context ? 1 : 0) + | ||
2944 | curr->softirq_context; | ||
2945 | if (depth) { | 2970 | if (depth) { |
2946 | struct held_lock *prev_hlock; | 2971 | struct held_lock *prev_hlock; |
2947 | 2972 | ||
@@ -2973,6 +2998,11 @@ static inline int mark_irqflags(struct task_struct *curr, | |||
2973 | return 1; | 2998 | return 1; |
2974 | } | 2999 | } |
2975 | 3000 | ||
3001 | static inline unsigned int task_irq_context(struct task_struct *task) | ||
3002 | { | ||
3003 | return 0; | ||
3004 | } | ||
3005 | |||
2976 | static inline int separate_irq_context(struct task_struct *curr, | 3006 | static inline int separate_irq_context(struct task_struct *curr, |
2977 | struct held_lock *hlock) | 3007 | struct held_lock *hlock) |
2978 | { | 3008 | { |
@@ -3241,6 +3271,7 @@ static int __lock_acquire(struct lockdep_map *lock, unsigned int subclass, | |||
3241 | hlock->acquire_ip = ip; | 3271 | hlock->acquire_ip = ip; |
3242 | hlock->instance = lock; | 3272 | hlock->instance = lock; |
3243 | hlock->nest_lock = nest_lock; | 3273 | hlock->nest_lock = nest_lock; |
3274 | hlock->irq_context = task_irq_context(curr); | ||
3244 | hlock->trylock = trylock; | 3275 | hlock->trylock = trylock; |
3245 | hlock->read = read; | 3276 | hlock->read = read; |
3246 | hlock->check = check; | 3277 | hlock->check = check; |
diff --git a/kernel/locking/lockdep_proc.c b/kernel/locking/lockdep_proc.c index dbb61a302548..a0f61effad25 100644 --- a/kernel/locking/lockdep_proc.c +++ b/kernel/locking/lockdep_proc.c | |||
@@ -141,6 +141,8 @@ static int lc_show(struct seq_file *m, void *v) | |||
141 | int i; | 141 | int i; |
142 | 142 | ||
143 | if (v == SEQ_START_TOKEN) { | 143 | if (v == SEQ_START_TOKEN) { |
144 | if (nr_chain_hlocks > MAX_LOCKDEP_CHAIN_HLOCKS) | ||
145 | seq_printf(m, "(buggered) "); | ||
144 | seq_printf(m, "all lock chains:\n"); | 146 | seq_printf(m, "all lock chains:\n"); |
145 | return 0; | 147 | return 0; |
146 | } | 148 | } |
diff --git a/kernel/workqueue.c b/kernel/workqueue.c index 2232ae3e3ad6..3bfdff06eea7 100644 --- a/kernel/workqueue.c +++ b/kernel/workqueue.c | |||
@@ -666,6 +666,35 @@ static void set_work_pool_and_clear_pending(struct work_struct *work, | |||
666 | */ | 666 | */ |
667 | smp_wmb(); | 667 | smp_wmb(); |
668 | set_work_data(work, (unsigned long)pool_id << WORK_OFFQ_POOL_SHIFT, 0); | 668 | set_work_data(work, (unsigned long)pool_id << WORK_OFFQ_POOL_SHIFT, 0); |
669 | /* | ||
670 | * The following mb guarantees that previous clear of a PENDING bit | ||
671 | * will not be reordered with any speculative LOADS or STORES from | ||
672 | * work->current_func, which is executed afterwards. This possible | ||
673 | * reordering can lead to a missed execution on attempt to qeueue | ||
674 | * the same @work. E.g. consider this case: | ||
675 | * | ||
676 | * CPU#0 CPU#1 | ||
677 | * ---------------------------- -------------------------------- | ||
678 | * | ||
679 | * 1 STORE event_indicated | ||
680 | * 2 queue_work_on() { | ||
681 | * 3 test_and_set_bit(PENDING) | ||
682 | * 4 } set_..._and_clear_pending() { | ||
683 | * 5 set_work_data() # clear bit | ||
684 | * 6 smp_mb() | ||
685 | * 7 work->current_func() { | ||
686 | * 8 LOAD event_indicated | ||
687 | * } | ||
688 | * | ||
689 | * Without an explicit full barrier speculative LOAD on line 8 can | ||
690 | * be executed before CPU#0 does STORE on line 1. If that happens, | ||
691 | * CPU#0 observes the PENDING bit is still set and new execution of | ||
692 | * a @work is not queued in a hope, that CPU#1 will eventually | ||
693 | * finish the queued @work. Meanwhile CPU#1 does not see | ||
694 | * event_indicated is set, because speculative LOAD was executed | ||
695 | * before actual STORE. | ||
696 | */ | ||
697 | smp_mb(); | ||
669 | } | 698 | } |
670 | 699 | ||
671 | static void clear_work_data(struct work_struct *work) | 700 | static void clear_work_data(struct work_struct *work) |