MIPS: kernel: Prepare the JR instruction for emulation on MIPS R6
The MIPS R6 JR instruction is an alias to the JALR one, so it may need emulation for non-R6 userlands. Signed-off-by: Markos Chandras <markos.chandras@imgtec.com>
This commit is contained in:
		
					parent
					
						
							
								b5ad2c2193
							
						
					
				
			
			
				commit
				
					
						5f9f41c474
					
				
			
		
					 3 changed files with 15 additions and 2 deletions
				
			
		|  | @ -13,6 +13,9 @@ | |||
| #include <asm/ptrace.h> | ||||
| #include <asm/inst.h> | ||||
| 
 | ||||
| static int mipsr2_emulation = 0; | ||||
| #define NO_R6EMU	(cpu_has_mips_r6 && !mipsr2_emulation) | ||||
| 
 | ||||
| extern int __isa_exception_epc(struct pt_regs *regs); | ||||
| extern int __compute_return_epc(struct pt_regs *regs); | ||||
| extern int __compute_return_epc_for_insn(struct pt_regs *regs, | ||||
|  |  | |||
|  | @ -417,6 +417,8 @@ int __compute_return_epc_for_insn(struct pt_regs *regs, | |||
| 			regs->regs[insn.r_format.rd] = epc + 8; | ||||
| 			/* Fall through */ | ||||
| 		case jr_op: | ||||
| 			if (NO_R6EMU && insn.r_format.func == jr_op) | ||||
| 				goto sigill_r6; | ||||
| 			regs->cp0_epc = regs->regs[insn.r_format.rs]; | ||||
| 			break; | ||||
| 		} | ||||
|  | @ -477,7 +479,7 @@ int __compute_return_epc_for_insn(struct pt_regs *regs, | |||
| 
 | ||||
| 		case bposge32_op: | ||||
| 			if (!cpu_has_dsp) | ||||
| 				goto sigill; | ||||
| 				goto sigill_dsp; | ||||
| 
 | ||||
| 			dspcontrol = rddsp(0x01); | ||||
| 
 | ||||
|  | @ -631,10 +633,15 @@ int __compute_return_epc_for_insn(struct pt_regs *regs, | |||
| 
 | ||||
| 	return ret; | ||||
| 
 | ||||
| sigill: | ||||
| sigill_dsp: | ||||
| 	printk("%s: DSP branch but not DSP ASE - sending SIGBUS.\n", current->comm); | ||||
| 	force_sig(SIGBUS, current); | ||||
| 	return -EFAULT; | ||||
| sigill_r6: | ||||
| 	pr_info("%s: R2 branch but r2-to-r6 emulator is not preset - sending SIGILL.\n", | ||||
| 		current->comm); | ||||
| 	force_sig(SIGILL, current); | ||||
| 	return -EFAULT; | ||||
| } | ||||
| EXPORT_SYMBOL_GPL(__compute_return_epc_for_insn); | ||||
| 
 | ||||
|  |  | |||
|  | @ -448,6 +448,9 @@ static int isBranchInstr(struct pt_regs *regs, struct mm_decoded_insn dec_insn, | |||
| 				dec_insn.next_pc_inc; | ||||
| 			/* Fall through */ | ||||
| 		case jr_op: | ||||
| 			/* For R6, JR already emulated in jalr_op */ | ||||
| 			if (NO_R6EMU && insn.r_format.opcode == jr_op) | ||||
| 				break; | ||||
| 			*contpc = regs->regs[insn.r_format.rs]; | ||||
| 			return 1; | ||||
| 		} | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Markos Chandras
				Markos Chandras