]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/blame - releases/4.4.13/mips-fix-watchpoint-restoration.patch
4.9-stable patches
[thirdparty/kernel/stable-queue.git] / releases / 4.4.13 / mips-fix-watchpoint-restoration.patch
CommitLineData
87d2113e
GKH
1From a7e89326b415b5d81c4b1016fd4a40db861eb58d Mon Sep 17 00:00:00 2001
2From: James Hogan <james.hogan@imgtec.com>
3Date: Tue, 1 Mar 2016 22:19:36 +0000
4Subject: MIPS: Fix watchpoint restoration
5
6From: James Hogan <james.hogan@imgtec.com>
7
8commit a7e89326b415b5d81c4b1016fd4a40db861eb58d upstream.
9
10Commit f51246efee2b ("MIPS: Get rid of finish_arch_switch().") moved the
11__restore_watch() call from finish_arch_switch() (i.e. after resume()
12returns) to before the resume() call in switch_to(). This results in
13watchpoints only being restored when a task is descheduled, preventing
14the watchpoints from being effective most of the time, except due to
15chance before the watchpoints are lazily removed.
16
17Fix the call sequence from switch_to() through to
18mips_install_watch_registers() to pass the task_struct pointer of the
19next task, instead of using current. This allows the watchpoints for the
20next (non-current) task to be restored without reintroducing
21finish_arch_switch().
22
23Fixes: f51246efee2b ("MIPS: Get rid of finish_arch_switch().")
24Signed-off-by: James Hogan <james.hogan@imgtec.com>
25Cc: Paul Burton <paul.burton@imgtec.com>
26Cc: linux-mips@linux-mips.org
27Patchwork: https://patchwork.linux-mips.org/patch/12726/
28Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
29Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
30
31---
32 arch/mips/include/asm/switch_to.h | 2 +-
33 arch/mips/include/asm/watch.h | 10 +++++-----
34 arch/mips/kernel/pm.c | 2 +-
35 arch/mips/kernel/watch.c | 5 ++---
36 4 files changed, 9 insertions(+), 10 deletions(-)
37
38--- a/arch/mips/include/asm/switch_to.h
39+++ b/arch/mips/include/asm/switch_to.h
40@@ -105,7 +105,7 @@ do { \
41 __clear_software_ll_bit(); \
42 if (cpu_has_userlocal) \
43 write_c0_userlocal(task_thread_info(next)->tp_value); \
44- __restore_watch(); \
45+ __restore_watch(next); \
46 (last) = resume(prev, next, task_thread_info(next)); \
47 } while (0)
48
49--- a/arch/mips/include/asm/watch.h
50+++ b/arch/mips/include/asm/watch.h
51@@ -12,21 +12,21 @@
52
53 #include <asm/mipsregs.h>
54
55-void mips_install_watch_registers(void);
56+void mips_install_watch_registers(struct task_struct *t);
57 void mips_read_watch_registers(void);
58 void mips_clear_watch_registers(void);
59 void mips_probe_watch_registers(struct cpuinfo_mips *c);
60
61 #ifdef CONFIG_HARDWARE_WATCHPOINTS
62-#define __restore_watch() do { \
63+#define __restore_watch(task) do { \
64 if (unlikely(test_bit(TIF_LOAD_WATCH, \
65- &current_thread_info()->flags))) { \
66- mips_install_watch_registers(); \
67+ &task_thread_info(task)->flags))) { \
68+ mips_install_watch_registers(task); \
69 } \
70 } while (0)
71
72 #else
73-#define __restore_watch() do {} while (0)
74+#define __restore_watch(task) do {} while (0)
75 #endif
76
77 #endif /* _ASM_WATCH_H */
78--- a/arch/mips/kernel/pm.c
79+++ b/arch/mips/kernel/pm.c
80@@ -56,7 +56,7 @@ static void mips_cpu_restore(void)
81 write_c0_userlocal(current_thread_info()->tp_value);
82
83 /* Restore watch registers */
84- __restore_watch();
85+ __restore_watch(current);
86 }
87
88 /**
89--- a/arch/mips/kernel/watch.c
90+++ b/arch/mips/kernel/watch.c
91@@ -15,10 +15,9 @@
92 * Install the watch registers for the current thread. A maximum of
93 * four registers are installed although the machine may have more.
94 */
95-void mips_install_watch_registers(void)
96+void mips_install_watch_registers(struct task_struct *t)
97 {
98- struct mips3264_watch_reg_state *watches =
99- &current->thread.watch.mips3264;
100+ struct mips3264_watch_reg_state *watches = &t->thread.watch.mips3264;
101 switch (current_cpu_data.watch_reg_use_cnt) {
102 default:
103 BUG();