--- zzzz-none-000/linux-3.10.107/arch/arm/kernel/traps.c 2017-06-27 09:49:32.000000000 +0000 +++ scorpion-7490-727/linux-3.10.107/arch/arm/kernel/traps.c 2021-02-04 17:41:59.000000000 +0000 @@ -25,15 +25,39 @@ #include #include #include +#include #include #include #include #include #include +#include #include #include #include +#include +#if defined(CONFIG_AVM_ENHANCED) +#include +#endif/*--- #if defined(CONFIG_AVM_ENHANCED) ---*/ + +#include + +#if defined(CONFIG_AVM_FASTIRQ) +int in_avm_wdt_handling(void); +void avm_die_panic_handling(const char *str, struct pt_regs *regs); + +void avm_die(void); + +#include +#include +#include + +#define _BUILD_AVM_CONTEXT_FUNC(func) firq_##func +#else +#define _BUILD_AVM_CONTEXT_FUNC(func) func +#define is_avm_rte() 0 +#endif/*--- #if defined(CONFIG_AVM_FASTIRQ) ---*/ static const char *handler[]= { "prefetch abort", @@ -61,7 +85,12 @@ void dump_backtrace_entry(unsigned long where, unsigned long from, unsigned long frame) { #ifdef CONFIG_KALLSYMS - printk("[<%08lx>] (%pS) from [<%08lx>] (%pS)\n", where, (void *)where, from, (void *)from); +#if defined(CONFIG_AVM_ENHANCED) + printk(KERN_ERR"%04lx: [<%08lx>] (%pS)\n", frame & (THREAD_SIZE - 1), where, (void *)where); +#else/*--- #if defined(CONFIG_AVM_ENHANCED) ---*/ + printk(KERN_DEFAULT "[<%08lx>] (%pS) from [<%08lx>] (%pS)\n", + where, (void *)where, from, (void *)from); +#endif/*--- #else ---*//*--- #if defined(CONFIG_AVM_ENHANCED) ---*/ #else printk("Function entered at [<%08lx>] from [<%08lx>]\n", where, from); #endif @@ -115,14 +144,14 @@ for (p = first, i = 0; i < 8 && p < top; i++, p += 4) { if (p >= bottom && p < top) { - unsigned long val; + unsigned long val; if (__get_user(val, (unsigned long *)p) == 0) sprintf(str + i * 9, " %08lx", val); else sprintf(str + i * 9, " ????????"); } } - printk("%s%04lx:%s\n", lvl, first & 0xffff, str); + printk("%s%04lx:%s\n", lvl, first & 0xffff, str); } set_fs(fs); @@ -169,6 +198,9 @@ #ifdef CONFIG_ARM_UNWIND static inline void dump_backtrace(struct pt_regs *regs, struct task_struct *tsk) { +#if defined(CONFIG_AVM_ENHANCED) + printk(KERN_EMERG"Backtrace:\n"); +#endif/*--- #endif ---*//*--- #if defined(CONFIG_AVM_ENHANCED) ---*/ unwind_backtrace(regs, tsk); } #else @@ -183,7 +215,7 @@ tsk = current; if (regs) { - fp = regs->ARM_fp; + fp = frame_pointer(regs); mode = processor_mode(regs); } else if (tsk != current) { fp = thread_saved_fp(tsk); @@ -194,14 +226,14 @@ } if (!fp) { - printk("no frame pointer"); + pr_cont("no frame pointer"); ok = 0; } else if (verify_stack(fp)) { - printk("invalid frame pointer 0x%08x", fp); + pr_cont("invalid frame pointer 0x%08x", fp); ok = 0; } else if (fp < (unsigned long)end_of_stack(tsk)) - printk("frame pointer underflow"); - printk("\n"); + pr_cont("frame pointer underflow"); + pr_cont("\n"); if (ok) c_backtrace(fp, mode); @@ -236,29 +268,57 @@ static int die_counter; int ret; - printk(KERN_EMERG "Internal error: %s: %x [#%d]" S_PREEMPT S_SMP - S_ISA "\n", str, err, ++die_counter); + static DEFINE_SPINLOCK(avm_recursive_die_lock); + + if (_BUILD_AVM_CONTEXT_FUNC(spin_trylock(&avm_recursive_die_lock))) { + +#if defined(CONFIG_AVM_FASTIRQ) + struct thread_info *pthread = NULL; + + pthread = current_thread_info_depend_on_context(regs); + if (virt_addr_valid(pthread)) { + tsk = pthread->task; + } else { + tsk = NULL; + } +#endif/*--- #if defined(CONFIG_AVM_FASTIRQ) ---*/ + + pr_emerg("Internal error: %s: %x [#%d]" S_PREEMPT S_SMP S_ISA "\n", + str, err, ++die_counter); + +#if defined(CONFIG_AVM_FASTIRQ) + printk( KERN_ERR "FIQ watchdog handling, master CPU calls die notifier ...\n" ); +#endif/*--- #if defined(CONFIG_AVM_FASTIRQ) ---*/ + /* trap and error numbers are mostly meaningless on ARM */ + ret = notify_die(DIE_OOPS, str, regs, err, (tsk ? tsk->thread.trap_no : 0), SIGSEGV); + + _BUILD_AVM_CONTEXT_FUNC(spin_unlock(&avm_recursive_die_lock)); + } else { + printk( KERN_ERR "FIQ watchdog handling: recursion in __die ...\n" ); + ret = NOTIFY_STOP; + } - /* trap and error numbers are mostly meaningless on ARM */ - ret = notify_die(DIE_OOPS, str, regs, err, tsk->thread.trap_no, SIGSEGV); if (ret == NOTIFY_STOP) return 1; print_modules(); __show_regs(regs); - printk(KERN_EMERG "Process %.*s (pid: %d, stack limit = 0x%p)\n", - TASK_COMM_LEN, tsk->comm, task_pid_nr(tsk), end_of_stack(tsk)); + pr_emerg("Process %.*s (pid: %d, stack limit = 0x%p)\n", + TASK_COMM_LEN, tsk->comm, task_pid_nr(tsk), end_of_stack(tsk)); if (!user_mode(regs) || in_interrupt()) { - dump_mem(KERN_EMERG, "Stack: ", regs->ARM_sp, - THREAD_SIZE + (unsigned long)task_stack_page(tsk)); + dump_mem(KERN_EMERG, "Stack: ", regs->ARM_sp, + THREAD_SIZE + (unsigned long)task_stack_page(tsk)); dump_backtrace(regs, tsk); dump_instr(KERN_EMERG, regs); +#if defined(CONFIG_AVM_ENHANCED) + show_stacktrace_memoryclassifier(regs); +#endif/*--- #if defined(CONFIG_AVM_ENHANCED) ---*/ } - return 0; } +#if !defined(CONFIG_AVM_FASTIRQ) static arch_spinlock_t die_lock = __ARCH_SPIN_LOCK_UNLOCKED; static int die_owner = -1; static unsigned int die_nest_count; @@ -288,7 +348,11 @@ static void oops_end(unsigned long flags, struct pt_regs *regs, int signr) { - if (regs && kexec_should_crash(current)) + struct task_struct *tsk = current; +#if defined(CONFIG_AVM_FASTIRQ) + tsk = current_thread_info_depend_on_context(regs)->task; +#endif/*--- #if defined(CONFIG_AVM_FASTIRQ) ---*/ + if (regs && kexec_should_crash(tsk)) crash_kexec(regs); bust_spinlocks(0); @@ -301,6 +365,11 @@ raw_local_irq_restore(flags); oops_exit(); +#if defined(CONFIG_AVM_FASTIRQ) + if(panic_oops_on_fiq) { + panic("Fatal exception in fastirq"); + } +#endif/*--- #if defined(CONFIG_AVM_FASTIRQ) ---*/ if (in_interrupt()) panic("Fatal exception in interrupt"); if (panic_on_oops) @@ -308,36 +377,68 @@ if (signr) do_exit(signr); } +#endif /* * This function is protected against re-entrancy. */ void die(const char *str, struct pt_regs *regs, int err) { - enum bug_trap_type bug_type = BUG_TRAP_TYPE_NONE; - unsigned long flags = oops_begin(); - int sig = SIGSEGV; - - if (!user_mode(regs)) - bug_type = report_bug(regs->ARM_pc, regs); - if (bug_type != BUG_TRAP_TYPE_NONE) - str = "Oops - BUG"; - if (__die(str, err, regs)) - sig = 0; +#if defined(CONFIG_AVM_FASTIRQ) + if( !in_avm_wdt_handling() ) { +#ifdef CONFIG_AVM_DEBUG + printk_avm_console_bend(0); +#endif + printk( KERN_INFO "Generic die() handling triggers AVM WD ...\n" ); + avm_die_panic_handling(str, regs); + } +#endif/*--- #if defined(CONFIG_AVM_FASTIRQ) ---*/ + { + enum bug_trap_type bug_type = BUG_TRAP_TYPE_NONE; +#if !defined(CONFIG_AVM_FASTIRQ) + unsigned long flags = oops_begin(); + int sig = SIGSEGV; +#else + int sig = SIGSEGV; - oops_end(flags, regs, sig); + tracing_off(); + /* Kernel Integritaet nicht mehr vertrauenswürdig */ + debug_locks_off(); + + bust_spinlocks(1); +#endif + if (!user_mode(regs)) + bug_type = report_bug(regs->ARM_pc, regs); + if (bug_type != BUG_TRAP_TYPE_NONE) + str = "Oops - BUG"; + + if (__die(str, err, regs)) + sig = 0; +#if !defined(CONFIG_AVM_FASTIRQ) + oops_end(flags, regs, sig); +#else + if( in_avm_wdt_handling() ) { + avm_die(); + return; + } +#endif + } } void arm_notify_die(const char *str, struct pt_regs *regs, struct siginfo *info, unsigned long err, unsigned long trap) { if (user_mode(regs)) { - current->thread.error_code = err; - current->thread.trap_no = trap; + struct task_struct *tsk = current; +#if defined(CONFIG_AVM_FASTIRQ) + tsk = current_thread_info_depend_on_context(regs)->task; +#endif/*--- #if defined(CONFIG_AVM_FASTIRQ) ---*/ + tsk->thread.error_code = err; + tsk->thread.trap_no = trap; - force_sig_info(info->si_signo, info, current); - } else { + force_sig_info(info->si_signo, info, tsk); + } else { die(str, regs, err); } } @@ -405,41 +506,69 @@ siginfo_t info; void __user *pc; +#if defined(CONFIG_AVM_FASTIRQ) + struct pt_regs fregs; + + prepare_register_for_trap(&fregs, ®s); + if (!user_mode(regs)) { + set_exc_regs(regs); + } + + if(processor_mode(regs) == FIQ_MODE) { + panic_oops_on_fiq = 1 + raw_smp_processor_id(); + } +#endif/*--- #if defined(CONFIG_AVM_FASTIRQ) ---*/ + early_printk("%s\n", __func__); pc = (void __user *)instruction_pointer(regs); - if (processor_mode(regs) == SVC_MODE) { + if (processor_mode(regs) == SVC_MODE +#if defined(CONFIG_AVM_FASTIRQ) + || (processor_mode(regs) == FIQ_MODE) +#endif/*--- #if defined(CONFIG_AVM_FASTIRQ) ---*/ + ) { #ifdef CONFIG_THUMB2_KERNEL if (thumb_mode(regs)) { - instr = ((u16 *)pc)[0]; + instr = __mem_to_opcode_thumb16(((u16 *)pc)[0]); if (is_wide_instruction(instr)) { - instr <<= 16; - instr |= ((u16 *)pc)[1]; + u16 inst2; + inst2 = __mem_to_opcode_thumb16(((u16 *)pc)[1]); + instr = __opcode_thumb32_compose(instr, inst2); } } else #endif - instr = *(u32 *) pc; + instr = __mem_to_opcode_arm(*(u32 *) pc); } else if (thumb_mode(regs)) { if (get_user(instr, (u16 __user *)pc)) goto die_sig; + instr = __mem_to_opcode_thumb16(instr); if (is_wide_instruction(instr)) { unsigned int instr2; if (get_user(instr2, (u16 __user *)pc+1)) goto die_sig; - instr <<= 16; - instr |= instr2; + instr2 = __mem_to_opcode_thumb16(instr2); + instr = __opcode_thumb32_compose(instr, instr2); } - } else if (get_user(instr, (u32 __user *)pc)) { - goto die_sig; + } else { + if (get_user(instr, (u32 __user *)pc)) + goto die_sig; + instr = __mem_to_opcode_arm(instr); } if (call_undef_hook(regs, instr) == 0) return; die_sig: + trace_undef_instr(regs, (void *)pc); + #ifdef CONFIG_DEBUG_USER if (user_debug & UDBG_UNDEFINED) { - printk(KERN_INFO "%s (%d): undefined instruction: pc=%p\n", - current->comm, task_pid_nr(current), pc); + struct task_struct *tsk = current; +#if defined(CONFIG_AVM_FASTIRQ) + tsk = current_thread_info_depend_on_context(regs)->task; +#endif/*--- #if defined(CONFIG_AVM_FASTIRQ) ---*/ + pr_info("%s (%d): undefined instruction: pc=%p\n", + tsk->comm, task_pid_nr(tsk), pc); + __show_regs(regs); dump_instr(KERN_INFO, regs); } #endif @@ -452,10 +581,29 @@ arm_notify_die("Oops - undefined instruction", regs, &info, 0, 6); } -asmlinkage void do_unexp_fiq (struct pt_regs *regs) +/* + * Handle FIQ similarly to NMI on x86 systems. + * + * The runtime environment for NMIs is extremely restrictive + * (NMIs can pre-empt critical sections meaning almost all locking is + * forbidden) meaning this default FIQ handling must only be used in + * circumstances where non-maskability improves robustness, such as + * watchdog or debug logic. + * + * This handler is not appropriate for general purpose use in drivers + * platform code and can be overrideen using set_fiq_handler. + */ +asmlinkage void __exception_irq_entry handle_fiq_as_nmi(struct pt_regs *regs) { - printk("Hmm. Unexpected FIQ received, but trying to continue\n"); - printk("You may have a hardware problem...\n"); + struct pt_regs *old_regs = set_irq_regs(regs); + + nmi_enter(); + + /* nop. FIQ handlers for special arch/arm features can be added here. */ + + nmi_exit(); + + set_irq_regs(old_regs); } /* @@ -466,29 +614,47 @@ */ asmlinkage void bad_mode(struct pt_regs *regs, int reason) { +#if defined(CONFIG_AVM_FASTIRQ) + struct pt_regs fregs; +#else console_verbose(); +#endif/*--- #if defined(CONFIG_AVM_FASTIRQ) ---*/ + + pr_crit("Bad mode in %s handler detected\n", handler[reason]); - printk(KERN_CRIT "Bad mode in %s handler detected\n", handler[reason]); +#if defined(CONFIG_AVM_FASTIRQ) + prepare_register_for_trap(&fregs, ®s); + if (!user_mode(regs)) { + set_exc_regs(regs); + } + + if(processor_mode(regs) == FIQ_MODE) { + if(reason == 4 /* BAD_UNDEFINSTR */) { + regs->ARM_pc -= thumb_mode(regs) ? 2 : 4; /*--- if undefined instruction so set pc on undefined instruction (so BUG_ON on fastirq possible) ---*/ + } + panic_oops_on_fiq = 1 + raw_smp_processor_id(); + } +#endif/*--- #if defined(CONFIG_AVM_FASTIRQ) ---*/ die("Oops - bad mode", regs, 0); +#if !defined(CONFIG_AVM_FASTIRQ) local_irq_disable(); panic("bad mode"); +#endif } static int bad_syscall(int n, struct pt_regs *regs) { - struct thread_info *thread = current_thread_info(); siginfo_t info; - if ((current->personality & PER_MASK) != PER_LINUX && - thread->exec_domain->handler) { - thread->exec_domain->handler(n, regs); + if ((current->personality & PER_MASK) != PER_LINUX) { + send_sig(SIGSEGV, current, 1); return regs->ARM_r0; } #ifdef CONFIG_DEBUG_USER if (user_debug & UDBG_SYSCALL) { - printk(KERN_ERR "[%d] %s: obsolete system call %08x.\n", + pr_err("[%d] %s: obsolete system call %08x.\n", task_pid_nr(current), current->comm, n); dump_instr(KERN_ERR, regs); } @@ -506,27 +672,37 @@ } static inline int -do_cache_op(unsigned long start, unsigned long end, int flags) +__do_cache_op(unsigned long start, unsigned long end) { - struct mm_struct *mm = current->active_mm; - struct vm_area_struct *vma; + int ret; + + do { + unsigned long chunk = min(PAGE_SIZE, end - start); + + if (fatal_signal_pending(current)) + return 0; + + ret = flush_cache_user_range(start, start + chunk); + if (ret) + return ret; + + cond_resched(); + start += chunk; + } while (start < end); + + return 0; +} +static inline int +do_cache_op(unsigned long start, unsigned long end, int flags) +{ if (end < start || flags) return -EINVAL; - down_read(&mm->mmap_sem); - vma = find_vma(mm, start); - if (vma && vma->vm_start < end) { - if (start < vma->vm_start) - start = vma->vm_start; - if (end > vma->vm_end) - end = vma->vm_end; + if (!access_ok(VERIFY_READ, start, end - start)) + return -EFAULT; - up_read(&mm->mmap_sem); - return flush_cache_user_range(start, end); - } - up_read(&mm->mmap_sem); - return -EINVAL; + return __do_cache_op(start, end); } /* @@ -534,9 +710,9 @@ * 0x9f0000 - 0x9fffff are some more esoteric system calls */ #define NR(x) ((__ARM_NR_##x) - __ARM_NR_BASE) + asmlinkage int arm_syscall(int no, struct pt_regs *regs) { - struct thread_info *thread = current_thread_info(); siginfo_t info; if ((no >> 16) != (__ARM_NR_BASE>> 16)) @@ -587,75 +763,9 @@ return regs->ARM_r0; case NR(set_tls): - thread->tp_value = regs->ARM_r0; - if (tls_emu) - return 0; - if (has_tls_reg) { - asm ("mcr p15, 0, %0, c13, c0, 3" - : : "r" (regs->ARM_r0)); - } else { - /* - * User space must never try to access this directly. - * Expect your app to break eventually if you do so. - * The user helper at 0xffff0fe0 must be used instead. - * (see entry-armv.S for details) - */ - *((unsigned int *)0xffff0ff0) = regs->ARM_r0; - } + set_tls(regs->ARM_r0); return 0; -#ifdef CONFIG_NEEDS_SYSCALL_FOR_CMPXCHG - /* - * Atomically store r1 in *r2 if *r2 is equal to r0 for user space. - * Return zero in r0 if *MEM was changed or non-zero if no exchange - * happened. Also set the user C flag accordingly. - * If access permissions have to be fixed up then non-zero is - * returned and the operation has to be re-attempted. - * - * *NOTE*: This is a ghost syscall private to the kernel. Only the - * __kuser_cmpxchg code in entry-armv.S should be aware of its - * existence. Don't ever use this from user code. - */ - case NR(cmpxchg): - for (;;) { - extern void do_DataAbort(unsigned long addr, unsigned int fsr, - struct pt_regs *regs); - unsigned long val; - unsigned long addr = regs->ARM_r2; - struct mm_struct *mm = current->mm; - pgd_t *pgd; pmd_t *pmd; pte_t *pte; - spinlock_t *ptl; - - regs->ARM_cpsr &= ~PSR_C_BIT; - down_read(&mm->mmap_sem); - pgd = pgd_offset(mm, addr); - if (!pgd_present(*pgd)) - goto bad_access; - pmd = pmd_offset(pgd, addr); - if (!pmd_present(*pmd)) - goto bad_access; - pte = pte_offset_map_lock(mm, pmd, addr, &ptl); - if (!pte_present(*pte) || !pte_write(*pte) || !pte_dirty(*pte)) { - pte_unmap_unlock(pte, ptl); - goto bad_access; - } - val = *(unsigned long *)addr; - val -= regs->ARM_r0; - if (val == 0) { - *(unsigned long *)addr = regs->ARM_r1; - regs->ARM_cpsr |= PSR_C_BIT; - } - pte_unmap_unlock(pte, ptl); - up_read(&mm->mmap_sem); - return val; - - bad_access: - up_read(&mm->mmap_sem); - /* simulate a write access fault */ - do_DataAbort(addr, 15 + (1 << 11), regs); - } -#endif - default: /* Calls 9f00xx..9f07ff are defined to return -ENOSYS if not implemented, rather than raising SIGILL. This @@ -671,12 +781,12 @@ * something catastrophic has happened */ if (user_debug & UDBG_SYSCALL) { - printk("[%d] %s: arm syscall %d\n", + pr_err("[%d] %s: arm syscall %d\n", task_pid_nr(current), current->comm, no); dump_instr("", regs); if (user_mode(regs)) { __show_regs(regs); - c_backtrace(regs->ARM_fp, processor_mode(regs)); + c_backtrace(frame_pointer(regs), processor_mode(regs)); } } #endif @@ -705,7 +815,7 @@ int reg = (instr >> 12) & 15; if (reg == 15) return 1; - regs->uregs[reg] = current_thread_info()->tp_value; + regs->uregs[reg] = current_thread_info()->tp_value[0]; regs->ARM_pc += 4; return 0; } @@ -728,14 +838,6 @@ #endif -void __bad_xchg(volatile void *ptr, int size) -{ - printk("xchg: bad data size: pc 0x%p, ptr 0x%p, size %d\n", - __builtin_return_address(0), ptr, size); - BUG(); -} -EXPORT_SYMBOL(__bad_xchg); - /* * A data abort trap was taken, but we did not handle the instruction. * Try to abort the user program, or panic if it was the kernel. @@ -746,12 +848,29 @@ unsigned long addr = instruction_pointer(regs); siginfo_t info; +#if defined(CONFIG_AVM_FASTIRQ) + struct pt_regs fregs; + + prepare_register_for_trap(&fregs, ®s); + if (!user_mode(regs)) { + set_exc_regs(regs); + } + + if(processor_mode(regs) == FIQ_MODE) { + panic_oops_on_fiq = 1 + raw_smp_processor_id(); + } +#endif/*--- #if defined(CONFIG_AVM_FASTIRQ) ---*/ + #ifdef CONFIG_DEBUG_USER if (user_debug & UDBG_BADABORT) { - printk(KERN_ERR "[%d] %s: bad data abort: code %d instr 0x%08lx\n", - task_pid_nr(current), current->comm, code, instr); + struct task_struct *tsk = current; +#if defined(CONFIG_AVM_FASTIRQ) + tsk = current_thread_info_depend_on_context(regs)->task; +#endif/*--- #if defined(CONFIG_AVM_FASTIRQ) ---*/ + pr_err("[%d] %s: bad data abort: code %d instr 0x%08lx\n", + task_pid_nr(current), current->comm, code, instr); dump_instr(KERN_ERR, regs); - show_pte(current->mm, addr); + show_pte(tsk->mm, addr); } #endif @@ -765,29 +884,29 @@ void __readwrite_bug(const char *fn) { - printk("%s called, but not implemented\n", fn); + pr_err("%s called, but not implemented\n", fn); BUG(); } EXPORT_SYMBOL(__readwrite_bug); void __pte_error(const char *file, int line, pte_t pte) { - printk("%s:%d: bad pte %08llx.\n", file, line, (long long)pte_val(pte)); + pr_err("%s:%d: bad pte %08llx.\n", file, line, (long long)pte_val(pte)); } void __pmd_error(const char *file, int line, pmd_t pmd) { - printk("%s:%d: bad pmd %08llx.\n", file, line, (long long)pmd_val(pmd)); + pr_err("%s:%d: bad pmd %08llx.\n", file, line, (long long)pmd_val(pmd)); } void __pgd_error(const char *file, int line, pgd_t pgd) { - printk("%s:%d: bad pgd %08llx.\n", file, line, (long long)pgd_val(pgd)); + pr_err("%s:%d: bad pgd %08llx.\n", file, line, (long long)pgd_val(pgd)); } asmlinkage void __div0(void) { - printk("Division by zero in kernel.\n"); + pr_err("Division by zero in kernel.\n"); dump_stack(); } EXPORT_SYMBOL(__div0); @@ -822,13 +941,14 @@ memcpy(vectors + 0xfe0, vectors + 0xfe8, 4); } #else -static void __init kuser_init(void *vectors) +static inline void __init kuser_init(void *vectors) { } #endif void __init early_trap_init(void *vectors_base) { +#ifndef CONFIG_CPU_V7M unsigned long vectors = (unsigned long)vectors_base; extern char __stubs_start[], __stubs_end[]; extern char __vectors_start[], __vectors_end[]; @@ -856,5 +976,11 @@ kuser_init(vectors_base); flush_icache_range(vectors, vectors + PAGE_SIZE * 2); - modify_domain(DOMAIN_USER, DOMAIN_CLIENT); +#else /* ifndef CONFIG_CPU_V7M */ + /* + * on V7-M there is no need to copy the vector table to a dedicated + * memory area. The address is configurable and so a table in the kernel + * image can be used. + */ +#endif }