diff options
-rw-r--r-- | arch/mips/kernel/traps.c | 36 |
1 files changed, 18 insertions, 18 deletions
diff --git a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c index b6f23343a8db..a671d3358eb6 100644 --- a/arch/mips/kernel/traps.c +++ b/arch/mips/kernel/traps.c | |||
@@ -901,10 +901,9 @@ void do_trap_or_bp(struct pt_regs *regs, unsigned int code, | |||
901 | 901 | ||
902 | asmlinkage void do_bp(struct pt_regs *regs) | 902 | asmlinkage void do_bp(struct pt_regs *regs) |
903 | { | 903 | { |
904 | unsigned long epc = msk_isa16_mode(exception_epc(regs)); | ||
904 | unsigned int opcode, bcode; | 905 | unsigned int opcode, bcode; |
905 | enum ctx_state prev_state; | 906 | enum ctx_state prev_state; |
906 | unsigned long epc; | ||
907 | u16 instr[2]; | ||
908 | mm_segment_t seg; | 907 | mm_segment_t seg; |
909 | 908 | ||
910 | seg = get_fs(); | 909 | seg = get_fs(); |
@@ -913,26 +912,28 @@ asmlinkage void do_bp(struct pt_regs *regs) | |||
913 | 912 | ||
914 | prev_state = exception_enter(); | 913 | prev_state = exception_enter(); |
915 | if (get_isa16_mode(regs->cp0_epc)) { | 914 | if (get_isa16_mode(regs->cp0_epc)) { |
916 | /* Calculate EPC. */ | 915 | u16 instr[2]; |
917 | epc = exception_epc(regs); | 916 | |
918 | if (cpu_has_mmips) { | 917 | if (__get_user(instr[0], (u16 __user *)epc)) |
919 | if ((__get_user(instr[0], (u16 __user *)msk_isa16_mode(epc)) || | 918 | goto out_sigsegv; |
920 | (__get_user(instr[1], (u16 __user *)msk_isa16_mode(epc + 2))))) | 919 | |
921 | goto out_sigsegv; | 920 | if (!cpu_has_mmips) { |
922 | opcode = (instr[0] << 16) | instr[1]; | ||
923 | } else { | ||
924 | /* MIPS16e mode */ | 921 | /* MIPS16e mode */ |
925 | if (__get_user(instr[0], | ||
926 | (u16 __user *)msk_isa16_mode(epc))) | ||
927 | goto out_sigsegv; | ||
928 | bcode = (instr[0] >> 5) & 0x3f; | 922 | bcode = (instr[0] >> 5) & 0x3f; |
929 | do_trap_or_bp(regs, bcode, "Break"); | 923 | } else if (mm_insn_16bit(instr[0])) { |
930 | goto out; | 924 | /* 16-bit microMIPS BREAK */ |
925 | bcode = instr[0] & 0xf; | ||
926 | } else { | ||
927 | /* 32-bit microMIPS BREAK */ | ||
928 | if (__get_user(instr[1], (u16 __user *)(epc + 2))) | ||
929 | goto out_sigsegv; | ||
930 | opcode = (instr[0] << 16) | instr[1]; | ||
931 | bcode = (opcode >> 6) & ((1 << 20) - 1); | ||
931 | } | 932 | } |
932 | } else { | 933 | } else { |
933 | if (__get_user(opcode, | 934 | if (__get_user(opcode, (unsigned int __user *)epc)) |
934 | (unsigned int __user *) exception_epc(regs))) | ||
935 | goto out_sigsegv; | 935 | goto out_sigsegv; |
936 | bcode = (opcode >> 6) & ((1 << 20) - 1); | ||
936 | } | 937 | } |
937 | 938 | ||
938 | /* | 939 | /* |
@@ -941,7 +942,6 @@ asmlinkage void do_bp(struct pt_regs *regs) | |||
941 | * Gas is bug-compatible, but not always, grrr... | 942 | * Gas is bug-compatible, but not always, grrr... |
942 | * We handle both cases with a simple heuristics. --macro | 943 | * We handle both cases with a simple heuristics. --macro |
943 | */ | 944 | */ |
944 | bcode = ((opcode >> 6) & ((1 << 20) - 1)); | ||
945 | if (bcode >= (1 << 10)) | 945 | if (bcode >= (1 << 10)) |
946 | bcode >>= 10; | 946 | bcode >>= 10; |
947 | 947 | ||