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 | ||
