Hi Jing, Thank you for the patch! Perhaps something to improve: [auto build test WARNING on arm/for-next] [cannot apply to v5.3-rc6 next-20190830] [if your patch is applied to the wrong git tree, please drop us a note to help improve the system] url: https://github.com/0day-ci/linux/commits/Jing-Xiangfeng/arm-fix-page-faults-in-do_alignment/20190831-173417 base: git://git.armlinux.org.uk/~rmk/linux-arm.git for-next config: arm-allmodconfig (attached as .config) compiler: arm-linux-gnueabi-gcc (GCC) 7.4.0 reproduce: wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross chmod +x ~/bin/make.cross # save the attached .config to linux build tree GCC_VERSION=7.4.0 make.cross ARCH=arm If you fix the issue, kindly add following tag Reported-by: kbuild test robot <lkp@xxxxxxxxx> All warnings (new ones prefixed by >>): arch/arm/mm/alignment.c: In function 'do_alignment': >> arch/arm/mm/alignment.c:792:28: warning: passing argument 1 of '__copy_from_user' makes pointer from integer without a cast [-Wint-conversion] fault = __copy_from_user(tinstr, ^~~~~~ In file included from include/linux/sched/task.h:11:0, from include/linux/sched/signal.h:9, from arch/arm/mm/alignment.c:20: include/linux/uaccess.h:67:1: note: expected 'void *' but argument is of type 'u16 {aka short unsigned int}' __copy_from_user(void *to, const void __user *from, unsigned long n) ^~~~~~~~~~~~~~~~ arch/arm/mm/alignment.c:801:30: warning: passing argument 1 of '__copy_from_user' makes pointer from integer without a cast [-Wint-conversion] fault = __copy_from_user(tinst2, ^~~~~~ In file included from include/linux/sched/task.h:11:0, from include/linux/sched/signal.h:9, from arch/arm/mm/alignment.c:20: include/linux/uaccess.h:67:1: note: expected 'void *' but argument is of type 'u16 {aka short unsigned int}' __copy_from_user(void *to, const void __user *from, unsigned long n) ^~~~~~~~~~~~~~~~ arch/arm/mm/alignment.c:813:28: warning: passing argument 1 of '__copy_from_user' makes pointer from integer without a cast [-Wint-conversion] fault = __copy_from_user(instr, ^~~~~ In file included from include/linux/sched/task.h:11:0, from include/linux/sched/signal.h:9, from arch/arm/mm/alignment.c:20: include/linux/uaccess.h:67:1: note: expected 'void *' but argument is of type 'long unsigned int' __copy_from_user(void *to, const void __user *from, unsigned long n) ^~~~~~~~~~~~~~~~ vim +/__copy_from_user +792 arch/arm/mm/alignment.c 769 770 static int 771 do_alignment(unsigned long addr, unsigned int fsr, struct pt_regs *regs) 772 { 773 union offset_union uninitialized_var(offset); 774 unsigned long instr = 0, instrptr; 775 int (*handler)(unsigned long addr, unsigned long instr, struct pt_regs *regs); 776 unsigned int type; 777 mm_segment_t fs; 778 unsigned int fault; 779 u16 tinstr = 0; 780 int isize = 4; 781 int thumb2_32b = 0; 782 783 if (interrupts_enabled(regs)) 784 local_irq_enable(); 785 786 instrptr = instruction_pointer(regs); 787 788 fs = get_fs(); 789 set_fs(KERNEL_DS); 790 if (thumb_mode(regs)) { 791 u16 *ptr = (u16 *)(instrptr & ~1); > 792 fault = __copy_from_user(tinstr, 793 (__force const void __user *)ptr, 794 sizeof(tinstr)); 795 tinstr = __mem_to_opcode_thumb16(tinstr); 796 if (!fault) { 797 if (cpu_architecture() >= CPU_ARCH_ARMv7 && 798 IS_T32(tinstr)) { 799 /* Thumb-2 32-bit */ 800 u16 tinst2 = 0; 801 fault = __copy_from_user(tinst2, 802 (__force const void __user *)(ptr+1), 803 sizeof(tinst2)); 804 tinst2 = __mem_to_opcode_thumb16(tinst2); 805 instr = __opcode_thumb32_compose(tinstr, tinst2); 806 thumb2_32b = 1; 807 } else { 808 isize = 2; 809 instr = thumb2arm(tinstr); 810 } 811 } 812 } else { 813 fault = __copy_from_user(instr, 814 (__force const void __user *)instrptr, 815 sizeof(instr)); 816 instr = __mem_to_opcode_arm(instr); 817 } 818 819 set_fs(fs); 820 if (fault) { 821 type = TYPE_FAULT; 822 goto bad_or_fault; 823 } 824 825 if (user_mode(regs)) 826 goto user; 827 828 ai_sys += 1; 829 ai_sys_last_pc = (void *)instruction_pointer(regs); 830 831 fixup: 832 833 regs->ARM_pc += isize; 834 835 switch (CODING_BITS(instr)) { 836 case 0x00000000: /* 3.13.4 load/store instruction extensions */ 837 if (LDSTHD_I_BIT(instr)) 838 offset.un = (instr & 0xf00) >> 4 | (instr & 15); 839 else 840 offset.un = regs->uregs[RM_BITS(instr)]; 841 842 if ((instr & 0x000000f0) == 0x000000b0 || /* LDRH, STRH */ 843 (instr & 0x001000f0) == 0x001000f0) /* LDRSH */ 844 handler = do_alignment_ldrhstrh; 845 else if ((instr & 0x001000f0) == 0x000000d0 || /* LDRD */ 846 (instr & 0x001000f0) == 0x000000f0) /* STRD */ 847 handler = do_alignment_ldrdstrd; 848 else if ((instr & 0x01f00ff0) == 0x01000090) /* SWP */ 849 goto swp; 850 else 851 goto bad; 852 break; 853 854 case 0x04000000: /* ldr or str immediate */ 855 if (COND_BITS(instr) == 0xf0000000) /* NEON VLDn, VSTn */ 856 goto bad; 857 offset.un = OFFSET_BITS(instr); 858 handler = do_alignment_ldrstr; 859 break; 860 861 case 0x06000000: /* ldr or str register */ 862 offset.un = regs->uregs[RM_BITS(instr)]; 863 864 if (IS_SHIFT(instr)) { 865 unsigned int shiftval = SHIFT_BITS(instr); 866 867 switch(SHIFT_TYPE(instr)) { 868 case SHIFT_LSL: 869 offset.un <<= shiftval; 870 break; 871 872 case SHIFT_LSR: 873 offset.un >>= shiftval; 874 break; 875 876 case SHIFT_ASR: 877 offset.sn >>= shiftval; 878 break; 879 880 case SHIFT_RORRRX: 881 if (shiftval == 0) { 882 offset.un >>= 1; 883 if (regs->ARM_cpsr & PSR_C_BIT) 884 offset.un |= 1 << 31; 885 } else 886 offset.un = offset.un >> shiftval | 887 offset.un << (32 - shiftval); 888 break; 889 } 890 } 891 handler = do_alignment_ldrstr; 892 break; 893 894 case 0x08000000: /* ldm or stm, or thumb-2 32bit instruction */ 895 if (thumb2_32b) { 896 offset.un = 0; 897 handler = do_alignment_t32_to_handler(&instr, regs, &offset); 898 } else { 899 offset.un = 0; 900 handler = do_alignment_ldmstm; 901 } 902 break; 903 904 default: 905 goto bad; 906 } 907 908 if (!handler) 909 goto bad; 910 type = handler(addr, instr, regs); 911 912 if (type == TYPE_ERROR || type == TYPE_FAULT) { 913 regs->ARM_pc -= isize; 914 goto bad_or_fault; 915 } 916 917 if (type == TYPE_LDST) 918 do_alignment_finish_ldst(addr, instr, regs, offset); 919 920 return 0; 921 922 bad_or_fault: 923 if (type == TYPE_ERROR) 924 goto bad; 925 /* 926 * We got a fault - fix it up, or die. 927 */ 928 do_bad_area(addr, fsr, regs); 929 return 0; 930 931 swp: 932 pr_err("Alignment trap: not handling swp instruction\n"); 933 934 bad: 935 /* 936 * Oops, we didn't handle the instruction. 937 */ 938 pr_err("Alignment trap: not handling instruction " 939 "%0*lx at [<%08lx>]\n", 940 isize << 1, 941 isize == 2 ? tinstr : instr, instrptr); 942 ai_skipped += 1; 943 return 1; 944 945 user: 946 ai_user += 1; 947 948 if (ai_usermode & UM_WARN) 949 printk("Alignment trap: %s (%d) PC=0x%08lx Instr=0x%0*lx " 950 "Address=0x%08lx FSR 0x%03x\n", current->comm, 951 task_pid_nr(current), instrptr, 952 isize << 1, 953 isize == 2 ? tinstr : instr, 954 addr, fsr); 955 956 if (ai_usermode & UM_FIXUP) 957 goto fixup; 958 959 if (ai_usermode & UM_SIGNAL) { 960 force_sig_fault(SIGBUS, BUS_ADRALN, (void __user *)addr); 961 } else { 962 /* 963 * We're about to disable the alignment trap and return to 964 * user space. But if an interrupt occurs before actually 965 * reaching user space, then the IRQ vector entry code will 966 * notice that we were still in kernel space and therefore 967 * the alignment trap won't be re-enabled in that case as it 968 * is presumed to be always on from kernel space. 969 * Let's prevent that race by disabling interrupts here (they 970 * are disabled on the way back to user space anyway in 971 * entry-common.S) and disable the alignment trap only if 972 * there is no work pending for this thread. 973 */ 974 raw_local_irq_disable(); 975 if (!(current_thread_info()->flags & _TIF_WORK_MASK)) 976 set_cr(cr_no_alignment); 977 } 978 979 return 0; 980 } 981 --- 0-DAY kernel test infrastructure Open Source Technology Center https://lists.01.org/pipermail/kbuild-all Intel Corporation
Attachment:
.config.gz
Description: application/gzip