diff options
Diffstat (limited to 'arch')
-rw-r--r-- | arch/mips/include/asm/switch_to.h | 9 | ||||
-rw-r--r-- | arch/mips/include/asm/thread_info.h | 2 | ||||
-rw-r--r-- | arch/mips/kernel/asm-offsets.c | 1 | ||||
-rw-r--r-- | arch/mips/kernel/entry.S | 18 | ||||
-rw-r--r-- | arch/mips/kernel/traps.c | 2 |
5 files changed, 28 insertions, 4 deletions
diff --git a/arch/mips/include/asm/switch_to.h b/arch/mips/include/asm/switch_to.h index b928b6f898cd..e92d6c4b5ed1 100644 --- a/arch/mips/include/asm/switch_to.h +++ b/arch/mips/include/asm/switch_to.h | |||
@@ -75,9 +75,12 @@ do { \ | |||
75 | #endif | 75 | #endif |
76 | 76 | ||
77 | #define __clear_software_ll_bit() \ | 77 | #define __clear_software_ll_bit() \ |
78 | do { \ | 78 | do { if (cpu_has_rw_llb) { \ |
79 | if (!__builtin_constant_p(cpu_has_llsc) || !cpu_has_llsc) \ | 79 | write_c0_lladdr(0); \ |
80 | ll_bit = 0; \ | 80 | } else { \ |
81 | if (!__builtin_constant_p(cpu_has_llsc) || !cpu_has_llsc)\ | ||
82 | ll_bit = 0; \ | ||
83 | } \ | ||
81 | } while (0) | 84 | } while (0) |
82 | 85 | ||
83 | #define switch_to(prev, next, last) \ | 86 | #define switch_to(prev, next, last) \ |
diff --git a/arch/mips/include/asm/thread_info.h b/arch/mips/include/asm/thread_info.h index 99eea59604e9..fb68fd2714fb 100644 --- a/arch/mips/include/asm/thread_info.h +++ b/arch/mips/include/asm/thread_info.h | |||
@@ -28,7 +28,7 @@ struct thread_info { | |||
28 | unsigned long tp_value; /* thread pointer */ | 28 | unsigned long tp_value; /* thread pointer */ |
29 | __u32 cpu; /* current CPU */ | 29 | __u32 cpu; /* current CPU */ |
30 | int preempt_count; /* 0 => preemptable, <0 => BUG */ | 30 | int preempt_count; /* 0 => preemptable, <0 => BUG */ |
31 | 31 | int r2_emul_return; /* 1 => Returning from R2 emulator */ | |
32 | mm_segment_t addr_limit; /* | 32 | mm_segment_t addr_limit; /* |
33 | * thread address space limit: | 33 | * thread address space limit: |
34 | * 0x7fffffff for user-thead | 34 | * 0x7fffffff for user-thead |
diff --git a/arch/mips/kernel/asm-offsets.c b/arch/mips/kernel/asm-offsets.c index b1d84bd4efb3..7b6c11aa1cae 100644 --- a/arch/mips/kernel/asm-offsets.c +++ b/arch/mips/kernel/asm-offsets.c | |||
@@ -97,6 +97,7 @@ void output_thread_info_defines(void) | |||
97 | OFFSET(TI_TP_VALUE, thread_info, tp_value); | 97 | OFFSET(TI_TP_VALUE, thread_info, tp_value); |
98 | OFFSET(TI_CPU, thread_info, cpu); | 98 | OFFSET(TI_CPU, thread_info, cpu); |
99 | OFFSET(TI_PRE_COUNT, thread_info, preempt_count); | 99 | OFFSET(TI_PRE_COUNT, thread_info, preempt_count); |
100 | OFFSET(TI_R2_EMUL_RET, thread_info, r2_emul_return); | ||
100 | OFFSET(TI_ADDR_LIMIT, thread_info, addr_limit); | 101 | OFFSET(TI_ADDR_LIMIT, thread_info, addr_limit); |
101 | OFFSET(TI_RESTART_BLOCK, thread_info, restart_block); | 102 | OFFSET(TI_RESTART_BLOCK, thread_info, restart_block); |
102 | OFFSET(TI_REGS, thread_info, regs); | 103 | OFFSET(TI_REGS, thread_info, regs); |
diff --git a/arch/mips/kernel/entry.S b/arch/mips/kernel/entry.S index d5ab21c3fd12..af41ba6db960 100644 --- a/arch/mips/kernel/entry.S +++ b/arch/mips/kernel/entry.S | |||
@@ -46,6 +46,11 @@ resume_userspace: | |||
46 | local_irq_disable # make sure we dont miss an | 46 | local_irq_disable # make sure we dont miss an |
47 | # interrupt setting need_resched | 47 | # interrupt setting need_resched |
48 | # between sampling and return | 48 | # between sampling and return |
49 | #ifdef CONFIG_MIPSR2_TO_R6_EMULATOR | ||
50 | lw k0, TI_R2_EMUL_RET($28) | ||
51 | bnez k0, restore_all_from_r2_emul | ||
52 | #endif | ||
53 | |||
49 | LONG_L a2, TI_FLAGS($28) # current->work | 54 | LONG_L a2, TI_FLAGS($28) # current->work |
50 | andi t0, a2, _TIF_WORK_MASK # (ignoring syscall_trace) | 55 | andi t0, a2, _TIF_WORK_MASK # (ignoring syscall_trace) |
51 | bnez t0, work_pending | 56 | bnez t0, work_pending |
@@ -114,6 +119,19 @@ restore_partial: # restore partial frame | |||
114 | RESTORE_SP_AND_RET | 119 | RESTORE_SP_AND_RET |
115 | .set at | 120 | .set at |
116 | 121 | ||
122 | #ifdef CONFIG_MIPSR2_TO_R6_EMULATOR | ||
123 | restore_all_from_r2_emul: # restore full frame | ||
124 | .set noat | ||
125 | sw zero, TI_R2_EMUL_RET($28) # reset it | ||
126 | RESTORE_TEMP | ||
127 | RESTORE_AT | ||
128 | RESTORE_STATIC | ||
129 | RESTORE_SOME | ||
130 | LONG_L sp, PT_R29(sp) | ||
131 | eretnc | ||
132 | .set at | ||
133 | #endif | ||
134 | |||
117 | work_pending: | 135 | work_pending: |
118 | andi t0, a2, _TIF_NEED_RESCHED # a2 is preloaded with TI_FLAGS | 136 | andi t0, a2, _TIF_NEED_RESCHED # a2 is preloaded with TI_FLAGS |
119 | beqz t0, work_notifysig | 137 | beqz t0, work_notifysig |
diff --git a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c index fc157322f609..afa447e5e97f 100644 --- a/arch/mips/kernel/traps.c +++ b/arch/mips/kernel/traps.c | |||
@@ -1039,12 +1039,14 @@ asmlinkage void do_ri(struct pt_regs *regs) | |||
1039 | switch (status) { | 1039 | switch (status) { |
1040 | case 0: | 1040 | case 0: |
1041 | case SIGEMT: | 1041 | case SIGEMT: |
1042 | task_thread_info(current)->r2_emul_return = 1; | ||
1042 | return; | 1043 | return; |
1043 | case SIGILL: | 1044 | case SIGILL: |
1044 | goto no_r2_instr; | 1045 | goto no_r2_instr; |
1045 | default: | 1046 | default: |
1046 | process_fpemu_return(status, | 1047 | process_fpemu_return(status, |
1047 | ¤t->thread.cp0_baduaddr); | 1048 | ¤t->thread.cp0_baduaddr); |
1049 | task_thread_info(current)->r2_emul_return = 1; | ||
1048 | return; | 1050 | return; |
1049 | } | 1051 | } |
1050 | } | 1052 | } |