aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mm/alignment.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/mm/alignment.c')
-rw-r--r--arch/arm/mm/alignment.c30
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)