diff options
author | Yang Shi <yang.shi@linaro.org> | 2019-02-13 11:14:23 -0500 |
---|---|---|
committer | Russell King <rmk+kernel@armlinux.org.uk> | 2019-02-26 06:24:50 -0500 |
commit | 143c2a89e0e5fda6c6fd08d7bc1126438c19ae90 (patch) | |
tree | 81172557d2a330840f8c97d87333f5eb770a1481 /arch/arm/kernel/patch.c | |
parent | fc67e6f120a388b611d94cc40baf99a5cc56b283 (diff) |
ARM: 8839/1: kprobe: make patch_lock a raw_spinlock_t
When running kprobe on -rt kernel, the below bug is caught:
|BUG: sleeping function called from invalid context at kernel/locking/rtmutex.c:931
|in_atomic(): 1, irqs_disabled(): 128, pid: 14, name: migration/0
|Preemption disabled at:[<802f2b98>] cpu_stopper_thread+0xc0/0x140
|CPU: 0 PID: 14 Comm: migration/0 Tainted: G O 4.8.3-rt2 #1
|Hardware name: Freescale LS1021A
|[<8025a43c>] (___might_sleep)
|[<80b5b324>] (rt_spin_lock)
|[<80b5c31c>] (__patch_text_real)
|[<80b5c3ac>] (patch_text_stop_machine)
|[<802f2920>] (multi_cpu_stop)
Since patch_text_stop_machine() is called in stop_machine() which
disables IRQ, sleepable lock should be not used in this atomic context,
so replace patch_lock to raw lock.
Signed-off-by: Yang Shi <yang.shi@linaro.org>
Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
Reviewed-by: Arnd Bergmann <arnd@arndb.de>
Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
Diffstat (limited to 'arch/arm/kernel/patch.c')
-rw-r--r-- | arch/arm/kernel/patch.c | 6 |
1 files changed, 3 insertions, 3 deletions
diff --git a/arch/arm/kernel/patch.c b/arch/arm/kernel/patch.c index a50dc00d79a2..d0a05a3bdb96 100644 --- a/arch/arm/kernel/patch.c +++ b/arch/arm/kernel/patch.c | |||
@@ -16,7 +16,7 @@ struct patch { | |||
16 | unsigned int insn; | 16 | unsigned int insn; |
17 | }; | 17 | }; |
18 | 18 | ||
19 | static DEFINE_SPINLOCK(patch_lock); | 19 | static DEFINE_RAW_SPINLOCK(patch_lock); |
20 | 20 | ||
21 | static void __kprobes *patch_map(void *addr, int fixmap, unsigned long *flags) | 21 | static void __kprobes *patch_map(void *addr, int fixmap, unsigned long *flags) |
22 | __acquires(&patch_lock) | 22 | __acquires(&patch_lock) |
@@ -33,7 +33,7 @@ static void __kprobes *patch_map(void *addr, int fixmap, unsigned long *flags) | |||
33 | return addr; | 33 | return addr; |
34 | 34 | ||
35 | if (flags) | 35 | if (flags) |
36 | spin_lock_irqsave(&patch_lock, *flags); | 36 | raw_spin_lock_irqsave(&patch_lock, *flags); |
37 | else | 37 | else |
38 | __acquire(&patch_lock); | 38 | __acquire(&patch_lock); |
39 | 39 | ||
@@ -48,7 +48,7 @@ static void __kprobes patch_unmap(int fixmap, unsigned long *flags) | |||
48 | clear_fixmap(fixmap); | 48 | clear_fixmap(fixmap); |
49 | 49 | ||
50 | if (flags) | 50 | if (flags) |
51 | spin_unlock_irqrestore(&patch_lock, *flags); | 51 | raw_spin_unlock_irqrestore(&patch_lock, *flags); |
52 | else | 52 | else |
53 | __release(&patch_lock); | 53 | __release(&patch_lock); |
54 | } | 54 | } |