hc
2023-12-11 d2ccde1c8e90d38cee87a1b0309ad2827f3fd30d
kernel/arch/arm/mm/alignment.c
....@@ -1,3 +1,4 @@
1
+// SPDX-License-Identifier: GPL-2.0-only
12 /*
23 * linux/arch/arm/mm/alignment.c
34 *
....@@ -6,10 +7,6 @@
67 * Thumb alignment fault fixups (c) 2004 MontaVista Software, Inc.
78 * - Adapted from gdb/sim/arm/thumbemu.c -- Thumb instruction emulation.
89 * Copyright (C) 1996, Cygnus Software Technologies Ltd.
9
- *
10
- * This program is free software; you can redistribute it and/or modify
11
- * it under the terms of the GNU General Public License version 2 as
12
- * published by the Free Software Foundation.
1310 */
1411 #include <linux/moduleparam.h>
1512 #include <linux/compiler.h>
....@@ -133,7 +130,7 @@
133130 static int alignment_proc_show(struct seq_file *m, void *v)
134131 {
135132 seq_printf(m, "User:\t\t%lu\n", ai_user);
136
- seq_printf(m, "System:\t\t%lu (%pF)\n", ai_sys, ai_sys_last_pc);
133
+ seq_printf(m, "System:\t\t%lu (%pS)\n", ai_sys, ai_sys_last_pc);
137134 seq_printf(m, "Skipped:\t%lu\n", ai_skipped);
138135 seq_printf(m, "Half:\t\t%lu\n", ai_half);
139136 seq_printf(m, "Word:\t\t%lu\n", ai_word);
....@@ -165,12 +162,12 @@
165162 return count;
166163 }
167164
168
-static const struct file_operations alignment_proc_fops = {
169
- .open = alignment_proc_open,
170
- .read = seq_read,
171
- .llseek = seq_lseek,
172
- .release = single_release,
173
- .write = alignment_proc_write,
165
+static const struct proc_ops alignment_proc_ops = {
166
+ .proc_open = alignment_proc_open,
167
+ .proc_read = seq_read,
168
+ .proc_lseek = seq_lseek,
169
+ .proc_release = single_release,
170
+ .proc_write = alignment_proc_write,
174171 };
175172 #endif /* CONFIG_PROC_FS */
176173
....@@ -327,7 +324,7 @@
327324 __put32_unaligned_check("strbt", val, addr)
328325
329326 static void
330
-do_alignment_finish_ldst(unsigned long addr, unsigned long instr, struct pt_regs *regs, union offset_union offset)
327
+do_alignment_finish_ldst(unsigned long addr, u32 instr, struct pt_regs *regs, union offset_union offset)
331328 {
332329 if (!LDST_U_BIT(instr))
333330 offset.un = -offset.un;
....@@ -340,7 +337,7 @@
340337 }
341338
342339 static int
343
-do_alignment_ldrhstrh(unsigned long addr, unsigned long instr, struct pt_regs *regs)
340
+do_alignment_ldrhstrh(unsigned long addr, u32 instr, struct pt_regs *regs)
344341 {
345342 unsigned int rd = RD_BITS(instr);
346343
....@@ -389,8 +386,7 @@
389386 }
390387
391388 static int
392
-do_alignment_ldrdstrd(unsigned long addr, unsigned long instr,
393
- struct pt_regs *regs)
389
+do_alignment_ldrdstrd(unsigned long addr, u32 instr, struct pt_regs *regs)
394390 {
395391 unsigned int rd = RD_BITS(instr);
396392 unsigned int rd2;
....@@ -452,7 +448,7 @@
452448 }
453449
454450 static int
455
-do_alignment_ldrstr(unsigned long addr, unsigned long instr, struct pt_regs *regs)
451
+do_alignment_ldrstr(unsigned long addr, u32 instr, struct pt_regs *regs)
456452 {
457453 unsigned int rd = RD_BITS(instr);
458454
....@@ -501,7 +497,7 @@
501497 * PU = 10 A B
502498 */
503499 static int
504
-do_alignment_ldmstm(unsigned long addr, unsigned long instr, struct pt_regs *regs)
500
+do_alignment_ldmstm(unsigned long addr, u32 instr, struct pt_regs *regs)
505501 {
506502 unsigned int rd, rn, correction, nr_regs, regbits;
507503 unsigned long eaddr, newaddr;
....@@ -542,7 +538,7 @@
542538 * processor for us.
543539 */
544540 if (addr != eaddr) {
545
- pr_err("LDMSTM: PC = %08lx, instr = %08lx, "
541
+ pr_err("LDMSTM: PC = %08lx, instr = %08x, "
546542 "addr = %08lx, eaddr = %08lx\n",
547543 instruction_pointer(regs), instr, addr, eaddr);
548544 show_regs(regs);
....@@ -698,7 +694,7 @@
698694 return subset[(L<<1) | ((tinstr & (1<<8)) >> 8)] |
699695 (tinstr & 255); /* register_list */
700696 }
701
- /* Else fall through for illegal instruction case */
697
+ fallthrough; /* for illegal instruction case */
702698
703699 default:
704700 return BAD_INSTR;
....@@ -719,10 +715,10 @@
719715 * 2. Register name Rt from ARMv7 is same as Rd from ARMv6 (Rd is Rt)
720716 */
721717 static void *
722
-do_alignment_t32_to_handler(unsigned long *pinstr, struct pt_regs *regs,
718
+do_alignment_t32_to_handler(u32 *pinstr, struct pt_regs *regs,
723719 union offset_union *poffset)
724720 {
725
- unsigned long instr = *pinstr;
721
+ u32 instr = *pinstr;
726722 u16 tinst1 = (instr >> 16) & 0xffff;
727723 u16 tinst2 = instr & 0xffff;
728724
....@@ -754,6 +750,8 @@
754750 case 0xe8e0:
755751 case 0xe9e0:
756752 poffset->un = (tinst2 & 0xff) << 2;
753
+ fallthrough;
754
+
757755 case 0xe940:
758756 case 0xe9c0:
759757 return do_alignment_ldrdstrd;
....@@ -768,7 +766,7 @@
768766 return NULL;
769767 }
770768
771
-static int alignment_get_arm(struct pt_regs *regs, u32 *ip, unsigned long *inst)
769
+static int alignment_get_arm(struct pt_regs *regs, u32 *ip, u32 *inst)
772770 {
773771 u32 instr = 0;
774772 int fault;
....@@ -776,7 +774,7 @@
776774 if (user_mode(regs))
777775 fault = get_user(instr, ip);
778776 else
779
- fault = probe_kernel_address(ip, instr);
777
+ fault = get_kernel_nofault(instr, ip);
780778
781779 *inst = __mem_to_opcode_arm(instr);
782780
....@@ -791,7 +789,7 @@
791789 if (user_mode(regs))
792790 fault = get_user(instr, ip);
793791 else
794
- fault = probe_kernel_address(ip, instr);
792
+ fault = get_kernel_nofault(instr, ip);
795793
796794 *inst = __mem_to_opcode_thumb16(instr);
797795
....@@ -801,10 +799,11 @@
801799 static int
802800 do_alignment(unsigned long addr, unsigned int fsr, struct pt_regs *regs)
803801 {
804
- union offset_union uninitialized_var(offset);
805
- unsigned long instr = 0, instrptr;
806
- int (*handler)(unsigned long addr, unsigned long instr, struct pt_regs *regs);
802
+ union offset_union offset;
803
+ unsigned long instrptr;
804
+ int (*handler)(unsigned long addr, u32 instr, struct pt_regs *regs);
807805 unsigned int type;
806
+ u32 instr = 0;
808807 u16 tinstr = 0;
809808 int isize = 4;
810809 int thumb2_32b = 0;
....@@ -936,6 +935,9 @@
936935 if (type == TYPE_LDST)
937936 do_alignment_finish_ldst(addr, instr, regs, offset);
938937
938
+ if (thumb_mode(regs))
939
+ regs->ARM_cpsr = it_advance(regs->ARM_cpsr);
940
+
939941 return 0;
940942
941943 bad_or_fault:
....@@ -955,7 +957,7 @@
955957 * Oops, we didn't handle the instruction.
956958 */
957959 pr_err("Alignment trap: not handling instruction "
958
- "%0*lx at [<%08lx>]\n",
960
+ "%0*x at [<%08lx>]\n",
959961 isize << 1,
960962 isize == 2 ? tinstr : instr, instrptr);
961963 ai_skipped += 1;
....@@ -965,7 +967,7 @@
965967 ai_user += 1;
966968
967969 if (ai_usermode & UM_WARN)
968
- printk("Alignment trap: %s (%d) PC=0x%08lx Instr=0x%0*lx "
970
+ printk("Alignment trap: %s (%d) PC=0x%08lx Instr=0x%0*x "
969971 "Address=0x%08lx FSR 0x%03x\n", current->comm,
970972 task_pid_nr(current), instrptr,
971973 isize << 1,
....@@ -976,15 +978,7 @@
976978 goto fixup;
977979
978980 if (ai_usermode & UM_SIGNAL) {
979
- siginfo_t si;
980
-
981
- clear_siginfo(&si);
982
- si.si_signo = SIGBUS;
983
- si.si_errno = 0;
984
- si.si_code = BUS_ADRALN;
985
- si.si_addr = (void __user *)addr;
986
-
987
- force_sig_info(si.si_signo, &si, current);
981
+ force_sig_fault(SIGBUS, BUS_ADRALN, (void __user *)addr);
988982 } else {
989983 /*
990984 * We're about to disable the alignment trap and return to
....@@ -1025,7 +1019,7 @@
10251019 struct proc_dir_entry *res;
10261020
10271021 res = proc_create("cpu/alignment", S_IWUSR | S_IRUGO, NULL,
1028
- &alignment_proc_fops);
1022
+ &alignment_proc_ops);
10291023 if (!res)
10301024 return -ENOMEM;
10311025 #endif
....@@ -1055,8 +1049,4 @@
10551049 return 0;
10561050 }
10571051
1058
-#ifdef CONFIG_ROCKCHIP_THUNDER_BOOT
1059
-fs_initcall_sync(alignment_init);
1060
-#else
10611052 fs_initcall(alignment_init);
1062
-#endif