aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/arm/include/asm/unistd.h2
-rw-r--r--arch/arm/include/uapi/asm/unistd.h2
-rw-r--r--arch/arm/kernel/calls.S2
-rw-r--r--arch/arm/mm/alignment.c30
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)