~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/arch/parisc/kernel/traps.c

Version: ~ [ linux-5.15-rc1 ] ~ [ linux-5.14.5 ] ~ [ linux-5.13.18 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.66 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.147 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.206 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.246 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.282 ] ~ [ linux-4.8.17 ] ~ [ linux-4.7.10 ] ~ [ linux-4.6.7 ] ~ [ linux-4.5.7 ] ~ [ linux-4.4.283 ] ~ [ linux-4.3.6 ] ~ [ linux-4.2.8 ] ~ [ linux-4.1.52 ] ~ [ linux-4.0.9 ] ~ [ linux-3.18.140 ] ~ [ linux-3.16.85 ] ~ [ linux-3.14.79 ] ~ [ linux-3.12.74 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.5 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 // SPDX-License-Identifier: GPL-2.0
  2 /*
  3  *  linux/arch/parisc/traps.c
  4  *
  5  *  Copyright (C) 1991, 1992  Linus Torvalds
  6  *  Copyright (C) 1999, 2000  Philipp Rumpf <prumpf@tux.org>
  7  */
  8 
  9 /*
 10  * 'Traps.c' handles hardware traps and faults after we have saved some
 11  * state in 'asm.s'.
 12  */
 13 
 14 #include <linux/sched.h>
 15 #include <linux/sched/debug.h>
 16 #include <linux/kernel.h>
 17 #include <linux/string.h>
 18 #include <linux/errno.h>
 19 #include <linux/ptrace.h>
 20 #include <linux/timer.h>
 21 #include <linux/delay.h>
 22 #include <linux/mm.h>
 23 #include <linux/module.h>
 24 #include <linux/smp.h>
 25 #include <linux/spinlock.h>
 26 #include <linux/init.h>
 27 #include <linux/interrupt.h>
 28 #include <linux/console.h>
 29 #include <linux/bug.h>
 30 #include <linux/ratelimit.h>
 31 #include <linux/uaccess.h>
 32 
 33 #include <asm/assembly.h>
 34 #include <asm/io.h>
 35 #include <asm/irq.h>
 36 #include <asm/traps.h>
 37 #include <asm/unaligned.h>
 38 #include <linux/atomic.h>
 39 #include <asm/smp.h>
 40 #include <asm/pdc.h>
 41 #include <asm/pdc_chassis.h>
 42 #include <asm/unwind.h>
 43 #include <asm/tlbflush.h>
 44 #include <asm/cacheflush.h>
 45 
 46 #include "../math-emu/math-emu.h"       /* for handle_fpe() */
 47 
 48 static void parisc_show_stack(struct task_struct *task,
 49         struct pt_regs *regs);
 50 
 51 static int printbinary(char *buf, unsigned long x, int nbits)
 52 {
 53         unsigned long mask = 1UL << (nbits - 1);
 54         while (mask != 0) {
 55                 *buf++ = (mask & x ? '1' : '');
 56                 mask >>= 1;
 57         }
 58         *buf = '\0';
 59 
 60         return nbits;
 61 }
 62 
 63 #ifdef CONFIG_64BIT
 64 #define RFMT "%016lx"
 65 #else
 66 #define RFMT "%08lx"
 67 #endif
 68 #define FFMT "%016llx"  /* fpregs are 64-bit always */
 69 
 70 #define PRINTREGS(lvl,r,f,fmt,x)        \
 71         printk("%s%s%02d-%02d  " fmt " " fmt " " fmt " " fmt "\n",      \
 72                 lvl, f, (x), (x+3), (r)[(x)+0], (r)[(x)+1],             \
 73                 (r)[(x)+2], (r)[(x)+3])
 74 
 75 static void print_gr(char *level, struct pt_regs *regs)
 76 {
 77         int i;
 78         char buf[64];
 79 
 80         printk("%s\n", level);
 81         printk("%s     YZrvWESTHLNXBCVMcbcbcbcbOGFRQPDI\n", level);
 82         printbinary(buf, regs->gr[0], 32);
 83         printk("%sPSW: %s %s\n", level, buf, print_tainted());
 84 
 85         for (i = 0; i < 32; i += 4)
 86                 PRINTREGS(level, regs->gr, "r", RFMT, i);
 87 }
 88 
 89 static void print_fr(char *level, struct pt_regs *regs)
 90 {
 91         int i;
 92         char buf[64];
 93         struct { u32 sw[2]; } s;
 94 
 95         /* FR are 64bit everywhere. Need to use asm to get the content
 96          * of fpsr/fper1, and we assume that we won't have a FP Identify
 97          * in our way, otherwise we're screwed.
 98          * The fldd is used to restore the T-bit if there was one, as the
 99          * store clears it anyway.
100          * PA2.0 book says "thou shall not use fstw on FPSR/FPERs" - T-Bone */
101         asm volatile ("fstd %%fr0,0(%1) \n\t"
102                       "fldd 0(%1),%%fr0 \n\t"
103                       : "=m" (s) : "r" (&s) : "r0");
104 
105         printk("%s\n", level);
106         printk("%s      VZOUICununcqcqcqcqcqcrmunTDVZOUI\n", level);
107         printbinary(buf, s.sw[0], 32);
108         printk("%sFPSR: %s\n", level, buf);
109         printk("%sFPER1: %08x\n", level, s.sw[1]);
110 
111         /* here we'll print fr0 again, tho it'll be meaningless */
112         for (i = 0; i < 32; i += 4)
113                 PRINTREGS(level, regs->fr, "fr", FFMT, i);
114 }
115 
116 void show_regs(struct pt_regs *regs)
117 {
118         int i, user;
119         char *level;
120         unsigned long cr30, cr31;
121 
122         user = user_mode(regs);
123         level = user ? KERN_DEBUG : KERN_CRIT;
124 
125         show_regs_print_info(level);
126 
127         print_gr(level, regs);
128 
129         for (i = 0; i < 8; i += 4)
130                 PRINTREGS(level, regs->sr, "sr", RFMT, i);
131 
132         if (user)
133                 print_fr(level, regs);
134 
135         cr30 = mfctl(30);
136         cr31 = mfctl(31);
137         printk("%s\n", level);
138         printk("%sIASQ: " RFMT " " RFMT " IAOQ: " RFMT " " RFMT "\n",
139                level, regs->iasq[0], regs->iasq[1], regs->iaoq[0], regs->iaoq[1]);
140         printk("%s IIR: %08lx    ISR: " RFMT "  IOR: " RFMT "\n",
141                level, regs->iir, regs->isr, regs->ior);
142         printk("%s CPU: %8d   CR30: " RFMT " CR31: " RFMT "\n",
143                level, current_thread_info()->cpu, cr30, cr31);
144         printk("%s ORIG_R28: " RFMT "\n", level, regs->orig_r28);
145 
146         if (user) {
147                 printk("%s IAOQ[0]: " RFMT "\n", level, regs->iaoq[0]);
148                 printk("%s IAOQ[1]: " RFMT "\n", level, regs->iaoq[1]);
149                 printk("%s RP(r2): " RFMT "\n", level, regs->gr[2]);
150         } else {
151                 printk("%s IAOQ[0]: %pS\n", level, (void *) regs->iaoq[0]);
152                 printk("%s IAOQ[1]: %pS\n", level, (void *) regs->iaoq[1]);
153                 printk("%s RP(r2): %pS\n", level, (void *) regs->gr[2]);
154 
155                 parisc_show_stack(current, regs);
156         }
157 }
158 
159 static DEFINE_RATELIMIT_STATE(_hppa_rs,
160         DEFAULT_RATELIMIT_INTERVAL, DEFAULT_RATELIMIT_BURST);
161 
162 #define parisc_printk_ratelimited(critical, regs, fmt, ...)     {             \
163         if ((critical || show_unhandled_signals) && __ratelimit(&_hppa_rs)) { \
164                 printk(fmt, ##__VA_ARGS__);                                   \
165                 show_regs(regs);                                              \
166         }                                                                     \
167 }
168 
169 
170 static void do_show_stack(struct unwind_frame_info *info)
171 {
172         int i = 1;
173 
174         printk(KERN_CRIT "Backtrace:\n");
175         while (i <= MAX_UNWIND_ENTRIES) {
176                 if (unwind_once(info) < 0 || info->ip == 0)
177                         break;
178 
179                 if (__kernel_text_address(info->ip)) {
180                         printk(KERN_CRIT " [<" RFMT ">] %pS\n",
181                                 info->ip, (void *) info->ip);
182                         i++;
183                 }
184         }
185         printk(KERN_CRIT "\n");
186 }
187 
188 static void parisc_show_stack(struct task_struct *task,
189         struct pt_regs *regs)
190 {
191         struct unwind_frame_info info;
192 
193         unwind_frame_init_task(&info, task, regs);
194 
195         do_show_stack(&info);
196 }
197 
198 void show_stack(struct task_struct *t, unsigned long *sp)
199 {
200         parisc_show_stack(t, NULL);
201 }
202 
203 int is_valid_bugaddr(unsigned long iaoq)
204 {
205         return 1;
206 }
207 
208 void die_if_kernel(char *str, struct pt_regs *regs, long err)
209 {
210         if (user_mode(regs)) {
211                 if (err == 0)
212                         return; /* STFU */
213 
214                 parisc_printk_ratelimited(1, regs,
215                         KERN_CRIT "%s (pid %d): %s (code %ld) at " RFMT "\n",
216                         current->comm, task_pid_nr(current), str, err, regs->iaoq[0]);
217 
218                 return;
219         }
220 
221         bust_spinlocks(1);
222 
223         oops_enter();
224 
225         /* Amuse the user in a SPARC fashion */
226         if (err) printk(KERN_CRIT
227                         "      _______________________________ \n"
228                         "     < Your System ate a SPARC! Gah! >\n"
229                         "      ------------------------------- \n"
230                         "             \\   ^__^\n"
231                         "                 (__)\\       )\\/\\\n"
232                         "                  U  ||----w |\n"
233                         "                     ||     ||\n");
234         
235         /* unlock the pdc lock if necessary */
236         pdc_emergency_unlock();
237 
238         /* maybe the kernel hasn't booted very far yet and hasn't been able 
239          * to initialize the serial or STI console. In that case we should 
240          * re-enable the pdc console, so that the user will be able to 
241          * identify the problem. */
242         if (!console_drivers)
243                 pdc_console_restart();
244         
245         if (err)
246                 printk(KERN_CRIT "%s (pid %d): %s (code %ld)\n",
247                         current->comm, task_pid_nr(current), str, err);
248 
249         /* Wot's wrong wif bein' racy? */
250         if (current->thread.flags & PARISC_KERNEL_DEATH) {
251                 printk(KERN_CRIT "%s() recursion detected.\n", __func__);
252                 local_irq_enable();
253                 while (1);
254         }
255         current->thread.flags |= PARISC_KERNEL_DEATH;
256 
257         show_regs(regs);
258         dump_stack();
259         add_taint(TAINT_DIE, LOCKDEP_NOW_UNRELIABLE);
260 
261         if (in_interrupt())
262                 panic("Fatal exception in interrupt");
263 
264         if (panic_on_oops)
265                 panic("Fatal exception");
266 
267         oops_exit();
268         do_exit(SIGSEGV);
269 }
270 
271 /* gdb uses break 4,8 */
272 #define GDB_BREAK_INSN 0x10004
273 static void handle_gdb_break(struct pt_regs *regs, int wot)
274 {
275         force_sig_fault(SIGTRAP, wot,
276                         (void __user *) (regs->iaoq[0] & ~3), current);
277 }
278 
279 static void handle_break(struct pt_regs *regs)
280 {
281         unsigned iir = regs->iir;
282 
283         if (unlikely(iir == PARISC_BUG_BREAK_INSN && !user_mode(regs))) {
284                 /* check if a BUG() or WARN() trapped here.  */
285                 enum bug_trap_type tt;
286                 tt = report_bug(regs->iaoq[0] & ~3, regs);
287                 if (tt == BUG_TRAP_TYPE_WARN) {
288                         regs->iaoq[0] += 4;
289                         regs->iaoq[1] += 4;
290                         return; /* return to next instruction when WARN_ON().  */
291                 }
292                 die_if_kernel("Unknown kernel breakpoint", regs,
293                         (tt == BUG_TRAP_TYPE_NONE) ? 9 : 0);
294         }
295 
296         if (unlikely(iir != GDB_BREAK_INSN))
297                 parisc_printk_ratelimited(0, regs,
298                         KERN_DEBUG "break %d,%d: pid=%d command='%s'\n",
299                         iir & 31, (iir>>13) & ((1<<13)-1),
300                         task_pid_nr(current), current->comm);
301 
302         /* send standard GDB signal */
303         handle_gdb_break(regs, TRAP_BRKPT);
304 }
305 
306 static void default_trap(int code, struct pt_regs *regs)
307 {
308         printk(KERN_ERR "Trap %d on CPU %d\n", code, smp_processor_id());
309         show_regs(regs);
310 }
311 
312 void (*cpu_lpmc) (int code, struct pt_regs *regs) __read_mostly = default_trap;
313 
314 
315 void transfer_pim_to_trap_frame(struct pt_regs *regs)
316 {
317     register int i;
318     extern unsigned int hpmc_pim_data[];
319     struct pdc_hpmc_pim_11 *pim_narrow;
320     struct pdc_hpmc_pim_20 *pim_wide;
321 
322     if (boot_cpu_data.cpu_type >= pcxu) {
323 
324         pim_wide = (struct pdc_hpmc_pim_20 *)hpmc_pim_data;
325 
326         /*
327          * Note: The following code will probably generate a
328          * bunch of truncation error warnings from the compiler.
329          * Could be handled with an ifdef, but perhaps there
330          * is a better way.
331          */
332 
333         regs->gr[0] = pim_wide->cr[22];
334 
335         for (i = 1; i < 32; i++)
336             regs->gr[i] = pim_wide->gr[i];
337 
338         for (i = 0; i < 32; i++)
339             regs->fr[i] = pim_wide->fr[i];
340 
341         for (i = 0; i < 8; i++)
342             regs->sr[i] = pim_wide->sr[i];
343 
344         regs->iasq[0] = pim_wide->cr[17];
345         regs->iasq[1] = pim_wide->iasq_back;
346         regs->iaoq[0] = pim_wide->cr[18];
347         regs->iaoq[1] = pim_wide->iaoq_back;
348 
349         regs->sar  = pim_wide->cr[11];
350         regs->iir  = pim_wide->cr[19];
351         regs->isr  = pim_wide->cr[20];
352         regs->ior  = pim_wide->cr[21];
353     }
354     else {
355         pim_narrow = (struct pdc_hpmc_pim_11 *)hpmc_pim_data;
356 
357         regs->gr[0] = pim_narrow->cr[22];
358 
359         for (i = 1; i < 32; i++)
360             regs->gr[i] = pim_narrow->gr[i];
361 
362         for (i = 0; i < 32; i++)
363             regs->fr[i] = pim_narrow->fr[i];
364 
365         for (i = 0; i < 8; i++)
366             regs->sr[i] = pim_narrow->sr[i];
367 
368         regs->iasq[0] = pim_narrow->cr[17];
369         regs->iasq[1] = pim_narrow->iasq_back;
370         regs->iaoq[0] = pim_narrow->cr[18];
371         regs->iaoq[1] = pim_narrow->iaoq_back;
372 
373         regs->sar  = pim_narrow->cr[11];
374         regs->iir  = pim_narrow->cr[19];
375         regs->isr  = pim_narrow->cr[20];
376         regs->ior  = pim_narrow->cr[21];
377     }
378 
379     /*
380      * The following fields only have meaning if we came through
381      * another path. So just zero them here.
382      */
383 
384     regs->ksp = 0;
385     regs->kpc = 0;
386     regs->orig_r28 = 0;
387 }
388 
389 
390 /*
391  * This routine is called as a last resort when everything else
392  * has gone clearly wrong. We get called for faults in kernel space,
393  * and HPMC's.
394  */
395 void parisc_terminate(char *msg, struct pt_regs *regs, int code, unsigned long offset)
396 {
397         static DEFINE_SPINLOCK(terminate_lock);
398 
399         bust_spinlocks(1);
400 
401         set_eiem(0);
402         local_irq_disable();
403         spin_lock(&terminate_lock);
404 
405         /* unlock the pdc lock if necessary */
406         pdc_emergency_unlock();
407 
408         /* restart pdc console if necessary */
409         if (!console_drivers)
410                 pdc_console_restart();
411 
412         /* Not all paths will gutter the processor... */
413         switch(code){
414 
415         case 1:
416                 transfer_pim_to_trap_frame(regs);
417                 break;
418 
419         default:
420                 /* Fall through */
421                 break;
422 
423         }
424             
425         {
426                 /* show_stack(NULL, (unsigned long *)regs->gr[30]); */
427                 struct unwind_frame_info info;
428                 unwind_frame_init(&info, current, regs);
429                 do_show_stack(&info);
430         }
431 
432         printk("\n");
433         pr_crit("%s: Code=%d (%s) at addr " RFMT "\n",
434                 msg, code, trap_name(code), offset);
435         show_regs(regs);
436 
437         spin_unlock(&terminate_lock);
438 
439         /* put soft power button back under hardware control;
440          * if the user had pressed it once at any time, the 
441          * system will shut down immediately right here. */
442         pdc_soft_power_button(0);
443         
444         /* Call kernel panic() so reboot timeouts work properly 
445          * FIXME: This function should be on the list of
446          * panic notifiers, and we should call panic
447          * directly from the location that we wish. 
448          * e.g. We should not call panic from
449          * parisc_terminate, but rather the oter way around.
450          * This hack works, prints the panic message twice,
451          * and it enables reboot timers!
452          */
453         panic(msg);
454 }
455 
456 void notrace handle_interruption(int code, struct pt_regs *regs)
457 {
458         unsigned long fault_address = 0;
459         unsigned long fault_space = 0;
460         int si_code;
461 
462         if (code == 1)
463             pdc_console_restart();  /* switch back to pdc if HPMC */
464         else
465             local_irq_enable();
466 
467         /* Security check:
468          * If the priority level is still user, and the
469          * faulting space is not equal to the active space
470          * then the user is attempting something in a space
471          * that does not belong to them. Kill the process.
472          *
473          * This is normally the situation when the user
474          * attempts to jump into the kernel space at the
475          * wrong offset, be it at the gateway page or a
476          * random location.
477          *
478          * We cannot normally signal the process because it
479          * could *be* on the gateway page, and processes
480          * executing on the gateway page can't have signals
481          * delivered.
482          * 
483          * We merely readjust the address into the users
484          * space, at a destination address of zero, and
485          * allow processing to continue.
486          */
487         if (((unsigned long)regs->iaoq[0] & 3) &&
488             ((unsigned long)regs->iasq[0] != (unsigned long)regs->sr[7])) { 
489                 /* Kill the user process later */
490                 regs->iaoq[0] = 0 | 3;
491                 regs->iaoq[1] = regs->iaoq[0] + 4;
492                 regs->iasq[0] = regs->iasq[1] = regs->sr[7];
493                 regs->gr[0] &= ~PSW_B;
494                 return;
495         }
496         
497 #if 0
498         printk(KERN_CRIT "Interruption # %d\n", code);
499 #endif
500 
501         switch(code) {
502 
503         case  1:
504                 /* High-priority machine check (HPMC) */
505                 
506                 /* set up a new led state on systems shipped with a LED State panel */
507                 pdc_chassis_send_status(PDC_CHASSIS_DIRECT_HPMC);
508 
509                 parisc_terminate("High Priority Machine Check (HPMC)",
510                                 regs, code, 0);
511                 /* NOT REACHED */
512                 
513         case  2:
514                 /* Power failure interrupt */
515                 printk(KERN_CRIT "Power failure interrupt !\n");
516                 return;
517 
518         case  3:
519                 /* Recovery counter trap */
520                 regs->gr[0] &= ~PSW_R;
521                 if (user_space(regs))
522                         handle_gdb_break(regs, TRAP_TRACE);
523                 /* else this must be the start of a syscall - just let it run */
524                 return;
525 
526         case  5:
527                 /* Low-priority machine check */
528                 pdc_chassis_send_status(PDC_CHASSIS_DIRECT_LPMC);
529                 
530                 flush_cache_all();
531                 flush_tlb_all();
532                 cpu_lpmc(5, regs);
533                 return;
534 
535         case  PARISC_ITLB_TRAP:
536                 /* Instruction TLB miss fault/Instruction page fault */
537                 fault_address = regs->iaoq[0];
538                 fault_space   = regs->iasq[0];
539                 break;
540 
541         case  8:
542                 /* Illegal instruction trap */
543                 die_if_kernel("Illegal instruction", regs, code);
544                 si_code = ILL_ILLOPC;
545                 goto give_sigill;
546 
547         case  9:
548                 /* Break instruction trap */
549                 handle_break(regs);
550                 return;
551 
552         case 10:
553                 /* Privileged operation trap */
554                 die_if_kernel("Privileged operation", regs, code);
555                 si_code = ILL_PRVOPC;
556                 goto give_sigill;
557 
558         case 11:
559                 /* Privileged register trap */
560                 if ((regs->iir & 0xffdfffe0) == 0x034008a0) {
561 
562                         /* This is a MFCTL cr26/cr27 to gr instruction.
563                          * PCXS traps on this, so we need to emulate it.
564                          */
565 
566                         if (regs->iir & 0x00200000)
567                                 regs->gr[regs->iir & 0x1f] = mfctl(27);
568                         else
569                                 regs->gr[regs->iir & 0x1f] = mfctl(26);
570 
571                         regs->iaoq[0] = regs->iaoq[1];
572                         regs->iaoq[1] += 4;
573                         regs->iasq[0] = regs->iasq[1];
574                         return;
575                 }
576 
577                 die_if_kernel("Privileged register usage", regs, code);
578                 si_code = ILL_PRVREG;
579         give_sigill:
580                 force_sig_fault(SIGILL, si_code,
581                                 (void __user *) regs->iaoq[0], current);
582                 return;
583 
584         case 12:
585                 /* Overflow Trap, let the userland signal handler do the cleanup */
586                 force_sig_fault(SIGFPE, FPE_INTOVF,
587                                 (void __user *) regs->iaoq[0], current);
588                 return;
589                 
590         case 13:
591                 /* Conditional Trap
592                    The condition succeeds in an instruction which traps
593                    on condition  */
594                 if(user_mode(regs)){
595                         /* Let userspace app figure it out from the insn pointed
596                          * to by si_addr.
597                          */
598                         force_sig_fault(SIGFPE, FPE_CONDTRAP,
599                                         (void __user *) regs->iaoq[0], current);
600                         return;
601                 } 
602                 /* The kernel doesn't want to handle condition codes */
603                 break;
604                 
605         case 14:
606                 /* Assist Exception Trap, i.e. floating point exception. */
607                 die_if_kernel("Floating point exception", regs, 0); /* quiet */
608                 __inc_irq_stat(irq_fpassist_count);
609                 handle_fpe(regs);
610                 return;
611 
612         case 15:
613                 /* Data TLB miss fault/Data page fault */
614                 /* Fall through */
615         case 16:
616                 /* Non-access instruction TLB miss fault */
617                 /* The instruction TLB entry needed for the target address of the FIC
618                    is absent, and hardware can't find it, so we get to cleanup */
619                 /* Fall through */
620         case 17:
621                 /* Non-access data TLB miss fault/Non-access data page fault */
622                 /* FIXME: 
623                          Still need to add slow path emulation code here!
624                          If the insn used a non-shadow register, then the tlb
625                          handlers could not have their side-effect (e.g. probe
626                          writing to a target register) emulated since rfir would
627                          erase the changes to said register. Instead we have to
628                          setup everything, call this function we are in, and emulate
629                          by hand. Technically we need to emulate:
630                          fdc,fdce,pdc,"fic,4f",prober,probeir,probew, probeiw
631                 */
632                 fault_address = regs->ior;
633                 fault_space = regs->isr;
634                 break;
635 
636         case 18:
637                 /* PCXS only -- later cpu's split this into types 26,27 & 28 */
638                 /* Check for unaligned access */
639                 if (check_unaligned(regs)) {
640                         handle_unaligned(regs);
641                         return;
642                 }
643                 /* Fall Through */
644         case 26: 
645                 /* PCXL: Data memory access rights trap */
646                 fault_address = regs->ior;
647                 fault_space   = regs->isr;
648                 break;
649 
650         case 19:
651                 /* Data memory break trap */
652                 regs->gr[0] |= PSW_X; /* So we can single-step over the trap */
653                 /* fall thru */
654         case 21:
655                 /* Page reference trap */
656                 handle_gdb_break(regs, TRAP_HWBKPT);
657                 return;
658 
659         case 25:
660                 /* Taken branch trap */
661                 regs->gr[0] &= ~PSW_T;
662                 if (user_space(regs))
663                         handle_gdb_break(regs, TRAP_BRANCH);
664                 /* else this must be the start of a syscall - just let it
665                  * run.
666                  */
667                 return;
668 
669         case  7:  
670                 /* Instruction access rights */
671                 /* PCXL: Instruction memory protection trap */
672 
673                 /*
674                  * This could be caused by either: 1) a process attempting
675                  * to execute within a vma that does not have execute
676                  * permission, or 2) an access rights violation caused by a
677                  * flush only translation set up by ptep_get_and_clear().
678                  * So we check the vma permissions to differentiate the two.
679                  * If the vma indicates we have execute permission, then
680                  * the cause is the latter one. In this case, we need to
681                  * call do_page_fault() to fix the problem.
682                  */
683 
684                 if (user_mode(regs)) {
685                         struct vm_area_struct *vma;
686 
687                         down_read(&current->mm->mmap_sem);
688                         vma = find_vma(current->mm,regs->iaoq[0]);
689                         if (vma && (regs->iaoq[0] >= vma->vm_start)
690                                 && (vma->vm_flags & VM_EXEC)) {
691 
692                                 fault_address = regs->iaoq[0];
693                                 fault_space = regs->iasq[0];
694 
695                                 up_read(&current->mm->mmap_sem);
696                                 break; /* call do_page_fault() */
697                         }
698                         up_read(&current->mm->mmap_sem);
699                 }
700                 /* Fall Through */
701         case 27: 
702                 /* Data memory protection ID trap */
703                 if (code == 27 && !user_mode(regs) &&
704                         fixup_exception(regs))
705                         return;
706 
707                 die_if_kernel("Protection id trap", regs, code);
708                 force_sig_fault(SIGSEGV, SEGV_MAPERR,
709                                 (code == 7)?
710                                 ((void __user *) regs->iaoq[0]) :
711                                 ((void __user *) regs->ior), current);
712                 return;
713 
714         case 28: 
715                 /* Unaligned data reference trap */
716                 handle_unaligned(regs);
717                 return;
718 
719         default:
720                 if (user_mode(regs)) {
721                         parisc_printk_ratelimited(0, regs, KERN_DEBUG
722                                 "handle_interruption() pid=%d command='%s'\n",
723                                 task_pid_nr(current), current->comm);
724                         /* SIGBUS, for lack of a better one. */
725                         force_sig_fault(SIGBUS, BUS_OBJERR,
726                                         (void __user *)regs->ior, current);
727                         return;
728                 }
729                 pdc_chassis_send_status(PDC_CHASSIS_DIRECT_PANIC);
730                 
731                 parisc_terminate("Unexpected interruption", regs, code, 0);
732                 /* NOT REACHED */
733         }
734 
735         if (user_mode(regs)) {
736             if ((fault_space >> SPACEID_SHIFT) != (regs->sr[7] >> SPACEID_SHIFT)) {
737                 parisc_printk_ratelimited(0, regs, KERN_DEBUG
738                                 "User fault %d on space 0x%08lx, pid=%d command='%s'\n",
739                                 code, fault_space,
740                                 task_pid_nr(current), current->comm);
741                 force_sig_fault(SIGSEGV, SEGV_MAPERR,
742                                 (void __user *)regs->ior, current);
743                 return;
744             }
745         }
746         else {
747 
748             /*
749              * The kernel should never fault on its own address space,
750              * unless pagefault_disable() was called before.
751              */
752 
753             if (fault_space == 0 && !faulthandler_disabled())
754             {
755                 /* Clean up and return if in exception table. */
756                 if (fixup_exception(regs))
757                         return;
758                 pdc_chassis_send_status(PDC_CHASSIS_DIRECT_PANIC);
759                 parisc_terminate("Kernel Fault", regs, code, fault_address);
760             }
761         }
762 
763         do_page_fault(regs, code, fault_address);
764 }
765 
766 
767 void __init initialize_ivt(const void *iva)
768 {
769         extern u32 os_hpmc_size;
770         extern const u32 os_hpmc[];
771 
772         int i;
773         u32 check = 0;
774         u32 *ivap;
775         u32 *hpmcp;
776         u32 length, instr;
777 
778         if (strcmp((const char *)iva, "cows can fly"))
779                 panic("IVT invalid");
780 
781         ivap = (u32 *)iva;
782 
783         for (i = 0; i < 8; i++)
784             *ivap++ = 0;
785 
786         /*
787          * Use PDC_INSTR firmware function to get instruction that invokes
788          * PDCE_CHECK in HPMC handler.  See programming note at page 1-31 of
789          * the PA 1.1 Firmware Architecture document.
790          */
791         if (pdc_instr(&instr) == PDC_OK)
792                 ivap[0] = instr;
793 
794         /*
795          * Rules for the checksum of the HPMC handler:
796          * 1. The IVA does not point to PDC/PDH space (ie: the OS has installed
797          *    its own IVA).
798          * 2. The word at IVA + 32 is nonzero.
799          * 3. If Length (IVA + 60) is not zero, then Length (IVA + 60) and
800          *    Address (IVA + 56) are word-aligned.
801          * 4. The checksum of the 8 words starting at IVA + 32 plus the sum of
802          *    the Length/4 words starting at Address is zero.
803          */
804 
805         /* Setup IVA and compute checksum for HPMC handler */
806         ivap[6] = (u32)__pa(os_hpmc);
807         length = os_hpmc_size;
808         ivap[7] = length;
809 
810         hpmcp = (u32 *)os_hpmc;
811 
812         for (i=0; i<length/4; i++)
813             check += *hpmcp++;
814 
815         for (i=0; i<8; i++)
816             check += ivap[i];
817 
818         ivap[5] = -check;
819 }
820         
821 
822 /* early_trap_init() is called before we set up kernel mappings and
823  * write-protect the kernel */
824 void  __init early_trap_init(void)
825 {
826         extern const void fault_vector_20;
827 
828 #ifndef CONFIG_64BIT
829         extern const void fault_vector_11;
830         initialize_ivt(&fault_vector_11);
831 #endif
832 
833         initialize_ivt(&fault_vector_20);
834 }
835 
836 void __init trap_init(void)
837 {
838 }
839 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | Wiki (Japanese) | Wiki (English) | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

osdn.jp