Commit c905929a authored by Linus Torvalds's avatar Linus Torvalds

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
parents 685b5f1d 274e91b8
...@@ -19,7 +19,7 @@ ...@@ -19,7 +19,7 @@
* This may need to be greater than __NR_last_syscall+1 in order to * This may need to be greater than __NR_last_syscall+1 in order to
* account for the padding in the syscall table * account for the padding in the syscall table
*/ */
#define __NR_syscalls (388) #define __NR_syscalls (392)
/* /*
* *NOTE*: This is a ghost syscall private to the kernel. Only the * *NOTE*: This is a ghost syscall private to the kernel. Only the
......
...@@ -414,6 +414,8 @@ ...@@ -414,6 +414,8 @@
#define __NR_memfd_create (__NR_SYSCALL_BASE+385) #define __NR_memfd_create (__NR_SYSCALL_BASE+385)
#define __NR_bpf (__NR_SYSCALL_BASE+386) #define __NR_bpf (__NR_SYSCALL_BASE+386)
#define __NR_execveat (__NR_SYSCALL_BASE+387) #define __NR_execveat (__NR_SYSCALL_BASE+387)
#define __NR_userfaultfd (__NR_SYSCALL_BASE+388)
#define __NR_membarrier (__NR_SYSCALL_BASE+389)
/* /*
* The following SWIs are ARM private. * The following SWIs are ARM private.
......
...@@ -397,6 +397,8 @@ ...@@ -397,6 +397,8 @@
/* 385 */ CALL(sys_memfd_create) /* 385 */ CALL(sys_memfd_create)
CALL(sys_bpf) CALL(sys_bpf)
CALL(sys_execveat) CALL(sys_execveat)
CALL(sys_userfaultfd)
CALL(sys_membarrier)
#ifndef syscalls_counted #ifndef syscalls_counted
.equ syscalls_padding, ((NR_syscalls + 3) & ~3) - NR_syscalls .equ syscalls_padding, ((NR_syscalls + 3) & ~3) - NR_syscalls
#define syscalls_counted #define syscalls_counted
......
...@@ -365,15 +365,21 @@ do_alignment_ldrhstrh(unsigned long addr, unsigned long instr, struct pt_regs *r ...@@ -365,15 +365,21 @@ do_alignment_ldrhstrh(unsigned long addr, unsigned long instr, struct pt_regs *r
user: user:
if (LDST_L_BIT(instr)) { if (LDST_L_BIT(instr)) {
unsigned long val; unsigned long val;
unsigned int __ua_flags = uaccess_save_and_enable();
get16t_unaligned_check(val, addr); get16t_unaligned_check(val, addr);
uaccess_restore(__ua_flags);
/* signed half-word? */ /* signed half-word? */
if (instr & 0x40) if (instr & 0x40)
val = (signed long)((signed short) val); val = (signed long)((signed short) val);
regs->uregs[rd] = val; regs->uregs[rd] = val;
} else } else {
unsigned int __ua_flags = uaccess_save_and_enable();
put16t_unaligned_check(regs->uregs[rd], addr); put16t_unaligned_check(regs->uregs[rd], addr);
uaccess_restore(__ua_flags);
}
return TYPE_LDST; return TYPE_LDST;
...@@ -420,14 +426,21 @@ do_alignment_ldrdstrd(unsigned long addr, unsigned long instr, ...@@ -420,14 +426,21 @@ do_alignment_ldrdstrd(unsigned long addr, unsigned long instr,
user: user:
if (load) { if (load) {
unsigned long val; unsigned long val, val2;
unsigned int __ua_flags = uaccess_save_and_enable();
get32t_unaligned_check(val, addr); get32t_unaligned_check(val, addr);
get32t_unaligned_check(val2, addr + 4);
uaccess_restore(__ua_flags);
regs->uregs[rd] = val; regs->uregs[rd] = val;
get32t_unaligned_check(val, addr + 4); regs->uregs[rd2] = val2;
regs->uregs[rd2] = val;
} else { } else {
unsigned int __ua_flags = uaccess_save_and_enable();
put32t_unaligned_check(regs->uregs[rd], addr); put32t_unaligned_check(regs->uregs[rd], addr);
put32t_unaligned_check(regs->uregs[rd2], addr + 4); put32t_unaligned_check(regs->uregs[rd2], addr + 4);
uaccess_restore(__ua_flags);
} }
return TYPE_LDST; return TYPE_LDST;
...@@ -458,10 +471,15 @@ do_alignment_ldrstr(unsigned long addr, unsigned long instr, struct pt_regs *reg ...@@ -458,10 +471,15 @@ do_alignment_ldrstr(unsigned long addr, unsigned long instr, struct pt_regs *reg
trans: trans:
if (LDST_L_BIT(instr)) { if (LDST_L_BIT(instr)) {
unsigned int val; unsigned int val;
unsigned int __ua_flags = uaccess_save_and_enable();
get32t_unaligned_check(val, addr); get32t_unaligned_check(val, addr);
uaccess_restore(__ua_flags);
regs->uregs[rd] = val; regs->uregs[rd] = val;
} else } else {
unsigned int __ua_flags = uaccess_save_and_enable();
put32t_unaligned_check(regs->uregs[rd], addr); put32t_unaligned_check(regs->uregs[rd], addr);
uaccess_restore(__ua_flags);
}
return TYPE_LDST; return TYPE_LDST;
fault: fault:
...@@ -531,6 +549,7 @@ do_alignment_ldmstm(unsigned long addr, unsigned long instr, struct pt_regs *reg ...@@ -531,6 +549,7 @@ do_alignment_ldmstm(unsigned long addr, unsigned long instr, struct pt_regs *reg
#endif #endif
if (user_mode(regs)) { if (user_mode(regs)) {
unsigned int __ua_flags = uaccess_save_and_enable();
for (regbits = REGMASK_BITS(instr), rd = 0; regbits; for (regbits = REGMASK_BITS(instr), rd = 0; regbits;
regbits >>= 1, rd += 1) regbits >>= 1, rd += 1)
if (regbits & 1) { if (regbits & 1) {
...@@ -542,6 +561,7 @@ do_alignment_ldmstm(unsigned long addr, unsigned long instr, struct pt_regs *reg ...@@ -542,6 +561,7 @@ do_alignment_ldmstm(unsigned long addr, unsigned long instr, struct pt_regs *reg
put32t_unaligned_check(regs->uregs[rd], eaddr); put32t_unaligned_check(regs->uregs[rd], eaddr);
eaddr += 4; eaddr += 4;
} }
uaccess_restore(__ua_flags);
} else { } else {
for (regbits = REGMASK_BITS(instr), rd = 0; regbits; for (regbits = REGMASK_BITS(instr), rd = 0; regbits;
regbits >>= 1, rd += 1) regbits >>= 1, rd += 1)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment