data.trace = trace;
        data.skip = trace->skip;
 -      base = (unsigned long)task_stack_page(current);
 -      asm("mov %0, fp" : "=r" (fp));
 +      base = (unsigned long)task_stack_page(tsk);
 +
 +      if (tsk != current) {
 +#ifdef CONFIG_SMP
 +              /*
 +               * What guarantees do we have here that 'tsk'
 +               * is not running on another CPU?
 +               */
 +              BUG();
 +#else
 +              data.no_sched_functions = 1;
 +              fp = thread_saved_fp(tsk);
 +#endif
 +      } else {
 +              data.no_sched_functions = 0;
 +              asm("mov %0, fp" : "=r" (fp));
 +      }
  
        walk_stackframe(fp, base, base + THREAD_SIZE, save_trace, &data);
 +      if (trace->nr_entries < trace->max_entries)
 +              trace->entries[trace->nr_entries++] = ULONG_MAX;
 +}
 +
 +void save_stack_trace(struct stack_trace *trace)
 +{
 +      save_stack_trace_tsk(current, trace);
  }
+ EXPORT_SYMBOL_GPL(save_stack_trace);
  #endif