Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

arc: use generic strncpy/strnlen from_user

Remove the arc implemenation of strncpy/strnlen and instead use the
generic versions. The arc version is fairly slow because it always does
byte accesses even for aligned data, and its checks for user_addr_max()
differ from the generic code.

Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Arnd Bergmann <arnd@arndb.de>

+7 -90
+2
arch/arc/Kconfig
··· 27 27 select GENERIC_PENDING_IRQ if SMP 28 28 select GENERIC_SCHED_CLOCK 29 29 select GENERIC_SMP_IDLE_THREAD 30 + select GENERIC_STRNCPY_FROM_USER 31 + select GENERIC_STRNLEN_USER 30 32 select HAVE_ARCH_KGDB 31 33 select HAVE_ARCH_TRACEHOOK 32 34 select HAVE_ARCH_TRANSPARENT_HUGEPAGE if ARC_MMU_V4
+5 -78
arch/arc/include/asm/uaccess.h
··· 655 655 return res; 656 656 } 657 657 658 - static inline long 659 - __arc_strncpy_from_user(char *dst, const char __user *src, long count) 660 - { 661 - long res = 0; 662 - char val; 663 - 664 - if (!access_ok(src, 1)) 665 - return -EFAULT; 666 - 667 - if (count == 0) 668 - return 0; 669 - 670 - __asm__ __volatile__( 671 - " mov lp_count, %5 \n" 672 - " lp 3f \n" 673 - "1: ldb.ab %3, [%2, 1] \n" 674 - " breq.d %3, 0, 3f \n" 675 - " stb.ab %3, [%1, 1] \n" 676 - " add %0, %0, 1 # Num of NON NULL bytes copied \n" 677 - "3: \n" 678 - " .section .fixup, \"ax\" \n" 679 - " .align 4 \n" 680 - "4: mov %0, %4 # sets @res as -EFAULT \n" 681 - " j 3b \n" 682 - " .previous \n" 683 - " .section __ex_table, \"a\" \n" 684 - " .align 4 \n" 685 - " .word 1b, 4b \n" 686 - " .previous \n" 687 - : "+r"(res), "+r"(dst), "+r"(src), "=r"(val) 688 - : "g"(-EFAULT), "r"(count) 689 - : "lp_count", "memory"); 690 - 691 - return res; 692 - } 693 - 694 - static inline long __arc_strnlen_user(const char __user *s, long n) 695 - { 696 - long res, tmp1, cnt; 697 - char val; 698 - 699 - if (!access_ok(s, 1)) 700 - return 0; 701 - 702 - __asm__ __volatile__( 703 - " mov %2, %1 \n" 704 - "1: ldb.ab %3, [%0, 1] \n" 705 - " breq.d %3, 0, 2f \n" 706 - " sub.f %2, %2, 1 \n" 707 - " bnz 1b \n" 708 - " sub %2, %2, 1 \n" 709 - "2: sub %0, %1, %2 \n" 710 - "3: ;nop \n" 711 - " .section .fixup, \"ax\" \n" 712 - " .align 4 \n" 713 - "4: mov %0, 0 \n" 714 - " j 3b \n" 715 - " .previous \n" 716 - " .section __ex_table, \"a\" \n" 717 - " .align 4 \n" 718 - " .word 1b, 4b \n" 719 - " .previous \n" 720 - : "=r"(res), "=r"(tmp1), "=r"(cnt), "=r"(val) 721 - : "0"(s), "1"(n) 722 - : "memory"); 723 - 724 - return res; 725 - } 726 - 727 658 #ifndef CONFIG_CC_OPTIMIZE_FOR_SIZE 728 659 729 660 #define INLINE_COPY_TO_USER 730 661 #define INLINE_COPY_FROM_USER 731 662 732 663 #define __clear_user(d, n) __arc_clear_user(d, n) 733 - #define strncpy_from_user(d, s, n) __arc_strncpy_from_user(d, s, n) 734 - #define strnlen_user(s, n) __arc_strnlen_user(s, n) 735 664 #else 736 665 extern unsigned long arc_clear_user_noinline(void __user *to, 737 666 unsigned long n); 738 - extern long arc_strncpy_from_user_noinline (char *dst, const char __user *src, 739 - long count); 740 - extern long arc_strnlen_user_noinline(const char __user *src, long n); 741 - 742 667 #define __clear_user(d, n) arc_clear_user_noinline(d, n) 743 - #define strncpy_from_user(d, s, n) arc_strncpy_from_user_noinline(d, s, n) 744 - #define strnlen_user(s, n) arc_strnlen_user_noinline(s, n) 745 - 746 668 #endif 669 + 670 + extern long strncpy_from_user(char *dst, const char __user *src, long count); 671 + #define strncpy_from_user(d, s, n) strncpy_from_user(d, s, n) 672 + extern long strnlen_user(const char __user *src, long n); 673 + #define strnlen_user(s, n) strnlen_user(s, n) 747 674 748 675 #include <asm/segment.h> 749 676 #include <asm-generic/uaccess.h>
-12
arch/arc/mm/extable.c
··· 32 32 } 33 33 EXPORT_SYMBOL(arc_clear_user_noinline); 34 34 35 - long arc_strncpy_from_user_noinline(char *dst, const char __user *src, 36 - long count) 37 - { 38 - return __arc_strncpy_from_user(dst, src, count); 39 - } 40 - EXPORT_SYMBOL(arc_strncpy_from_user_noinline); 41 - 42 - long arc_strnlen_user_noinline(const char __user *src, long n) 43 - { 44 - return __arc_strnlen_user(src, n); 45 - } 46 - EXPORT_SYMBOL(arc_strnlen_user_noinline); 47 35 #endif