瀏覽代碼

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
Linus Torvalds 10 年之前
父節點
當前提交
c905929ac9
共有 4 個文件被更改,包括 30 次插入6 次删除
  1. 1 1
      arch/arm/include/asm/unistd.h
  2. 2 0
      arch/arm/include/uapi/asm/unistd.h
  3. 2 0
      arch/arm/kernel/calls.S
  4. 25 5
      arch/arm/mm/alignment.c

+ 1 - 1
arch/arm/include/asm/unistd.h

@@ -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

+ 2 - 0
arch/arm/include/uapi/asm/unistd.h

@@ -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.

+ 2 - 0
arch/arm/kernel/calls.S

@@ -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

+ 25 - 5
arch/arm/mm/alignment.c

@@ -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,
 
 
  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] = val;
+		regs->uregs[rd2] = val2;
 	} 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
  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
 #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
 					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)