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