aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/mips/kernel/process.c34
1 files changed, 32 insertions, 2 deletions
diff --git a/arch/mips/kernel/process.c b/arch/mips/kernel/process.c
index 785bf2a4129a..a682a87bcc04 100644
--- a/arch/mips/kernel/process.c
+++ b/arch/mips/kernel/process.c
@@ -224,6 +224,9 @@ struct mips_frame_info {
224 int pc_offset; 224 int pc_offset;
225}; 225};
226 226
227#define J_TARGET(pc,target) \
228 (((unsigned long)(pc) & 0xf0000000) | ((target) << 2))
229
227static inline int is_ra_save_ins(union mips_instruction *ip) 230static inline int is_ra_save_ins(union mips_instruction *ip)
228{ 231{
229#ifdef CONFIG_CPU_MICROMIPS 232#ifdef CONFIG_CPU_MICROMIPS
@@ -395,15 +398,42 @@ err:
395 398
396static struct mips_frame_info schedule_mfi __read_mostly; 399static struct mips_frame_info schedule_mfi __read_mostly;
397 400
401#ifdef CONFIG_KALLSYMS
402static unsigned long get___schedule_addr(void)
403{
404 return kallsyms_lookup_name("__schedule");
405}
406#else
407static unsigned long get___schedule_addr(void)
408{
409 union mips_instruction *ip = (void *)schedule;
410 int max_insns = 8;
411 int i;
412
413 for (i = 0; i < max_insns; i++, ip++) {
414 if (ip->j_format.opcode == j_op)
415 return J_TARGET(ip, ip->j_format.target);
416 }
417 return 0;
418}
419#endif
420
398static int __init frame_info_init(void) 421static int __init frame_info_init(void)
399{ 422{
400 unsigned long size = 0; 423 unsigned long size = 0;
401#ifdef CONFIG_KALLSYMS 424#ifdef CONFIG_KALLSYMS
402 unsigned long ofs; 425 unsigned long ofs;
426#endif
427 unsigned long addr;
403 428
404 kallsyms_lookup_size_offset((unsigned long)schedule, &size, &ofs); 429 addr = get___schedule_addr();
430 if (!addr)
431 addr = (unsigned long)schedule;
432
433#ifdef CONFIG_KALLSYMS
434 kallsyms_lookup_size_offset(addr, &size, &ofs);
405#endif 435#endif
406 schedule_mfi.func = schedule; 436 schedule_mfi.func = (void *)addr;
407 schedule_mfi.func_size = size; 437 schedule_mfi.func_size = size;
408 438
409 get_frame_info(&schedule_mfi); 439 get_frame_info(&schedule_mfi);