diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2015-09-27 06:48:48 -0400 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2015-09-27 06:48:48 -0400 |
| commit | c905929ac9b94061b2c8226c5e47a26d30ed7ea1 (patch) | |
| tree | a08b07d08558691025c2a6c327903eb52fa71e33 | |
| parent | 685b5f1de6405bf87e38fed7c893a1de0a8d3218 (diff) | |
| parent | 274e91b81ed22957b510ad2988359584eea95dae (diff) | |
Merge branch 'fixes' of git://ftp.arm.linux.org.uk/~rmk/linux-arm
Pull ARM fixes from Russell King:
"Just two fixes: wire up the new system calls added during the last
merge window, and fix another user access site"
* 'fixes' of git://ftp.arm.linux.org.uk/~rmk/linux-arm:
ARM: alignment: fix alignment handling for uaccess changes
ARM: wire up new syscalls
| -rw-r--r-- | arch/arm/include/asm/unistd.h | 2 | ||||
| -rw-r--r-- | arch/arm/include/uapi/asm/unistd.h | 2 | ||||
| -rw-r--r-- | arch/arm/kernel/calls.S | 2 | ||||
| -rw-r--r-- | arch/arm/mm/alignment.c | 30 |
4 files changed, 30 insertions, 6 deletions
diff --git a/arch/arm/include/asm/unistd.h b/arch/arm/include/asm/unistd.h index 32640c431a08..7cba573c2cc9 100644 --- a/arch/arm/include/asm/unistd.h +++ b/arch/arm/include/asm/unistd.h | |||
| @@ -19,7 +19,7 @@ | |||
| 19 | * This may need to be greater than __NR_last_syscall+1 in order to | 19 | * This may need to be greater than __NR_last_syscall+1 in order to |
| 20 | * account for the padding in the syscall table | 20 | * account for the padding in the syscall table |
| 21 | */ | 21 | */ |
| 22 | #define __NR_syscalls (388) | 22 | #define __NR_syscalls (392) |
| 23 | 23 | ||
| 24 | /* | 24 | /* |
| 25 | * *NOTE*: This is a ghost syscall private to the kernel. Only the | 25 | * *NOTE*: This is a ghost syscall private to the kernel. Only the |
diff --git a/arch/arm/include/uapi/asm/unistd.h b/arch/arm/include/uapi/asm/unistd.h index 0c3f5a0dafd3..7a2a32a1d5a8 100644 --- a/arch/arm/include/uapi/asm/unistd.h +++ b/arch/arm/include/uapi/asm/unistd.h | |||
| @@ -414,6 +414,8 @@ | |||
| 414 | #define __NR_memfd_create (__NR_SYSCALL_BASE+385) | 414 | #define __NR_memfd_create (__NR_SYSCALL_BASE+385) |
| 415 | #define __NR_bpf (__NR_SYSCALL_BASE+386) | 415 | #define __NR_bpf (__NR_SYSCALL_BASE+386) |
| 416 | #define __NR_execveat (__NR_SYSCALL_BASE+387) | 416 | #define __NR_execveat (__NR_SYSCALL_BASE+387) |
| 417 | #define __NR_userfaultfd (__NR_SYSCALL_BASE+388) | ||
| 418 | #define __NR_membarrier (__NR_SYSCALL_BASE+389) | ||
| 417 | 419 | ||
| 418 | /* | 420 | /* |
| 419 | * The following SWIs are ARM private. | 421 | * The following SWIs are ARM private. |
diff --git a/arch/arm/kernel/calls.S b/arch/arm/kernel/calls.S index 05745eb838c5..fde6c88d560c 100644 --- a/arch/arm/kernel/calls.S +++ b/arch/arm/kernel/calls.S | |||
| @@ -397,6 +397,8 @@ | |||
| 397 | /* 385 */ CALL(sys_memfd_create) | 397 | /* 385 */ CALL(sys_memfd_create) |
| 398 | CALL(sys_bpf) | 398 | CALL(sys_bpf) |
| 399 | CALL(sys_execveat) | 399 | CALL(sys_execveat) |
| 400 | CALL(sys_userfaultfd) | ||
| 401 | CALL(sys_membarrier) | ||
| 400 | #ifndef syscalls_counted | 402 | #ifndef syscalls_counted |
| 401 | .equ syscalls_padding, ((NR_syscalls + 3) & ~3) - NR_syscalls | 403 | .equ syscalls_padding, ((NR_syscalls + 3) & ~3) - NR_syscalls |
| 402 | #define syscalls_counted | 404 | #define syscalls_counted |
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) |
