aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/mips/include/asm/mips-r2-to-r6-emul.h2
-rw-r--r--arch/mips/kernel/mips-r2-to-r6-emul.c12
-rw-r--r--arch/mips/kernel/traps.c18
3 files changed, 20 insertions, 12 deletions
diff --git a/arch/mips/include/asm/mips-r2-to-r6-emul.h b/arch/mips/include/asm/mips-r2-to-r6-emul.h
index 1f6ea8352ca9..20621e1ca238 100644
--- a/arch/mips/include/asm/mips-r2-to-r6-emul.h
+++ b/arch/mips/include/asm/mips-r2-to-r6-emul.h
@@ -79,7 +79,7 @@ struct r2_decoder_table {
79}; 79};
80 80
81 81
82extern void do_trap_or_bp(struct pt_regs *regs, unsigned int code, 82extern void do_trap_or_bp(struct pt_regs *regs, unsigned int code, int si_code,
83 const char *str); 83 const char *str);
84 84
85#ifndef CONFIG_MIPSR2_TO_R6_EMULATOR 85#ifndef CONFIG_MIPSR2_TO_R6_EMULATOR
diff --git a/arch/mips/kernel/mips-r2-to-r6-emul.c b/arch/mips/kernel/mips-r2-to-r6-emul.c
index 1f5aac7f9ec3..3fff89ae760b 100644
--- a/arch/mips/kernel/mips-r2-to-r6-emul.c
+++ b/arch/mips/kernel/mips-r2-to-r6-emul.c
@@ -940,42 +940,42 @@ repeat:
940 switch (rt) { 940 switch (rt) {
941 case tgei_op: 941 case tgei_op:
942 if ((long)regs->regs[rs] >= MIPSInst_SIMM(inst)) 942 if ((long)regs->regs[rs] >= MIPSInst_SIMM(inst))
943 do_trap_or_bp(regs, 0, "TGEI"); 943 do_trap_or_bp(regs, 0, 0, "TGEI");
944 944
945 MIPS_R2_STATS(traps); 945 MIPS_R2_STATS(traps);
946 946
947 break; 947 break;
948 case tgeiu_op: 948 case tgeiu_op:
949 if (regs->regs[rs] >= MIPSInst_UIMM(inst)) 949 if (regs->regs[rs] >= MIPSInst_UIMM(inst))
950 do_trap_or_bp(regs, 0, "TGEIU"); 950 do_trap_or_bp(regs, 0, 0, "TGEIU");
951 951
952 MIPS_R2_STATS(traps); 952 MIPS_R2_STATS(traps);
953 953
954 break; 954 break;
955 case tlti_op: 955 case tlti_op:
956 if ((long)regs->regs[rs] < MIPSInst_SIMM(inst)) 956 if ((long)regs->regs[rs] < MIPSInst_SIMM(inst))
957 do_trap_or_bp(regs, 0, "TLTI"); 957 do_trap_or_bp(regs, 0, 0, "TLTI");
958 958
959 MIPS_R2_STATS(traps); 959 MIPS_R2_STATS(traps);
960 960
961 break; 961 break;
962 case tltiu_op: 962 case tltiu_op:
963 if (regs->regs[rs] < MIPSInst_UIMM(inst)) 963 if (regs->regs[rs] < MIPSInst_UIMM(inst))
964 do_trap_or_bp(regs, 0, "TLTIU"); 964 do_trap_or_bp(regs, 0, 0, "TLTIU");
965 965
966 MIPS_R2_STATS(traps); 966 MIPS_R2_STATS(traps);
967 967
968 break; 968 break;
969 case teqi_op: 969 case teqi_op:
970 if (regs->regs[rs] == MIPSInst_SIMM(inst)) 970 if (regs->regs[rs] == MIPSInst_SIMM(inst))
971 do_trap_or_bp(regs, 0, "TEQI"); 971 do_trap_or_bp(regs, 0, 0, "TEQI");
972 972
973 MIPS_R2_STATS(traps); 973 MIPS_R2_STATS(traps);
974 974
975 break; 975 break;
976 case tnei_op: 976 case tnei_op:
977 if (regs->regs[rs] != MIPSInst_SIMM(inst)) 977 if (regs->regs[rs] != MIPSInst_SIMM(inst))
978 do_trap_or_bp(regs, 0, "TNEI"); 978 do_trap_or_bp(regs, 0, 0, "TNEI");
979 979
980 MIPS_R2_STATS(traps); 980 MIPS_R2_STATS(traps);
981 981
diff --git a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c
index e701eb0aa99c..80339ce64521 100644
--- a/arch/mips/kernel/traps.c
+++ b/arch/mips/kernel/traps.c
@@ -56,6 +56,7 @@
56#include <asm/pgtable.h> 56#include <asm/pgtable.h>
57#include <asm/ptrace.h> 57#include <asm/ptrace.h>
58#include <asm/sections.h> 58#include <asm/sections.h>
59#include <asm/siginfo.h>
59#include <asm/tlbdebug.h> 60#include <asm/tlbdebug.h>
60#include <asm/traps.h> 61#include <asm/traps.h>
61#include <asm/uaccess.h> 62#include <asm/uaccess.h>
@@ -871,7 +872,7 @@ out:
871 exception_exit(prev_state); 872 exception_exit(prev_state);
872} 873}
873 874
874void do_trap_or_bp(struct pt_regs *regs, unsigned int code, 875void do_trap_or_bp(struct pt_regs *regs, unsigned int code, int si_code,
875 const char *str) 876 const char *str)
876{ 877{
877 siginfo_t info = { 0 }; 878 siginfo_t info = { 0 };
@@ -928,7 +929,13 @@ void do_trap_or_bp(struct pt_regs *regs, unsigned int code,
928 default: 929 default:
929 scnprintf(b, sizeof(b), "%s instruction in kernel code", str); 930 scnprintf(b, sizeof(b), "%s instruction in kernel code", str);
930 die_if_kernel(b, regs); 931 die_if_kernel(b, regs);
931 force_sig(SIGTRAP, current); 932 if (si_code) {
933 info.si_signo = SIGTRAP;
934 info.si_code = si_code;
935 force_sig_info(SIGTRAP, &info, current);
936 } else {
937 force_sig(SIGTRAP, current);
938 }
932 } 939 }
933} 940}
934 941
@@ -1012,7 +1019,7 @@ asmlinkage void do_bp(struct pt_regs *regs)
1012 break; 1019 break;
1013 } 1020 }
1014 1021
1015 do_trap_or_bp(regs, bcode, "Break"); 1022 do_trap_or_bp(regs, bcode, TRAP_BRKPT, "Break");
1016 1023
1017out: 1024out:
1018 set_fs(seg); 1025 set_fs(seg);
@@ -1054,7 +1061,7 @@ asmlinkage void do_tr(struct pt_regs *regs)
1054 tcode = (opcode >> 6) & ((1 << 10) - 1); 1061 tcode = (opcode >> 6) & ((1 << 10) - 1);
1055 } 1062 }
1056 1063
1057 do_trap_or_bp(regs, tcode, "Trap"); 1064 do_trap_or_bp(regs, tcode, 0, "Trap");
1058 1065
1059out: 1066out:
1060 set_fs(seg); 1067 set_fs(seg);
@@ -1492,6 +1499,7 @@ asmlinkage void do_mdmx(struct pt_regs *regs)
1492 */ 1499 */
1493asmlinkage void do_watch(struct pt_regs *regs) 1500asmlinkage void do_watch(struct pt_regs *regs)
1494{ 1501{
1502 siginfo_t info = { .si_signo = SIGTRAP, .si_code = TRAP_HWBKPT };
1495 enum ctx_state prev_state; 1503 enum ctx_state prev_state;
1496 u32 cause; 1504 u32 cause;
1497 1505
@@ -1512,7 +1520,7 @@ asmlinkage void do_watch(struct pt_regs *regs)
1512 if (test_tsk_thread_flag(current, TIF_LOAD_WATCH)) { 1520 if (test_tsk_thread_flag(current, TIF_LOAD_WATCH)) {
1513 mips_read_watch_registers(); 1521 mips_read_watch_registers();
1514 local_irq_enable(); 1522 local_irq_enable();
1515 force_sig(SIGTRAP, current); 1523 force_sig_info(SIGTRAP, &info, current);
1516 } else { 1524 } else {
1517 mips_clear_watch_registers(); 1525 mips_clear_watch_registers();
1518 local_irq_enable(); 1526 local_irq_enable();