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