hc
2024-02-20 102a0743326a03cd1a1202ceda21e175b7d3575c
kernel/arch/mips/kernel/unaligned.c
....@@ -89,10 +89,9 @@
8989 #include <asm/fpu.h>
9090 #include <asm/fpu_emulator.h>
9191 #include <asm/inst.h>
92
+#include <asm/unaligned-emul.h>
93
+#include <asm/mmu_context.h>
9294 #include <linux/uaccess.h>
93
-
94
-#define STR(x) __STR(x)
95
-#define __STR(x) #x
9695
9796 enum {
9897 UNALIGNED_ACTION_QUIET,
....@@ -107,794 +106,15 @@
107106 #endif
108107 extern void show_registers(struct pt_regs *regs);
109108
110
-#ifdef __BIG_ENDIAN
111
-#define _LoadHW(addr, value, res, type) \
112
-do { \
113
- __asm__ __volatile__ (".set\tnoat\n" \
114
- "1:\t"type##_lb("%0", "0(%2)")"\n" \
115
- "2:\t"type##_lbu("$1", "1(%2)")"\n\t"\
116
- "sll\t%0, 0x8\n\t" \
117
- "or\t%0, $1\n\t" \
118
- "li\t%1, 0\n" \
119
- "3:\t.set\tat\n\t" \
120
- ".insn\n\t" \
121
- ".section\t.fixup,\"ax\"\n\t" \
122
- "4:\tli\t%1, %3\n\t" \
123
- "j\t3b\n\t" \
124
- ".previous\n\t" \
125
- ".section\t__ex_table,\"a\"\n\t" \
126
- STR(PTR)"\t1b, 4b\n\t" \
127
- STR(PTR)"\t2b, 4b\n\t" \
128
- ".previous" \
129
- : "=&r" (value), "=r" (res) \
130
- : "r" (addr), "i" (-EFAULT)); \
131
-} while(0)
132
-
133
-#ifndef CONFIG_CPU_MIPSR6
134
-#define _LoadW(addr, value, res, type) \
135
-do { \
136
- __asm__ __volatile__ ( \
137
- "1:\t"type##_lwl("%0", "(%2)")"\n" \
138
- "2:\t"type##_lwr("%0", "3(%2)")"\n\t"\
139
- "li\t%1, 0\n" \
140
- "3:\n\t" \
141
- ".insn\n\t" \
142
- ".section\t.fixup,\"ax\"\n\t" \
143
- "4:\tli\t%1, %3\n\t" \
144
- "j\t3b\n\t" \
145
- ".previous\n\t" \
146
- ".section\t__ex_table,\"a\"\n\t" \
147
- STR(PTR)"\t1b, 4b\n\t" \
148
- STR(PTR)"\t2b, 4b\n\t" \
149
- ".previous" \
150
- : "=&r" (value), "=r" (res) \
151
- : "r" (addr), "i" (-EFAULT)); \
152
-} while(0)
153
-
154
-#else
155
-/* MIPSR6 has no lwl instruction */
156
-#define _LoadW(addr, value, res, type) \
157
-do { \
158
- __asm__ __volatile__ ( \
159
- ".set\tpush\n" \
160
- ".set\tnoat\n\t" \
161
- "1:"type##_lb("%0", "0(%2)")"\n\t" \
162
- "2:"type##_lbu("$1", "1(%2)")"\n\t" \
163
- "sll\t%0, 0x8\n\t" \
164
- "or\t%0, $1\n\t" \
165
- "3:"type##_lbu("$1", "2(%2)")"\n\t" \
166
- "sll\t%0, 0x8\n\t" \
167
- "or\t%0, $1\n\t" \
168
- "4:"type##_lbu("$1", "3(%2)")"\n\t" \
169
- "sll\t%0, 0x8\n\t" \
170
- "or\t%0, $1\n\t" \
171
- "li\t%1, 0\n" \
172
- ".set\tpop\n" \
173
- "10:\n\t" \
174
- ".insn\n\t" \
175
- ".section\t.fixup,\"ax\"\n\t" \
176
- "11:\tli\t%1, %3\n\t" \
177
- "j\t10b\n\t" \
178
- ".previous\n\t" \
179
- ".section\t__ex_table,\"a\"\n\t" \
180
- STR(PTR)"\t1b, 11b\n\t" \
181
- STR(PTR)"\t2b, 11b\n\t" \
182
- STR(PTR)"\t3b, 11b\n\t" \
183
- STR(PTR)"\t4b, 11b\n\t" \
184
- ".previous" \
185
- : "=&r" (value), "=r" (res) \
186
- : "r" (addr), "i" (-EFAULT)); \
187
-} while(0)
188
-
189
-#endif /* CONFIG_CPU_MIPSR6 */
190
-
191
-#define _LoadHWU(addr, value, res, type) \
192
-do { \
193
- __asm__ __volatile__ ( \
194
- ".set\tnoat\n" \
195
- "1:\t"type##_lbu("%0", "0(%2)")"\n" \
196
- "2:\t"type##_lbu("$1", "1(%2)")"\n\t"\
197
- "sll\t%0, 0x8\n\t" \
198
- "or\t%0, $1\n\t" \
199
- "li\t%1, 0\n" \
200
- "3:\n\t" \
201
- ".insn\n\t" \
202
- ".set\tat\n\t" \
203
- ".section\t.fixup,\"ax\"\n\t" \
204
- "4:\tli\t%1, %3\n\t" \
205
- "j\t3b\n\t" \
206
- ".previous\n\t" \
207
- ".section\t__ex_table,\"a\"\n\t" \
208
- STR(PTR)"\t1b, 4b\n\t" \
209
- STR(PTR)"\t2b, 4b\n\t" \
210
- ".previous" \
211
- : "=&r" (value), "=r" (res) \
212
- : "r" (addr), "i" (-EFAULT)); \
213
-} while(0)
214
-
215
-#ifndef CONFIG_CPU_MIPSR6
216
-#define _LoadWU(addr, value, res, type) \
217
-do { \
218
- __asm__ __volatile__ ( \
219
- "1:\t"type##_lwl("%0", "(%2)")"\n" \
220
- "2:\t"type##_lwr("%0", "3(%2)")"\n\t"\
221
- "dsll\t%0, %0, 32\n\t" \
222
- "dsrl\t%0, %0, 32\n\t" \
223
- "li\t%1, 0\n" \
224
- "3:\n\t" \
225
- ".insn\n\t" \
226
- "\t.section\t.fixup,\"ax\"\n\t" \
227
- "4:\tli\t%1, %3\n\t" \
228
- "j\t3b\n\t" \
229
- ".previous\n\t" \
230
- ".section\t__ex_table,\"a\"\n\t" \
231
- STR(PTR)"\t1b, 4b\n\t" \
232
- STR(PTR)"\t2b, 4b\n\t" \
233
- ".previous" \
234
- : "=&r" (value), "=r" (res) \
235
- : "r" (addr), "i" (-EFAULT)); \
236
-} while(0)
237
-
238
-#define _LoadDW(addr, value, res) \
239
-do { \
240
- __asm__ __volatile__ ( \
241
- "1:\tldl\t%0, (%2)\n" \
242
- "2:\tldr\t%0, 7(%2)\n\t" \
243
- "li\t%1, 0\n" \
244
- "3:\n\t" \
245
- ".insn\n\t" \
246
- "\t.section\t.fixup,\"ax\"\n\t" \
247
- "4:\tli\t%1, %3\n\t" \
248
- "j\t3b\n\t" \
249
- ".previous\n\t" \
250
- ".section\t__ex_table,\"a\"\n\t" \
251
- STR(PTR)"\t1b, 4b\n\t" \
252
- STR(PTR)"\t2b, 4b\n\t" \
253
- ".previous" \
254
- : "=&r" (value), "=r" (res) \
255
- : "r" (addr), "i" (-EFAULT)); \
256
-} while(0)
257
-
258
-#else
259
-/* MIPSR6 has not lwl and ldl instructions */
260
-#define _LoadWU(addr, value, res, type) \
261
-do { \
262
- __asm__ __volatile__ ( \
263
- ".set\tpush\n\t" \
264
- ".set\tnoat\n\t" \
265
- "1:"type##_lbu("%0", "0(%2)")"\n\t" \
266
- "2:"type##_lbu("$1", "1(%2)")"\n\t" \
267
- "sll\t%0, 0x8\n\t" \
268
- "or\t%0, $1\n\t" \
269
- "3:"type##_lbu("$1", "2(%2)")"\n\t" \
270
- "sll\t%0, 0x8\n\t" \
271
- "or\t%0, $1\n\t" \
272
- "4:"type##_lbu("$1", "3(%2)")"\n\t" \
273
- "sll\t%0, 0x8\n\t" \
274
- "or\t%0, $1\n\t" \
275
- "li\t%1, 0\n" \
276
- ".set\tpop\n" \
277
- "10:\n\t" \
278
- ".insn\n\t" \
279
- ".section\t.fixup,\"ax\"\n\t" \
280
- "11:\tli\t%1, %3\n\t" \
281
- "j\t10b\n\t" \
282
- ".previous\n\t" \
283
- ".section\t__ex_table,\"a\"\n\t" \
284
- STR(PTR)"\t1b, 11b\n\t" \
285
- STR(PTR)"\t2b, 11b\n\t" \
286
- STR(PTR)"\t3b, 11b\n\t" \
287
- STR(PTR)"\t4b, 11b\n\t" \
288
- ".previous" \
289
- : "=&r" (value), "=r" (res) \
290
- : "r" (addr), "i" (-EFAULT)); \
291
-} while(0)
292
-
293
-#define _LoadDW(addr, value, res) \
294
-do { \
295
- __asm__ __volatile__ ( \
296
- ".set\tpush\n\t" \
297
- ".set\tnoat\n\t" \
298
- "1:lb\t%0, 0(%2)\n\t" \
299
- "2:lbu\t $1, 1(%2)\n\t" \
300
- "dsll\t%0, 0x8\n\t" \
301
- "or\t%0, $1\n\t" \
302
- "3:lbu\t$1, 2(%2)\n\t" \
303
- "dsll\t%0, 0x8\n\t" \
304
- "or\t%0, $1\n\t" \
305
- "4:lbu\t$1, 3(%2)\n\t" \
306
- "dsll\t%0, 0x8\n\t" \
307
- "or\t%0, $1\n\t" \
308
- "5:lbu\t$1, 4(%2)\n\t" \
309
- "dsll\t%0, 0x8\n\t" \
310
- "or\t%0, $1\n\t" \
311
- "6:lbu\t$1, 5(%2)\n\t" \
312
- "dsll\t%0, 0x8\n\t" \
313
- "or\t%0, $1\n\t" \
314
- "7:lbu\t$1, 6(%2)\n\t" \
315
- "dsll\t%0, 0x8\n\t" \
316
- "or\t%0, $1\n\t" \
317
- "8:lbu\t$1, 7(%2)\n\t" \
318
- "dsll\t%0, 0x8\n\t" \
319
- "or\t%0, $1\n\t" \
320
- "li\t%1, 0\n" \
321
- ".set\tpop\n\t" \
322
- "10:\n\t" \
323
- ".insn\n\t" \
324
- ".section\t.fixup,\"ax\"\n\t" \
325
- "11:\tli\t%1, %3\n\t" \
326
- "j\t10b\n\t" \
327
- ".previous\n\t" \
328
- ".section\t__ex_table,\"a\"\n\t" \
329
- STR(PTR)"\t1b, 11b\n\t" \
330
- STR(PTR)"\t2b, 11b\n\t" \
331
- STR(PTR)"\t3b, 11b\n\t" \
332
- STR(PTR)"\t4b, 11b\n\t" \
333
- STR(PTR)"\t5b, 11b\n\t" \
334
- STR(PTR)"\t6b, 11b\n\t" \
335
- STR(PTR)"\t7b, 11b\n\t" \
336
- STR(PTR)"\t8b, 11b\n\t" \
337
- ".previous" \
338
- : "=&r" (value), "=r" (res) \
339
- : "r" (addr), "i" (-EFAULT)); \
340
-} while(0)
341
-
342
-#endif /* CONFIG_CPU_MIPSR6 */
343
-
344
-
345
-#define _StoreHW(addr, value, res, type) \
346
-do { \
347
- __asm__ __volatile__ ( \
348
- ".set\tnoat\n" \
349
- "1:\t"type##_sb("%1", "1(%2)")"\n" \
350
- "srl\t$1, %1, 0x8\n" \
351
- "2:\t"type##_sb("$1", "0(%2)")"\n" \
352
- ".set\tat\n\t" \
353
- "li\t%0, 0\n" \
354
- "3:\n\t" \
355
- ".insn\n\t" \
356
- ".section\t.fixup,\"ax\"\n\t" \
357
- "4:\tli\t%0, %3\n\t" \
358
- "j\t3b\n\t" \
359
- ".previous\n\t" \
360
- ".section\t__ex_table,\"a\"\n\t" \
361
- STR(PTR)"\t1b, 4b\n\t" \
362
- STR(PTR)"\t2b, 4b\n\t" \
363
- ".previous" \
364
- : "=r" (res) \
365
- : "r" (value), "r" (addr), "i" (-EFAULT));\
366
-} while(0)
367
-
368
-#ifndef CONFIG_CPU_MIPSR6
369
-#define _StoreW(addr, value, res, type) \
370
-do { \
371
- __asm__ __volatile__ ( \
372
- "1:\t"type##_swl("%1", "(%2)")"\n" \
373
- "2:\t"type##_swr("%1", "3(%2)")"\n\t"\
374
- "li\t%0, 0\n" \
375
- "3:\n\t" \
376
- ".insn\n\t" \
377
- ".section\t.fixup,\"ax\"\n\t" \
378
- "4:\tli\t%0, %3\n\t" \
379
- "j\t3b\n\t" \
380
- ".previous\n\t" \
381
- ".section\t__ex_table,\"a\"\n\t" \
382
- STR(PTR)"\t1b, 4b\n\t" \
383
- STR(PTR)"\t2b, 4b\n\t" \
384
- ".previous" \
385
- : "=r" (res) \
386
- : "r" (value), "r" (addr), "i" (-EFAULT)); \
387
-} while(0)
388
-
389
-#define _StoreDW(addr, value, res) \
390
-do { \
391
- __asm__ __volatile__ ( \
392
- "1:\tsdl\t%1,(%2)\n" \
393
- "2:\tsdr\t%1, 7(%2)\n\t" \
394
- "li\t%0, 0\n" \
395
- "3:\n\t" \
396
- ".insn\n\t" \
397
- ".section\t.fixup,\"ax\"\n\t" \
398
- "4:\tli\t%0, %3\n\t" \
399
- "j\t3b\n\t" \
400
- ".previous\n\t" \
401
- ".section\t__ex_table,\"a\"\n\t" \
402
- STR(PTR)"\t1b, 4b\n\t" \
403
- STR(PTR)"\t2b, 4b\n\t" \
404
- ".previous" \
405
- : "=r" (res) \
406
- : "r" (value), "r" (addr), "i" (-EFAULT)); \
407
-} while(0)
408
-
409
-#else
410
-/* MIPSR6 has no swl and sdl instructions */
411
-#define _StoreW(addr, value, res, type) \
412
-do { \
413
- __asm__ __volatile__ ( \
414
- ".set\tpush\n\t" \
415
- ".set\tnoat\n\t" \
416
- "1:"type##_sb("%1", "3(%2)")"\n\t" \
417
- "srl\t$1, %1, 0x8\n\t" \
418
- "2:"type##_sb("$1", "2(%2)")"\n\t" \
419
- "srl\t$1, $1, 0x8\n\t" \
420
- "3:"type##_sb("$1", "1(%2)")"\n\t" \
421
- "srl\t$1, $1, 0x8\n\t" \
422
- "4:"type##_sb("$1", "0(%2)")"\n\t" \
423
- ".set\tpop\n\t" \
424
- "li\t%0, 0\n" \
425
- "10:\n\t" \
426
- ".insn\n\t" \
427
- ".section\t.fixup,\"ax\"\n\t" \
428
- "11:\tli\t%0, %3\n\t" \
429
- "j\t10b\n\t" \
430
- ".previous\n\t" \
431
- ".section\t__ex_table,\"a\"\n\t" \
432
- STR(PTR)"\t1b, 11b\n\t" \
433
- STR(PTR)"\t2b, 11b\n\t" \
434
- STR(PTR)"\t3b, 11b\n\t" \
435
- STR(PTR)"\t4b, 11b\n\t" \
436
- ".previous" \
437
- : "=&r" (res) \
438
- : "r" (value), "r" (addr), "i" (-EFAULT) \
439
- : "memory"); \
440
-} while(0)
441
-
442
-#define _StoreDW(addr, value, res) \
443
-do { \
444
- __asm__ __volatile__ ( \
445
- ".set\tpush\n\t" \
446
- ".set\tnoat\n\t" \
447
- "1:sb\t%1, 7(%2)\n\t" \
448
- "dsrl\t$1, %1, 0x8\n\t" \
449
- "2:sb\t$1, 6(%2)\n\t" \
450
- "dsrl\t$1, $1, 0x8\n\t" \
451
- "3:sb\t$1, 5(%2)\n\t" \
452
- "dsrl\t$1, $1, 0x8\n\t" \
453
- "4:sb\t$1, 4(%2)\n\t" \
454
- "dsrl\t$1, $1, 0x8\n\t" \
455
- "5:sb\t$1, 3(%2)\n\t" \
456
- "dsrl\t$1, $1, 0x8\n\t" \
457
- "6:sb\t$1, 2(%2)\n\t" \
458
- "dsrl\t$1, $1, 0x8\n\t" \
459
- "7:sb\t$1, 1(%2)\n\t" \
460
- "dsrl\t$1, $1, 0x8\n\t" \
461
- "8:sb\t$1, 0(%2)\n\t" \
462
- "dsrl\t$1, $1, 0x8\n\t" \
463
- ".set\tpop\n\t" \
464
- "li\t%0, 0\n" \
465
- "10:\n\t" \
466
- ".insn\n\t" \
467
- ".section\t.fixup,\"ax\"\n\t" \
468
- "11:\tli\t%0, %3\n\t" \
469
- "j\t10b\n\t" \
470
- ".previous\n\t" \
471
- ".section\t__ex_table,\"a\"\n\t" \
472
- STR(PTR)"\t1b, 11b\n\t" \
473
- STR(PTR)"\t2b, 11b\n\t" \
474
- STR(PTR)"\t3b, 11b\n\t" \
475
- STR(PTR)"\t4b, 11b\n\t" \
476
- STR(PTR)"\t5b, 11b\n\t" \
477
- STR(PTR)"\t6b, 11b\n\t" \
478
- STR(PTR)"\t7b, 11b\n\t" \
479
- STR(PTR)"\t8b, 11b\n\t" \
480
- ".previous" \
481
- : "=&r" (res) \
482
- : "r" (value), "r" (addr), "i" (-EFAULT) \
483
- : "memory"); \
484
-} while(0)
485
-
486
-#endif /* CONFIG_CPU_MIPSR6 */
487
-
488
-#else /* __BIG_ENDIAN */
489
-
490
-#define _LoadHW(addr, value, res, type) \
491
-do { \
492
- __asm__ __volatile__ (".set\tnoat\n" \
493
- "1:\t"type##_lb("%0", "1(%2)")"\n" \
494
- "2:\t"type##_lbu("$1", "0(%2)")"\n\t"\
495
- "sll\t%0, 0x8\n\t" \
496
- "or\t%0, $1\n\t" \
497
- "li\t%1, 0\n" \
498
- "3:\t.set\tat\n\t" \
499
- ".insn\n\t" \
500
- ".section\t.fixup,\"ax\"\n\t" \
501
- "4:\tli\t%1, %3\n\t" \
502
- "j\t3b\n\t" \
503
- ".previous\n\t" \
504
- ".section\t__ex_table,\"a\"\n\t" \
505
- STR(PTR)"\t1b, 4b\n\t" \
506
- STR(PTR)"\t2b, 4b\n\t" \
507
- ".previous" \
508
- : "=&r" (value), "=r" (res) \
509
- : "r" (addr), "i" (-EFAULT)); \
510
-} while(0)
511
-
512
-#ifndef CONFIG_CPU_MIPSR6
513
-#define _LoadW(addr, value, res, type) \
514
-do { \
515
- __asm__ __volatile__ ( \
516
- "1:\t"type##_lwl("%0", "3(%2)")"\n" \
517
- "2:\t"type##_lwr("%0", "(%2)")"\n\t"\
518
- "li\t%1, 0\n" \
519
- "3:\n\t" \
520
- ".insn\n\t" \
521
- ".section\t.fixup,\"ax\"\n\t" \
522
- "4:\tli\t%1, %3\n\t" \
523
- "j\t3b\n\t" \
524
- ".previous\n\t" \
525
- ".section\t__ex_table,\"a\"\n\t" \
526
- STR(PTR)"\t1b, 4b\n\t" \
527
- STR(PTR)"\t2b, 4b\n\t" \
528
- ".previous" \
529
- : "=&r" (value), "=r" (res) \
530
- : "r" (addr), "i" (-EFAULT)); \
531
-} while(0)
532
-
533
-#else
534
-/* MIPSR6 has no lwl instruction */
535
-#define _LoadW(addr, value, res, type) \
536
-do { \
537
- __asm__ __volatile__ ( \
538
- ".set\tpush\n" \
539
- ".set\tnoat\n\t" \
540
- "1:"type##_lb("%0", "3(%2)")"\n\t" \
541
- "2:"type##_lbu("$1", "2(%2)")"\n\t" \
542
- "sll\t%0, 0x8\n\t" \
543
- "or\t%0, $1\n\t" \
544
- "3:"type##_lbu("$1", "1(%2)")"\n\t" \
545
- "sll\t%0, 0x8\n\t" \
546
- "or\t%0, $1\n\t" \
547
- "4:"type##_lbu("$1", "0(%2)")"\n\t" \
548
- "sll\t%0, 0x8\n\t" \
549
- "or\t%0, $1\n\t" \
550
- "li\t%1, 0\n" \
551
- ".set\tpop\n" \
552
- "10:\n\t" \
553
- ".insn\n\t" \
554
- ".section\t.fixup,\"ax\"\n\t" \
555
- "11:\tli\t%1, %3\n\t" \
556
- "j\t10b\n\t" \
557
- ".previous\n\t" \
558
- ".section\t__ex_table,\"a\"\n\t" \
559
- STR(PTR)"\t1b, 11b\n\t" \
560
- STR(PTR)"\t2b, 11b\n\t" \
561
- STR(PTR)"\t3b, 11b\n\t" \
562
- STR(PTR)"\t4b, 11b\n\t" \
563
- ".previous" \
564
- : "=&r" (value), "=r" (res) \
565
- : "r" (addr), "i" (-EFAULT)); \
566
-} while(0)
567
-
568
-#endif /* CONFIG_CPU_MIPSR6 */
569
-
570
-
571
-#define _LoadHWU(addr, value, res, type) \
572
-do { \
573
- __asm__ __volatile__ ( \
574
- ".set\tnoat\n" \
575
- "1:\t"type##_lbu("%0", "1(%2)")"\n" \
576
- "2:\t"type##_lbu("$1", "0(%2)")"\n\t"\
577
- "sll\t%0, 0x8\n\t" \
578
- "or\t%0, $1\n\t" \
579
- "li\t%1, 0\n" \
580
- "3:\n\t" \
581
- ".insn\n\t" \
582
- ".set\tat\n\t" \
583
- ".section\t.fixup,\"ax\"\n\t" \
584
- "4:\tli\t%1, %3\n\t" \
585
- "j\t3b\n\t" \
586
- ".previous\n\t" \
587
- ".section\t__ex_table,\"a\"\n\t" \
588
- STR(PTR)"\t1b, 4b\n\t" \
589
- STR(PTR)"\t2b, 4b\n\t" \
590
- ".previous" \
591
- : "=&r" (value), "=r" (res) \
592
- : "r" (addr), "i" (-EFAULT)); \
593
-} while(0)
594
-
595
-#ifndef CONFIG_CPU_MIPSR6
596
-#define _LoadWU(addr, value, res, type) \
597
-do { \
598
- __asm__ __volatile__ ( \
599
- "1:\t"type##_lwl("%0", "3(%2)")"\n" \
600
- "2:\t"type##_lwr("%0", "(%2)")"\n\t"\
601
- "dsll\t%0, %0, 32\n\t" \
602
- "dsrl\t%0, %0, 32\n\t" \
603
- "li\t%1, 0\n" \
604
- "3:\n\t" \
605
- ".insn\n\t" \
606
- "\t.section\t.fixup,\"ax\"\n\t" \
607
- "4:\tli\t%1, %3\n\t" \
608
- "j\t3b\n\t" \
609
- ".previous\n\t" \
610
- ".section\t__ex_table,\"a\"\n\t" \
611
- STR(PTR)"\t1b, 4b\n\t" \
612
- STR(PTR)"\t2b, 4b\n\t" \
613
- ".previous" \
614
- : "=&r" (value), "=r" (res) \
615
- : "r" (addr), "i" (-EFAULT)); \
616
-} while(0)
617
-
618
-#define _LoadDW(addr, value, res) \
619
-do { \
620
- __asm__ __volatile__ ( \
621
- "1:\tldl\t%0, 7(%2)\n" \
622
- "2:\tldr\t%0, (%2)\n\t" \
623
- "li\t%1, 0\n" \
624
- "3:\n\t" \
625
- ".insn\n\t" \
626
- "\t.section\t.fixup,\"ax\"\n\t" \
627
- "4:\tli\t%1, %3\n\t" \
628
- "j\t3b\n\t" \
629
- ".previous\n\t" \
630
- ".section\t__ex_table,\"a\"\n\t" \
631
- STR(PTR)"\t1b, 4b\n\t" \
632
- STR(PTR)"\t2b, 4b\n\t" \
633
- ".previous" \
634
- : "=&r" (value), "=r" (res) \
635
- : "r" (addr), "i" (-EFAULT)); \
636
-} while(0)
637
-
638
-#else
639
-/* MIPSR6 has not lwl and ldl instructions */
640
-#define _LoadWU(addr, value, res, type) \
641
-do { \
642
- __asm__ __volatile__ ( \
643
- ".set\tpush\n\t" \
644
- ".set\tnoat\n\t" \
645
- "1:"type##_lbu("%0", "3(%2)")"\n\t" \
646
- "2:"type##_lbu("$1", "2(%2)")"\n\t" \
647
- "sll\t%0, 0x8\n\t" \
648
- "or\t%0, $1\n\t" \
649
- "3:"type##_lbu("$1", "1(%2)")"\n\t" \
650
- "sll\t%0, 0x8\n\t" \
651
- "or\t%0, $1\n\t" \
652
- "4:"type##_lbu("$1", "0(%2)")"\n\t" \
653
- "sll\t%0, 0x8\n\t" \
654
- "or\t%0, $1\n\t" \
655
- "li\t%1, 0\n" \
656
- ".set\tpop\n" \
657
- "10:\n\t" \
658
- ".insn\n\t" \
659
- ".section\t.fixup,\"ax\"\n\t" \
660
- "11:\tli\t%1, %3\n\t" \
661
- "j\t10b\n\t" \
662
- ".previous\n\t" \
663
- ".section\t__ex_table,\"a\"\n\t" \
664
- STR(PTR)"\t1b, 11b\n\t" \
665
- STR(PTR)"\t2b, 11b\n\t" \
666
- STR(PTR)"\t3b, 11b\n\t" \
667
- STR(PTR)"\t4b, 11b\n\t" \
668
- ".previous" \
669
- : "=&r" (value), "=r" (res) \
670
- : "r" (addr), "i" (-EFAULT)); \
671
-} while(0)
672
-
673
-#define _LoadDW(addr, value, res) \
674
-do { \
675
- __asm__ __volatile__ ( \
676
- ".set\tpush\n\t" \
677
- ".set\tnoat\n\t" \
678
- "1:lb\t%0, 7(%2)\n\t" \
679
- "2:lbu\t$1, 6(%2)\n\t" \
680
- "dsll\t%0, 0x8\n\t" \
681
- "or\t%0, $1\n\t" \
682
- "3:lbu\t$1, 5(%2)\n\t" \
683
- "dsll\t%0, 0x8\n\t" \
684
- "or\t%0, $1\n\t" \
685
- "4:lbu\t$1, 4(%2)\n\t" \
686
- "dsll\t%0, 0x8\n\t" \
687
- "or\t%0, $1\n\t" \
688
- "5:lbu\t$1, 3(%2)\n\t" \
689
- "dsll\t%0, 0x8\n\t" \
690
- "or\t%0, $1\n\t" \
691
- "6:lbu\t$1, 2(%2)\n\t" \
692
- "dsll\t%0, 0x8\n\t" \
693
- "or\t%0, $1\n\t" \
694
- "7:lbu\t$1, 1(%2)\n\t" \
695
- "dsll\t%0, 0x8\n\t" \
696
- "or\t%0, $1\n\t" \
697
- "8:lbu\t$1, 0(%2)\n\t" \
698
- "dsll\t%0, 0x8\n\t" \
699
- "or\t%0, $1\n\t" \
700
- "li\t%1, 0\n" \
701
- ".set\tpop\n\t" \
702
- "10:\n\t" \
703
- ".insn\n\t" \
704
- ".section\t.fixup,\"ax\"\n\t" \
705
- "11:\tli\t%1, %3\n\t" \
706
- "j\t10b\n\t" \
707
- ".previous\n\t" \
708
- ".section\t__ex_table,\"a\"\n\t" \
709
- STR(PTR)"\t1b, 11b\n\t" \
710
- STR(PTR)"\t2b, 11b\n\t" \
711
- STR(PTR)"\t3b, 11b\n\t" \
712
- STR(PTR)"\t4b, 11b\n\t" \
713
- STR(PTR)"\t5b, 11b\n\t" \
714
- STR(PTR)"\t6b, 11b\n\t" \
715
- STR(PTR)"\t7b, 11b\n\t" \
716
- STR(PTR)"\t8b, 11b\n\t" \
717
- ".previous" \
718
- : "=&r" (value), "=r" (res) \
719
- : "r" (addr), "i" (-EFAULT)); \
720
-} while(0)
721
-#endif /* CONFIG_CPU_MIPSR6 */
722
-
723
-#define _StoreHW(addr, value, res, type) \
724
-do { \
725
- __asm__ __volatile__ ( \
726
- ".set\tnoat\n" \
727
- "1:\t"type##_sb("%1", "0(%2)")"\n" \
728
- "srl\t$1,%1, 0x8\n" \
729
- "2:\t"type##_sb("$1", "1(%2)")"\n" \
730
- ".set\tat\n\t" \
731
- "li\t%0, 0\n" \
732
- "3:\n\t" \
733
- ".insn\n\t" \
734
- ".section\t.fixup,\"ax\"\n\t" \
735
- "4:\tli\t%0, %3\n\t" \
736
- "j\t3b\n\t" \
737
- ".previous\n\t" \
738
- ".section\t__ex_table,\"a\"\n\t" \
739
- STR(PTR)"\t1b, 4b\n\t" \
740
- STR(PTR)"\t2b, 4b\n\t" \
741
- ".previous" \
742
- : "=r" (res) \
743
- : "r" (value), "r" (addr), "i" (-EFAULT));\
744
-} while(0)
745
-
746
-#ifndef CONFIG_CPU_MIPSR6
747
-#define _StoreW(addr, value, res, type) \
748
-do { \
749
- __asm__ __volatile__ ( \
750
- "1:\t"type##_swl("%1", "3(%2)")"\n" \
751
- "2:\t"type##_swr("%1", "(%2)")"\n\t"\
752
- "li\t%0, 0\n" \
753
- "3:\n\t" \
754
- ".insn\n\t" \
755
- ".section\t.fixup,\"ax\"\n\t" \
756
- "4:\tli\t%0, %3\n\t" \
757
- "j\t3b\n\t" \
758
- ".previous\n\t" \
759
- ".section\t__ex_table,\"a\"\n\t" \
760
- STR(PTR)"\t1b, 4b\n\t" \
761
- STR(PTR)"\t2b, 4b\n\t" \
762
- ".previous" \
763
- : "=r" (res) \
764
- : "r" (value), "r" (addr), "i" (-EFAULT)); \
765
-} while(0)
766
-
767
-#define _StoreDW(addr, value, res) \
768
-do { \
769
- __asm__ __volatile__ ( \
770
- "1:\tsdl\t%1, 7(%2)\n" \
771
- "2:\tsdr\t%1, (%2)\n\t" \
772
- "li\t%0, 0\n" \
773
- "3:\n\t" \
774
- ".insn\n\t" \
775
- ".section\t.fixup,\"ax\"\n\t" \
776
- "4:\tli\t%0, %3\n\t" \
777
- "j\t3b\n\t" \
778
- ".previous\n\t" \
779
- ".section\t__ex_table,\"a\"\n\t" \
780
- STR(PTR)"\t1b, 4b\n\t" \
781
- STR(PTR)"\t2b, 4b\n\t" \
782
- ".previous" \
783
- : "=r" (res) \
784
- : "r" (value), "r" (addr), "i" (-EFAULT)); \
785
-} while(0)
786
-
787
-#else
788
-/* MIPSR6 has no swl and sdl instructions */
789
-#define _StoreW(addr, value, res, type) \
790
-do { \
791
- __asm__ __volatile__ ( \
792
- ".set\tpush\n\t" \
793
- ".set\tnoat\n\t" \
794
- "1:"type##_sb("%1", "0(%2)")"\n\t" \
795
- "srl\t$1, %1, 0x8\n\t" \
796
- "2:"type##_sb("$1", "1(%2)")"\n\t" \
797
- "srl\t$1, $1, 0x8\n\t" \
798
- "3:"type##_sb("$1", "2(%2)")"\n\t" \
799
- "srl\t$1, $1, 0x8\n\t" \
800
- "4:"type##_sb("$1", "3(%2)")"\n\t" \
801
- ".set\tpop\n\t" \
802
- "li\t%0, 0\n" \
803
- "10:\n\t" \
804
- ".insn\n\t" \
805
- ".section\t.fixup,\"ax\"\n\t" \
806
- "11:\tli\t%0, %3\n\t" \
807
- "j\t10b\n\t" \
808
- ".previous\n\t" \
809
- ".section\t__ex_table,\"a\"\n\t" \
810
- STR(PTR)"\t1b, 11b\n\t" \
811
- STR(PTR)"\t2b, 11b\n\t" \
812
- STR(PTR)"\t3b, 11b\n\t" \
813
- STR(PTR)"\t4b, 11b\n\t" \
814
- ".previous" \
815
- : "=&r" (res) \
816
- : "r" (value), "r" (addr), "i" (-EFAULT) \
817
- : "memory"); \
818
-} while(0)
819
-
820
-#define _StoreDW(addr, value, res) \
821
-do { \
822
- __asm__ __volatile__ ( \
823
- ".set\tpush\n\t" \
824
- ".set\tnoat\n\t" \
825
- "1:sb\t%1, 0(%2)\n\t" \
826
- "dsrl\t$1, %1, 0x8\n\t" \
827
- "2:sb\t$1, 1(%2)\n\t" \
828
- "dsrl\t$1, $1, 0x8\n\t" \
829
- "3:sb\t$1, 2(%2)\n\t" \
830
- "dsrl\t$1, $1, 0x8\n\t" \
831
- "4:sb\t$1, 3(%2)\n\t" \
832
- "dsrl\t$1, $1, 0x8\n\t" \
833
- "5:sb\t$1, 4(%2)\n\t" \
834
- "dsrl\t$1, $1, 0x8\n\t" \
835
- "6:sb\t$1, 5(%2)\n\t" \
836
- "dsrl\t$1, $1, 0x8\n\t" \
837
- "7:sb\t$1, 6(%2)\n\t" \
838
- "dsrl\t$1, $1, 0x8\n\t" \
839
- "8:sb\t$1, 7(%2)\n\t" \
840
- "dsrl\t$1, $1, 0x8\n\t" \
841
- ".set\tpop\n\t" \
842
- "li\t%0, 0\n" \
843
- "10:\n\t" \
844
- ".insn\n\t" \
845
- ".section\t.fixup,\"ax\"\n\t" \
846
- "11:\tli\t%0, %3\n\t" \
847
- "j\t10b\n\t" \
848
- ".previous\n\t" \
849
- ".section\t__ex_table,\"a\"\n\t" \
850
- STR(PTR)"\t1b, 11b\n\t" \
851
- STR(PTR)"\t2b, 11b\n\t" \
852
- STR(PTR)"\t3b, 11b\n\t" \
853
- STR(PTR)"\t4b, 11b\n\t" \
854
- STR(PTR)"\t5b, 11b\n\t" \
855
- STR(PTR)"\t6b, 11b\n\t" \
856
- STR(PTR)"\t7b, 11b\n\t" \
857
- STR(PTR)"\t8b, 11b\n\t" \
858
- ".previous" \
859
- : "=&r" (res) \
860
- : "r" (value), "r" (addr), "i" (-EFAULT) \
861
- : "memory"); \
862
-} while(0)
863
-
864
-#endif /* CONFIG_CPU_MIPSR6 */
865
-#endif
866
-
867
-#define LoadHWU(addr, value, res) _LoadHWU(addr, value, res, kernel)
868
-#define LoadHWUE(addr, value, res) _LoadHWU(addr, value, res, user)
869
-#define LoadWU(addr, value, res) _LoadWU(addr, value, res, kernel)
870
-#define LoadWUE(addr, value, res) _LoadWU(addr, value, res, user)
871
-#define LoadHW(addr, value, res) _LoadHW(addr, value, res, kernel)
872
-#define LoadHWE(addr, value, res) _LoadHW(addr, value, res, user)
873
-#define LoadW(addr, value, res) _LoadW(addr, value, res, kernel)
874
-#define LoadWE(addr, value, res) _LoadW(addr, value, res, user)
875
-#define LoadDW(addr, value, res) _LoadDW(addr, value, res)
876
-
877
-#define StoreHW(addr, value, res) _StoreHW(addr, value, res, kernel)
878
-#define StoreHWE(addr, value, res) _StoreHW(addr, value, res, user)
879
-#define StoreW(addr, value, res) _StoreW(addr, value, res, kernel)
880
-#define StoreWE(addr, value, res) _StoreW(addr, value, res, user)
881
-#define StoreDW(addr, value, res) _StoreDW(addr, value, res)
882
-
883109 static void emulate_load_store_insn(struct pt_regs *regs,
884110 void __user *addr, unsigned int __user *pc)
885111 {
112
+ unsigned long origpc, orig31, value;
886113 union mips_instruction insn;
887
- unsigned long value;
888
- unsigned int res, preempted;
889
- unsigned long origpc;
890
- unsigned long orig31;
891
- void __user *fault_addr = NULL;
114
+ unsigned int res;
892115 #ifdef CONFIG_EVA
893116 mm_segment_t seg;
894117 #endif
895
- union fpureg *fpr;
896
- enum msa_2b_fmt df;
897
- unsigned int wd;
898118 origpc = (unsigned long)pc;
899119 orig31 = regs->regs[31];
900120
....@@ -943,7 +163,7 @@
943163 if (insn.dsp_format.func == lx_op) {
944164 switch (insn.dsp_format.op) {
945165 case lwx_op:
946
- if (!access_ok(VERIFY_READ, addr, 4))
166
+ if (!access_ok(addr, 4))
947167 goto sigbus;
948168 LoadW(addr, value, res);
949169 if (res)
....@@ -952,7 +172,7 @@
952172 regs->regs[insn.dsp_format.rd] = value;
953173 break;
954174 case lhx_op:
955
- if (!access_ok(VERIFY_READ, addr, 2))
175
+ if (!access_ok(addr, 2))
956176 goto sigbus;
957177 LoadHW(addr, value, res);
958178 if (res)
....@@ -971,84 +191,83 @@
971191 * memory, so we need to "switch" the address limit to
972192 * user space, so that address check can work properly.
973193 */
974
- seg = get_fs();
975
- set_fs(USER_DS);
194
+ seg = force_uaccess_begin();
976195 switch (insn.spec3_format.func) {
977196 case lhe_op:
978
- if (!access_ok(VERIFY_READ, addr, 2)) {
979
- set_fs(seg);
197
+ if (!access_ok(addr, 2)) {
198
+ force_uaccess_end(seg);
980199 goto sigbus;
981200 }
982201 LoadHWE(addr, value, res);
983202 if (res) {
984
- set_fs(seg);
203
+ force_uaccess_end(seg);
985204 goto fault;
986205 }
987206 compute_return_epc(regs);
988207 regs->regs[insn.spec3_format.rt] = value;
989208 break;
990209 case lwe_op:
991
- if (!access_ok(VERIFY_READ, addr, 4)) {
992
- set_fs(seg);
210
+ if (!access_ok(addr, 4)) {
211
+ force_uaccess_end(seg);
993212 goto sigbus;
994213 }
995214 LoadWE(addr, value, res);
996215 if (res) {
997
- set_fs(seg);
216
+ force_uaccess_end(seg);
998217 goto fault;
999218 }
1000219 compute_return_epc(regs);
1001220 regs->regs[insn.spec3_format.rt] = value;
1002221 break;
1003222 case lhue_op:
1004
- if (!access_ok(VERIFY_READ, addr, 2)) {
1005
- set_fs(seg);
223
+ if (!access_ok(addr, 2)) {
224
+ force_uaccess_end(seg);
1006225 goto sigbus;
1007226 }
1008227 LoadHWUE(addr, value, res);
1009228 if (res) {
1010
- set_fs(seg);
229
+ force_uaccess_end(seg);
1011230 goto fault;
1012231 }
1013232 compute_return_epc(regs);
1014233 regs->regs[insn.spec3_format.rt] = value;
1015234 break;
1016235 case she_op:
1017
- if (!access_ok(VERIFY_WRITE, addr, 2)) {
1018
- set_fs(seg);
236
+ if (!access_ok(addr, 2)) {
237
+ force_uaccess_end(seg);
1019238 goto sigbus;
1020239 }
1021240 compute_return_epc(regs);
1022241 value = regs->regs[insn.spec3_format.rt];
1023242 StoreHWE(addr, value, res);
1024243 if (res) {
1025
- set_fs(seg);
244
+ force_uaccess_end(seg);
1026245 goto fault;
1027246 }
1028247 break;
1029248 case swe_op:
1030
- if (!access_ok(VERIFY_WRITE, addr, 4)) {
1031
- set_fs(seg);
249
+ if (!access_ok(addr, 4)) {
250
+ force_uaccess_end(seg);
1032251 goto sigbus;
1033252 }
1034253 compute_return_epc(regs);
1035254 value = regs->regs[insn.spec3_format.rt];
1036255 StoreWE(addr, value, res);
1037256 if (res) {
1038
- set_fs(seg);
257
+ force_uaccess_end(seg);
1039258 goto fault;
1040259 }
1041260 break;
1042261 default:
1043
- set_fs(seg);
262
+ force_uaccess_end(seg);
1044263 goto sigill;
1045264 }
1046
- set_fs(seg);
265
+ force_uaccess_end(seg);
1047266 }
1048267 #endif
1049268 break;
1050269 case lh_op:
1051
- if (!access_ok(VERIFY_READ, addr, 2))
270
+ if (!access_ok(addr, 2))
1052271 goto sigbus;
1053272
1054273 if (IS_ENABLED(CONFIG_EVA)) {
....@@ -1067,7 +286,7 @@
1067286 break;
1068287
1069288 case lw_op:
1070
- if (!access_ok(VERIFY_READ, addr, 4))
289
+ if (!access_ok(addr, 4))
1071290 goto sigbus;
1072291
1073292 if (IS_ENABLED(CONFIG_EVA)) {
....@@ -1086,7 +305,7 @@
1086305 break;
1087306
1088307 case lhu_op:
1089
- if (!access_ok(VERIFY_READ, addr, 2))
308
+ if (!access_ok(addr, 2))
1090309 goto sigbus;
1091310
1092311 if (IS_ENABLED(CONFIG_EVA)) {
....@@ -1113,7 +332,7 @@
1113332 * would blow up, so for now we don't handle unaligned 64-bit
1114333 * instructions on 32-bit kernels.
1115334 */
1116
- if (!access_ok(VERIFY_READ, addr, 4))
335
+ if (!access_ok(addr, 4))
1117336 goto sigbus;
1118337
1119338 LoadWU(addr, value, res);
....@@ -1136,7 +355,7 @@
1136355 * would blow up, so for now we don't handle unaligned 64-bit
1137356 * instructions on 32-bit kernels.
1138357 */
1139
- if (!access_ok(VERIFY_READ, addr, 8))
358
+ if (!access_ok(addr, 8))
1140359 goto sigbus;
1141360
1142361 LoadDW(addr, value, res);
....@@ -1151,7 +370,7 @@
1151370 goto sigill;
1152371
1153372 case sh_op:
1154
- if (!access_ok(VERIFY_WRITE, addr, 2))
373
+ if (!access_ok(addr, 2))
1155374 goto sigbus;
1156375
1157376 compute_return_epc(regs);
....@@ -1171,7 +390,7 @@
1171390 break;
1172391
1173392 case sw_op:
1174
- if (!access_ok(VERIFY_WRITE, addr, 4))
393
+ if (!access_ok(addr, 4))
1175394 goto sigbus;
1176395
1177396 compute_return_epc(regs);
....@@ -1199,7 +418,7 @@
1199418 * would blow up, so for now we don't handle unaligned 64-bit
1200419 * instructions on 32-bit kernels.
1201420 */
1202
- if (!access_ok(VERIFY_WRITE, addr, 8))
421
+ if (!access_ok(addr, 8))
1203422 goto sigbus;
1204423
1205424 compute_return_epc(regs);
....@@ -1213,15 +432,18 @@
1213432 /* Cannot handle 64-bit instructions in 32-bit kernel */
1214433 goto sigill;
1215434
435
+#ifdef CONFIG_MIPS_FP_SUPPORT
436
+
1216437 case lwc1_op:
1217438 case ldc1_op:
1218439 case swc1_op:
1219440 case sdc1_op:
1220
- case cop1x_op:
441
+ case cop1x_op: {
442
+ void __user *fault_addr = NULL;
443
+
1221444 die_if_kernel("Unaligned FP access in kernel code", regs);
1222445 BUG_ON(!used_math());
1223446
1224
- lose_fpu(1); /* Save FPU state for the emulator. */
1225447 res = fpu_emulator_cop1Handler(regs, &current->thread.fpu, 1,
1226448 &fault_addr);
1227449 own_fpu(1); /* Restore FPU state. */
....@@ -1232,8 +454,16 @@
1232454 if (res == 0)
1233455 break;
1234456 return;
457
+ }
458
+#endif /* CONFIG_MIPS_FP_SUPPORT */
1235459
1236
- case msa_op:
460
+#ifdef CONFIG_CPU_HAS_MSA
461
+
462
+ case msa_op: {
463
+ unsigned int wd, preempted;
464
+ enum msa_2b_fmt df;
465
+ union fpureg *fpr;
466
+
1237467 if (!cpu_has_msa)
1238468 goto sigill;
1239469
....@@ -1250,7 +480,7 @@
1250480
1251481 switch (insn.msa_mi10_format.func) {
1252482 case msa_ld_op:
1253
- if (!access_ok(VERIFY_READ, addr, sizeof(*fpr)))
483
+ if (!access_ok(addr, sizeof(*fpr)))
1254484 goto sigbus;
1255485
1256486 do {
....@@ -1286,7 +516,7 @@
1286516 break;
1287517
1288518 case msa_st_op:
1289
- if (!access_ok(VERIFY_WRITE, addr, sizeof(*fpr)))
519
+ if (!access_ok(addr, sizeof(*fpr)))
1290520 goto sigbus;
1291521
1292522 /*
....@@ -1310,6 +540,8 @@
1310540
1311541 compute_return_epc(regs);
1312542 break;
543
+ }
544
+#endif /* CONFIG_CPU_HAS_MSA */
1313545
1314546 #ifndef CONFIG_CPU_MIPSR6
1315547 /*
....@@ -1358,20 +590,20 @@
1358590 return;
1359591
1360592 die_if_kernel("Unhandled kernel unaligned access", regs);
1361
- force_sig(SIGSEGV, current);
593
+ force_sig(SIGSEGV);
1362594
1363595 return;
1364596
1365597 sigbus:
1366598 die_if_kernel("Unhandled kernel unaligned access", regs);
1367
- force_sig(SIGBUS, current);
599
+ force_sig(SIGBUS);
1368600
1369601 return;
1370602
1371603 sigill:
1372604 die_if_kernel
1373605 ("Unhandled kernel unaligned access or invalid instruction", regs);
1374
- force_sig(SIGILL, current);
606
+ force_sig(SIGILL);
1375607 }
1376608
1377609 /* Recode table from 16-bit register notation to 32-bit GPR. */
....@@ -1394,7 +626,6 @@
1394626 unsigned long origpc, contpc;
1395627 union mips_instruction insn;
1396628 struct mm_decoded_insn mminsn;
1397
- void __user *fault_addr = NULL;
1398629
1399630 origpc = regs->cp0_epc;
1400631 orig31 = regs->regs[31];
....@@ -1458,7 +689,7 @@
1458689 if (reg == 31)
1459690 goto sigbus;
1460691
1461
- if (!access_ok(VERIFY_READ, addr, 8))
692
+ if (!access_ok(addr, 8))
1462693 goto sigbus;
1463694
1464695 LoadW(addr, value, res);
....@@ -1477,7 +708,7 @@
1477708 if (reg == 31)
1478709 goto sigbus;
1479710
1480
- if (!access_ok(VERIFY_WRITE, addr, 8))
711
+ if (!access_ok(addr, 8))
1481712 goto sigbus;
1482713
1483714 value = regs->regs[reg];
....@@ -1497,7 +728,7 @@
1497728 if (reg == 31)
1498729 goto sigbus;
1499730
1500
- if (!access_ok(VERIFY_READ, addr, 16))
731
+ if (!access_ok(addr, 16))
1501732 goto sigbus;
1502733
1503734 LoadDW(addr, value, res);
....@@ -1520,7 +751,7 @@
1520751 if (reg == 31)
1521752 goto sigbus;
1522753
1523
- if (!access_ok(VERIFY_WRITE, addr, 16))
754
+ if (!access_ok(addr, 16))
1524755 goto sigbus;
1525756
1526757 value = regs->regs[reg];
....@@ -1543,11 +774,10 @@
1543774 if ((rvar > 9) || !reg)
1544775 goto sigill;
1545776 if (reg & 0x10) {
1546
- if (!access_ok
1547
- (VERIFY_READ, addr, 4 * (rvar + 1)))
777
+ if (!access_ok(addr, 4 * (rvar + 1)))
1548778 goto sigbus;
1549779 } else {
1550
- if (!access_ok(VERIFY_READ, addr, 4 * rvar))
780
+ if (!access_ok(addr, 4 * rvar))
1551781 goto sigbus;
1552782 }
1553783 if (rvar == 9)
....@@ -1580,11 +810,10 @@
1580810 if ((rvar > 9) || !reg)
1581811 goto sigill;
1582812 if (reg & 0x10) {
1583
- if (!access_ok
1584
- (VERIFY_WRITE, addr, 4 * (rvar + 1)))
813
+ if (!access_ok(addr, 4 * (rvar + 1)))
1585814 goto sigbus;
1586815 } else {
1587
- if (!access_ok(VERIFY_WRITE, addr, 4 * rvar))
816
+ if (!access_ok(addr, 4 * rvar))
1588817 goto sigbus;
1589818 }
1590819 if (rvar == 9)
....@@ -1618,11 +847,10 @@
1618847 if ((rvar > 9) || !reg)
1619848 goto sigill;
1620849 if (reg & 0x10) {
1621
- if (!access_ok
1622
- (VERIFY_READ, addr, 8 * (rvar + 1)))
850
+ if (!access_ok(addr, 8 * (rvar + 1)))
1623851 goto sigbus;
1624852 } else {
1625
- if (!access_ok(VERIFY_READ, addr, 8 * rvar))
853
+ if (!access_ok(addr, 8 * rvar))
1626854 goto sigbus;
1627855 }
1628856 if (rvar == 9)
....@@ -1660,11 +888,10 @@
1660888 if ((rvar > 9) || !reg)
1661889 goto sigill;
1662890 if (reg & 0x10) {
1663
- if (!access_ok
1664
- (VERIFY_WRITE, addr, 8 * (rvar + 1)))
891
+ if (!access_ok(addr, 8 * (rvar + 1)))
1665892 goto sigbus;
1666893 } else {
1667
- if (!access_ok(VERIFY_WRITE, addr, 8 * rvar))
894
+ if (!access_ok(addr, 8 * rvar))
1668895 goto sigbus;
1669896 }
1670897 if (rvar == 9)
....@@ -1710,6 +937,7 @@
1710937 /* LL,SC,LLD,SCD are not serviced */
1711938 goto sigbus;
1712939
940
+#ifdef CONFIG_MIPS_FP_SUPPORT
1713941 case mm_pool32f_op:
1714942 switch (insn.mm_x_format.func) {
1715943 case mm_lwxc1_func:
....@@ -1724,7 +952,9 @@
1724952 case mm_ldc132_op:
1725953 case mm_sdc132_op:
1726954 case mm_lwc132_op:
1727
- case mm_swc132_op:
955
+ case mm_swc132_op: {
956
+ void __user *fault_addr = NULL;
957
+
1728958 fpu_emul:
1729959 /* roll back jump/branch */
1730960 regs->cp0_epc = origpc;
....@@ -1734,7 +964,6 @@
1734964 BUG_ON(!used_math());
1735965 BUG_ON(!is_fpu_owner());
1736966
1737
- lose_fpu(1); /* save the FPU state for the emulator */
1738967 res = fpu_emulator_cop1Handler(regs, &current->thread.fpu, 1,
1739968 &fault_addr);
1740969 own_fpu(1); /* restore FPU state */
....@@ -1745,6 +974,8 @@
1745974 if (res == 0)
1746975 goto success;
1747976 return;
977
+ }
978
+#endif /* CONFIG_MIPS_FP_SUPPORT */
1748979
1749980 case mm_lh32_op:
1750981 reg = insn.mm_i_format.rt;
....@@ -1779,7 +1010,7 @@
17791010 case mm_lwm16_op:
17801011 reg = insn.mm16_m_format.rlist;
17811012 rvar = reg + 1;
1782
- if (!access_ok(VERIFY_READ, addr, 4 * rvar))
1013
+ if (!access_ok(addr, 4 * rvar))
17831014 goto sigbus;
17841015
17851016 for (i = 16; rvar; rvar--, i++) {
....@@ -1799,7 +1030,7 @@
17991030 case mm_swm16_op:
18001031 reg = insn.mm16_m_format.rlist;
18011032 rvar = reg + 1;
1802
- if (!access_ok(VERIFY_WRITE, addr, 4 * rvar))
1033
+ if (!access_ok(addr, 4 * rvar))
18031034 goto sigbus;
18041035
18051036 for (i = 16; rvar; rvar--, i++) {
....@@ -1853,7 +1084,7 @@
18531084 }
18541085
18551086 loadHW:
1856
- if (!access_ok(VERIFY_READ, addr, 2))
1087
+ if (!access_ok(addr, 2))
18571088 goto sigbus;
18581089
18591090 LoadHW(addr, value, res);
....@@ -1863,7 +1094,7 @@
18631094 goto success;
18641095
18651096 loadHWU:
1866
- if (!access_ok(VERIFY_READ, addr, 2))
1097
+ if (!access_ok(addr, 2))
18671098 goto sigbus;
18681099
18691100 LoadHWU(addr, value, res);
....@@ -1873,7 +1104,7 @@
18731104 goto success;
18741105
18751106 loadW:
1876
- if (!access_ok(VERIFY_READ, addr, 4))
1107
+ if (!access_ok(addr, 4))
18771108 goto sigbus;
18781109
18791110 LoadW(addr, value, res);
....@@ -1891,7 +1122,7 @@
18911122 * would blow up, so for now we don't handle unaligned 64-bit
18921123 * instructions on 32-bit kernels.
18931124 */
1894
- if (!access_ok(VERIFY_READ, addr, 4))
1125
+ if (!access_ok(addr, 4))
18951126 goto sigbus;
18961127
18971128 LoadWU(addr, value, res);
....@@ -1913,7 +1144,7 @@
19131144 * would blow up, so for now we don't handle unaligned 64-bit
19141145 * instructions on 32-bit kernels.
19151146 */
1916
- if (!access_ok(VERIFY_READ, addr, 8))
1147
+ if (!access_ok(addr, 8))
19171148 goto sigbus;
19181149
19191150 LoadDW(addr, value, res);
....@@ -1927,7 +1158,7 @@
19271158 goto sigill;
19281159
19291160 storeHW:
1930
- if (!access_ok(VERIFY_WRITE, addr, 2))
1161
+ if (!access_ok(addr, 2))
19311162 goto sigbus;
19321163
19331164 value = regs->regs[reg];
....@@ -1937,7 +1168,7 @@
19371168 goto success;
19381169
19391170 storeW:
1940
- if (!access_ok(VERIFY_WRITE, addr, 4))
1171
+ if (!access_ok(addr, 4))
19411172 goto sigbus;
19421173
19431174 value = regs->regs[reg];
....@@ -1955,7 +1186,7 @@
19551186 * would blow up, so for now we don't handle unaligned 64-bit
19561187 * instructions on 32-bit kernels.
19571188 */
1958
- if (!access_ok(VERIFY_WRITE, addr, 8))
1189
+ if (!access_ok(addr, 8))
19591190 goto sigbus;
19601191
19611192 value = regs->regs[reg];
....@@ -1985,20 +1216,20 @@
19851216 return;
19861217
19871218 die_if_kernel("Unhandled kernel unaligned access", regs);
1988
- force_sig(SIGSEGV, current);
1219
+ force_sig(SIGSEGV);
19891220
19901221 return;
19911222
19921223 sigbus:
19931224 die_if_kernel("Unhandled kernel unaligned access", regs);
1994
- force_sig(SIGBUS, current);
1225
+ force_sig(SIGBUS);
19951226
19961227 return;
19971228
19981229 sigill:
19991230 die_if_kernel
20001231 ("Unhandled kernel unaligned access or invalid instruction", regs);
2001
- force_sig(SIGILL, current);
1232
+ force_sig(SIGILL);
20021233 }
20031234
20041235 static void emulate_load_store_MIPS16e(struct pt_regs *regs, void __user * addr)
....@@ -2113,7 +1344,7 @@
21131344 goto sigbus;
21141345
21151346 case MIPS16e_lh_op:
2116
- if (!access_ok(VERIFY_READ, addr, 2))
1347
+ if (!access_ok(addr, 2))
21171348 goto sigbus;
21181349
21191350 LoadHW(addr, value, res);
....@@ -2124,7 +1355,7 @@
21241355 break;
21251356
21261357 case MIPS16e_lhu_op:
2127
- if (!access_ok(VERIFY_READ, addr, 2))
1358
+ if (!access_ok(addr, 2))
21281359 goto sigbus;
21291360
21301361 LoadHWU(addr, value, res);
....@@ -2137,7 +1368,7 @@
21371368 case MIPS16e_lw_op:
21381369 case MIPS16e_lwpc_op:
21391370 case MIPS16e_lwsp_op:
2140
- if (!access_ok(VERIFY_READ, addr, 4))
1371
+ if (!access_ok(addr, 4))
21411372 goto sigbus;
21421373
21431374 LoadW(addr, value, res);
....@@ -2156,7 +1387,7 @@
21561387 * would blow up, so for now we don't handle unaligned 64-bit
21571388 * instructions on 32-bit kernels.
21581389 */
2159
- if (!access_ok(VERIFY_READ, addr, 4))
1390
+ if (!access_ok(addr, 4))
21601391 goto sigbus;
21611392
21621393 LoadWU(addr, value, res);
....@@ -2180,7 +1411,7 @@
21801411 * would blow up, so for now we don't handle unaligned 64-bit
21811412 * instructions on 32-bit kernels.
21821413 */
2183
- if (!access_ok(VERIFY_READ, addr, 8))
1414
+ if (!access_ok(addr, 8))
21841415 goto sigbus;
21851416
21861417 LoadDW(addr, value, res);
....@@ -2195,7 +1426,7 @@
21951426 goto sigill;
21961427
21971428 case MIPS16e_sh_op:
2198
- if (!access_ok(VERIFY_WRITE, addr, 2))
1429
+ if (!access_ok(addr, 2))
21991430 goto sigbus;
22001431
22011432 MIPS16e_compute_return_epc(regs, &oldinst);
....@@ -2208,7 +1439,7 @@
22081439 case MIPS16e_sw_op:
22091440 case MIPS16e_swsp_op:
22101441 case MIPS16e_i8_op: /* actually - MIPS16e_swrasp_func */
2211
- if (!access_ok(VERIFY_WRITE, addr, 4))
1442
+ if (!access_ok(addr, 4))
22121443 goto sigbus;
22131444
22141445 MIPS16e_compute_return_epc(regs, &oldinst);
....@@ -2228,7 +1459,7 @@
22281459 * would blow up, so for now we don't handle unaligned 64-bit
22291460 * instructions on 32-bit kernels.
22301461 */
2231
- if (!access_ok(VERIFY_WRITE, addr, 8))
1462
+ if (!access_ok(addr, 8))
22321463 goto sigbus;
22331464
22341465 MIPS16e_compute_return_epc(regs, &oldinst);
....@@ -2265,20 +1496,20 @@
22651496 return;
22661497
22671498 die_if_kernel("Unhandled kernel unaligned access", regs);
2268
- force_sig(SIGSEGV, current);
1499
+ force_sig(SIGSEGV);
22691500
22701501 return;
22711502
22721503 sigbus:
22731504 die_if_kernel("Unhandled kernel unaligned access", regs);
2274
- force_sig(SIGBUS, current);
1505
+ force_sig(SIGBUS);
22751506
22761507 return;
22771508
22781509 sigill:
22791510 die_if_kernel
22801511 ("Unhandled kernel unaligned access or invalid instruction", regs);
2281
- force_sig(SIGILL, current);
1512
+ force_sig(SIGILL);
22821513 }
22831514
22841515 asmlinkage void do_ade(struct pt_regs *regs)
....@@ -2339,7 +1570,7 @@
23391570 set_fs(seg);
23401571
23411572 return;
2342
- }
1573
+ }
23431574
23441575 goto sigbus;
23451576 }
....@@ -2358,7 +1589,7 @@
23581589
23591590 sigbus:
23601591 die_if_kernel("Kernel unaligned instruction access", regs);
2361
- force_sig(SIGBUS, current);
1592
+ force_sig(SIGBUS);
23621593
23631594 /*
23641595 * XXX On return from the signal handler we should advance the epc
....@@ -2369,18 +1600,10 @@
23691600 #ifdef CONFIG_DEBUG_FS
23701601 static int __init debugfs_unaligned(void)
23711602 {
2372
- struct dentry *d;
2373
-
2374
- if (!mips_debugfs_dir)
2375
- return -ENODEV;
2376
- d = debugfs_create_u32("unaligned_instructions", S_IRUGO,
2377
- mips_debugfs_dir, &unaligned_instructions);
2378
- if (!d)
2379
- return -ENOMEM;
2380
- d = debugfs_create_u32("unaligned_action", S_IRUGO | S_IWUSR,
2381
- mips_debugfs_dir, &unaligned_action);
2382
- if (!d)
2383
- return -ENOMEM;
1603
+ debugfs_create_u32("unaligned_instructions", S_IRUGO, mips_debugfs_dir,
1604
+ &unaligned_instructions);
1605
+ debugfs_create_u32("unaligned_action", S_IRUGO | S_IWUSR,
1606
+ mips_debugfs_dir, &unaligned_action);
23841607 return 0;
23851608 }
23861609 arch_initcall(debugfs_unaligned);