MIPS: Fix watchpoint restoration
Commitf51246efee
("MIPS: Get rid of finish_arch_switch().") moved the __restore_watch() call from finish_arch_switch() (i.e. after resume() returns) to before the resume() call in switch_to(). This results in watchpoints only being restored when a task is descheduled, preventing the watchpoints from being effective most of the time, except due to chance before the watchpoints are lazily removed. Fix the call sequence from switch_to() through to mips_install_watch_registers() to pass the task_struct pointer of the next task, instead of using current. This allows the watchpoints for the next (non-current) task to be restored without reintroducing finish_arch_switch(). Fixes:f51246efee
("MIPS: Get rid of finish_arch_switch().") Signed-off-by: James Hogan <james.hogan@imgtec.com> Cc: Paul Burton <paul.burton@imgtec.com> Cc: linux-mips@linux-mips.org Cc: <stable@vger.kernel.org> # 4.3.x- Patchwork: https://patchwork.linux-mips.org/patch/12726/ Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
This commit is contained in:
parent
81a76d7119
commit
a7e89326b4
|
@ -105,7 +105,7 @@ do { \
|
|||
__clear_software_ll_bit(); \
|
||||
if (cpu_has_userlocal) \
|
||||
write_c0_userlocal(task_thread_info(next)->tp_value); \
|
||||
__restore_watch(); \
|
||||
__restore_watch(next); \
|
||||
(last) = resume(prev, next, task_thread_info(next)); \
|
||||
} while (0)
|
||||
|
||||
|
|
|
@ -12,21 +12,21 @@
|
|||
|
||||
#include <asm/mipsregs.h>
|
||||
|
||||
void mips_install_watch_registers(void);
|
||||
void mips_install_watch_registers(struct task_struct *t);
|
||||
void mips_read_watch_registers(void);
|
||||
void mips_clear_watch_registers(void);
|
||||
void mips_probe_watch_registers(struct cpuinfo_mips *c);
|
||||
|
||||
#ifdef CONFIG_HARDWARE_WATCHPOINTS
|
||||
#define __restore_watch() do { \
|
||||
#define __restore_watch(task) do { \
|
||||
if (unlikely(test_bit(TIF_LOAD_WATCH, \
|
||||
¤t_thread_info()->flags))) { \
|
||||
mips_install_watch_registers(); \
|
||||
&task_thread_info(task)->flags))) { \
|
||||
mips_install_watch_registers(task); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#else
|
||||
#define __restore_watch() do {} while (0)
|
||||
#define __restore_watch(task) do {} while (0)
|
||||
#endif
|
||||
|
||||
#endif /* _ASM_WATCH_H */
|
||||
|
|
|
@ -56,7 +56,7 @@ static void mips_cpu_restore(void)
|
|||
write_c0_userlocal(current_thread_info()->tp_value);
|
||||
|
||||
/* Restore watch registers */
|
||||
__restore_watch();
|
||||
__restore_watch(current);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -15,10 +15,9 @@
|
|||
* Install the watch registers for the current thread. A maximum of
|
||||
* four registers are installed although the machine may have more.
|
||||
*/
|
||||
void mips_install_watch_registers(void)
|
||||
void mips_install_watch_registers(struct task_struct *t)
|
||||
{
|
||||
struct mips3264_watch_reg_state *watches =
|
||||
¤t->thread.watch.mips3264;
|
||||
struct mips3264_watch_reg_state *watches = &t->thread.watch.mips3264;
|
||||
switch (current_cpu_data.watch_reg_use_cnt) {
|
||||
default:
|
||||
BUG();
|
||||
|
|
Loading…
Reference in New Issue