diff options
Diffstat (limited to 'arch/powerpc/kernel/traps.c')
-rw-r--r-- | arch/powerpc/kernel/traps.c | 55 |
1 files changed, 46 insertions, 9 deletions
diff --git a/arch/powerpc/kernel/traps.c b/arch/powerpc/kernel/traps.c index 4b5b7ff4f78..878fbddb6ae 100644 --- a/arch/powerpc/kernel/traps.c +++ b/arch/powerpc/kernel/traps.c | |||
@@ -967,6 +967,20 @@ void altivec_unavailable_exception(struct pt_regs *regs) | |||
967 | die("Unrecoverable VMX/Altivec Unavailable Exception", regs, SIGABRT); | 967 | die("Unrecoverable VMX/Altivec Unavailable Exception", regs, SIGABRT); |
968 | } | 968 | } |
969 | 969 | ||
970 | void vsx_unavailable_exception(struct pt_regs *regs) | ||
971 | { | ||
972 | if (user_mode(regs)) { | ||
973 | /* A user program has executed an vsx instruction, | ||
974 | but this kernel doesn't support vsx. */ | ||
975 | _exception(SIGILL, regs, ILL_ILLOPC, regs->nip); | ||
976 | return; | ||
977 | } | ||
978 | |||
979 | printk(KERN_EMERG "Unrecoverable VSX Unavailable Exception " | ||
980 | "%lx at %lx\n", regs->trap, regs->nip); | ||
981 | die("Unrecoverable VSX Unavailable Exception", regs, SIGABRT); | ||
982 | } | ||
983 | |||
970 | void performance_monitor_exception(struct pt_regs *regs) | 984 | void performance_monitor_exception(struct pt_regs *regs) |
971 | { | 985 | { |
972 | perf_irq(regs); | 986 | perf_irq(regs); |
@@ -1030,21 +1044,29 @@ void SoftwareEmulation(struct pt_regs *regs) | |||
1030 | 1044 | ||
1031 | #if defined(CONFIG_40x) || defined(CONFIG_BOOKE) | 1045 | #if defined(CONFIG_40x) || defined(CONFIG_BOOKE) |
1032 | 1046 | ||
1033 | void DebugException(struct pt_regs *regs, unsigned long debug_status) | 1047 | void __kprobes DebugException(struct pt_regs *regs, unsigned long debug_status) |
1034 | { | 1048 | { |
1035 | if (debug_status & DBSR_IC) { /* instruction completion */ | 1049 | if (debug_status & DBSR_IC) { /* instruction completion */ |
1036 | regs->msr &= ~MSR_DE; | 1050 | regs->msr &= ~MSR_DE; |
1051 | |||
1052 | /* Disable instruction completion */ | ||
1053 | mtspr(SPRN_DBCR0, mfspr(SPRN_DBCR0) & ~DBCR0_IC); | ||
1054 | /* Clear the instruction completion event */ | ||
1055 | mtspr(SPRN_DBSR, DBSR_IC); | ||
1056 | |||
1057 | if (notify_die(DIE_SSTEP, "single_step", regs, 5, | ||
1058 | 5, SIGTRAP) == NOTIFY_STOP) { | ||
1059 | return; | ||
1060 | } | ||
1061 | |||
1062 | if (debugger_sstep(regs)) | ||
1063 | return; | ||
1064 | |||
1037 | if (user_mode(regs)) { | 1065 | if (user_mode(regs)) { |
1038 | current->thread.dbcr0 &= ~DBCR0_IC; | 1066 | current->thread.dbcr0 &= ~DBCR0_IC; |
1039 | } else { | ||
1040 | /* Disable instruction completion */ | ||
1041 | mtspr(SPRN_DBCR0, mfspr(SPRN_DBCR0) & ~DBCR0_IC); | ||
1042 | /* Clear the instruction completion event */ | ||
1043 | mtspr(SPRN_DBSR, DBSR_IC); | ||
1044 | if (debugger_sstep(regs)) | ||
1045 | return; | ||
1046 | } | 1067 | } |
1047 | _exception(SIGTRAP, regs, TRAP_TRACE, 0); | 1068 | |
1069 | _exception(SIGTRAP, regs, TRAP_TRACE, regs->nip); | ||
1048 | } | 1070 | } |
1049 | } | 1071 | } |
1050 | #endif /* CONFIG_4xx || CONFIG_BOOKE */ | 1072 | #endif /* CONFIG_4xx || CONFIG_BOOKE */ |
@@ -1091,6 +1113,21 @@ void altivec_assist_exception(struct pt_regs *regs) | |||
1091 | } | 1113 | } |
1092 | #endif /* CONFIG_ALTIVEC */ | 1114 | #endif /* CONFIG_ALTIVEC */ |
1093 | 1115 | ||
1116 | #ifdef CONFIG_VSX | ||
1117 | void vsx_assist_exception(struct pt_regs *regs) | ||
1118 | { | ||
1119 | if (!user_mode(regs)) { | ||
1120 | printk(KERN_EMERG "VSX assist exception in kernel mode" | ||
1121 | " at %lx\n", regs->nip); | ||
1122 | die("Kernel VSX assist exception", regs, SIGILL); | ||
1123 | } | ||
1124 | |||
1125 | flush_vsx_to_thread(current); | ||
1126 | printk(KERN_INFO "VSX assist not supported at %lx\n", regs->nip); | ||
1127 | _exception(SIGILL, regs, ILL_ILLOPC, regs->nip); | ||
1128 | } | ||
1129 | #endif /* CONFIG_VSX */ | ||
1130 | |||
1094 | #ifdef CONFIG_FSL_BOOKE | 1131 | #ifdef CONFIG_FSL_BOOKE |
1095 | void CacheLockingException(struct pt_regs *regs, unsigned long address, | 1132 | void CacheLockingException(struct pt_regs *regs, unsigned long address, |
1096 | unsigned long error_code) | 1133 | unsigned long error_code) |