diff options
Diffstat (limited to 'arch/arm/mm/alignment.c')
-rw-r--r-- | arch/arm/mm/alignment.c | 30 |
1 files changed, 25 insertions, 5 deletions
diff --git a/arch/arm/mm/alignment.c b/arch/arm/mm/alignment.c index 9769f1eefe3b..00b7f7de28a1 100644 --- a/arch/arm/mm/alignment.c +++ b/arch/arm/mm/alignment.c | |||
@@ -365,15 +365,21 @@ do_alignment_ldrhstrh(unsigned long addr, unsigned long instr, struct pt_regs *r | |||
365 | user: | 365 | user: |
366 | if (LDST_L_BIT(instr)) { | 366 | if (LDST_L_BIT(instr)) { |
367 | unsigned long val; | 367 | unsigned long val; |
368 | unsigned int __ua_flags = uaccess_save_and_enable(); | ||
369 | |||
368 | get16t_unaligned_check(val, addr); | 370 | get16t_unaligned_check(val, addr); |
371 | uaccess_restore(__ua_flags); | ||
369 | 372 | ||
370 | /* signed half-word? */ | 373 | /* signed half-word? */ |
371 | if (instr & 0x40) | 374 | if (instr & 0x40) |
372 | val = (signed long)((signed short) val); | 375 | val = (signed long)((signed short) val); |
373 | 376 | ||
374 | regs->uregs[rd] = val; | 377 | regs->uregs[rd] = val; |
375 | } else | 378 | } else { |
379 | unsigned int __ua_flags = uaccess_save_and_enable(); | ||
376 | put16t_unaligned_check(regs->uregs[rd], addr); | 380 | put16t_unaligned_check(regs->uregs[rd], addr); |
381 | uaccess_restore(__ua_flags); | ||
382 | } | ||
377 | 383 | ||
378 | return TYPE_LDST; | 384 | return TYPE_LDST; |
379 | 385 | ||
@@ -420,14 +426,21 @@ do_alignment_ldrdstrd(unsigned long addr, unsigned long instr, | |||
420 | 426 | ||
421 | user: | 427 | user: |
422 | if (load) { | 428 | if (load) { |
423 | unsigned long val; | 429 | unsigned long val, val2; |
430 | unsigned int __ua_flags = uaccess_save_and_enable(); | ||
431 | |||
424 | get32t_unaligned_check(val, addr); | 432 | get32t_unaligned_check(val, addr); |
433 | get32t_unaligned_check(val2, addr + 4); | ||
434 | |||
435 | uaccess_restore(__ua_flags); | ||
436 | |||
425 | regs->uregs[rd] = val; | 437 | regs->uregs[rd] = val; |
426 | get32t_unaligned_check(val, addr + 4); | 438 | regs->uregs[rd2] = val2; |
427 | regs->uregs[rd2] = val; | ||
428 | } else { | 439 | } else { |
440 | unsigned int __ua_flags = uaccess_save_and_enable(); | ||
429 | put32t_unaligned_check(regs->uregs[rd], addr); | 441 | put32t_unaligned_check(regs->uregs[rd], addr); |
430 | put32t_unaligned_check(regs->uregs[rd2], addr + 4); | 442 | put32t_unaligned_check(regs->uregs[rd2], addr + 4); |
443 | uaccess_restore(__ua_flags); | ||
431 | } | 444 | } |
432 | 445 | ||
433 | return TYPE_LDST; | 446 | return TYPE_LDST; |
@@ -458,10 +471,15 @@ do_alignment_ldrstr(unsigned long addr, unsigned long instr, struct pt_regs *reg | |||
458 | trans: | 471 | trans: |
459 | if (LDST_L_BIT(instr)) { | 472 | if (LDST_L_BIT(instr)) { |
460 | unsigned int val; | 473 | unsigned int val; |
474 | unsigned int __ua_flags = uaccess_save_and_enable(); | ||
461 | get32t_unaligned_check(val, addr); | 475 | get32t_unaligned_check(val, addr); |
476 | uaccess_restore(__ua_flags); | ||
462 | regs->uregs[rd] = val; | 477 | regs->uregs[rd] = val; |
463 | } else | 478 | } else { |
479 | unsigned int __ua_flags = uaccess_save_and_enable(); | ||
464 | put32t_unaligned_check(regs->uregs[rd], addr); | 480 | put32t_unaligned_check(regs->uregs[rd], addr); |
481 | uaccess_restore(__ua_flags); | ||
482 | } | ||
465 | return TYPE_LDST; | 483 | return TYPE_LDST; |
466 | 484 | ||
467 | fault: | 485 | fault: |
@@ -531,6 +549,7 @@ do_alignment_ldmstm(unsigned long addr, unsigned long instr, struct pt_regs *reg | |||
531 | #endif | 549 | #endif |
532 | 550 | ||
533 | if (user_mode(regs)) { | 551 | if (user_mode(regs)) { |
552 | unsigned int __ua_flags = uaccess_save_and_enable(); | ||
534 | for (regbits = REGMASK_BITS(instr), rd = 0; regbits; | 553 | for (regbits = REGMASK_BITS(instr), rd = 0; regbits; |
535 | regbits >>= 1, rd += 1) | 554 | regbits >>= 1, rd += 1) |
536 | if (regbits & 1) { | 555 | if (regbits & 1) { |
@@ -542,6 +561,7 @@ do_alignment_ldmstm(unsigned long addr, unsigned long instr, struct pt_regs *reg | |||
542 | put32t_unaligned_check(regs->uregs[rd], eaddr); | 561 | put32t_unaligned_check(regs->uregs[rd], eaddr); |
543 | eaddr += 4; | 562 | eaddr += 4; |
544 | } | 563 | } |
564 | uaccess_restore(__ua_flags); | ||
545 | } else { | 565 | } else { |
546 | for (regbits = REGMASK_BITS(instr), rd = 0; regbits; | 566 | for (regbits = REGMASK_BITS(instr), rd = 0; regbits; |
547 | regbits >>= 1, rd += 1) | 567 | regbits >>= 1, rd += 1) |