]> git.karo-electronics.de Git - karo-tx-linux.git/blob - arch/mips/kernel/unaligned.c
MIPS: unaligned: Fix regular load/store instruction emulation for EVA
[karo-tx-linux.git] / 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, 1999, 2002 by Ralf Baechle
9  * Copyright (C) 1999 Silicon Graphics, Inc.
10  * Copyright (C) 2014 Imagination Technologies Ltd.
11  *
12  * This file contains exception handler for address error exception with the
13  * special capability to execute faulting instructions in software.  The
14  * handler does not try to handle the case when the program counter points
15  * to an address not aligned to a word boundary.
16  *
17  * Putting data to unaligned addresses is a bad practice even on Intel where
18  * only the performance is affected.  Much worse is that such code is non-
19  * portable.  Due to several programs that die on MIPS due to alignment
20  * problems I decided to implement this handler anyway though I originally
21  * didn't intend to do this at all for user code.
22  *
23  * For now I enable fixing of address errors by default to make life easier.
24  * I however intend to disable this somewhen in the future when the alignment
25  * problems with user programs have been fixed.  For programmers this is the
26  * right way to go.
27  *
28  * Fixing address errors is a per process option.  The option is inherited
29  * across fork(2) and execve(2) calls.  If you really want to use the
30  * option in your user programs - I discourage the use of the software
31  * emulation strongly - use the following code in your userland stuff:
32  *
33  * #include <sys/sysmips.h>
34  *
35  * ...
36  * sysmips(MIPS_FIXADE, x);
37  * ...
38  *
39  * The argument x is 0 for disabling software emulation, enabled otherwise.
40  *
41  * Below a little program to play around with this feature.
42  *
43  * #include <stdio.h>
44  * #include <sys/sysmips.h>
45  *
46  * struct foo {
47  *         unsigned char bar[8];
48  * };
49  *
50  * main(int argc, char *argv[])
51  * {
52  *         struct foo x = {0, 1, 2, 3, 4, 5, 6, 7};
53  *         unsigned int *p = (unsigned int *) (x.bar + 3);
54  *         int i;
55  *
56  *         if (argc > 1)
57  *                 sysmips(MIPS_FIXADE, atoi(argv[1]));
58  *
59  *         printf("*p = %08lx\n", *p);
60  *
61  *         *p = 0xdeadface;
62  *
63  *         for(i = 0; i <= 7; i++)
64  *         printf("%02x ", x.bar[i]);
65  *         printf("\n");
66  * }
67  *
68  * Coprocessor loads are not supported; I think this case is unimportant
69  * in the practice.
70  *
71  * TODO: Handle ndc (attempted store to doubleword in uncached memory)
72  *       exception for the R6000.
73  *       A store crossing a page boundary might be executed only partially.
74  *       Undo the partial store in this case.
75  */
76 #include <linux/context_tracking.h>
77 #include <linux/mm.h>
78 #include <linux/signal.h>
79 #include <linux/smp.h>
80 #include <linux/sched.h>
81 #include <linux/debugfs.h>
82 #include <linux/perf_event.h>
83
84 #include <asm/asm.h>
85 #include <asm/branch.h>
86 #include <asm/byteorder.h>
87 #include <asm/cop2.h>
88 #include <asm/fpu.h>
89 #include <asm/fpu_emulator.h>
90 #include <asm/inst.h>
91 #include <asm/uaccess.h>
92 #include <asm/fpu.h>
93 #include <asm/fpu_emulator.h>
94
95 #define STR(x)  __STR(x)
96 #define __STR(x)  #x
97
98 enum {
99         UNALIGNED_ACTION_QUIET,
100         UNALIGNED_ACTION_SIGNAL,
101         UNALIGNED_ACTION_SHOW,
102 };
103 #ifdef CONFIG_DEBUG_FS
104 static u32 unaligned_instructions;
105 static u32 unaligned_action;
106 #else
107 #define unaligned_action UNALIGNED_ACTION_QUIET
108 #endif
109 extern void show_registers(struct pt_regs *regs);
110
111 #ifdef __BIG_ENDIAN
112 #define     _LoadHW(addr, value, res, type)  \
113 do {                                                        \
114                 __asm__ __volatile__ (".set\tnoat\n"        \
115                         "1:\t"type##_lb("%0", "0(%2)")"\n"  \
116                         "2:\t"type##_lbu("$1", "1(%2)")"\n\t"\
117                         "sll\t%0, 0x8\n\t"                  \
118                         "or\t%0, $1\n\t"                    \
119                         "li\t%1, 0\n"                       \
120                         "3:\t.set\tat\n\t"                  \
121                         ".insn\n\t"                         \
122                         ".section\t.fixup,\"ax\"\n\t"       \
123                         "4:\tli\t%1, %3\n\t"                \
124                         "j\t3b\n\t"                         \
125                         ".previous\n\t"                     \
126                         ".section\t__ex_table,\"a\"\n\t"    \
127                         STR(PTR)"\t1b, 4b\n\t"              \
128                         STR(PTR)"\t2b, 4b\n\t"              \
129                         ".previous"                         \
130                         : "=&r" (value), "=r" (res)         \
131                         : "r" (addr), "i" (-EFAULT));       \
132 } while(0)
133
134 #ifndef CONFIG_CPU_MIPSR6
135 #define     _LoadW(addr, value, res, type)   \
136 do {                                                        \
137                 __asm__ __volatile__ (                      \
138                         "1:\t"type##_lwl("%0", "(%2)")"\n"   \
139                         "2:\t"type##_lwr("%0", "3(%2)")"\n\t"\
140                         "li\t%1, 0\n"                       \
141                         "3:\n\t"                            \
142                         ".insn\n\t"                         \
143                         ".section\t.fixup,\"ax\"\n\t"       \
144                         "4:\tli\t%1, %3\n\t"                \
145                         "j\t3b\n\t"                         \
146                         ".previous\n\t"                     \
147                         ".section\t__ex_table,\"a\"\n\t"    \
148                         STR(PTR)"\t1b, 4b\n\t"              \
149                         STR(PTR)"\t2b, 4b\n\t"              \
150                         ".previous"                         \
151                         : "=&r" (value), "=r" (res)         \
152                         : "r" (addr), "i" (-EFAULT));       \
153 } while(0)
154
155 #else
156 /* MIPSR6 has no lwl instruction */
157 #define     _LoadW(addr, value, res, type) \
158 do {                                                        \
159                 __asm__ __volatile__ (                      \
160                         ".set\tpush\n"                      \
161                         ".set\tnoat\n\t"                    \
162                         "1:"type##_lb("%0", "0(%2)")"\n\t"  \
163                         "2:"type##_lbu("$1", "1(%2)")"\n\t" \
164                         "sll\t%0, 0x8\n\t"                  \
165                         "or\t%0, $1\n\t"                    \
166                         "3:"type##_lbu("$1", "2(%2)")"\n\t" \
167                         "sll\t%0, 0x8\n\t"                  \
168                         "or\t%0, $1\n\t"                    \
169                         "4:"type##_lbu("$1", "3(%2)")"\n\t" \
170                         "sll\t%0, 0x8\n\t"                  \
171                         "or\t%0, $1\n\t"                    \
172                         "li\t%1, 0\n"                       \
173                         ".set\tpop\n"                       \
174                         "10:\n\t"                           \
175                         ".insn\n\t"                         \
176                         ".section\t.fixup,\"ax\"\n\t"       \
177                         "11:\tli\t%1, %3\n\t"               \
178                         "j\t10b\n\t"                        \
179                         ".previous\n\t"                     \
180                         ".section\t__ex_table,\"a\"\n\t"    \
181                         STR(PTR)"\t1b, 11b\n\t"             \
182                         STR(PTR)"\t2b, 11b\n\t"             \
183                         STR(PTR)"\t3b, 11b\n\t"             \
184                         STR(PTR)"\t4b, 11b\n\t"             \
185                         ".previous"                         \
186                         : "=&r" (value), "=r" (res)         \
187                         : "r" (addr), "i" (-EFAULT));       \
188 } while(0)
189
190 #endif /* CONFIG_CPU_MIPSR6 */
191
192 #define     _LoadHWU(addr, value, res, type) \
193 do {                                                        \
194                 __asm__ __volatile__ (                      \
195                         ".set\tnoat\n"                      \
196                         "1:\t"type##_lbu("%0", "0(%2)")"\n" \
197                         "2:\t"type##_lbu("$1", "1(%2)")"\n\t"\
198                         "sll\t%0, 0x8\n\t"                  \
199                         "or\t%0, $1\n\t"                    \
200                         "li\t%1, 0\n"                       \
201                         "3:\n\t"                            \
202                         ".insn\n\t"                         \
203                         ".set\tat\n\t"                      \
204                         ".section\t.fixup,\"ax\"\n\t"       \
205                         "4:\tli\t%1, %3\n\t"                \
206                         "j\t3b\n\t"                         \
207                         ".previous\n\t"                     \
208                         ".section\t__ex_table,\"a\"\n\t"    \
209                         STR(PTR)"\t1b, 4b\n\t"              \
210                         STR(PTR)"\t2b, 4b\n\t"              \
211                         ".previous"                         \
212                         : "=&r" (value), "=r" (res)         \
213                         : "r" (addr), "i" (-EFAULT));       \
214 } while(0)
215
216 #ifndef CONFIG_CPU_MIPSR6
217 #define     _LoadWU(addr, value, res, type)  \
218 do {                                                        \
219                 __asm__ __volatile__ (                      \
220                         "1:\t"type##_lwl("%0", "(%2)")"\n"  \
221                         "2:\t"type##_lwr("%0", "3(%2)")"\n\t"\
222                         "dsll\t%0, %0, 32\n\t"              \
223                         "dsrl\t%0, %0, 32\n\t"              \
224                         "li\t%1, 0\n"                       \
225                         "3:\n\t"                            \
226                         ".insn\n\t"                         \
227                         "\t.section\t.fixup,\"ax\"\n\t"     \
228                         "4:\tli\t%1, %3\n\t"                \
229                         "j\t3b\n\t"                         \
230                         ".previous\n\t"                     \
231                         ".section\t__ex_table,\"a\"\n\t"    \
232                         STR(PTR)"\t1b, 4b\n\t"              \
233                         STR(PTR)"\t2b, 4b\n\t"              \
234                         ".previous"                         \
235                         : "=&r" (value), "=r" (res)         \
236                         : "r" (addr), "i" (-EFAULT));       \
237 } while(0)
238
239 #define     _LoadDW(addr, value, res)  \
240 do {                                                        \
241                 __asm__ __volatile__ (                      \
242                         "1:\tldl\t%0, (%2)\n"               \
243                         "2:\tldr\t%0, 7(%2)\n\t"            \
244                         "li\t%1, 0\n"                       \
245                         "3:\n\t"                            \
246                         ".insn\n\t"                         \
247                         "\t.section\t.fixup,\"ax\"\n\t"     \
248                         "4:\tli\t%1, %3\n\t"                \
249                         "j\t3b\n\t"                         \
250                         ".previous\n\t"                     \
251                         ".section\t__ex_table,\"a\"\n\t"    \
252                         STR(PTR)"\t1b, 4b\n\t"              \
253                         STR(PTR)"\t2b, 4b\n\t"              \
254                         ".previous"                         \
255                         : "=&r" (value), "=r" (res)         \
256                         : "r" (addr), "i" (-EFAULT));       \
257 } while(0)
258
259 #else
260 /* MIPSR6 has not lwl and ldl instructions */
261 #define     _LoadWU(addr, value, res, type) \
262 do {                                                        \
263                 __asm__ __volatile__ (                      \
264                         ".set\tpush\n\t"                    \
265                         ".set\tnoat\n\t"                    \
266                         "1:"type##_lbu("%0", "0(%2)")"\n\t" \
267                         "2:"type##_lbu("$1", "1(%2)")"\n\t" \
268                         "sll\t%0, 0x8\n\t"                  \
269                         "or\t%0, $1\n\t"                    \
270                         "3:"type##_lbu("$1", "2(%2)")"\n\t" \
271                         "sll\t%0, 0x8\n\t"                  \
272                         "or\t%0, $1\n\t"                    \
273                         "4:"type##_lbu("$1", "3(%2)")"\n\t" \
274                         "sll\t%0, 0x8\n\t"                  \
275                         "or\t%0, $1\n\t"                    \
276                         "li\t%1, 0\n"                       \
277                         ".set\tpop\n"                       \
278                         "10:\n\t"                           \
279                         ".insn\n\t"                         \
280                         ".section\t.fixup,\"ax\"\n\t"       \
281                         "11:\tli\t%1, %3\n\t"               \
282                         "j\t10b\n\t"                        \
283                         ".previous\n\t"                     \
284                         ".section\t__ex_table,\"a\"\n\t"    \
285                         STR(PTR)"\t1b, 11b\n\t"             \
286                         STR(PTR)"\t2b, 11b\n\t"             \
287                         STR(PTR)"\t3b, 11b\n\t"             \
288                         STR(PTR)"\t4b, 11b\n\t"             \
289                         ".previous"                         \
290                         : "=&r" (value), "=r" (res)         \
291                         : "r" (addr), "i" (-EFAULT));       \
292 } while(0)
293
294 #define     _LoadDW(addr, value, res)  \
295 do {                                                        \
296                 __asm__ __volatile__ (                      \
297                         ".set\tpush\n\t"                    \
298                         ".set\tnoat\n\t"                    \
299                         "1:lb\t%0, 0(%2)\n\t"               \
300                         "2:lbu\t $1, 1(%2)\n\t"             \
301                         "dsll\t%0, 0x8\n\t"                 \
302                         "or\t%0, $1\n\t"                    \
303                         "3:lbu\t$1, 2(%2)\n\t"              \
304                         "dsll\t%0, 0x8\n\t"                 \
305                         "or\t%0, $1\n\t"                    \
306                         "4:lbu\t$1, 3(%2)\n\t"              \
307                         "dsll\t%0, 0x8\n\t"                 \
308                         "or\t%0, $1\n\t"                    \
309                         "5:lbu\t$1, 4(%2)\n\t"              \
310                         "dsll\t%0, 0x8\n\t"                 \
311                         "or\t%0, $1\n\t"                    \
312                         "6:lbu\t$1, 5(%2)\n\t"              \
313                         "dsll\t%0, 0x8\n\t"                 \
314                         "or\t%0, $1\n\t"                    \
315                         "7:lbu\t$1, 6(%2)\n\t"              \
316                         "dsll\t%0, 0x8\n\t"                 \
317                         "or\t%0, $1\n\t"                    \
318                         "8:lbu\t$1, 7(%2)\n\t"              \
319                         "dsll\t%0, 0x8\n\t"                 \
320                         "or\t%0, $1\n\t"                    \
321                         "li\t%1, 0\n"                       \
322                         ".set\tpop\n\t"                     \
323                         "10:\n\t"                           \
324                         ".insn\n\t"                         \
325                         ".section\t.fixup,\"ax\"\n\t"       \
326                         "11:\tli\t%1, %3\n\t"               \
327                         "j\t10b\n\t"                        \
328                         ".previous\n\t"                     \
329                         ".section\t__ex_table,\"a\"\n\t"    \
330                         STR(PTR)"\t1b, 11b\n\t"             \
331                         STR(PTR)"\t2b, 11b\n\t"             \
332                         STR(PTR)"\t3b, 11b\n\t"             \
333                         STR(PTR)"\t4b, 11b\n\t"             \
334                         STR(PTR)"\t5b, 11b\n\t"             \
335                         STR(PTR)"\t6b, 11b\n\t"             \
336                         STR(PTR)"\t7b, 11b\n\t"             \
337                         STR(PTR)"\t8b, 11b\n\t"             \
338                         ".previous"                         \
339                         : "=&r" (value), "=r" (res)         \
340                         : "r" (addr), "i" (-EFAULT));       \
341 } while(0)
342
343 #endif /* CONFIG_CPU_MIPSR6 */
344
345
346 #define     _StoreHW(addr, value, res, type) \
347 do {                                                        \
348                 __asm__ __volatile__ (                      \
349                         ".set\tnoat\n"                      \
350                         "1:\t"type##_sb("%1", "1(%2)")"\n"  \
351                         "srl\t$1, %1, 0x8\n"                \
352                         "2:\t"type##_sb("$1", "0(%2)")"\n"  \
353                         ".set\tat\n\t"                      \
354                         "li\t%0, 0\n"                       \
355                         "3:\n\t"                            \
356                         ".insn\n\t"                         \
357                         ".section\t.fixup,\"ax\"\n\t"       \
358                         "4:\tli\t%0, %3\n\t"                \
359                         "j\t3b\n\t"                         \
360                         ".previous\n\t"                     \
361                         ".section\t__ex_table,\"a\"\n\t"    \
362                         STR(PTR)"\t1b, 4b\n\t"              \
363                         STR(PTR)"\t2b, 4b\n\t"              \
364                         ".previous"                         \
365                         : "=r" (res)                        \
366                         : "r" (value), "r" (addr), "i" (-EFAULT));\
367 } while(0)
368
369 #ifndef CONFIG_CPU_MIPSR6
370 #define     _StoreW(addr, value, res, type)  \
371 do {                                                        \
372                 __asm__ __volatile__ (                      \
373                         "1:\t"type##_swl("%1", "(%2)")"\n"  \
374                         "2:\t"type##_swr("%1", "3(%2)")"\n\t"\
375                         "li\t%0, 0\n"                       \
376                         "3:\n\t"                            \
377                         ".insn\n\t"                         \
378                         ".section\t.fixup,\"ax\"\n\t"       \
379                         "4:\tli\t%0, %3\n\t"                \
380                         "j\t3b\n\t"                         \
381                         ".previous\n\t"                     \
382                         ".section\t__ex_table,\"a\"\n\t"    \
383                         STR(PTR)"\t1b, 4b\n\t"              \
384                         STR(PTR)"\t2b, 4b\n\t"              \
385                         ".previous"                         \
386                 : "=r" (res)                                \
387                 : "r" (value), "r" (addr), "i" (-EFAULT));  \
388 } while(0)
389
390 #define     _StoreDW(addr, value, res) \
391 do {                                                        \
392                 __asm__ __volatile__ (                      \
393                         "1:\tsdl\t%1,(%2)\n"                \
394                         "2:\tsdr\t%1, 7(%2)\n\t"            \
395                         "li\t%0, 0\n"                       \
396                         "3:\n\t"                            \
397                         ".insn\n\t"                         \
398                         ".section\t.fixup,\"ax\"\n\t"       \
399                         "4:\tli\t%0, %3\n\t"                \
400                         "j\t3b\n\t"                         \
401                         ".previous\n\t"                     \
402                         ".section\t__ex_table,\"a\"\n\t"    \
403                         STR(PTR)"\t1b, 4b\n\t"              \
404                         STR(PTR)"\t2b, 4b\n\t"              \
405                         ".previous"                         \
406                 : "=r" (res)                                \
407                 : "r" (value), "r" (addr), "i" (-EFAULT));  \
408 } while(0)
409
410 #else
411 /* MIPSR6 has no swl and sdl instructions */
412 #define     _StoreW(addr, value, res, type)  \
413 do {                                                        \
414                 __asm__ __volatile__ (                      \
415                         ".set\tpush\n\t"                    \
416                         ".set\tnoat\n\t"                    \
417                         "1:"type##_sb("%1", "3(%2)")"\n\t"  \
418                         "srl\t$1, %1, 0x8\n\t"              \
419                         "2:"type##_sb("$1", "2(%2)")"\n\t"  \
420                         "srl\t$1, $1,  0x8\n\t"             \
421                         "3:"type##_sb("$1", "1(%2)")"\n\t"  \
422                         "srl\t$1, $1, 0x8\n\t"              \
423                         "4:"type##_sb("$1", "0(%2)")"\n\t"  \
424                         ".set\tpop\n\t"                     \
425                         "li\t%0, 0\n"                       \
426                         "10:\n\t"                           \
427                         ".insn\n\t"                         \
428                         ".section\t.fixup,\"ax\"\n\t"       \
429                         "11:\tli\t%0, %3\n\t"               \
430                         "j\t10b\n\t"                        \
431                         ".previous\n\t"                     \
432                         ".section\t__ex_table,\"a\"\n\t"    \
433                         STR(PTR)"\t1b, 11b\n\t"             \
434                         STR(PTR)"\t2b, 11b\n\t"             \
435                         STR(PTR)"\t3b, 11b\n\t"             \
436                         STR(PTR)"\t4b, 11b\n\t"             \
437                         ".previous"                         \
438                 : "=&r" (res)                               \
439                 : "r" (value), "r" (addr), "i" (-EFAULT)    \
440                 : "memory");                                \
441 } while(0)
442
443 #define     StoreDW(addr, value, res) \
444 do {                                                        \
445                 __asm__ __volatile__ (                      \
446                         ".set\tpush\n\t"                    \
447                         ".set\tnoat\n\t"                    \
448                         "1:sb\t%1, 7(%2)\n\t"               \
449                         "dsrl\t$1, %1, 0x8\n\t"             \
450                         "2:sb\t$1, 6(%2)\n\t"               \
451                         "dsrl\t$1, $1, 0x8\n\t"             \
452                         "3:sb\t$1, 5(%2)\n\t"               \
453                         "dsrl\t$1, $1, 0x8\n\t"             \
454                         "4:sb\t$1, 4(%2)\n\t"               \
455                         "dsrl\t$1, $1, 0x8\n\t"             \
456                         "5:sb\t$1, 3(%2)\n\t"               \
457                         "dsrl\t$1, $1, 0x8\n\t"             \
458                         "6:sb\t$1, 2(%2)\n\t"               \
459                         "dsrl\t$1, $1, 0x8\n\t"             \
460                         "7:sb\t$1, 1(%2)\n\t"               \
461                         "dsrl\t$1, $1, 0x8\n\t"             \
462                         "8:sb\t$1, 0(%2)\n\t"               \
463                         "dsrl\t$1, $1, 0x8\n\t"             \
464                         ".set\tpop\n\t"                     \
465                         "li\t%0, 0\n"                       \
466                         "10:\n\t"                           \
467                         ".insn\n\t"                         \
468                         ".section\t.fixup,\"ax\"\n\t"       \
469                         "11:\tli\t%0, %3\n\t"               \
470                         "j\t10b\n\t"                        \
471                         ".previous\n\t"                     \
472                         ".section\t__ex_table,\"a\"\n\t"    \
473                         STR(PTR)"\t1b, 11b\n\t"             \
474                         STR(PTR)"\t2b, 11b\n\t"             \
475                         STR(PTR)"\t3b, 11b\n\t"             \
476                         STR(PTR)"\t4b, 11b\n\t"             \
477                         STR(PTR)"\t5b, 11b\n\t"             \
478                         STR(PTR)"\t6b, 11b\n\t"             \
479                         STR(PTR)"\t7b, 11b\n\t"             \
480                         STR(PTR)"\t8b, 11b\n\t"             \
481                         ".previous"                         \
482                 : "=&r" (res)                               \
483                 : "r" (value), "r" (addr), "i" (-EFAULT)    \
484                 : "memory");                                \
485 } while(0)
486
487 #endif /* CONFIG_CPU_MIPSR6 */
488
489 #else /* __BIG_ENDIAN */
490
491 #define     _LoadHW(addr, value, res, type)  \
492 do {                                                        \
493                 __asm__ __volatile__ (".set\tnoat\n"        \
494                         "1:\t"type##_lb("%0", "1(%2)")"\n"  \
495                         "2:\t"type##_lbu("$1", "0(%2)")"\n\t"\
496                         "sll\t%0, 0x8\n\t"                  \
497                         "or\t%0, $1\n\t"                    \
498                         "li\t%1, 0\n"                       \
499                         "3:\t.set\tat\n\t"                  \
500                         ".insn\n\t"                         \
501                         ".section\t.fixup,\"ax\"\n\t"       \
502                         "4:\tli\t%1, %3\n\t"                \
503                         "j\t3b\n\t"                         \
504                         ".previous\n\t"                     \
505                         ".section\t__ex_table,\"a\"\n\t"    \
506                         STR(PTR)"\t1b, 4b\n\t"              \
507                         STR(PTR)"\t2b, 4b\n\t"              \
508                         ".previous"                         \
509                         : "=&r" (value), "=r" (res)         \
510                         : "r" (addr), "i" (-EFAULT));       \
511 } while(0)
512
513 #ifndef CONFIG_CPU_MIPSR6
514 #define     _LoadW(addr, value, res, type)   \
515 do {                                                        \
516                 __asm__ __volatile__ (                      \
517                         "1:\t"type##_lwl("%0", "3(%2)")"\n" \
518                         "2:\t"type##_lwr("%0", "(%2)")"\n\t"\
519                         "li\t%1, 0\n"                       \
520                         "3:\n\t"                            \
521                         ".insn\n\t"                         \
522                         ".section\t.fixup,\"ax\"\n\t"       \
523                         "4:\tli\t%1, %3\n\t"                \
524                         "j\t3b\n\t"                         \
525                         ".previous\n\t"                     \
526                         ".section\t__ex_table,\"a\"\n\t"    \
527                         STR(PTR)"\t1b, 4b\n\t"              \
528                         STR(PTR)"\t2b, 4b\n\t"              \
529                         ".previous"                         \
530                         : "=&r" (value), "=r" (res)         \
531                         : "r" (addr), "i" (-EFAULT));       \
532 } while(0)
533
534 #else
535 /* MIPSR6 has no lwl instruction */
536 #define     _LoadW(addr, value, res, type) \
537 do {                                                        \
538                 __asm__ __volatile__ (                      \
539                         ".set\tpush\n"                      \
540                         ".set\tnoat\n\t"                    \
541                         "1:"type##_lb("%0", "3(%2)")"\n\t"  \
542                         "2:"type##_lbu("$1", "2(%2)")"\n\t" \
543                         "sll\t%0, 0x8\n\t"                  \
544                         "or\t%0, $1\n\t"                    \
545                         "3:"type##_lbu("$1", "1(%2)")"\n\t" \
546                         "sll\t%0, 0x8\n\t"                  \
547                         "or\t%0, $1\n\t"                    \
548                         "4:"type##_lbu("$1", "0(%2)")"\n\t" \
549                         "sll\t%0, 0x8\n\t"                  \
550                         "or\t%0, $1\n\t"                    \
551                         "li\t%1, 0\n"                       \
552                         ".set\tpop\n"                       \
553                         "10:\n\t"                           \
554                         ".insn\n\t"                         \
555                         ".section\t.fixup,\"ax\"\n\t"       \
556                         "11:\tli\t%1, %3\n\t"               \
557                         "j\t10b\n\t"                        \
558                         ".previous\n\t"                     \
559                         ".section\t__ex_table,\"a\"\n\t"    \
560                         STR(PTR)"\t1b, 11b\n\t"             \
561                         STR(PTR)"\t2b, 11b\n\t"             \
562                         STR(PTR)"\t3b, 11b\n\t"             \
563                         STR(PTR)"\t4b, 11b\n\t"             \
564                         ".previous"                         \
565                         : "=&r" (value), "=r" (res)         \
566                         : "r" (addr), "i" (-EFAULT));       \
567 } while(0)
568
569 #endif /* CONFIG_CPU_MIPSR6 */
570
571
572 #define     _LoadHWU(addr, value, res, type) \
573 do {                                                        \
574                 __asm__ __volatile__ (                      \
575                         ".set\tnoat\n"                      \
576                         "1:\t"type##_lbu("%0", "1(%2)")"\n" \
577                         "2:\t"type##_lbu("$1", "0(%2)")"\n\t"\
578                         "sll\t%0, 0x8\n\t"                  \
579                         "or\t%0, $1\n\t"                    \
580                         "li\t%1, 0\n"                       \
581                         "3:\n\t"                            \
582                         ".insn\n\t"                         \
583                         ".set\tat\n\t"                      \
584                         ".section\t.fixup,\"ax\"\n\t"       \
585                         "4:\tli\t%1, %3\n\t"                \
586                         "j\t3b\n\t"                         \
587                         ".previous\n\t"                     \
588                         ".section\t__ex_table,\"a\"\n\t"    \
589                         STR(PTR)"\t1b, 4b\n\t"              \
590                         STR(PTR)"\t2b, 4b\n\t"              \
591                         ".previous"                         \
592                         : "=&r" (value), "=r" (res)         \
593                         : "r" (addr), "i" (-EFAULT));       \
594 } while(0)
595
596 #ifndef CONFIG_CPU_MIPSR6
597 #define     _LoadWU(addr, value, res, type)  \
598 do {                                                        \
599                 __asm__ __volatile__ (                      \
600                         "1:\t"type##_lwl("%0", "3(%2)")"\n" \
601                         "2:\t"type##_lwr("%0", "(%2)")"\n\t"\
602                         "dsll\t%0, %0, 32\n\t"              \
603                         "dsrl\t%0, %0, 32\n\t"              \
604                         "li\t%1, 0\n"                       \
605                         "3:\n\t"                            \
606                         ".insn\n\t"                         \
607                         "\t.section\t.fixup,\"ax\"\n\t"     \
608                         "4:\tli\t%1, %3\n\t"                \
609                         "j\t3b\n\t"                         \
610                         ".previous\n\t"                     \
611                         ".section\t__ex_table,\"a\"\n\t"    \
612                         STR(PTR)"\t1b, 4b\n\t"              \
613                         STR(PTR)"\t2b, 4b\n\t"              \
614                         ".previous"                         \
615                         : "=&r" (value), "=r" (res)         \
616                         : "r" (addr), "i" (-EFAULT));       \
617 } while(0)
618
619 #define     _LoadDW(addr, value, res)  \
620 do {                                                        \
621                 __asm__ __volatile__ (                      \
622                         "1:\tldl\t%0, 7(%2)\n"              \
623                         "2:\tldr\t%0, (%2)\n\t"             \
624                         "li\t%1, 0\n"                       \
625                         "3:\n\t"                            \
626                         ".insn\n\t"                         \
627                         "\t.section\t.fixup,\"ax\"\n\t"     \
628                         "4:\tli\t%1, %3\n\t"                \
629                         "j\t3b\n\t"                         \
630                         ".previous\n\t"                     \
631                         ".section\t__ex_table,\"a\"\n\t"    \
632                         STR(PTR)"\t1b, 4b\n\t"              \
633                         STR(PTR)"\t2b, 4b\n\t"              \
634                         ".previous"                         \
635                         : "=&r" (value), "=r" (res)         \
636                         : "r" (addr), "i" (-EFAULT));       \
637 } while(0)
638
639 #else
640 /* MIPSR6 has not lwl and ldl instructions */
641 #define     _LoadWU(addr, value, res, type) \
642 do {                                                        \
643                 __asm__ __volatile__ (                      \
644                         ".set\tpush\n\t"                    \
645                         ".set\tnoat\n\t"                    \
646                         "1:"type##_lbu("%0", "3(%2)")"\n\t" \
647                         "2:"type##_lbu("$1", "2(%2)")"\n\t" \
648                         "sll\t%0, 0x8\n\t"                  \
649                         "or\t%0, $1\n\t"                    \
650                         "3:"type##_lbu("$1", "1(%2)")"\n\t" \
651                         "sll\t%0, 0x8\n\t"                  \
652                         "or\t%0, $1\n\t"                    \
653                         "4:"type##_lbu("$1", "0(%2)")"\n\t" \
654                         "sll\t%0, 0x8\n\t"                  \
655                         "or\t%0, $1\n\t"                    \
656                         "li\t%1, 0\n"                       \
657                         ".set\tpop\n"                       \
658                         "10:\n\t"                           \
659                         ".insn\n\t"                         \
660                         ".section\t.fixup,\"ax\"\n\t"       \
661                         "11:\tli\t%1, %3\n\t"               \
662                         "j\t10b\n\t"                        \
663                         ".previous\n\t"                     \
664                         ".section\t__ex_table,\"a\"\n\t"    \
665                         STR(PTR)"\t1b, 11b\n\t"             \
666                         STR(PTR)"\t2b, 11b\n\t"             \
667                         STR(PTR)"\t3b, 11b\n\t"             \
668                         STR(PTR)"\t4b, 11b\n\t"             \
669                         ".previous"                         \
670                         : "=&r" (value), "=r" (res)         \
671                         : "r" (addr), "i" (-EFAULT));       \
672 } while(0)
673
674 #define     _LoadDW(addr, value, res)  \
675 do {                                                        \
676                 __asm__ __volatile__ (                      \
677                         ".set\tpush\n\t"                    \
678                         ".set\tnoat\n\t"                    \
679                         "1:lb\t%0, 7(%2)\n\t"               \
680                         "2:lbu\t$1, 6(%2)\n\t"              \
681                         "dsll\t%0, 0x8\n\t"                 \
682                         "or\t%0, $1\n\t"                    \
683                         "3:lbu\t$1, 5(%2)\n\t"              \
684                         "dsll\t%0, 0x8\n\t"                 \
685                         "or\t%0, $1\n\t"                    \
686                         "4:lbu\t$1, 4(%2)\n\t"              \
687                         "dsll\t%0, 0x8\n\t"                 \
688                         "or\t%0, $1\n\t"                    \
689                         "5:lbu\t$1, 3(%2)\n\t"              \
690                         "dsll\t%0, 0x8\n\t"                 \
691                         "or\t%0, $1\n\t"                    \
692                         "6:lbu\t$1, 2(%2)\n\t"              \
693                         "dsll\t%0, 0x8\n\t"                 \
694                         "or\t%0, $1\n\t"                    \
695                         "7:lbu\t$1, 1(%2)\n\t"              \
696                         "dsll\t%0, 0x8\n\t"                 \
697                         "or\t%0, $1\n\t"                    \
698                         "8:lbu\t$1, 0(%2)\n\t"              \
699                         "dsll\t%0, 0x8\n\t"                 \
700                         "or\t%0, $1\n\t"                    \
701                         "li\t%1, 0\n"                       \
702                         ".set\tpop\n\t"                     \
703                         "10:\n\t"                           \
704                         ".insn\n\t"                         \
705                         ".section\t.fixup,\"ax\"\n\t"       \
706                         "11:\tli\t%1, %3\n\t"               \
707                         "j\t10b\n\t"                        \
708                         ".previous\n\t"                     \
709                         ".section\t__ex_table,\"a\"\n\t"    \
710                         STR(PTR)"\t1b, 11b\n\t"             \
711                         STR(PTR)"\t2b, 11b\n\t"             \
712                         STR(PTR)"\t3b, 11b\n\t"             \
713                         STR(PTR)"\t4b, 11b\n\t"             \
714                         STR(PTR)"\t5b, 11b\n\t"             \
715                         STR(PTR)"\t6b, 11b\n\t"             \
716                         STR(PTR)"\t7b, 11b\n\t"             \
717                         STR(PTR)"\t8b, 11b\n\t"             \
718                         ".previous"                         \
719                         : "=&r" (value), "=r" (res)         \
720                         : "r" (addr), "i" (-EFAULT));       \
721 } while(0)
722 #endif /* CONFIG_CPU_MIPSR6 */
723
724 #define     _StoreHW(addr, value, res, type) \
725 do {                                                        \
726                 __asm__ __volatile__ (                      \
727                         ".set\tnoat\n"                      \
728                         "1:\t"type##_sb("%1", "0(%2)")"\n"  \
729                         "srl\t$1,%1, 0x8\n"                 \
730                         "2:\t"type##_sb("$1", "1(%2)")"\n"  \
731                         ".set\tat\n\t"                      \
732                         "li\t%0, 0\n"                       \
733                         "3:\n\t"                            \
734                         ".insn\n\t"                         \
735                         ".section\t.fixup,\"ax\"\n\t"       \
736                         "4:\tli\t%0, %3\n\t"                \
737                         "j\t3b\n\t"                         \
738                         ".previous\n\t"                     \
739                         ".section\t__ex_table,\"a\"\n\t"    \
740                         STR(PTR)"\t1b, 4b\n\t"              \
741                         STR(PTR)"\t2b, 4b\n\t"              \
742                         ".previous"                         \
743                         : "=r" (res)                        \
744                         : "r" (value), "r" (addr), "i" (-EFAULT));\
745 } while(0)
746
747 #ifndef CONFIG_CPU_MIPSR6
748 #define     _StoreW(addr, value, res, type)  \
749 do {                                                        \
750                 __asm__ __volatile__ (                      \
751                         "1:\t"type##_swl("%1", "3(%2)")"\n" \
752                         "2:\t"type##_swr("%1", "(%2)")"\n\t"\
753                         "li\t%0, 0\n"                       \
754                         "3:\n\t"                            \
755                         ".insn\n\t"                         \
756                         ".section\t.fixup,\"ax\"\n\t"       \
757                         "4:\tli\t%0, %3\n\t"                \
758                         "j\t3b\n\t"                         \
759                         ".previous\n\t"                     \
760                         ".section\t__ex_table,\"a\"\n\t"    \
761                         STR(PTR)"\t1b, 4b\n\t"              \
762                         STR(PTR)"\t2b, 4b\n\t"              \
763                         ".previous"                         \
764                 : "=r" (res)                                \
765                 : "r" (value), "r" (addr), "i" (-EFAULT));  \
766 } while(0)
767
768 #define     _StoreDW(addr, value, res) \
769 do {                                                        \
770                 __asm__ __volatile__ (                      \
771                         "1:\tsdl\t%1, 7(%2)\n"              \
772                         "2:\tsdr\t%1, (%2)\n\t"             \
773                         "li\t%0, 0\n"                       \
774                         "3:\n\t"                            \
775                         ".insn\n\t"                         \
776                         ".section\t.fixup,\"ax\"\n\t"       \
777                         "4:\tli\t%0, %3\n\t"                \
778                         "j\t3b\n\t"                         \
779                         ".previous\n\t"                     \
780                         ".section\t__ex_table,\"a\"\n\t"    \
781                         STR(PTR)"\t1b, 4b\n\t"              \
782                         STR(PTR)"\t2b, 4b\n\t"              \
783                         ".previous"                         \
784                 : "=r" (res)                                \
785                 : "r" (value), "r" (addr), "i" (-EFAULT));  \
786 } while(0)
787
788 #else
789 /* MIPSR6 has no swl and sdl instructions */
790 #define     _StoreW(addr, value, res, type)  \
791 do {                                                        \
792                 __asm__ __volatile__ (                      \
793                         ".set\tpush\n\t"                    \
794                         ".set\tnoat\n\t"                    \
795                         "1:"type##_sb("%1", "0(%2)")"\n\t"  \
796                         "srl\t$1, %1, 0x8\n\t"              \
797                         "2:"type##_sb("$1", "1(%2)")"\n\t"  \
798                         "srl\t$1, $1,  0x8\n\t"             \
799                         "3:"type##_sb("$1", "2(%2)")"\n\t"  \
800                         "srl\t$1, $1, 0x8\n\t"              \
801                         "4:"type##_sb("$1", "3(%2)")"\n\t"  \
802                         ".set\tpop\n\t"                     \
803                         "li\t%0, 0\n"                       \
804                         "10:\n\t"                           \
805                         ".insn\n\t"                         \
806                         ".section\t.fixup,\"ax\"\n\t"       \
807                         "11:\tli\t%0, %3\n\t"               \
808                         "j\t10b\n\t"                        \
809                         ".previous\n\t"                     \
810                         ".section\t__ex_table,\"a\"\n\t"    \
811                         STR(PTR)"\t1b, 11b\n\t"             \
812                         STR(PTR)"\t2b, 11b\n\t"             \
813                         STR(PTR)"\t3b, 11b\n\t"             \
814                         STR(PTR)"\t4b, 11b\n\t"             \
815                         ".previous"                         \
816                 : "=&r" (res)                               \
817                 : "r" (value), "r" (addr), "i" (-EFAULT)    \
818                 : "memory");                                \
819 } while(0)
820
821 #define     _StoreDW(addr, value, res) \
822 do {                                                        \
823                 __asm__ __volatile__ (                      \
824                         ".set\tpush\n\t"                    \
825                         ".set\tnoat\n\t"                    \
826                         "1:sb\t%1, 0(%2)\n\t"               \
827                         "dsrl\t$1, %1, 0x8\n\t"             \
828                         "2:sb\t$1, 1(%2)\n\t"               \
829                         "dsrl\t$1, $1, 0x8\n\t"             \
830                         "3:sb\t$1, 2(%2)\n\t"               \
831                         "dsrl\t$1, $1, 0x8\n\t"             \
832                         "4:sb\t$1, 3(%2)\n\t"               \
833                         "dsrl\t$1, $1, 0x8\n\t"             \
834                         "5:sb\t$1, 4(%2)\n\t"               \
835                         "dsrl\t$1, $1, 0x8\n\t"             \
836                         "6:sb\t$1, 5(%2)\n\t"               \
837                         "dsrl\t$1, $1, 0x8\n\t"             \
838                         "7:sb\t$1, 6(%2)\n\t"               \
839                         "dsrl\t$1, $1, 0x8\n\t"             \
840                         "8:sb\t$1, 7(%2)\n\t"               \
841                         "dsrl\t$1, $1, 0x8\n\t"             \
842                         ".set\tpop\n\t"                     \
843                         "li\t%0, 0\n"                       \
844                         "10:\n\t"                           \
845                         ".insn\n\t"                         \
846                         ".section\t.fixup,\"ax\"\n\t"       \
847                         "11:\tli\t%0, %3\n\t"               \
848                         "j\t10b\n\t"                        \
849                         ".previous\n\t"                     \
850                         ".section\t__ex_table,\"a\"\n\t"    \
851                         STR(PTR)"\t1b, 11b\n\t"             \
852                         STR(PTR)"\t2b, 11b\n\t"             \
853                         STR(PTR)"\t3b, 11b\n\t"             \
854                         STR(PTR)"\t4b, 11b\n\t"             \
855                         STR(PTR)"\t5b, 11b\n\t"             \
856                         STR(PTR)"\t6b, 11b\n\t"             \
857                         STR(PTR)"\t7b, 11b\n\t"             \
858                         STR(PTR)"\t8b, 11b\n\t"             \
859                         ".previous"                         \
860                 : "=&r" (res)                               \
861                 : "r" (value), "r" (addr), "i" (-EFAULT)    \
862                 : "memory");                                \
863 } while(0)
864
865 #endif /* CONFIG_CPU_MIPSR6 */
866 #endif
867
868 #define LoadHWU(addr, value, res)       _LoadHWU(addr, value, res, kernel)
869 #define LoadHWUE(addr, value, res)      _LoadHWU(addr, value, res, user)
870 #define LoadWU(addr, value, res)        _LoadWU(addr, value, res, kernel)
871 #define LoadWUE(addr, value, res)       _LoadWU(addr, value, res, user)
872 #define LoadHW(addr, value, res)        _LoadHW(addr, value, res, kernel)
873 #define LoadHWE(addr, value, res)       _LoadHW(addr, value, res, user)
874 #define LoadW(addr, value, res)         _LoadW(addr, value, res, kernel)
875 #define LoadWE(addr, value, res)        _LoadW(addr, value, res, user)
876 #define LoadDW(addr, value, res)        _LoadDW(addr, value, res)
877
878 #define StoreHW(addr, value, res)       _StoreHW(addr, value, res, kernel)
879 #define StoreHWE(addr, value, res)      _StoreHW(addr, value, res, user)
880 #define StoreW(addr, value, res)        _StoreW(addr, value, res, kernel)
881 #define StoreWE(addr, value, res)       _StoreW(addr, value, res, user)
882 #define StoreDW(addr, value, res)       _StoreDW(addr, value, res)
883
884 static void emulate_load_store_insn(struct pt_regs *regs,
885         void __user *addr, unsigned int __user *pc)
886 {
887         union mips_instruction insn;
888         unsigned long value;
889         unsigned int res;
890         unsigned long origpc;
891         unsigned long orig31;
892         void __user *fault_addr = NULL;
893 #ifdef  CONFIG_EVA
894         mm_segment_t seg;
895 #endif
896         origpc = (unsigned long)pc;
897         orig31 = regs->regs[31];
898
899         perf_sw_event(PERF_COUNT_SW_EMULATION_FAULTS, 1, regs, 0);
900
901         /*
902          * This load never faults.
903          */
904         __get_user(insn.word, pc);
905
906         switch (insn.i_format.opcode) {
907                 /*
908                  * These are instructions that a compiler doesn't generate.  We
909                  * can assume therefore that the code is MIPS-aware and
910                  * really buggy.  Emulating these instructions would break the
911                  * semantics anyway.
912                  */
913         case ll_op:
914         case lld_op:
915         case sc_op:
916         case scd_op:
917
918                 /*
919                  * For these instructions the only way to create an address
920                  * error is an attempted access to kernel/supervisor address
921                  * space.
922                  */
923         case ldl_op:
924         case ldr_op:
925         case lwl_op:
926         case lwr_op:
927         case sdl_op:
928         case sdr_op:
929         case swl_op:
930         case swr_op:
931         case lb_op:
932         case lbu_op:
933         case sb_op:
934                 goto sigbus;
935
936                 /*
937                  * The remaining opcodes are the ones that are really of
938                  * interest.
939                  */
940 #ifdef CONFIG_EVA
941         case spec3_op:
942                 /*
943                  * we can land here only from kernel accessing user memory,
944                  * so we need to "switch" the address limit to user space, so
945                  * address check can work properly.
946                  */
947                 seg = get_fs();
948                 set_fs(USER_DS);
949                 switch (insn.spec3_format.func) {
950                 case lhe_op:
951                         if (!access_ok(VERIFY_READ, addr, 2)) {
952                                 set_fs(seg);
953                                 goto sigbus;
954                         }
955                         LoadHWE(addr, value, res);
956                         if (res) {
957                                 set_fs(seg);
958                                 goto fault;
959                         }
960                         compute_return_epc(regs);
961                         regs->regs[insn.spec3_format.rt] = value;
962                         break;
963                 case lwe_op:
964                         if (!access_ok(VERIFY_READ, addr, 4)) {
965                                 set_fs(seg);
966                                 goto sigbus;
967                         }
968                                 LoadWE(addr, value, res);
969                         if (res) {
970                                 set_fs(seg);
971                                 goto fault;
972                         }
973                         compute_return_epc(regs);
974                         regs->regs[insn.spec3_format.rt] = value;
975                         break;
976                 case lhue_op:
977                         if (!access_ok(VERIFY_READ, addr, 2)) {
978                                 set_fs(seg);
979                                 goto sigbus;
980                         }
981                         LoadHWUE(addr, value, res);
982                         if (res) {
983                                 set_fs(seg);
984                                 goto fault;
985                         }
986                         compute_return_epc(regs);
987                         regs->regs[insn.spec3_format.rt] = value;
988                         break;
989                 case she_op:
990                         if (!access_ok(VERIFY_WRITE, addr, 2)) {
991                                 set_fs(seg);
992                                 goto sigbus;
993                         }
994                         compute_return_epc(regs);
995                         value = regs->regs[insn.spec3_format.rt];
996                         StoreHWE(addr, value, res);
997                         if (res) {
998                                 set_fs(seg);
999                                 goto fault;
1000                         }
1001                         break;
1002                 case swe_op:
1003                         if (!access_ok(VERIFY_WRITE, addr, 4)) {
1004                                 set_fs(seg);
1005                                 goto sigbus;
1006                         }
1007                         compute_return_epc(regs);
1008                         value = regs->regs[insn.spec3_format.rt];
1009                         StoreWE(addr, value, res);
1010                         if (res) {
1011                                 set_fs(seg);
1012                                 goto fault;
1013                         }
1014                         break;
1015                 default:
1016                         set_fs(seg);
1017                         goto sigill;
1018                 }
1019                 set_fs(seg);
1020                 break;
1021 #endif
1022         case lh_op:
1023                 if (!access_ok(VERIFY_READ, addr, 2))
1024                         goto sigbus;
1025
1026                 if (config_enabled(CONFIG_EVA)) {
1027                         if (segment_eq(get_fs(), get_ds()))
1028                                 LoadHW(addr, value, res);
1029                         else
1030                                 LoadHWE(addr, value, res);
1031                 } else {
1032                         LoadHW(addr, value, res);
1033                 }
1034
1035                 if (res)
1036                         goto fault;
1037                 compute_return_epc(regs);
1038                 regs->regs[insn.i_format.rt] = value;
1039                 break;
1040
1041         case lw_op:
1042                 if (!access_ok(VERIFY_READ, addr, 4))
1043                         goto sigbus;
1044
1045                 if (config_enabled(CONFIG_EVA)) {
1046                         if (segment_eq(get_fs(), get_ds()))
1047                                 LoadW(addr, value, res);
1048                         else
1049                                 LoadWE(addr, value, res);
1050                 } else {
1051                         LoadW(addr, value, res);
1052                 }
1053
1054                 if (res)
1055                         goto fault;
1056                 compute_return_epc(regs);
1057                 regs->regs[insn.i_format.rt] = value;
1058                 break;
1059
1060         case lhu_op:
1061                 if (!access_ok(VERIFY_READ, addr, 2))
1062                         goto sigbus;
1063
1064                 if (config_enabled(CONFIG_EVA)) {
1065                         if (segment_eq(get_fs(), get_ds()))
1066                                 LoadHWU(addr, value, res);
1067                         else
1068                                 LoadHWUE(addr, value, res);
1069                 } else {
1070                         LoadHWU(addr, value, res);
1071                 }
1072
1073                 if (res)
1074                         goto fault;
1075                 compute_return_epc(regs);
1076                 regs->regs[insn.i_format.rt] = value;
1077                 break;
1078
1079         case lwu_op:
1080 #ifdef CONFIG_64BIT
1081                 /*
1082                  * A 32-bit kernel might be running on a 64-bit processor.  But
1083                  * if we're on a 32-bit processor and an i-cache incoherency
1084                  * or race makes us see a 64-bit instruction here the sdl/sdr
1085                  * would blow up, so for now we don't handle unaligned 64-bit
1086                  * instructions on 32-bit kernels.
1087                  */
1088                 if (!access_ok(VERIFY_READ, addr, 4))
1089                         goto sigbus;
1090
1091                 LoadWU(addr, value, res);
1092                 if (res)
1093                         goto fault;
1094                 compute_return_epc(regs);
1095                 regs->regs[insn.i_format.rt] = value;
1096                 break;
1097 #endif /* CONFIG_64BIT */
1098
1099                 /* Cannot handle 64-bit instructions in 32-bit kernel */
1100                 goto sigill;
1101
1102         case ld_op:
1103 #ifdef CONFIG_64BIT
1104                 /*
1105                  * A 32-bit kernel might be running on a 64-bit processor.  But
1106                  * if we're on a 32-bit processor and an i-cache incoherency
1107                  * or race makes us see a 64-bit instruction here the sdl/sdr
1108                  * would blow up, so for now we don't handle unaligned 64-bit
1109                  * instructions on 32-bit kernels.
1110                  */
1111                 if (!access_ok(VERIFY_READ, addr, 8))
1112                         goto sigbus;
1113
1114                 LoadDW(addr, value, res);
1115                 if (res)
1116                         goto fault;
1117                 compute_return_epc(regs);
1118                 regs->regs[insn.i_format.rt] = value;
1119                 break;
1120 #endif /* CONFIG_64BIT */
1121
1122                 /* Cannot handle 64-bit instructions in 32-bit kernel */
1123                 goto sigill;
1124
1125         case sh_op:
1126                 if (!access_ok(VERIFY_WRITE, addr, 2))
1127                         goto sigbus;
1128
1129                 compute_return_epc(regs);
1130                 value = regs->regs[insn.i_format.rt];
1131
1132                 if (config_enabled(CONFIG_EVA)) {
1133                         if (segment_eq(get_fs(), get_ds()))
1134                                 StoreHW(addr, value, res);
1135                         else
1136                                 StoreHWE(addr, value, res);
1137                 } else {
1138                         StoreHW(addr, value, res);
1139                 }
1140
1141                 if (res)
1142                         goto fault;
1143                 break;
1144
1145         case sw_op:
1146                 if (!access_ok(VERIFY_WRITE, addr, 4))
1147                         goto sigbus;
1148
1149                 compute_return_epc(regs);
1150                 value = regs->regs[insn.i_format.rt];
1151
1152                 if (config_enabled(CONFIG_EVA)) {
1153                         if (segment_eq(get_fs(), get_ds()))
1154                                 StoreW(addr, value, res);
1155                         else
1156                                 StoreWE(addr, value, res);
1157                 } else {
1158                         StoreW(addr, value, res);
1159                 }
1160
1161                 if (res)
1162                         goto fault;
1163                 break;
1164
1165         case sd_op:
1166 #ifdef CONFIG_64BIT
1167                 /*
1168                  * A 32-bit kernel might be running on a 64-bit processor.  But
1169                  * if we're on a 32-bit processor and an i-cache incoherency
1170                  * or race makes us see a 64-bit instruction here the sdl/sdr
1171                  * would blow up, so for now we don't handle unaligned 64-bit
1172                  * instructions on 32-bit kernels.
1173                  */
1174                 if (!access_ok(VERIFY_WRITE, addr, 8))
1175                         goto sigbus;
1176
1177                 compute_return_epc(regs);
1178                 value = regs->regs[insn.i_format.rt];
1179                 StoreDW(addr, value, res);
1180                 if (res)
1181                         goto fault;
1182                 break;
1183 #endif /* CONFIG_64BIT */
1184
1185                 /* Cannot handle 64-bit instructions in 32-bit kernel */
1186                 goto sigill;
1187
1188         case lwc1_op:
1189         case ldc1_op:
1190         case swc1_op:
1191         case sdc1_op:
1192                 die_if_kernel("Unaligned FP access in kernel code", regs);
1193                 BUG_ON(!used_math());
1194
1195                 lose_fpu(1);    /* Save FPU state for the emulator. */
1196                 res = fpu_emulator_cop1Handler(regs, &current->thread.fpu, 1,
1197                                                &fault_addr);
1198                 own_fpu(1);     /* Restore FPU state. */
1199
1200                 /* Signal if something went wrong. */
1201                 process_fpemu_return(res, fault_addr);
1202
1203                 if (res == 0)
1204                         break;
1205                 return;
1206
1207 #ifndef CONFIG_CPU_MIPSR6
1208         /*
1209          * COP2 is available to implementor for application specific use.
1210          * It's up to applications to register a notifier chain and do
1211          * whatever they have to do, including possible sending of signals.
1212          *
1213          * This instruction has been reallocated in Release 6
1214          */
1215         case lwc2_op:
1216                 cu2_notifier_call_chain(CU2_LWC2_OP, regs);
1217                 break;
1218
1219         case ldc2_op:
1220                 cu2_notifier_call_chain(CU2_LDC2_OP, regs);
1221                 break;
1222
1223         case swc2_op:
1224                 cu2_notifier_call_chain(CU2_SWC2_OP, regs);
1225                 break;
1226
1227         case sdc2_op:
1228                 cu2_notifier_call_chain(CU2_SDC2_OP, regs);
1229                 break;
1230 #endif
1231         default:
1232                 /*
1233                  * Pheeee...  We encountered an yet unknown instruction or
1234                  * cache coherence problem.  Die sucker, die ...
1235                  */
1236                 goto sigill;
1237         }
1238
1239 #ifdef CONFIG_DEBUG_FS
1240         unaligned_instructions++;
1241 #endif
1242
1243         return;
1244
1245 fault:
1246         /* roll back jump/branch */
1247         regs->cp0_epc = origpc;
1248         regs->regs[31] = orig31;
1249         /* Did we have an exception handler installed? */
1250         if (fixup_exception(regs))
1251                 return;
1252
1253         die_if_kernel("Unhandled kernel unaligned access", regs);
1254         force_sig(SIGSEGV, current);
1255
1256         return;
1257
1258 sigbus:
1259         die_if_kernel("Unhandled kernel unaligned access", regs);
1260         force_sig(SIGBUS, current);
1261
1262         return;
1263
1264 sigill:
1265         die_if_kernel
1266             ("Unhandled kernel unaligned access or invalid instruction", regs);
1267         force_sig(SIGILL, current);
1268 }
1269
1270 /* Recode table from 16-bit register notation to 32-bit GPR. */
1271 const int reg16to32[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
1272
1273 /* Recode table from 16-bit STORE register notation to 32-bit GPR. */
1274 const int reg16to32st[] = { 0, 17, 2, 3, 4, 5, 6, 7 };
1275
1276 static void emulate_load_store_microMIPS(struct pt_regs *regs,
1277                                          void __user *addr)
1278 {
1279         unsigned long value;
1280         unsigned int res;
1281         int i;
1282         unsigned int reg = 0, rvar;
1283         unsigned long orig31;
1284         u16 __user *pc16;
1285         u16 halfword;
1286         unsigned int word;
1287         unsigned long origpc, contpc;
1288         union mips_instruction insn;
1289         struct mm_decoded_insn mminsn;
1290         void __user *fault_addr = NULL;
1291
1292         origpc = regs->cp0_epc;
1293         orig31 = regs->regs[31];
1294
1295         mminsn.micro_mips_mode = 1;
1296
1297         /*
1298          * This load never faults.
1299          */
1300         pc16 = (unsigned short __user *)msk_isa16_mode(regs->cp0_epc);
1301         __get_user(halfword, pc16);
1302         pc16++;
1303         contpc = regs->cp0_epc + 2;
1304         word = ((unsigned int)halfword << 16);
1305         mminsn.pc_inc = 2;
1306
1307         if (!mm_insn_16bit(halfword)) {
1308                 __get_user(halfword, pc16);
1309                 pc16++;
1310                 contpc = regs->cp0_epc + 4;
1311                 mminsn.pc_inc = 4;
1312                 word |= halfword;
1313         }
1314         mminsn.insn = word;
1315
1316         if (get_user(halfword, pc16))
1317                 goto fault;
1318         mminsn.next_pc_inc = 2;
1319         word = ((unsigned int)halfword << 16);
1320
1321         if (!mm_insn_16bit(halfword)) {
1322                 pc16++;
1323                 if (get_user(halfword, pc16))
1324                         goto fault;
1325                 mminsn.next_pc_inc = 4;
1326                 word |= halfword;
1327         }
1328         mminsn.next_insn = word;
1329
1330         insn = (union mips_instruction)(mminsn.insn);
1331         if (mm_isBranchInstr(regs, mminsn, &contpc))
1332                 insn = (union mips_instruction)(mminsn.next_insn);
1333
1334         /*  Parse instruction to find what to do */
1335
1336         switch (insn.mm_i_format.opcode) {
1337
1338         case mm_pool32a_op:
1339                 switch (insn.mm_x_format.func) {
1340                 case mm_lwxs_op:
1341                         reg = insn.mm_x_format.rd;
1342                         goto loadW;
1343                 }
1344
1345                 goto sigbus;
1346
1347         case mm_pool32b_op:
1348                 switch (insn.mm_m_format.func) {
1349                 case mm_lwp_func:
1350                         reg = insn.mm_m_format.rd;
1351                         if (reg == 31)
1352                                 goto sigbus;
1353
1354                         if (!access_ok(VERIFY_READ, addr, 8))
1355                                 goto sigbus;
1356
1357                         LoadW(addr, value, res);
1358                         if (res)
1359                                 goto fault;
1360                         regs->regs[reg] = value;
1361                         addr += 4;
1362                         LoadW(addr, value, res);
1363                         if (res)
1364                                 goto fault;
1365                         regs->regs[reg + 1] = value;
1366                         goto success;
1367
1368                 case mm_swp_func:
1369                         reg = insn.mm_m_format.rd;
1370                         if (reg == 31)
1371                                 goto sigbus;
1372
1373                         if (!access_ok(VERIFY_WRITE, addr, 8))
1374                                 goto sigbus;
1375
1376                         value = regs->regs[reg];
1377                         StoreW(addr, value, res);
1378                         if (res)
1379                                 goto fault;
1380                         addr += 4;
1381                         value = regs->regs[reg + 1];
1382                         StoreW(addr, value, res);
1383                         if (res)
1384                                 goto fault;
1385                         goto success;
1386
1387                 case mm_ldp_func:
1388 #ifdef CONFIG_64BIT
1389                         reg = insn.mm_m_format.rd;
1390                         if (reg == 31)
1391                                 goto sigbus;
1392
1393                         if (!access_ok(VERIFY_READ, addr, 16))
1394                                 goto sigbus;
1395
1396                         LoadDW(addr, value, res);
1397                         if (res)
1398                                 goto fault;
1399                         regs->regs[reg] = value;
1400                         addr += 8;
1401                         LoadDW(addr, value, res);
1402                         if (res)
1403                                 goto fault;
1404                         regs->regs[reg + 1] = value;
1405                         goto success;
1406 #endif /* CONFIG_64BIT */
1407
1408                         goto sigill;
1409
1410                 case mm_sdp_func:
1411 #ifdef CONFIG_64BIT
1412                         reg = insn.mm_m_format.rd;
1413                         if (reg == 31)
1414                                 goto sigbus;
1415
1416                         if (!access_ok(VERIFY_WRITE, addr, 16))
1417                                 goto sigbus;
1418
1419                         value = regs->regs[reg];
1420                         StoreDW(addr, value, res);
1421                         if (res)
1422                                 goto fault;
1423                         addr += 8;
1424                         value = regs->regs[reg + 1];
1425                         StoreDW(addr, value, res);
1426                         if (res)
1427                                 goto fault;
1428                         goto success;
1429 #endif /* CONFIG_64BIT */
1430
1431                         goto sigill;
1432
1433                 case mm_lwm32_func:
1434                         reg = insn.mm_m_format.rd;
1435                         rvar = reg & 0xf;
1436                         if ((rvar > 9) || !reg)
1437                                 goto sigill;
1438                         if (reg & 0x10) {
1439                                 if (!access_ok
1440                                     (VERIFY_READ, addr, 4 * (rvar + 1)))
1441                                         goto sigbus;
1442                         } else {
1443                                 if (!access_ok(VERIFY_READ, addr, 4 * rvar))
1444                                         goto sigbus;
1445                         }
1446                         if (rvar == 9)
1447                                 rvar = 8;
1448                         for (i = 16; rvar; rvar--, i++) {
1449                                 LoadW(addr, value, res);
1450                                 if (res)
1451                                         goto fault;
1452                                 addr += 4;
1453                                 regs->regs[i] = value;
1454                         }
1455                         if ((reg & 0xf) == 9) {
1456                                 LoadW(addr, value, res);
1457                                 if (res)
1458                                         goto fault;
1459                                 addr += 4;
1460                                 regs->regs[30] = value;
1461                         }
1462                         if (reg & 0x10) {
1463                                 LoadW(addr, value, res);
1464                                 if (res)
1465                                         goto fault;
1466                                 regs->regs[31] = value;
1467                         }
1468                         goto success;
1469
1470                 case mm_swm32_func:
1471                         reg = insn.mm_m_format.rd;
1472                         rvar = reg & 0xf;
1473                         if ((rvar > 9) || !reg)
1474                                 goto sigill;
1475                         if (reg & 0x10) {
1476                                 if (!access_ok
1477                                     (VERIFY_WRITE, addr, 4 * (rvar + 1)))
1478                                         goto sigbus;
1479                         } else {
1480                                 if (!access_ok(VERIFY_WRITE, addr, 4 * rvar))
1481                                         goto sigbus;
1482                         }
1483                         if (rvar == 9)
1484                                 rvar = 8;
1485                         for (i = 16; rvar; rvar--, i++) {
1486                                 value = regs->regs[i];
1487                                 StoreW(addr, value, res);
1488                                 if (res)
1489                                         goto fault;
1490                                 addr += 4;
1491                         }
1492                         if ((reg & 0xf) == 9) {
1493                                 value = regs->regs[30];
1494                                 StoreW(addr, value, res);
1495                                 if (res)
1496                                         goto fault;
1497                                 addr += 4;
1498                         }
1499                         if (reg & 0x10) {
1500                                 value = regs->regs[31];
1501                                 StoreW(addr, value, res);
1502                                 if (res)
1503                                         goto fault;
1504                         }
1505                         goto success;
1506
1507                 case mm_ldm_func:
1508 #ifdef CONFIG_64BIT
1509                         reg = insn.mm_m_format.rd;
1510                         rvar = reg & 0xf;
1511                         if ((rvar > 9) || !reg)
1512                                 goto sigill;
1513                         if (reg & 0x10) {
1514                                 if (!access_ok
1515                                     (VERIFY_READ, addr, 8 * (rvar + 1)))
1516                                         goto sigbus;
1517                         } else {
1518                                 if (!access_ok(VERIFY_READ, addr, 8 * rvar))
1519                                         goto sigbus;
1520                         }
1521                         if (rvar == 9)
1522                                 rvar = 8;
1523
1524                         for (i = 16; rvar; rvar--, i++) {
1525                                 LoadDW(addr, value, res);
1526                                 if (res)
1527                                         goto fault;
1528                                 addr += 4;
1529                                 regs->regs[i] = value;
1530                         }
1531                         if ((reg & 0xf) == 9) {
1532                                 LoadDW(addr, value, res);
1533                                 if (res)
1534                                         goto fault;
1535                                 addr += 8;
1536                                 regs->regs[30] = value;
1537                         }
1538                         if (reg & 0x10) {
1539                                 LoadDW(addr, value, res);
1540                                 if (res)
1541                                         goto fault;
1542                                 regs->regs[31] = value;
1543                         }
1544                         goto success;
1545 #endif /* CONFIG_64BIT */
1546
1547                         goto sigill;
1548
1549                 case mm_sdm_func:
1550 #ifdef CONFIG_64BIT
1551                         reg = insn.mm_m_format.rd;
1552                         rvar = reg & 0xf;
1553                         if ((rvar > 9) || !reg)
1554                                 goto sigill;
1555                         if (reg & 0x10) {
1556                                 if (!access_ok
1557                                     (VERIFY_WRITE, addr, 8 * (rvar + 1)))
1558                                         goto sigbus;
1559                         } else {
1560                                 if (!access_ok(VERIFY_WRITE, addr, 8 * rvar))
1561                                         goto sigbus;
1562                         }
1563                         if (rvar == 9)
1564                                 rvar = 8;
1565
1566                         for (i = 16; rvar; rvar--, i++) {
1567                                 value = regs->regs[i];
1568                                 StoreDW(addr, value, res);
1569                                 if (res)
1570                                         goto fault;
1571                                 addr += 8;
1572                         }
1573                         if ((reg & 0xf) == 9) {
1574                                 value = regs->regs[30];
1575                                 StoreDW(addr, value, res);
1576                                 if (res)
1577                                         goto fault;
1578                                 addr += 8;
1579                         }
1580                         if (reg & 0x10) {
1581                                 value = regs->regs[31];
1582                                 StoreDW(addr, value, res);
1583                                 if (res)
1584                                         goto fault;
1585                         }
1586                         goto success;
1587 #endif /* CONFIG_64BIT */
1588
1589                         goto sigill;
1590
1591                         /*  LWC2, SWC2, LDC2, SDC2 are not serviced */
1592                 }
1593
1594                 goto sigbus;
1595
1596         case mm_pool32c_op:
1597                 switch (insn.mm_m_format.func) {
1598                 case mm_lwu_func:
1599                         reg = insn.mm_m_format.rd;
1600                         goto loadWU;
1601                 }
1602
1603                 /*  LL,SC,LLD,SCD are not serviced */
1604                 goto sigbus;
1605
1606         case mm_pool32f_op:
1607                 switch (insn.mm_x_format.func) {
1608                 case mm_lwxc1_func:
1609                 case mm_swxc1_func:
1610                 case mm_ldxc1_func:
1611                 case mm_sdxc1_func:
1612                         goto fpu_emul;
1613                 }
1614
1615                 goto sigbus;
1616
1617         case mm_ldc132_op:
1618         case mm_sdc132_op:
1619         case mm_lwc132_op:
1620         case mm_swc132_op:
1621 fpu_emul:
1622                 /* roll back jump/branch */
1623                 regs->cp0_epc = origpc;
1624                 regs->regs[31] = orig31;
1625
1626                 die_if_kernel("Unaligned FP access in kernel code", regs);
1627                 BUG_ON(!used_math());
1628                 BUG_ON(!is_fpu_owner());
1629
1630                 lose_fpu(1);    /* save the FPU state for the emulator */
1631                 res = fpu_emulator_cop1Handler(regs, &current->thread.fpu, 1,
1632                                                &fault_addr);
1633                 own_fpu(1);     /* restore FPU state */
1634
1635                 /* If something went wrong, signal */
1636                 process_fpemu_return(res, fault_addr);
1637
1638                 if (res == 0)
1639                         goto success;
1640                 return;
1641
1642         case mm_lh32_op:
1643                 reg = insn.mm_i_format.rt;
1644                 goto loadHW;
1645
1646         case mm_lhu32_op:
1647                 reg = insn.mm_i_format.rt;
1648                 goto loadHWU;
1649
1650         case mm_lw32_op:
1651                 reg = insn.mm_i_format.rt;
1652                 goto loadW;
1653
1654         case mm_sh32_op:
1655                 reg = insn.mm_i_format.rt;
1656                 goto storeHW;
1657
1658         case mm_sw32_op:
1659                 reg = insn.mm_i_format.rt;
1660                 goto storeW;
1661
1662         case mm_ld32_op:
1663                 reg = insn.mm_i_format.rt;
1664                 goto loadDW;
1665
1666         case mm_sd32_op:
1667                 reg = insn.mm_i_format.rt;
1668                 goto storeDW;
1669
1670         case mm_pool16c_op:
1671                 switch (insn.mm16_m_format.func) {
1672                 case mm_lwm16_op:
1673                         reg = insn.mm16_m_format.rlist;
1674                         rvar = reg + 1;
1675                         if (!access_ok(VERIFY_READ, addr, 4 * rvar))
1676                                 goto sigbus;
1677
1678                         for (i = 16; rvar; rvar--, i++) {
1679                                 LoadW(addr, value, res);
1680                                 if (res)
1681                                         goto fault;
1682                                 addr += 4;
1683                                 regs->regs[i] = value;
1684                         }
1685                         LoadW(addr, value, res);
1686                         if (res)
1687                                 goto fault;
1688                         regs->regs[31] = value;
1689
1690                         goto success;
1691
1692                 case mm_swm16_op:
1693                         reg = insn.mm16_m_format.rlist;
1694                         rvar = reg + 1;
1695                         if (!access_ok(VERIFY_WRITE, addr, 4 * rvar))
1696                                 goto sigbus;
1697
1698                         for (i = 16; rvar; rvar--, i++) {
1699                                 value = regs->regs[i];
1700                                 StoreW(addr, value, res);
1701                                 if (res)
1702                                         goto fault;
1703                                 addr += 4;
1704                         }
1705                         value = regs->regs[31];
1706                         StoreW(addr, value, res);
1707                         if (res)
1708                                 goto fault;
1709
1710                         goto success;
1711
1712                 }
1713
1714                 goto sigbus;
1715
1716         case mm_lhu16_op:
1717                 reg = reg16to32[insn.mm16_rb_format.rt];
1718                 goto loadHWU;
1719
1720         case mm_lw16_op:
1721                 reg = reg16to32[insn.mm16_rb_format.rt];
1722                 goto loadW;
1723
1724         case mm_sh16_op:
1725                 reg = reg16to32st[insn.mm16_rb_format.rt];
1726                 goto storeHW;
1727
1728         case mm_sw16_op:
1729                 reg = reg16to32st[insn.mm16_rb_format.rt];
1730                 goto storeW;
1731
1732         case mm_lwsp16_op:
1733                 reg = insn.mm16_r5_format.rt;
1734                 goto loadW;
1735
1736         case mm_swsp16_op:
1737                 reg = insn.mm16_r5_format.rt;
1738                 goto storeW;
1739
1740         case mm_lwgp16_op:
1741                 reg = reg16to32[insn.mm16_r3_format.rt];
1742                 goto loadW;
1743
1744         default:
1745                 goto sigill;
1746         }
1747
1748 loadHW:
1749         if (!access_ok(VERIFY_READ, addr, 2))
1750                 goto sigbus;
1751
1752         LoadHW(addr, value, res);
1753         if (res)
1754                 goto fault;
1755         regs->regs[reg] = value;
1756         goto success;
1757
1758 loadHWU:
1759         if (!access_ok(VERIFY_READ, addr, 2))
1760                 goto sigbus;
1761
1762         LoadHWU(addr, value, res);
1763         if (res)
1764                 goto fault;
1765         regs->regs[reg] = value;
1766         goto success;
1767
1768 loadW:
1769         if (!access_ok(VERIFY_READ, addr, 4))
1770                 goto sigbus;
1771
1772         LoadW(addr, value, res);
1773         if (res)
1774                 goto fault;
1775         regs->regs[reg] = value;
1776         goto success;
1777
1778 loadWU:
1779 #ifdef CONFIG_64BIT
1780         /*
1781          * A 32-bit kernel might be running on a 64-bit processor.  But
1782          * if we're on a 32-bit processor and an i-cache incoherency
1783          * or race makes us see a 64-bit instruction here the sdl/sdr
1784          * would blow up, so for now we don't handle unaligned 64-bit
1785          * instructions on 32-bit kernels.
1786          */
1787         if (!access_ok(VERIFY_READ, addr, 4))
1788                 goto sigbus;
1789
1790         LoadWU(addr, value, res);
1791         if (res)
1792                 goto fault;
1793         regs->regs[reg] = value;
1794         goto success;
1795 #endif /* CONFIG_64BIT */
1796
1797         /* Cannot handle 64-bit instructions in 32-bit kernel */
1798         goto sigill;
1799
1800 loadDW:
1801 #ifdef CONFIG_64BIT
1802         /*
1803          * A 32-bit kernel might be running on a 64-bit processor.  But
1804          * if we're on a 32-bit processor and an i-cache incoherency
1805          * or race makes us see a 64-bit instruction here the sdl/sdr
1806          * would blow up, so for now we don't handle unaligned 64-bit
1807          * instructions on 32-bit kernels.
1808          */
1809         if (!access_ok(VERIFY_READ, addr, 8))
1810                 goto sigbus;
1811
1812         LoadDW(addr, value, res);
1813         if (res)
1814                 goto fault;
1815         regs->regs[reg] = value;
1816         goto success;
1817 #endif /* CONFIG_64BIT */
1818
1819         /* Cannot handle 64-bit instructions in 32-bit kernel */
1820         goto sigill;
1821
1822 storeHW:
1823         if (!access_ok(VERIFY_WRITE, addr, 2))
1824                 goto sigbus;
1825
1826         value = regs->regs[reg];
1827         StoreHW(addr, value, res);
1828         if (res)
1829                 goto fault;
1830         goto success;
1831
1832 storeW:
1833         if (!access_ok(VERIFY_WRITE, addr, 4))
1834                 goto sigbus;
1835
1836         value = regs->regs[reg];
1837         StoreW(addr, value, res);
1838         if (res)
1839                 goto fault;
1840         goto success;
1841
1842 storeDW:
1843 #ifdef CONFIG_64BIT
1844         /*
1845          * A 32-bit kernel might be running on a 64-bit processor.  But
1846          * if we're on a 32-bit processor and an i-cache incoherency
1847          * or race makes us see a 64-bit instruction here the sdl/sdr
1848          * would blow up, so for now we don't handle unaligned 64-bit
1849          * instructions on 32-bit kernels.
1850          */
1851         if (!access_ok(VERIFY_WRITE, addr, 8))
1852                 goto sigbus;
1853
1854         value = regs->regs[reg];
1855         StoreDW(addr, value, res);
1856         if (res)
1857                 goto fault;
1858         goto success;
1859 #endif /* CONFIG_64BIT */
1860
1861         /* Cannot handle 64-bit instructions in 32-bit kernel */
1862         goto sigill;
1863
1864 success:
1865         regs->cp0_epc = contpc; /* advance or branch */
1866
1867 #ifdef CONFIG_DEBUG_FS
1868         unaligned_instructions++;
1869 #endif
1870         return;
1871
1872 fault:
1873         /* roll back jump/branch */
1874         regs->cp0_epc = origpc;
1875         regs->regs[31] = orig31;
1876         /* Did we have an exception handler installed? */
1877         if (fixup_exception(regs))
1878                 return;
1879
1880         die_if_kernel("Unhandled kernel unaligned access", regs);
1881         force_sig(SIGSEGV, current);
1882
1883         return;
1884
1885 sigbus:
1886         die_if_kernel("Unhandled kernel unaligned access", regs);
1887         force_sig(SIGBUS, current);
1888
1889         return;
1890
1891 sigill:
1892         die_if_kernel
1893             ("Unhandled kernel unaligned access or invalid instruction", regs);
1894         force_sig(SIGILL, current);
1895 }
1896
1897 static void emulate_load_store_MIPS16e(struct pt_regs *regs, void __user * addr)
1898 {
1899         unsigned long value;
1900         unsigned int res;
1901         int reg;
1902         unsigned long orig31;
1903         u16 __user *pc16;
1904         unsigned long origpc;
1905         union mips16e_instruction mips16inst, oldinst;
1906
1907         origpc = regs->cp0_epc;
1908         orig31 = regs->regs[31];
1909         pc16 = (unsigned short __user *)msk_isa16_mode(origpc);
1910         /*
1911          * This load never faults.
1912          */
1913         __get_user(mips16inst.full, pc16);
1914         oldinst = mips16inst;
1915
1916         /* skip EXTEND instruction */
1917         if (mips16inst.ri.opcode == MIPS16e_extend_op) {
1918                 pc16++;
1919                 __get_user(mips16inst.full, pc16);
1920         } else if (delay_slot(regs)) {
1921                 /*  skip jump instructions */
1922                 /*  JAL/JALX are 32 bits but have OPCODE in first short int */
1923                 if (mips16inst.ri.opcode == MIPS16e_jal_op)
1924                         pc16++;
1925                 pc16++;
1926                 if (get_user(mips16inst.full, pc16))
1927                         goto sigbus;
1928         }
1929
1930         switch (mips16inst.ri.opcode) {
1931         case MIPS16e_i64_op:    /* I64 or RI64 instruction */
1932                 switch (mips16inst.i64.func) {  /* I64/RI64 func field check */
1933                 case MIPS16e_ldpc_func:
1934                 case MIPS16e_ldsp_func:
1935                         reg = reg16to32[mips16inst.ri64.ry];
1936                         goto loadDW;
1937
1938                 case MIPS16e_sdsp_func:
1939                         reg = reg16to32[mips16inst.ri64.ry];
1940                         goto writeDW;
1941
1942                 case MIPS16e_sdrasp_func:
1943                         reg = 29;       /* GPRSP */
1944                         goto writeDW;
1945                 }
1946
1947                 goto sigbus;
1948
1949         case MIPS16e_swsp_op:
1950         case MIPS16e_lwpc_op:
1951         case MIPS16e_lwsp_op:
1952                 reg = reg16to32[mips16inst.ri.rx];
1953                 break;
1954
1955         case MIPS16e_i8_op:
1956                 if (mips16inst.i8.func != MIPS16e_swrasp_func)
1957                         goto sigbus;
1958                 reg = 29;       /* GPRSP */
1959                 break;
1960
1961         default:
1962                 reg = reg16to32[mips16inst.rri.ry];
1963                 break;
1964         }
1965
1966         switch (mips16inst.ri.opcode) {
1967
1968         case MIPS16e_lb_op:
1969         case MIPS16e_lbu_op:
1970         case MIPS16e_sb_op:
1971                 goto sigbus;
1972
1973         case MIPS16e_lh_op:
1974                 if (!access_ok(VERIFY_READ, addr, 2))
1975                         goto sigbus;
1976
1977                 LoadHW(addr, value, res);
1978                 if (res)
1979                         goto fault;
1980                 MIPS16e_compute_return_epc(regs, &oldinst);
1981                 regs->regs[reg] = value;
1982                 break;
1983
1984         case MIPS16e_lhu_op:
1985                 if (!access_ok(VERIFY_READ, addr, 2))
1986                         goto sigbus;
1987
1988                 LoadHWU(addr, value, res);
1989                 if (res)
1990                         goto fault;
1991                 MIPS16e_compute_return_epc(regs, &oldinst);
1992                 regs->regs[reg] = value;
1993                 break;
1994
1995         case MIPS16e_lw_op:
1996         case MIPS16e_lwpc_op:
1997         case MIPS16e_lwsp_op:
1998                 if (!access_ok(VERIFY_READ, addr, 4))
1999                         goto sigbus;
2000
2001                 LoadW(addr, value, res);
2002                 if (res)
2003                         goto fault;
2004                 MIPS16e_compute_return_epc(regs, &oldinst);
2005                 regs->regs[reg] = value;
2006                 break;
2007
2008         case MIPS16e_lwu_op:
2009 #ifdef CONFIG_64BIT
2010                 /*
2011                  * A 32-bit kernel might be running on a 64-bit processor.  But
2012                  * if we're on a 32-bit processor and an i-cache incoherency
2013                  * or race makes us see a 64-bit instruction here the sdl/sdr
2014                  * would blow up, so for now we don't handle unaligned 64-bit
2015                  * instructions on 32-bit kernels.
2016                  */
2017                 if (!access_ok(VERIFY_READ, addr, 4))
2018                         goto sigbus;
2019
2020                 LoadWU(addr, value, res);
2021                 if (res)
2022                         goto fault;
2023                 MIPS16e_compute_return_epc(regs, &oldinst);
2024                 regs->regs[reg] = value;
2025                 break;
2026 #endif /* CONFIG_64BIT */
2027
2028                 /* Cannot handle 64-bit instructions in 32-bit kernel */
2029                 goto sigill;
2030
2031         case MIPS16e_ld_op:
2032 loadDW:
2033 #ifdef CONFIG_64BIT
2034                 /*
2035                  * A 32-bit kernel might be running on a 64-bit processor.  But
2036                  * if we're on a 32-bit processor and an i-cache incoherency
2037                  * or race makes us see a 64-bit instruction here the sdl/sdr
2038                  * would blow up, so for now we don't handle unaligned 64-bit
2039                  * instructions on 32-bit kernels.
2040                  */
2041                 if (!access_ok(VERIFY_READ, addr, 8))
2042                         goto sigbus;
2043
2044                 LoadDW(addr, value, res);
2045                 if (res)
2046                         goto fault;
2047                 MIPS16e_compute_return_epc(regs, &oldinst);
2048                 regs->regs[reg] = value;
2049                 break;
2050 #endif /* CONFIG_64BIT */
2051
2052                 /* Cannot handle 64-bit instructions in 32-bit kernel */
2053                 goto sigill;
2054
2055         case MIPS16e_sh_op:
2056                 if (!access_ok(VERIFY_WRITE, addr, 2))
2057                         goto sigbus;
2058
2059                 MIPS16e_compute_return_epc(regs, &oldinst);
2060                 value = regs->regs[reg];
2061                 StoreHW(addr, value, res);
2062                 if (res)
2063                         goto fault;
2064                 break;
2065
2066         case MIPS16e_sw_op:
2067         case MIPS16e_swsp_op:
2068         case MIPS16e_i8_op:     /* actually - MIPS16e_swrasp_func */
2069                 if (!access_ok(VERIFY_WRITE, addr, 4))
2070                         goto sigbus;
2071
2072                 MIPS16e_compute_return_epc(regs, &oldinst);
2073                 value = regs->regs[reg];
2074                 StoreW(addr, value, res);
2075                 if (res)
2076                         goto fault;
2077                 break;
2078
2079         case MIPS16e_sd_op:
2080 writeDW:
2081 #ifdef CONFIG_64BIT
2082                 /*
2083                  * A 32-bit kernel might be running on a 64-bit processor.  But
2084                  * if we're on a 32-bit processor and an i-cache incoherency
2085                  * or race makes us see a 64-bit instruction here the sdl/sdr
2086                  * would blow up, so for now we don't handle unaligned 64-bit
2087                  * instructions on 32-bit kernels.
2088                  */
2089                 if (!access_ok(VERIFY_WRITE, addr, 8))
2090                         goto sigbus;
2091
2092                 MIPS16e_compute_return_epc(regs, &oldinst);
2093                 value = regs->regs[reg];
2094                 StoreDW(addr, value, res);
2095                 if (res)
2096                         goto fault;
2097                 break;
2098 #endif /* CONFIG_64BIT */
2099
2100                 /* Cannot handle 64-bit instructions in 32-bit kernel */
2101                 goto sigill;
2102
2103         default:
2104                 /*
2105                  * Pheeee...  We encountered an yet unknown instruction or
2106                  * cache coherence problem.  Die sucker, die ...
2107                  */
2108                 goto sigill;
2109         }
2110
2111 #ifdef CONFIG_DEBUG_FS
2112         unaligned_instructions++;
2113 #endif
2114
2115         return;
2116
2117 fault:
2118         /* roll back jump/branch */
2119         regs->cp0_epc = origpc;
2120         regs->regs[31] = orig31;
2121         /* Did we have an exception handler installed? */
2122         if (fixup_exception(regs))
2123                 return;
2124
2125         die_if_kernel("Unhandled kernel unaligned access", regs);
2126         force_sig(SIGSEGV, current);
2127
2128         return;
2129
2130 sigbus:
2131         die_if_kernel("Unhandled kernel unaligned access", regs);
2132         force_sig(SIGBUS, current);
2133
2134         return;
2135
2136 sigill:
2137         die_if_kernel
2138             ("Unhandled kernel unaligned access or invalid instruction", regs);
2139         force_sig(SIGILL, current);
2140 }
2141
2142 asmlinkage void do_ade(struct pt_regs *regs)
2143 {
2144         enum ctx_state prev_state;
2145         unsigned int __user *pc;
2146         mm_segment_t seg;
2147
2148         prev_state = exception_enter();
2149         perf_sw_event(PERF_COUNT_SW_ALIGNMENT_FAULTS,
2150                         1, regs, regs->cp0_badvaddr);
2151         /*
2152          * Did we catch a fault trying to load an instruction?
2153          */
2154         if (regs->cp0_badvaddr == regs->cp0_epc)
2155                 goto sigbus;
2156
2157         if (user_mode(regs) && !test_thread_flag(TIF_FIXADE))
2158                 goto sigbus;
2159         if (unaligned_action == UNALIGNED_ACTION_SIGNAL)
2160                 goto sigbus;
2161
2162         /*
2163          * Do branch emulation only if we didn't forward the exception.
2164          * This is all so but ugly ...
2165          */
2166
2167         /*
2168          * Are we running in microMIPS mode?
2169          */
2170         if (get_isa16_mode(regs->cp0_epc)) {
2171                 /*
2172                  * Did we catch a fault trying to load an instruction in
2173                  * 16-bit mode?
2174                  */
2175                 if (regs->cp0_badvaddr == msk_isa16_mode(regs->cp0_epc))
2176                         goto sigbus;
2177                 if (unaligned_action == UNALIGNED_ACTION_SHOW)
2178                         show_registers(regs);
2179
2180                 if (cpu_has_mmips) {
2181                         seg = get_fs();
2182                         if (!user_mode(regs))
2183                                 set_fs(KERNEL_DS);
2184                         emulate_load_store_microMIPS(regs,
2185                                 (void __user *)regs->cp0_badvaddr);
2186                         set_fs(seg);
2187
2188                         return;
2189                 }
2190
2191                 if (cpu_has_mips16) {
2192                         seg = get_fs();
2193                         if (!user_mode(regs))
2194                                 set_fs(KERNEL_DS);
2195                         emulate_load_store_MIPS16e(regs,
2196                                 (void __user *)regs->cp0_badvaddr);
2197                         set_fs(seg);
2198
2199                         return;
2200         }
2201
2202                 goto sigbus;
2203         }
2204
2205         if (unaligned_action == UNALIGNED_ACTION_SHOW)
2206                 show_registers(regs);
2207         pc = (unsigned int __user *)exception_epc(regs);
2208
2209         seg = get_fs();
2210         if (!user_mode(regs))
2211                 set_fs(KERNEL_DS);
2212         emulate_load_store_insn(regs, (void __user *)regs->cp0_badvaddr, pc);
2213         set_fs(seg);
2214
2215         return;
2216
2217 sigbus:
2218         die_if_kernel("Kernel unaligned instruction access", regs);
2219         force_sig(SIGBUS, current);
2220
2221         /*
2222          * XXX On return from the signal handler we should advance the epc
2223          */
2224         exception_exit(prev_state);
2225 }
2226
2227 #ifdef CONFIG_DEBUG_FS
2228 extern struct dentry *mips_debugfs_dir;
2229 static int __init debugfs_unaligned(void)
2230 {
2231         struct dentry *d;
2232
2233         if (!mips_debugfs_dir)
2234                 return -ENODEV;
2235         d = debugfs_create_u32("unaligned_instructions", S_IRUGO,
2236                                mips_debugfs_dir, &unaligned_instructions);
2237         if (!d)
2238                 return -ENOMEM;
2239         d = debugfs_create_u32("unaligned_action", S_IRUGO | S_IWUSR,
2240                                mips_debugfs_dir, &unaligned_action);
2241         if (!d)
2242                 return -ENOMEM;
2243         return 0;
2244 }
2245 __initcall(debugfs_unaligned);
2246 #endif