--- zzzz-none-000/linux-5.4.213/arch/arm/mm/alignment.c 2022-09-15 10:04:56.000000000 +0000 +++ alder-5690pro-762/linux-5.4.213/arch/arm/mm/alignment.c 2024-08-14 09:01:28.000000000 +0000 @@ -27,7 +27,10 @@ #include "fault.h" #include "mm.h" - +#if defined(CONFIG_ARM_UNWIND) +#include +#endif/*--- #if defined(CONFIG_ARM_UNWIND) ---*/ + /* * 32-bit misaligned trap handler (c) 1998 San Mehat (CCC) -July 1998 * /proc/sys/debug/alignment, modified and integrated into @@ -73,8 +76,6 @@ #define IS_T32(hi16) \ (((hi16) & 0xe000) == 0xe000 && ((hi16) & 0x1800)) -static unsigned long ai_user; -static unsigned long ai_sys; static void *ai_sys_last_pc; static unsigned long ai_skipped; static unsigned long ai_half; @@ -90,6 +91,62 @@ #define UM_FIXUP (1 << 1) #define UM_SIGNAL (1 << 2) +#if defined(CONFIG_AVM_ENHANCED) +#include +static struct _ai_info { + unsigned long ai_count; + unsigned long last_pc; + char last_comm[TASK_COMM_LEN]; +} ai_info[2]; + +#define UM_BT (1 << 3) + +#define AI_SYS 0 +#define AI_USER 1 + +#define ai_user ai_info[AI_USER].ai_count +#define ai_sys ai_info[AI_SYS].ai_count + +/**--------------------------------------------------------------------------------**\ +\**--------------------------------------------------------------------------------**/ +static inline void inc_ai_info(int ai_idx, unsigned long pc) { + ai_info[ai_idx].ai_count++; + ai_info[ai_idx].last_pc = pc; + memcpy(ai_info[ai_idx].last_comm, current->comm, TASK_COMM_LEN); + ai_add_to_scorelist(pc, (ai_idx == AI_USER) ? 1 : 0); +} +/**--------------------------------------------------------------------------------**\ + * \\brief: + * Liefere Unaligned-Daten + * user: 0 Kernel 1 Userland + * ret: Zeiger auf last_comm des Userprozesses +\**--------------------------------------------------------------------------------**/ +const char *get_last_unaligned_info(unsigned long *ai_count, unsigned long *last_pc, int user) { + int idx = user ? AI_USER : AI_SYS; + if(ai_count) *ai_count = ai_info[idx].ai_count; + if(last_pc) *last_pc = ai_info[idx].last_pc; + return ai_info[idx].last_comm; +} +static int ai_kernelmode = UM_FIXUP; + +/*--------------------------------------------------------------------------------*\ +\*--------------------------------------------------------------------------------*/ +static char *map_mode(char *txt, int mode) { + int len = sprintf(txt, "%s%s%s%s%s", + (mode == 0) ? "ignore " : "", + (mode & UM_FIXUP) ? "fixup+" : "", + (mode & UM_SIGNAL) ? "signal+" : "", + (mode & UM_WARN) ? "warn+" : "", + (mode & UM_BT) ? "backtrace " : "" ); + txt[len-1] = 0; + return txt; +} +#else/*--- #if defined(CONFIG_AVM_ENHANCED) ---*/ +static unsigned long ai_user; +static unsigned long ai_sys; +#endif/*--- #else ---*//*--- #if defined(CONFIG_AVM_ENHANCED) ---*/ + + /* Return true if and only if the ARMv6 unaligned access model is in use. */ static bool cpu_is_v6_unaligned(void) { @@ -139,6 +196,19 @@ seq_printf(m, "Multi:\t\t%lu\n", ai_multi); seq_printf(m, "User faults:\t%i (%s)\n", ai_usermode, usermode_action[ai_usermode]); +#if defined(CONFIG_AVM_ENHANCED) + { + char txt[64]; + int ret; + seq_printf(m, "Kernel faults:\t%i (%s)\n", min(8,ai_kernelmode + 4), map_mode(txt, ai_kernelmode)); + if((ret = ai_show_scorelist(m, 1)) != ai_user) { + if(ret) seq_printf(m, "... only the newest user-unaligneds shown\n"); + } + if((ret = ai_show_scorelist(m, 0)) != ai_sys) { + if(ret) seq_printf(m, "... only the newest kernel-unaligneds shown\n"); + } + } +#endif/*--- #if defined(CONFIG_AVM_ENHANCED) ---*/ return 0; } @@ -152,12 +222,38 @@ size_t count, loff_t *pos) { char mode; +#if defined(CONFIG_AVM_ENHANCED) + char txt[4][64]; +#endif/*--- #if defined(CONFIG_AVM_ENHANCED) ---*/ if (count > 0) { if (get_user(mode, buffer)) return -EFAULT; - if (mode >= '0' && mode <= '5') + if (mode >= '0' && mode <= '5') { ai_usermode = safe_usermode(mode - '0', true); +#if defined(CONFIG_AVM_ENHANCED) + pr_err("set user unaligned-mode: %s\n", map_mode(txt[0], ai_usermode)); + } else if (mode >= '6' && mode <= '8') { + ai_kernelmode = mode == '6' ? UM_FIXUP : + mode == '7' ? UM_FIXUP | UM_WARN : UM_FIXUP | UM_WARN | UM_BT; + pr_err("set kernel unaligned-mode: %s\n", map_mode(txt[0], ai_kernelmode)); + } else { + pr_err("parameter: user '2' %s '3' %s '4' %s '5' %s \n", map_mode(txt[0], UM_FIXUP), + map_mode(txt[1], UM_FIXUP | UM_WARN), + map_mode(txt[2], UM_SIGNAL), + map_mode(txt[3], UM_SIGNAL | UM_WARN)); + pr_err(" system '6' %s '7' %s" +#if defined(CONFIG_ARM_UNWIND) + " '8' %s" +#endif/*--- #if defined(CONFIG_ARM_UNWIND) ---*/ + "\n", map_mode(txt[0], UM_FIXUP), + map_mode(txt[1], UM_FIXUP | UM_WARN) +#if defined(CONFIG_ARM_UNWIND) + ,map_mode(txt[2], UM_FIXUP | UM_WARN | UM_BT) +#endif/*--- #if defined(CONFIG_ARM_UNWIND) ---*/ + ); +#endif/*--- #if defined(CONFIG_AVM_ENHANCED) ---*/ + } } return count; } @@ -843,7 +939,40 @@ if (user_mode(regs)) goto user; +#if defined(CONFIG_AVM_ENHANCED) + inc_ai_info(AI_SYS, instrptr); + if(ai_kernelmode & UM_WARN) { + pr_err("Kernel Alignment trap %lu: %s (%d) PC=0x%lxS Instr=0x%0*x " + "Address=0x%08lx FSR 0x%03x\n", ai_sys, current->comm, + task_pid_nr(current), instrptr, + isize << 1, + isize == 2 ? tinstr : instr, + addr, fsr); + print_code_range(NULL, "Kernel Alignment trap:", instrptr, thumb_mode(regs)); + } +#if defined(CONFIG_ARM_UNWIND) + if(ai_kernelmode & UM_BT) { + unwind_backtrace(regs, NULL); + } +#endif/*--- #if defined(CONFIG_ARM_UNWIND) ---*/ + if(ai_kernelmode & UM_FIXUP) { + goto fixup; + } + if(ai_kernelmode & UM_SIGNAL) { + struct kernel_siginfo info; + + info.si_signo = SIGBUS; + info.si_errno = 0; + info.si_code = BUS_ADRALN; + info.si_addr = (void __user *)addr; + + force_sig_info(&info); + } + goto bad; +#else/*--- #if defined(CONFIG_AVM_ENHANCED) ---*/ ai_sys += 1; +#endif/*--- #else ---*//*--- #if defined(CONFIG_AVM_ENHANCED) ---*/ + ai_sys_last_pc = (void *)instruction_pointer(regs); fixup: @@ -964,10 +1093,14 @@ return 1; user: +#if defined(CONFIG_AVM_ENHANCED) + inc_ai_info(AI_USER, instrptr); +#else/*--- #if defined(CONFIG_AVM_ENHANCED) ---*/ ai_user += 1; +#endif/*--- #else ---*//*--- #if defined(CONFIG_AVM_ENHANCED) ---*/ if (ai_usermode & UM_WARN) - printk("Alignment trap: %s (%d) PC=0x%08lx Instr=0x%0*x " + pr_err("User-Alignment trap: %s (%d) PC=0x%08lx Instr=0x%0*x " "Address=0x%08lx FSR 0x%03x\n", current->comm, task_pid_nr(current), instrptr, isize << 1,