aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/fault-injection/fault-injection.txt11
-rw-r--r--kernel/futex.c89
-rw-r--r--lib/Kconfig.debug7
3 files changed, 105 insertions, 2 deletions
diff --git a/Documentation/fault-injection/fault-injection.txt b/Documentation/fault-injection/fault-injection.txt
index 4cf1a2a6bd72..415484f3d59a 100644
--- a/Documentation/fault-injection/fault-injection.txt
+++ b/Documentation/fault-injection/fault-injection.txt
@@ -15,6 +15,10 @@ o fail_page_alloc
15 15
16 injects page allocation failures. (alloc_pages(), get_free_pages(), ...) 16 injects page allocation failures. (alloc_pages(), get_free_pages(), ...)
17 17
18o fail_futex
19
20 injects futex deadlock and uaddr fault errors.
21
18o fail_make_request 22o fail_make_request
19 23
20 injects disk IO errors on devices permitted by setting 24 injects disk IO errors on devices permitted by setting
@@ -113,6 +117,12 @@ configuration of fault-injection capabilities.
113 specifies the minimum page allocation order to be injected 117 specifies the minimum page allocation order to be injected
114 failures. 118 failures.
115 119
120- /sys/kernel/debug/fail_futex/ignore-private:
121
122 Format: { 'Y' | 'N' }
123 default is 'N', setting it to 'Y' will disable failure injections
124 when dealing with private (address space) futexes.
125
116o Boot option 126o Boot option
117 127
118In order to inject faults while debugfs is not available (early boot time), 128In order to inject faults while debugfs is not available (early boot time),
@@ -121,6 +131,7 @@ use the boot option:
121 failslab= 131 failslab=
122 fail_page_alloc= 132 fail_page_alloc=
123 fail_make_request= 133 fail_make_request=
134 fail_futex=
124 mmc_core.fail_request=<interval>,<probability>,<space>,<times> 135 mmc_core.fail_request=<interval>,<probability>,<space>,<times>
125 136
126How to add new fault injection capability 137How to add new fault injection capability
diff --git a/kernel/futex.c b/kernel/futex.c
index 153eb22b0fc0..6ea31bb703c9 100644
--- a/kernel/futex.c
+++ b/kernel/futex.c
@@ -64,6 +64,7 @@
64#include <linux/hugetlb.h> 64#include <linux/hugetlb.h>
65#include <linux/freezer.h> 65#include <linux/freezer.h>
66#include <linux/bootmem.h> 66#include <linux/bootmem.h>
67#include <linux/fault-inject.h>
67 68
68#include <asm/futex.h> 69#include <asm/futex.h>
69 70
@@ -258,6 +259,66 @@ static unsigned long __read_mostly futex_hashsize;
258 259
259static struct futex_hash_bucket *futex_queues; 260static struct futex_hash_bucket *futex_queues;
260 261
262/*
263 * Fault injections for futexes.
264 */
265#ifdef CONFIG_FAIL_FUTEX
266
267static struct {
268 struct fault_attr attr;
269
270 u32 ignore_private;
271} fail_futex = {
272 .attr = FAULT_ATTR_INITIALIZER,
273 .ignore_private = 0,
274};
275
276static int __init setup_fail_futex(char *str)
277{
278 return setup_fault_attr(&fail_futex.attr, str);
279}
280__setup("fail_futex=", setup_fail_futex);
281
282bool should_fail_futex(bool fshared)
283{
284 if (fail_futex.ignore_private && !fshared)
285 return false;
286
287 return should_fail(&fail_futex.attr, 1);
288}
289
290#ifdef CONFIG_FAULT_INJECTION_DEBUG_FS
291
292static int __init fail_futex_debugfs(void)
293{
294 umode_t mode = S_IFREG | S_IRUSR | S_IWUSR;
295 struct dentry *dir;
296
297 dir = fault_create_debugfs_attr("fail_futex", NULL,
298 &fail_futex.attr);
299 if (IS_ERR(dir))
300 return PTR_ERR(dir);
301
302 if (!debugfs_create_bool("ignore-private", mode, dir,
303 &fail_futex.ignore_private)) {
304 debugfs_remove_recursive(dir);
305 return -ENOMEM;
306 }
307
308 return 0;
309}
310
311late_initcall(fail_futex_debugfs);
312
313#endif /* CONFIG_FAULT_INJECTION_DEBUG_FS */
314
315#else
316static inline bool should_fail_futex(bool fshared)
317{
318 return false;
319}
320#endif /* CONFIG_FAIL_FUTEX */
321
261static inline void futex_get_mm(union futex_key *key) 322static inline void futex_get_mm(union futex_key *key)
262{ 323{
263 atomic_inc(&key->private.mm->mm_count); 324 atomic_inc(&key->private.mm->mm_count);
@@ -413,6 +474,9 @@ get_futex_key(u32 __user *uaddr, int fshared, union futex_key *key, int rw)
413 if (unlikely(!access_ok(rw, uaddr, sizeof(u32)))) 474 if (unlikely(!access_ok(rw, uaddr, sizeof(u32))))
414 return -EFAULT; 475 return -EFAULT;
415 476
477 if (unlikely(should_fail_futex(fshared)))
478 return -EFAULT;
479
416 /* 480 /*
417 * PROCESS_PRIVATE futexes are fast. 481 * PROCESS_PRIVATE futexes are fast.
418 * As the mm cannot disappear under us and the 'key' only needs 482 * As the mm cannot disappear under us and the 'key' only needs
@@ -428,6 +492,10 @@ get_futex_key(u32 __user *uaddr, int fshared, union futex_key *key, int rw)
428 } 492 }
429 493
430again: 494again:
495 /* Ignore any VERIFY_READ mapping (futex common case) */
496 if (unlikely(should_fail_futex(fshared)))
497 return -EFAULT;
498
431 err = get_user_pages_fast(address, 1, 1, &page); 499 err = get_user_pages_fast(address, 1, 1, &page);
432 /* 500 /*
433 * If write access is not required (eg. FUTEX_WAIT), try 501 * If write access is not required (eg. FUTEX_WAIT), try
@@ -516,7 +584,7 @@ again:
516 * A RO anonymous page will never change and thus doesn't make 584 * A RO anonymous page will never change and thus doesn't make
517 * sense for futex operations. 585 * sense for futex operations.
518 */ 586 */
519 if (ro) { 587 if (unlikely(should_fail_futex(fshared)) || ro) {
520 err = -EFAULT; 588 err = -EFAULT;
521 goto out; 589 goto out;
522 } 590 }
@@ -974,6 +1042,9 @@ static int lock_pi_update_atomic(u32 __user *uaddr, u32 uval, u32 newval)
974{ 1042{
975 u32 uninitialized_var(curval); 1043 u32 uninitialized_var(curval);
976 1044
1045 if (unlikely(should_fail_futex(true)))
1046 return -EFAULT;
1047
977 if (unlikely(cmpxchg_futex_value_locked(&curval, uaddr, uval, newval))) 1048 if (unlikely(cmpxchg_futex_value_locked(&curval, uaddr, uval, newval)))
978 return -EFAULT; 1049 return -EFAULT;
979 1050
@@ -1015,12 +1086,18 @@ static int futex_lock_pi_atomic(u32 __user *uaddr, struct futex_hash_bucket *hb,
1015 if (get_futex_value_locked(&uval, uaddr)) 1086 if (get_futex_value_locked(&uval, uaddr))
1016 return -EFAULT; 1087 return -EFAULT;
1017 1088
1089 if (unlikely(should_fail_futex(true)))
1090 return -EFAULT;
1091
1018 /* 1092 /*
1019 * Detect deadlocks. 1093 * Detect deadlocks.
1020 */ 1094 */
1021 if ((unlikely((uval & FUTEX_TID_MASK) == vpid))) 1095 if ((unlikely((uval & FUTEX_TID_MASK) == vpid)))
1022 return -EDEADLK; 1096 return -EDEADLK;
1023 1097
1098 if ((unlikely(should_fail_futex(true))))
1099 return -EDEADLK;
1100
1024 /* 1101 /*
1025 * Lookup existing state first. If it exists, try to attach to 1102 * Lookup existing state first. If it exists, try to attach to
1026 * its pi_state. 1103 * its pi_state.
@@ -1155,6 +1232,9 @@ static int wake_futex_pi(u32 __user *uaddr, u32 uval, struct futex_q *this,
1155 */ 1232 */
1156 newval = FUTEX_WAITERS | task_pid_vnr(new_owner); 1233 newval = FUTEX_WAITERS | task_pid_vnr(new_owner);
1157 1234
1235 if (unlikely(should_fail_futex(true)))
1236 ret = -EFAULT;
1237
1158 if (cmpxchg_futex_value_locked(&curval, uaddr, uval, newval)) 1238 if (cmpxchg_futex_value_locked(&curval, uaddr, uval, newval))
1159 ret = -EFAULT; 1239 ret = -EFAULT;
1160 else if (curval != uval) 1240 else if (curval != uval)
@@ -1457,6 +1537,9 @@ static int futex_proxy_trylock_atomic(u32 __user *pifutex,
1457 if (get_futex_value_locked(&curval, pifutex)) 1537 if (get_futex_value_locked(&curval, pifutex))
1458 return -EFAULT; 1538 return -EFAULT;
1459 1539
1540 if (unlikely(should_fail_futex(true)))
1541 return -EFAULT;
1542
1460 /* 1543 /*
1461 * Find the top_waiter and determine if there are additional waiters. 1544 * Find the top_waiter and determine if there are additional waiters.
1462 * If the caller intends to requeue more than 1 waiter to pifutex, 1545 * If the caller intends to requeue more than 1 waiter to pifutex,
@@ -2537,7 +2620,7 @@ int handle_early_requeue_pi_wakeup(struct futex_hash_bucket *hb,
2537 * futex_wait_requeue_pi() - Wait on uaddr and take uaddr2 2620 * futex_wait_requeue_pi() - Wait on uaddr and take uaddr2
2538 * @uaddr: the futex we initially wait on (non-pi) 2621 * @uaddr: the futex we initially wait on (non-pi)
2539 * @flags: futex flags (FLAGS_SHARED, FLAGS_CLOCKRT, etc.), they must be 2622 * @flags: futex flags (FLAGS_SHARED, FLAGS_CLOCKRT, etc.), they must be
2540 * the same type, no requeueing from private to shared, etc. 2623 * the same type, no requeueing from private to shared, etc.
2541 * @val: the expected value of uaddr 2624 * @val: the expected value of uaddr
2542 * @abs_time: absolute timeout 2625 * @abs_time: absolute timeout
2543 * @bitset: 32 bit wakeup bitset set by userspace, defaults to all 2626 * @bitset: 32 bit wakeup bitset set by userspace, defaults to all
@@ -3012,6 +3095,8 @@ SYSCALL_DEFINE6(futex, u32 __user *, uaddr, int, op, u32, val,
3012 if (utime && (cmd == FUTEX_WAIT || cmd == FUTEX_LOCK_PI || 3095 if (utime && (cmd == FUTEX_WAIT || cmd == FUTEX_LOCK_PI ||
3013 cmd == FUTEX_WAIT_BITSET || 3096 cmd == FUTEX_WAIT_BITSET ||
3014 cmd == FUTEX_WAIT_REQUEUE_PI)) { 3097 cmd == FUTEX_WAIT_REQUEUE_PI)) {
3098 if (unlikely(should_fail_futex(!(op & FUTEX_PRIVATE_FLAG))))
3099 return -EFAULT;
3015 if (copy_from_user(&ts, utime, sizeof(ts)) != 0) 3100 if (copy_from_user(&ts, utime, sizeof(ts)) != 0)
3016 return -EFAULT; 3101 return -EFAULT;
3017 if (!timespec_valid(&ts)) 3102 if (!timespec_valid(&ts))
diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug
index e2894b23efb6..22554d6f720f 100644
--- a/lib/Kconfig.debug
+++ b/lib/Kconfig.debug
@@ -1542,6 +1542,13 @@ config FAIL_MMC_REQUEST
1542 and to test how the mmc host driver handles retries from 1542 and to test how the mmc host driver handles retries from
1543 the block device. 1543 the block device.
1544 1544
1545config FAIL_FUTEX
1546 bool "Fault-injection capability for futexes"
1547 select DEBUG_FS
1548 depends on FAULT_INJECTION && FUTEX
1549 help
1550 Provide fault-injection capability for futexes.
1551
1545config FAULT_INJECTION_DEBUG_FS 1552config FAULT_INJECTION_DEBUG_FS
1546 bool "Debugfs entries for fault-injection capabilities" 1553 bool "Debugfs entries for fault-injection capabilities"
1547 depends on FAULT_INJECTION && SYSFS && DEBUG_FS 1554 depends on FAULT_INJECTION && SYSFS && DEBUG_FS