@ -55,7 +55,9 @@ int mips_dsemul(struct pt_regs *regs, mips_instruction ir, unsigned long cpc)
struct emuframe __user * fr ;
int err ;
if ( ir = = 0 ) { /* a nop is easy */
if ( ( get_isa16_mode ( regs - > cp0_epc ) & & ( ( ir > > 16 ) = = MM_NOP16 ) ) | |
( ir = = 0 ) ) {
/* NOP is easy */
regs - > cp0_epc = cpc ;
regs - > cp0_cause & = ~ CAUSEF_BD ;
return 0 ;
@ -91,8 +93,16 @@ int mips_dsemul(struct pt_regs *regs, mips_instruction ir, unsigned long cpc)
if ( unlikely ( ! access_ok ( VERIFY_WRITE , fr , sizeof ( struct emuframe ) ) ) )
return SIGBUS ;
err = __put_user ( ir , & fr - > emul ) ;
err | = __put_user ( ( mips_instruction ) BREAK_MATH , & fr - > badinst ) ;
if ( get_isa16_mode ( regs - > cp0_epc ) ) {
err = __put_user ( ir > > 16 , ( u16 __user * ) ( & fr - > emul ) ) ;
err | = __put_user ( ir & 0xffff , ( u16 __user * ) ( ( long ) ( & fr - > emul ) + 2 ) ) ;
err | = __put_user ( BREAK_MATH > > 16 , ( u16 __user * ) ( & fr - > badinst ) ) ;
err | = __put_user ( BREAK_MATH & 0xffff , ( u16 __user * ) ( ( long ) ( & fr - > badinst ) + 2 ) ) ;
} else {
err = __put_user ( ir , & fr - > emul ) ;
err | = __put_user ( ( mips_instruction ) BREAK_MATH , & fr - > badinst ) ;
}
err | = __put_user ( ( mips_instruction ) BD_COOKIE , & fr - > cookie ) ;
err | = __put_user ( cpc , & fr - > epc ) ;
@ -101,7 +111,8 @@ int mips_dsemul(struct pt_regs *regs, mips_instruction ir, unsigned long cpc)
return SIGBUS ;
}
regs - > cp0_epc = ( unsigned long ) & fr - > emul ;
regs - > cp0_epc = ( ( unsigned long ) & fr - > emul ) |
get_isa16_mode ( regs - > cp0_epc ) ;
flush_cache_sigtramp ( ( unsigned long ) & fr - > badinst ) ;
@ -114,9 +125,10 @@ int do_dsemulret(struct pt_regs *xcp)
unsigned long epc ;
u32 insn , cookie ;
int err = 0 ;
u16 instr [ 2 ] ;
fr = ( struct emuframe __user * )
( xcp - > cp0_epc - sizeof ( mips_instruction ) ) ;
( msk_isa16_mode ( xcp - > cp0_epc ) - sizeof ( mips_instruction ) ) ;
/*
* If we can ' t even access the area , something is very wrong , but we ' ll
@ -131,7 +143,13 @@ int do_dsemulret(struct pt_regs *xcp)
* - Is the instruction pointed to by the EPC an BREAK_MATH ?
* - Is the following memory word the BD_COOKIE ?
*/
err = __get_user ( insn , & fr - > badinst ) ;
if ( get_isa16_mode ( xcp - > cp0_epc ) ) {
err = __get_user ( instr [ 0 ] , ( u16 __user * ) ( & fr - > badinst ) ) ;
err | = __get_user ( instr [ 1 ] , ( u16 __user * ) ( ( long ) ( & fr - > badinst ) + 2 ) ) ;
insn = ( instr [ 0 ] < < 16 ) | instr [ 1 ] ;
} else {
err = __get_user ( insn , & fr - > badinst ) ;
}
err | = __get_user ( cookie , & fr - > cookie ) ;
if ( unlikely ( err | | ( insn ! = BREAK_MATH ) | | ( cookie ! = BD_COOKIE ) ) ) {