~ubuntu-branches/ubuntu/precise/linux-ti-omap4/precise

« back to all changes in this revision

Viewing changes to arch/powerpc/kernel/traps.c

  • Committer: Bazaar Package Importer
  • Author(s): Paolo Pisati
  • Date: 2011-06-29 15:23:51 UTC
  • mfrom: (26.1.1 natty-proposed)
  • Revision ID: james.westby@ubuntu.com-20110629152351-xs96tm303d95rpbk
Tags: 3.0.0-1200.2
* Rebased against 3.0.0-6.7
* BSP from TI based on 3.0.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
34
34
#include <linux/bug.h>
35
35
#include <linux/kdebug.h>
36
36
#include <linux/debugfs.h>
37
 
#include <linux/ltt-core.h>
38
 
#include <trace/trap.h>
 
37
#include <linux/ratelimit.h>
39
38
 
40
39
#include <asm/emulated_ops.h>
41
40
#include <asm/pgtable.h>
57
56
#endif
58
57
#include <asm/kexec.h>
59
58
#include <asm/ppc-opcode.h>
 
59
#include <asm/rio.h>
60
60
 
61
61
#if defined(CONFIG_DEBUGGER) || defined(CONFIG_KEXEC)
62
62
int (*__debugger)(struct pt_regs *regs) __read_mostly;
77
77
#endif
78
78
 
79
79
/*
80
 
 * Also used in time.c and fault.c.
81
 
 */
82
 
DEFINE_TRACE(trap_entry);
83
 
DEFINE_TRACE(trap_exit);
84
 
 
85
 
/*
86
80
 * Trap & Exception support
87
81
 */
88
82
 
149
143
#ifdef CONFIG_NUMA
150
144
                printk("NUMA ");
151
145
#endif
152
 
#ifdef CONFIG_LTT
153
 
                printk("LTT NESTING LEVEL : %u ", __get_cpu_var(ltt_nesting));
154
 
                printk("\n");
155
 
#endif
156
146
                printk("%s\n", ppc_md.name ? ppc_md.name : "");
157
147
 
158
 
                sysfs_printk_last_file();
159
148
                if (notify_die(DIE_OOPS, str, regs, err, 255,
160
149
                               SIGSEGV) == NOTIFY_STOP)
161
150
                        return 1;
209
198
                if (die("Exception in kernel mode", regs, signr))
210
199
                        return;
211
200
        } else if (show_unhandled_signals &&
212
 
                    unhandled_signal(current, signr) &&
213
 
                    printk_ratelimit()) {
214
 
                        printk(regs->msr & MSR_SF ? fmt64 : fmt32,
215
 
                                current->comm, current->pid, signr,
216
 
                                addr, regs->nip, regs->link, code);
217
 
                }
218
 
 
219
 
        trace_trap_entry(regs, regs->trap);
 
201
                   unhandled_signal(current, signr)) {
 
202
                printk_ratelimited(regs->msr & MSR_64BIT ? fmt64 : fmt32,
 
203
                                   current->comm, current->pid, signr,
 
204
                                   addr, regs->nip, regs->link, code);
 
205
        }
220
206
 
221
207
        memset(&info, 0, sizeof(info));
222
208
        info.si_signo = signr;
223
209
        info.si_code = code;
224
210
        info.si_addr = (void __user *) addr;
225
211
        force_sig_info(signr, &info, current);
226
 
        trace_trap_exit();
227
212
}
228
213
 
229
214
#ifdef CONFIG_PPC64
236
221
        }
237
222
 
238
223
#ifdef CONFIG_KEXEC
239
 
        cpu_set(smp_processor_id(), cpus_in_sr);
 
224
        cpumask_set_cpu(smp_processor_id(), &cpus_in_sr);
240
225
#endif
241
226
 
242
227
        die("System Reset", regs, SIGABRT);
440
425
        unsigned long reason = mcsr;
441
426
        int recoverable = 1;
442
427
 
 
428
        if (reason & MCSR_LD) {
 
429
                recoverable = fsl_rio_mcheck_exception(regs);
 
430
                if (recoverable == 1)
 
431
                        goto silent_out;
 
432
        }
 
433
 
443
434
        printk("Machine check in kernel mode.\n");
444
435
        printk("Caused by (from MCSR=%lx): ", reason);
445
436
 
515
506
                       reason & MCSR_MEA ? "Effective" : "Physical", addr);
516
507
        }
517
508
 
 
509
silent_out:
518
510
        mtspr(SPRN_MCSR, mcsr);
519
511
        return mfspr(SPRN_MCSR) == 0 && recoverable;
520
512
}
523
515
{
524
516
        unsigned long reason = get_mc_reason(regs);
525
517
 
 
518
        if (reason & MCSR_BUS_RBERR) {
 
519
                if (fsl_rio_mcheck_exception(regs))
 
520
                        return 1;
 
521
        }
 
522
 
526
523
        printk("Machine check in kernel mode.\n");
527
524
        printk("Caused by (from MCSR=%lx): ", reason);
528
525
 
924
921
                return emulate_isel(regs, instword);
925
922
        }
926
923
 
 
924
#ifdef CONFIG_PPC64
 
925
        /* Emulate the mfspr rD, DSCR. */
 
926
        if (((instword & PPC_INST_MFSPR_DSCR_MASK) == PPC_INST_MFSPR_DSCR) &&
 
927
                        cpu_has_feature(CPU_FTR_DSCR)) {
 
928
                PPC_WARN_EMULATED(mfdscr, regs);
 
929
                rd = (instword >> 21) & 0x1f;
 
930
                regs->gpr[rd] = mfspr(SPRN_DSCR);
 
931
                return 0;
 
932
        }
 
933
        /* Emulate the mtspr DSCR, rD. */
 
934
        if (((instword & PPC_INST_MTSPR_DSCR_MASK) == PPC_INST_MTSPR_DSCR) &&
 
935
                        cpu_has_feature(CPU_FTR_DSCR)) {
 
936
                PPC_WARN_EMULATED(mtdscr, regs);
 
937
                rd = (instword >> 21) & 0x1f;
 
938
                mtspr(SPRN_DSCR, regs->gpr[rd]);
 
939
                current->thread.dscr_inherit = 1;
 
940
                return 0;
 
941
        }
 
942
#endif
 
943
 
927
944
        return -EINVAL;
928
945
}
929
946
 
974
991
         * ESR_DST (!?) or 0.  In the process of chasing this with the
975
992
         * hardware people - not sure if it can happen on any illegal
976
993
         * instruction or only on FP instructions, whether there is a
977
 
         * pattern to occurences etc. -dgibson 31/Mar/2003 */
 
994
         * pattern to occurrences etc. -dgibson 31/Mar/2003 */
978
995
        switch (do_mathemu(regs)) {
979
996
        case 0:
980
997
                emulate_single_step(regs);
1102
1119
{
1103
1120
        __get_cpu_var(irq_stat).pmu_irqs++;
1104
1121
 
1105
 
        trace_trap_entry(regs, regs->trap);
1106
1122
        perf_irq(regs);
1107
 
        trace_trap_exit();
1108
1123
}
1109
1124
 
1110
1125
#ifdef CONFIG_8xx
1325
1340
                /* got an error reading the instruction */
1326
1341
                _exception(SIGSEGV, regs, SEGV_ACCERR, regs->nip);
1327
1342
        } else {
1328
 
                trace_trap_entry(regs, regs->trap);
1329
1343
                /* didn't recognize the instruction */
1330
1344
                /* XXX quick hack for now: set the non-Java bit in the VSCR */
1331
 
                if (printk_ratelimit())
1332
 
                        printk(KERN_ERR "Unrecognized altivec instruction "
1333
 
                               "in %s at %lx\n", current->comm, regs->nip);
 
1345
                printk_ratelimited(KERN_ERR "Unrecognized altivec instruction "
 
1346
                                   "in %s at %lx\n", current->comm, regs->nip);
1334
1347
                current->thread.vscr.u[3] |= 0x10000;
1335
 
                trace_trap_exit();
1336
1348
        }
1337
1349
}
1338
1350
#endif /* CONFIG_ALTIVEC */
1525
1537
#ifdef CONFIG_VSX
1526
1538
        WARN_EMULATED_SETUP(vsx),
1527
1539
#endif
 
1540
#ifdef CONFIG_PPC64
 
1541
        WARN_EMULATED_SETUP(mfdscr),
 
1542
        WARN_EMULATED_SETUP(mtdscr),
 
1543
#endif
1528
1544
};
1529
1545
 
1530
1546
u32 ppc_warn_emulated;
1531
1547
 
1532
1548
void ppc_warn_emulated_print(const char *type)
1533
1549
{
1534
 
        if (printk_ratelimit())
1535
 
                pr_warning("%s used emulated %s instruction\n", current->comm,
1536
 
                           type);
 
1550
        pr_warn_ratelimited("%s used emulated %s instruction\n", current->comm,
 
1551
                            type);
1537
1552
}
1538
1553
 
1539
1554
static int __init ppc_warn_emulated_init(void)