diff options
Diffstat (limited to 'arch/arm/kernel/process.c')
-rw-r--r-- | arch/arm/kernel/process.c | 24 |
1 files changed, 24 insertions, 0 deletions
diff --git a/arch/arm/kernel/process.c b/arch/arm/kernel/process.c index 401e38be1f78..3af34bf4f4df 100644 --- a/arch/arm/kernel/process.c +++ b/arch/arm/kernel/process.c | |||
@@ -29,6 +29,7 @@ | |||
29 | #include <linux/utsname.h> | 29 | #include <linux/utsname.h> |
30 | #include <linux/uaccess.h> | 30 | #include <linux/uaccess.h> |
31 | #include <linux/random.h> | 31 | #include <linux/random.h> |
32 | #include <linux/hw_breakpoint.h> | ||
32 | 33 | ||
33 | #include <asm/cacheflush.h> | 34 | #include <asm/cacheflush.h> |
34 | #include <asm/leds.h> | 35 | #include <asm/leds.h> |
@@ -135,6 +136,25 @@ EXPORT_SYMBOL(pm_power_off); | |||
135 | void (*arm_pm_restart)(char str, const char *cmd) = arm_machine_restart; | 136 | void (*arm_pm_restart)(char str, const char *cmd) = arm_machine_restart; |
136 | EXPORT_SYMBOL_GPL(arm_pm_restart); | 137 | EXPORT_SYMBOL_GPL(arm_pm_restart); |
137 | 138 | ||
139 | static void do_nothing(void *unused) | ||
140 | { | ||
141 | } | ||
142 | |||
143 | /* | ||
144 | * cpu_idle_wait - Used to ensure that all the CPUs discard old value of | ||
145 | * pm_idle and update to new pm_idle value. Required while changing pm_idle | ||
146 | * handler on SMP systems. | ||
147 | * | ||
148 | * Caller must have changed pm_idle to the new value before the call. Old | ||
149 | * pm_idle value will not be used by any CPU after the return of this function. | ||
150 | */ | ||
151 | void cpu_idle_wait(void) | ||
152 | { | ||
153 | smp_mb(); | ||
154 | /* kick all the CPUs so that they exit out of pm_idle */ | ||
155 | smp_call_function(do_nothing, NULL, 1); | ||
156 | } | ||
157 | EXPORT_SYMBOL_GPL(cpu_idle_wait); | ||
138 | 158 | ||
139 | /* | 159 | /* |
140 | * This is our default idle handler. We need to disable | 160 | * This is our default idle handler. We need to disable |
@@ -317,6 +337,8 @@ void flush_thread(void) | |||
317 | struct thread_info *thread = current_thread_info(); | 337 | struct thread_info *thread = current_thread_info(); |
318 | struct task_struct *tsk = current; | 338 | struct task_struct *tsk = current; |
319 | 339 | ||
340 | flush_ptrace_hw_breakpoint(tsk); | ||
341 | |||
320 | memset(thread->used_cp, 0, sizeof(thread->used_cp)); | 342 | memset(thread->used_cp, 0, sizeof(thread->used_cp)); |
321 | memset(&tsk->thread.debug, 0, sizeof(struct debug_info)); | 343 | memset(&tsk->thread.debug, 0, sizeof(struct debug_info)); |
322 | memset(&thread->fpstate, 0, sizeof(union fp_state)); | 344 | memset(&thread->fpstate, 0, sizeof(union fp_state)); |
@@ -345,6 +367,8 @@ copy_thread(unsigned long clone_flags, unsigned long stack_start, | |||
345 | thread->cpu_context.sp = (unsigned long)childregs; | 367 | thread->cpu_context.sp = (unsigned long)childregs; |
346 | thread->cpu_context.pc = (unsigned long)ret_from_fork; | 368 | thread->cpu_context.pc = (unsigned long)ret_from_fork; |
347 | 369 | ||
370 | clear_ptrace_hw_breakpoint(p); | ||
371 | |||
348 | if (clone_flags & CLONE_SETTLS) | 372 | if (clone_flags & CLONE_SETTLS) |
349 | thread->tp_value = regs->ARM_r3; | 373 | thread->tp_value = regs->ARM_r3; |
350 | 374 | ||