summaryrefslogtreecommitdiffstats
path: root/arch/mips/kernel/process.c
diff options
context:
space:
mode:
authorMark Brown <broonie@opensource.wolfsonmicro.com>2013-05-21 11:39:21 -0500
committerMark Brown <broonie@opensource.wolfsonmicro.com>2013-05-21 11:39:21 -0500
commit4510dbe324876f2f2f3dc9931e97ec0e98f1ee26 (patch)
treed42a8ff24b82e0c6b01756b3f2c33756fc30fc17 /arch/mips/kernel/process.c
parentb296263398f08d21e68d5d7b2afc43228c208b71 (diff)
parentc7788792a5e7b0d5d7f96d0766b4cb6112d47d75 (diff)
downloadblackbird-op-linux-4510dbe324876f2f2f3dc9931e97ec0e98f1ee26.tar.gz
blackbird-op-linux-4510dbe324876f2f2f3dc9931e97ec0e98f1ee26.zip
Merge tag 'v3.10-rc2' into asoc-ux500
Linux 3.10-rc2
Diffstat (limited to 'arch/mips/kernel/process.c')
-rw-r--r--arch/mips/kernel/process.c40
1 files changed, 36 insertions, 4 deletions
diff --git a/arch/mips/kernel/process.c b/arch/mips/kernel/process.c
index eb902c1f0cad..a682a87bcc04 100644
--- a/arch/mips/kernel/process.c
+++ b/arch/mips/kernel/process.c
@@ -224,6 +224,9 @@ struct mips_frame_info {
int pc_offset;
};
+#define J_TARGET(pc,target) \
+ (((unsigned long)(pc) & 0xf0000000) | ((target) << 2))
+
static inline int is_ra_save_ins(union mips_instruction *ip)
{
#ifdef CONFIG_CPU_MICROMIPS
@@ -264,7 +267,7 @@ static inline int is_ra_save_ins(union mips_instruction *ip)
#endif
}
-static inline int is_jal_jalr_jr_ins(union mips_instruction *ip)
+static inline int is_jump_ins(union mips_instruction *ip)
{
#ifdef CONFIG_CPU_MICROMIPS
/*
@@ -288,6 +291,8 @@ static inline int is_jal_jalr_jr_ins(union mips_instruction *ip)
return 0;
return (((ip->u_format.uimmediate >> 6) & mm_jalr_op) == mm_jalr_op);
#else
+ if (ip->j_format.opcode == j_op)
+ return 1;
if (ip->j_format.opcode == jal_op)
return 1;
if (ip->r_format.opcode != spec_op)
@@ -350,7 +355,7 @@ static int get_frame_info(struct mips_frame_info *info)
for (i = 0; i < max_insns; i++, ip++) {
- if (is_jal_jalr_jr_ins(ip))
+ if (is_jump_ins(ip))
break;
if (!info->frame_size) {
if (is_sp_move_ins(ip))
@@ -393,15 +398,42 @@ err:
static struct mips_frame_info schedule_mfi __read_mostly;
+#ifdef CONFIG_KALLSYMS
+static unsigned long get___schedule_addr(void)
+{
+ return kallsyms_lookup_name("__schedule");
+}
+#else
+static unsigned long get___schedule_addr(void)
+{
+ union mips_instruction *ip = (void *)schedule;
+ int max_insns = 8;
+ int i;
+
+ for (i = 0; i < max_insns; i++, ip++) {
+ if (ip->j_format.opcode == j_op)
+ return J_TARGET(ip, ip->j_format.target);
+ }
+ return 0;
+}
+#endif
+
static int __init frame_info_init(void)
{
unsigned long size = 0;
#ifdef CONFIG_KALLSYMS
unsigned long ofs;
+#endif
+ unsigned long addr;
- kallsyms_lookup_size_offset((unsigned long)schedule, &size, &ofs);
+ addr = get___schedule_addr();
+ if (!addr)
+ addr = (unsigned long)schedule;
+
+#ifdef CONFIG_KALLSYMS
+ kallsyms_lookup_size_offset(addr, &size, &ofs);
#endif
- schedule_mfi.func = schedule;
+ schedule_mfi.func = (void *)addr;
schedule_mfi.func_size = size;
get_frame_info(&schedule_mfi);
OpenPOWER on IntegriCloud