File: /usr/src/linux/arch/mips/kernel/unaligned.c

1     /*
2      * Handle unaligned accesses by emulation.
3      *
4      * This file is subject to the terms and conditions of the GNU General Public
5      * License.  See the file "COPYING" in the main directory of this archive
6      * for more details.
7      *
8      * Copyright (C) 1996, 1998 by Ralf Baechle
9      * Copyright (C) 1999 Silicon Graphics, Inc.
10      *
11      * This file contains exception handler for address error exception with the
12      * special capability to execute faulting instructions in software.  The
13      * handler does not try to handle the case when the program counter points
14      * to an address not aligned to a word boundary.
15      *
16      * Putting data to unaligned addresses is a bad practice even on Intel where
17      * only the performance is affected.  Much worse is that such code is non-
18      * portable.  Due to several programs that die on MIPS due to alignment
19      * problems I decided to implement this handler anyway though I originally
20      * didn't intend to do this at all for user code.
21      *
22      * For now I enable fixing of address errors by default to make life easier.
23      * I however intend to disable this somewhen in the future when the alignment
24      * problems with user programs have been fixed.  For programmers this is the
25      * right way to go.
26      *
27      * Fixing address errors is a per process option.  The option is inherited
28      * across fork(2) and execve(2) calls.  If you really want to use the
29      * option in your user programs - I discourage the use of the software
30      * emulation strongly - use the following code in your userland stuff:
31      *
32      * #include <sys/sysmips.h>
33      *
34      * ...
35      * sysmips(MIPS_FIXADE, x);
36      * ...
37      *
38      * The argument x is 0 for disabling software emulation, enabled otherwise.
39      *
40      * Below a little program to play around with this feature.
41      *
42      * #include <stdio.h>
43      * #include <asm/sysmips.h>
44      * 
45      * struct foo {
46      *         unsigned char bar[8];
47      * };
48      *
49      * main(int argc, char *argv[])
50      * {
51      *         struct foo x = {0, 1, 2, 3, 4, 5, 6, 7};
52      *         unsigned int *p = (unsigned int *) (x.bar + 3);
53      *         int i;
54      *
55      *         if (argc > 1)
56      *                 sysmips(MIPS_FIXADE, atoi(argv[1]));
57      *
58      *         printf("*p = %08lx\n", *p);
59      *
60      *         *p = 0xdeadface;
61      *
62      *         for(i = 0; i <= 7; i++)
63      *         printf("%02x ", x.bar[i]);
64      *         printf("\n");
65      * }
66      *
67      * Coprocessor loads are not supported; I think this case is unimportant
68      * in the practice.
69      *
70      * TODO: Handle ndc (attempted store to doubleword in uncached memory)
71      *       exception for the R6000.
72      *       A store crossing a page boundary might be executed only partially.
73      *       Undo the partial store in this case.
74      */
75     #include <linux/config.h>
76     #include <linux/mm.h>
77     #include <linux/signal.h>
78     #include <linux/smp.h>
79     #include <linux/smp_lock.h>
80     
81     #include <asm/asm.h>
82     #include <asm/branch.h>
83     #include <asm/byteorder.h>
84     #include <asm/inst.h>
85     #include <asm/uaccess.h>
86     #include <asm/system.h>
87     
88     #define STR(x)  __STR(x)
89     #define __STR(x)  #x
90     
91     /*
92      * User code may only access USEG; kernel code may access the
93      * entire address space.
94      */
95     #define check_axs(pc,a,s)				\
96     	if ((long)(~(pc) & ((a) | ((a)+(s)))) < 0)	\
97     		goto sigbus;
98     
99     static inline void
100     emulate_load_store_insn(struct pt_regs *regs,
101                             unsigned long addr,
102                             unsigned long pc)
103     {
104     	union mips_instruction insn;
105     	unsigned long value, fixup;
106     
107     	regs->regs[0] = 0;
108     	/*
109     	 * This load never faults.
110     	 */
111     	__get_user(insn.word, (unsigned int *)pc);
112     
113     	switch (insn.i_format.opcode) {
114     	/*
115     	 * These are instructions that a compiler doesn't generate.  We
116     	 * can assume therefore that the code is MIPS-aware and
117     	 * really buggy.  Emulating these instructions would break the
118     	 * semantics anyway.
119     	 */
120     	case ll_op:
121     	case lld_op:
122     	case sc_op:
123     	case scd_op:
124     
125     	/*
126     	 * For these instructions the only way to create an address
127     	 * error is an attempted access to kernel/supervisor address
128     	 * space.
129     	 */
130     	case ldl_op:
131     	case ldr_op:
132     	case lwl_op:
133     	case lwr_op:
134     	case sdl_op:
135     	case sdr_op:
136     	case swl_op:
137     	case swr_op:
138     	case lb_op:
139     	case lbu_op:
140     	case sb_op:
141     		goto sigbus;
142     
143     	/*
144     	 * The remaining opcodes are the ones that are really of interest.
145     	 */
146     	case lh_op:
147     		check_axs(pc, addr, 2);
148     		__asm__(
149     			".set\tnoat\n"
150     #ifdef __BIG_ENDIAN
151     			"1:\tlb\t%0,0(%1)\n"
152     			"2:\tlbu\t$1,1(%1)\n\t"
153     #endif
154     #ifdef __LITTLE_ENDIAN
155     			"1:\tlb\t%0,1(%1)\n"
156     			"2:\tlbu\t$1,0(%1)\n\t"
157     #endif
158     			"sll\t%0,0x8\n\t"
159     			"or\t%0,$1\n\t"
160     			".set\tat\n\t"
161     			".section\t__ex_table,\"a\"\n\t"
162     			STR(PTR)"\t1b,%2\n\t"
163     			STR(PTR)"\t2b,%2\n\t"
164     			".previous"
165     			:"=&r" (value)
166     			:"r" (addr), "i" (&&fault)
167     			:"$1");
168     		regs->regs[insn.i_format.rt] = value;
169     		return;
170     
171     	case lw_op:
172     		check_axs(pc, addr, 4);
173     		__asm__(
174     #ifdef __BIG_ENDIAN
175     			"1:\tlwl\t%0,(%1)\n"
176     			"2:\tlwr\t%0,3(%1)\n\t"
177     #endif
178     #ifdef __LITTLE_ENDIAN
179     			"1:\tlwl\t%0,3(%1)\n"
180     			"2:\tlwr\t%0,(%1)\n\t"
181     #endif
182     			".section\t__ex_table,\"a\"\n\t"
183     			STR(PTR)"\t1b,%2\n\t"
184     			STR(PTR)"\t2b,%2\n\t"
185     			".previous"
186     			:"=&r" (value)
187     			:"r" (addr), "i" (&&fault));
188     			regs->regs[insn.i_format.rt] = value;
189     			return;
190     
191     	case lhu_op:
192     		check_axs(pc, addr, 2);
193     		__asm__(
194     			".set\tnoat\n"
195     #ifdef __BIG_ENDIAN
196     			"1:\tlbu\t%0,0(%1)\n"
197     			"2:\tlbu\t$1,1(%1)\n\t"
198     #endif
199     #ifdef __LITTLE_ENDIAN
200     			"1:\tlbu\t%0,1(%1)\n"
201     			"2:\tlbu\t$1,0(%1)\n\t"
202     #endif
203     			"sll\t%0,0x8\n\t"
204     			"or\t%0,$1\n\t"
205     			".set\tat\n\t"
206     			".section\t__ex_table,\"a\"\n\t"
207     			STR(PTR)"\t1b,%2\n\t"
208     			STR(PTR)"\t2b,%2\n\t"
209     			".previous"
210     			:"=&r" (value)
211     			:"r" (addr), "i" (&&fault)
212     			:"$1");
213     		regs->regs[insn.i_format.rt] = value;
214     		return;
215     
216     	case lwu_op:
217     		check_axs(pc, addr, 4);
218     		__asm__(
219     #ifdef __BIG_ENDIAN
220     			"1:\tlwl\t%0,(%1)\n"
221     			"2:\tlwr\t%0,3(%1)\n\t"
222     #endif
223     #ifdef __LITTLE_ENDIAN
224     			"1:\tlwl\t%0,3(%1)\n"
225     			"2:\tlwr\t%0,(%1)\n\t"
226     #endif
227     			".section\t__ex_table,\"a\"\n\t"
228     			STR(PTR)"\t1b,%2\n\t"
229     			STR(PTR)"\t2b,%2\n\t"
230     			".previous"
231     			:"=&r" (value)
232     			:"r" (addr), "i" (&&fault));
233     		value &= 0xffffffff;
234     		regs->regs[insn.i_format.rt] = value;
235     		return;
236     
237     	case ld_op:
238     		check_axs(pc, addr, 8);
239     		__asm__(
240     			".set\tmips3\n"
241     #ifdef __BIG_ENDIAN
242     			"1:\tldl\t%0,(%1)\n"
243     			"2:\tldr\t%0,7(%1)\n\t"
244     #endif
245     #ifdef __LITTLE_ENDIAN
246     			"1:\tldl\t%0,7(%1)\n"
247     			"2:\tldr\t%0,(%1)\n\t"
248     #endif
249     			".set\tmips0\n\t"
250     			".section\t__ex_table,\"a\"\n\t"
251     			STR(PTR)"\t1b,%2\n\t"
252     			STR(PTR)"\t2b,%2\n\t"
253     			".previous"
254     			:"=&r" (value)
255     			:"r" (addr), "i" (&&fault));
256     		regs->regs[insn.i_format.rt] = value;
257     		return;
258     
259     	case sh_op:
260     		check_axs(pc, addr, 2);
261     		value = regs->regs[insn.i_format.rt];
262     		__asm__(
263     #ifdef __BIG_ENDIAN
264     			".set\tnoat\n"
265     			"1:\tsb\t%0,1(%1)\n\t"
266     			"srl\t$1,%0,0x8\n"
267     			"2:\tsb\t$1,0(%1)\n\t"
268     			".set\tat\n\t"
269     #endif
270     #ifdef __LITTLE_ENDIAN
271     			".set\tnoat\n"
272     			"1:\tsb\t%0,0(%1)\n\t"
273     			"srl\t$1,%0,0x8\n"
274     			"2:\tsb\t$1,1(%1)\n\t"
275     			".set\tat\n\t"
276     #endif
277     			".section\t__ex_table,\"a\"\n\t"
278     			STR(PTR)"\t1b,%2\n\t"
279     			STR(PTR)"\t2b,%2\n\t"
280     			".previous"
281     			: /* no outputs */
282     			:"r" (value), "r" (addr), "i" (&&fault)
283     			:"$1");
284     		return;
285     
286     	case sw_op:
287     		check_axs(pc, addr, 4);
288     		value = regs->regs[insn.i_format.rt];
289     		__asm__(
290     #ifdef __BIG_ENDIAN
291     			"1:\tswl\t%0,(%1)\n"
292     			"2:\tswr\t%0,3(%1)\n\t"
293     #endif
294     #ifdef __LITTLE_ENDIAN
295     			"1:\tswl\t%0,3(%1)\n"
296     			"2:\tswr\t%0,(%1)\n\t"
297     #endif
298     			".section\t__ex_table,\"a\"\n\t"
299     			STR(PTR)"\t1b,%2\n\t"
300     			STR(PTR)"\t2b,%2\n\t"
301     			".previous"
302     			: /* no outputs */
303     			:"r" (value), "r" (addr), "i" (&&fault));
304     		return;
305     
306     	case sd_op:
307     		check_axs(pc, addr, 8);
308     		value = regs->regs[insn.i_format.rt];
309     		__asm__(
310     			".set\tmips3\n"
311     #ifdef __BIG_ENDIAN
312     			"1:\tsdl\t%0,(%1)\n"
313     			"2:\tsdr\t%0,7(%1)\n\t"
314     #endif
315     #ifdef __LITTLE_ENDIAN
316     			"1:\tsdl\t%0,7(%1)\n"
317     			"2:\tsdr\t%0,(%1)\n\t"
318     #endif
319     			".set\tmips0\n\t"
320     			".section\t__ex_table,\"a\"\n\t"
321     			STR(PTR)"\t1b,%2\n\t"
322     			STR(PTR)"\t2b,%2\n\t"
323     			".previous"
324     			: /* no outputs */
325     			:"r" (value), "r" (addr), "i" (&&fault));
326     		return;
327     
328     	case lwc1_op:
329     	case ldc1_op:
330     	case swc1_op:
331     	case sdc1_op:
332     		/*
333     		 * I herewith declare: this does not happen.  So send SIGBUS.
334     		 */
335     		goto sigbus;
336     
337     	case lwc2_op:
338     	case ldc2_op:
339     	case swc2_op:
340     	case sdc2_op:
341     		/*
342     		 * These are the coprocessor 2 load/stores.  The current
343     		 * implementations don't use cp2 and cp2 should always be
344     		 * disabled in c0_status.  So send SIGILL.
345                      * (No longer true: The Sony Praystation uses cp2 for
346                      * 3D matrix operations.  Dunno if that thingy has a MMU ...)
347     		 */
348     	default:
349     		/*
350     		 * Pheeee...  We encountered an yet unknown instruction or
351     		 * cache coherence problem.  Die sucker, die ...
352     		 */
353     		goto sigill;
354     	}
355     	return;
356     
357     fault:
358     	/* Did we have an exception handler installed? */
359     	fixup = search_exception_table(regs->cp0_epc);
360     	if (fixup) {
361     		long new_epc;
362     		new_epc = fixup_exception(dpf_reg, fixup, regs->cp0_epc);
363     		printk(KERN_DEBUG "%s: Forwarding exception at [<%lx>] (%lx)\n",
364     		       current->comm, regs->cp0_epc, new_epc);
365     		regs->cp0_epc = new_epc;
366     		return;
367     	}
368     
369     	die_if_kernel ("Unhandled kernel unaligned access", regs);
370     	send_sig(SIGSEGV, current, 1);
371     	return;
372     sigbus:
373     	die_if_kernel ("Unhandled kernel unaligned access", regs);
374     	send_sig(SIGBUS, current, 1);
375     	return;
376     sigill:
377     	die_if_kernel ("Unhandled kernel unaligned access or invalid instruction", regs);
378     	send_sig(SIGILL, current, 1);
379     	return;
380     }
381     
382     #ifdef CONFIG_PROC_FS
383     unsigned long unaligned_instructions;
384     #endif
385     
386     asmlinkage void do_ade(struct pt_regs *regs)
387     {
388     	unsigned long pc;
389     	extern int do_dsemulret(struct pt_regs *);
390     
391     	/* 
392     	 * Address errors may be deliberately induced
393     	 * by the FPU emulator to take retake control
394     	 * of the CPU after executing the instruction
395     	 * in the delay slot of an emulated branch.
396     	 */
397     
398     	if ((unsigned long)regs->cp0_epc == current->thread.dsemul_aerpc) {
399     		do_dsemulret(regs);
400     		return;
401     	}
402     
403     	/*
404     	 * Did we catch a fault trying to load an instruction?
405     	 * This also catches attempts to activate MIPS16 code on
406     	 * CPUs which don't support it.
407     	 */
408     	if (regs->cp0_badvaddr == regs->cp0_epc)
409     		goto sigbus;
410     
411     	pc = regs->cp0_epc + ((regs->cp0_cause & CAUSEF_BD) ? 4 : 0);
412     	if (compute_return_epc(regs))
413     		return;
414     	if ((current->thread.mflags & MF_FIXADE) == 0)
415     		goto sigbus;
416     
417     	emulate_load_store_insn(regs, regs->cp0_badvaddr, pc);
418     #ifdef CONFIG_PROC_FS
419     	unaligned_instructions++;
420     #endif
421     
422     	return;
423     
424     sigbus:
425     	die_if_kernel ("Kernel unaligned instruction access", regs);
426     	force_sig(SIGBUS, current);
427     
428     	return;
429     }
430