diff options
-rw-r--r-- | arch/mips/include/asm/mips-r2-to-r6-emul.h | 2 | ||||
-rw-r--r-- | arch/mips/kernel/mips-r2-to-r6-emul.c | 12 | ||||
-rw-r--r-- | arch/mips/kernel/traps.c | 18 |
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 | ||
82 | extern void do_trap_or_bp(struct pt_regs *regs, unsigned int code, | 82 | extern 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 | ||
874 | void do_trap_or_bp(struct pt_regs *regs, unsigned int code, | 875 | void 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 | ||
1017 | out: | 1024 | out: |
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 | ||
1059 | out: | 1066 | out: |
1060 | set_fs(seg); | 1067 | set_fs(seg); |
@@ -1492,6 +1499,7 @@ asmlinkage void do_mdmx(struct pt_regs *regs) | |||
1492 | */ | 1499 | */ |
1493 | asmlinkage void do_watch(struct pt_regs *regs) | 1500 | asmlinkage 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(); |