diff options
Diffstat (limited to 'arch/arc/kernel')
29 files changed, 440 insertions, 658 deletions
diff --git a/arch/arc/kernel/Makefile b/arch/arc/kernel/Makefile index 8c4fc4b54c14..fa94fff02419 100644 --- a/arch/arc/kernel/Makefile +++ b/arch/arc/kernel/Makefile @@ -3,8 +3,10 @@ # Copyright (C) 2004, 2007-2010, 2011-2012 Synopsys, Inc. (www.synopsys.com) # -obj-y := arcksyms.o setup.o irq.o reset.o ptrace.o process.o devtree.o +obj-y := head.o arcksyms.o setup.o irq.o reset.o ptrace.o process.o devtree.o obj-y += signal.o traps.o sys.o troubleshoot.o stacktrace.o disasm.o +obj-y += ctx_sw_asm.o + obj-$(CONFIG_ISA_ARCOMPACT) += entry-compact.o intc-compact.o obj-$(CONFIG_ISA_ARCV2) += entry-arcv2.o intc-arcv2.o @@ -24,11 +26,4 @@ ifdef CONFIG_ISA_ARCOMPACT CFLAGS_fpu.o += -mdpfp endif -ifdef CONFIG_ARC_DW2_UNWIND -CFLAGS_ctx_sw.o += -fno-omit-frame-pointer -obj-y += ctx_sw.o -else -obj-y += ctx_sw_asm.o -endif - -extra-y := vmlinux.lds head.o +always-$(KBUILD_BUILTIN) := vmlinux.lds diff --git a/arch/arc/kernel/Makefile.syscalls b/arch/arc/kernel/Makefile.syscalls new file mode 100644 index 000000000000..391d30ab7a83 --- /dev/null +++ b/arch/arc/kernel/Makefile.syscalls @@ -0,0 +1,3 @@ +# SPDX-License-Identifier: GPL-2.0 + +syscall_abis_32 += arc time32 renameat stat64 rlimit diff --git a/arch/arc/kernel/asm-offsets.c b/arch/arc/kernel/asm-offsets.c index 0e884036ab74..f77deb799175 100644 --- a/arch/arc/kernel/asm-offsets.c +++ b/arch/arc/kernel/asm-offsets.c @@ -20,13 +20,13 @@ int main(void) BLANK(); - DEFINE(THREAD_KSP, offsetof(struct thread_struct, ksp)); DEFINE(THREAD_CALLEE_REG, offsetof(struct thread_struct, callee_reg)); DEFINE(THREAD_FAULT_ADDR, offsetof(struct thread_struct, fault_address)); BLANK(); + DEFINE(THREAD_INFO_KSP, offsetof(struct thread_info, ksp)); DEFINE(THREAD_INFO_FLAGS, offsetof(struct thread_info, flags)); DEFINE(THREAD_INFO_PREEMPT_COUNT, offsetof(struct thread_info, preempt_count)); @@ -46,7 +46,8 @@ int main(void) BLANK(); DEFINE(PT_status32, offsetof(struct pt_regs, status32)); - DEFINE(PT_event, offsetof(struct pt_regs, event)); + DEFINE(PT_event, offsetof(struct pt_regs, ecr)); + DEFINE(PT_bta, offsetof(struct pt_regs, bta)); DEFINE(PT_sp, offsetof(struct pt_regs, sp)); DEFINE(PT_r0, offsetof(struct pt_regs, r0)); DEFINE(PT_r1, offsetof(struct pt_regs, r1)); @@ -61,13 +62,9 @@ int main(void) DEFINE(PT_r26, offsetof(struct pt_regs, r26)); DEFINE(PT_ret, offsetof(struct pt_regs, ret)); DEFINE(PT_blink, offsetof(struct pt_regs, blink)); + OFFSET(PT_fp, pt_regs, fp); DEFINE(PT_lpe, offsetof(struct pt_regs, lp_end)); DEFINE(PT_lpc, offsetof(struct pt_regs, lp_count)); - DEFINE(PT_user_r25, offsetof(struct pt_regs, user_r25)); - - DEFINE(SZ_CALLEE_REGS, sizeof(struct callee_regs)); - DEFINE(SZ_PT_REGS, sizeof(struct pt_regs)); - #ifdef CONFIG_ISA_ARCV2 OFFSET(PT_r12, pt_regs, r12); OFFSET(PT_r30, pt_regs, r30); @@ -80,5 +77,8 @@ int main(void) OFFSET(PT_DSP_CTRL, pt_regs, DSP_CTRL); #endif + DEFINE(SZ_CALLEE_REGS, sizeof(struct callee_regs)); + DEFINE(SZ_PT_REGS, sizeof(struct pt_regs)); + return 0; } diff --git a/arch/arc/kernel/ctx_sw.c b/arch/arc/kernel/ctx_sw.c deleted file mode 100644 index 1a76f2d6f694..000000000000 --- a/arch/arc/kernel/ctx_sw.c +++ /dev/null @@ -1,112 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * Copyright (C) 2004, 2007-2010, 2011-2012 Synopsys, Inc. (www.synopsys.com) - * - * Vineetg: Aug 2009 - * -"C" version of lowest level context switch asm macro called by schedular - * gcc doesn't generate the dward CFI info for hand written asm, hence can't - * backtrace out of it (e.g. tasks sleeping in kernel). - * So we cheat a bit by writing almost similar code in inline-asm. - * -This is a hacky way of doing things, but there is no other simple way. - * I don't want/intend to extend unwinding code to understand raw asm - */ - -#include <asm/asm-offsets.h> -#include <linux/sched.h> -#include <linux/sched/debug.h> - -#define KSP_WORD_OFF ((TASK_THREAD + THREAD_KSP) / 4) - -struct task_struct *__sched -__switch_to(struct task_struct *prev_task, struct task_struct *next_task) -{ - unsigned int tmp; - unsigned int prev = (unsigned int)prev_task; - unsigned int next = (unsigned int)next_task; - - __asm__ __volatile__( - /* FP/BLINK save generated by gcc (standard function prologue */ - "st.a r13, [sp, -4] \n\t" - "st.a r14, [sp, -4] \n\t" - "st.a r15, [sp, -4] \n\t" - "st.a r16, [sp, -4] \n\t" - "st.a r17, [sp, -4] \n\t" - "st.a r18, [sp, -4] \n\t" - "st.a r19, [sp, -4] \n\t" - "st.a r20, [sp, -4] \n\t" - "st.a r21, [sp, -4] \n\t" - "st.a r22, [sp, -4] \n\t" - "st.a r23, [sp, -4] \n\t" - "st.a r24, [sp, -4] \n\t" -#ifndef CONFIG_ARC_CURR_IN_REG - "st.a r25, [sp, -4] \n\t" -#else - "sub sp, sp, 4 \n\t" /* usual r25 placeholder */ -#endif - - /* set ksp of outgoing task in tsk->thread.ksp */ -#if KSP_WORD_OFF <= 255 - "st.as sp, [%3, %1] \n\t" -#else - /* - * Workaround for NR_CPUS=4k - * %1 is bigger than 255 (S9 offset for st.as) - */ - "add2 r24, %3, %1 \n\t" - "st sp, [r24] \n\t" -#endif - - /* - * setup _current_task with incoming tsk. - * optionally, set r25 to that as well - * For SMP extra work to get to &_current_task[cpu] - * (open coded SET_CURR_TASK_ON_CPU) - */ -#ifndef CONFIG_SMP - "st %2, [@_current_task] \n\t" -#else - "lr r24, [identity] \n\t" - "lsr r24, r24, 8 \n\t" - "bmsk r24, r24, 7 \n\t" - "add2 r24, @_current_task, r24 \n\t" - "st %2, [r24] \n\t" -#endif -#ifdef CONFIG_ARC_CURR_IN_REG - "mov r25, %2 \n\t" -#endif - - /* get ksp of incoming task from tsk->thread.ksp */ - "ld.as sp, [%2, %1] \n\t" - - /* start loading it's CALLEE reg file */ - -#ifndef CONFIG_ARC_CURR_IN_REG - "ld.ab r25, [sp, 4] \n\t" -#else - "add sp, sp, 4 \n\t" -#endif - "ld.ab r24, [sp, 4] \n\t" - "ld.ab r23, [sp, 4] \n\t" - "ld.ab r22, [sp, 4] \n\t" - "ld.ab r21, [sp, 4] \n\t" - "ld.ab r20, [sp, 4] \n\t" - "ld.ab r19, [sp, 4] \n\t" - "ld.ab r18, [sp, 4] \n\t" - "ld.ab r17, [sp, 4] \n\t" - "ld.ab r16, [sp, 4] \n\t" - "ld.ab r15, [sp, 4] \n\t" - "ld.ab r14, [sp, 4] \n\t" - "ld.ab r13, [sp, 4] \n\t" - - /* last (ret value) = prev : although for ARC it mov r0, r0 */ - "mov %0, %3 \n\t" - - /* FP/BLINK restore generated by gcc (standard func epilogue */ - - : "=r"(tmp) - : "n"(KSP_WORD_OFF), "r"(next), "r"(prev) - : "blink" - ); - - return (struct task_struct *)tmp; -} diff --git a/arch/arc/kernel/ctx_sw_asm.S b/arch/arc/kernel/ctx_sw_asm.S index 02c461484761..48e1f21976ed 100644 --- a/arch/arc/kernel/ctx_sw_asm.S +++ b/arch/arc/kernel/ctx_sw_asm.S @@ -11,50 +11,54 @@ #include <asm/entry.h> /* For the SAVE_* macros */ #include <asm/asm-offsets.h> -#define KSP_WORD_OFF ((TASK_THREAD + THREAD_KSP) / 4) - -;################### Low Level Context Switch ########################## +; IN +; - r0: prev task (also current) +; - r1: next task +; OUT +; - r0: prev task (so r0 not touched) .section .sched.text,"ax",@progbits - .align 4 - .global __switch_to - .type __switch_to, @function -__switch_to: - CFI_STARTPROC - - /* Save regs on kernel mode stack of task */ - st.a blink, [sp, -4] - st.a fp, [sp, -4] - SAVE_CALLEE_SAVED_KERNEL +ENTRY_CFI(__switch_to) - /* Save the now KSP in task->thread.ksp */ -#if KSP_WORD_OFF <= 255 - st.as sp, [r0, KSP_WORD_OFF] -#else - /* Workaround for NR_CPUS=4k as ST.as can only take s9 offset */ - add2 r24, r0, KSP_WORD_OFF - st sp, [r24] -#endif - /* - * Return last task in r0 (return reg) - * On ARC, Return reg = First Arg reg = r0. - * Since we already have last task in r0, - * don't need to do anything special to return it - */ + /* save kernel stack frame regs of @prev task */ + push blink + CFI_DEF_CFA_OFFSET 4 + CFI_OFFSET r31, -4 + + push fp + CFI_DEF_CFA_OFFSET 8 + CFI_OFFSET r27, -8 + + mov fp, sp + CFI_DEF_CFA_REGISTER r27 + + /* kernel mode callee regs of @prev */ + SAVE_CALLEE_SAVED_KERNEL /* - * switch to new task, contained in r1 - * Temp reg r3 is required to get the ptr to store val + * save final SP to @prev->thread_info.ksp + * @prev is "current" so thread_info derived from SP */ - SET_CURR_TASK_ON_CPU r1, r3 + GET_CURR_THR_INFO_FROM_SP r10 + st sp, [r10, THREAD_INFO_KSP] + + /* update @next in _current_task[] and GP register caching it */ + SET_CURR_TASK_ON_CPU r1, r10 - /* reload SP with kernel mode stack pointer in task->thread.ksp */ - ld.as sp, [r1, (TASK_THREAD + THREAD_KSP)/4] + /* load SP from @next->thread_info.ksp */ + ld r10, [r1, TASK_THREAD_INFO] + ld sp, [r10, THREAD_INFO_KSP] - /* restore the registers */ + /* restore callee regs, stack frame regs of @next */ RESTORE_CALLEE_SAVED_KERNEL - ld.ab fp, [sp, 4] - ld.ab blink, [sp, 4] - j [blink] + pop fp + CFI_RESTORE r27 + CFI_DEF_CFA r28, 4 + + pop blink + CFI_RESTORE r31 + CFI_DEF_CFA_OFFSET 0 + + j [blink] END_CFI(__switch_to) diff --git a/arch/arc/kernel/devtree.c b/arch/arc/kernel/devtree.c index 721d465f1580..cc6ac7d128aa 100644 --- a/arch/arc/kernel/devtree.c +++ b/arch/arc/kernel/devtree.c @@ -12,6 +12,7 @@ #include <linux/of.h> #include <linux/of_fdt.h> #include <asm/mach_desc.h> +#include <asm/serial.h> #ifdef CONFIG_SERIAL_EARLYCON @@ -61,7 +62,7 @@ const struct machine_desc * __init setup_machine_fdt(void *dt) const struct machine_desc *mdesc; unsigned long dt_root; - if (!early_init_dt_scan(dt)) + if (!early_init_dt_scan(dt, __pa(dt))) return NULL; mdesc = of_flat_dt_match_machine(NULL, arch_get_next_mach); diff --git a/arch/arc/kernel/entry-arcv2.S b/arch/arc/kernel/entry-arcv2.S index a7e6a2174187..e238b5fd3c8c 100644 --- a/arch/arc/kernel/entry-arcv2.S +++ b/arch/arc/kernel/entry-arcv2.S @@ -5,7 +5,7 @@ * Copyright (C) 2013 Synopsys, Inc. (www.synopsys.com) */ -#include <linux/linkage.h> /* ARC_{EXTRY,EXIT} */ +#include <linux/linkage.h> /* ARC_{ENTRY,EXIT} */ #include <asm/entry.h> /* SAVE_ALL_{INT1,INT2,TRAP...} */ #include <asm/errno.h> #include <asm/arcregs.h> @@ -31,7 +31,7 @@ VECTOR res_service ; Reset Vector VECTOR mem_service ; Mem exception VECTOR instr_service ; Instrn Error VECTOR EV_MachineCheck ; Fatal Machine check -VECTOR EV_TLBMissI ; Intruction TLB miss +VECTOR EV_TLBMissI ; Instruction TLB miss VECTOR EV_TLBMissD ; Data TLB miss VECTOR EV_TLBProtV ; Protection Violation VECTOR EV_PrivilegeV ; Privilege Violation @@ -76,11 +76,11 @@ ENTRY(handle_interrupt) # query in hard ISR path would return false (since .IE is set) which would # trips genirq interrupt handling asserts. # - # So do a "soft" disable of interrutps here. + # So do a "soft" disable of interrupts here. # # Note this disable is only for consistent book-keeping as further interrupts # will be disabled anyways even w/o this. Hardware tracks active interrupts - # seperately in AUX_IRQ_ACT.active and will not take new interrupts + # separately in AUX_IRQ_ACT.active and will not take new interrupts # unless this one returns (or higher prio becomes pending in 2-prio scheme) IRQ_DISABLE @@ -125,11 +125,6 @@ ENTRY(mem_service) EXCEPTION_PROLOGUE - lr r0, [efa] - mov r1, sp - - FAKE_RET_FROM_EXCPN - bl do_memory_error b ret_from_exception END(mem_service) @@ -138,11 +133,6 @@ ENTRY(EV_Misaligned) EXCEPTION_PROLOGUE - lr r0, [efa] ; Faulting Data address - mov r1, sp - - FAKE_RET_FROM_EXCPN - SAVE_CALLEE_SAVED_USER mov r2, sp ; callee_regs @@ -163,11 +153,6 @@ ENTRY(EV_TLBProtV) EXCEPTION_PROLOGUE - lr r0, [efa] ; Faulting Data address - mov r1, sp ; pt_regs - - FAKE_RET_FROM_EXCPN - mov blink, ret_from_exception b do_page_fault diff --git a/arch/arc/kernel/entry-compact.S b/arch/arc/kernel/entry-compact.S index 5cb0cd7e4eab..774c03cc1d1a 100644 --- a/arch/arc/kernel/entry-compact.S +++ b/arch/arc/kernel/entry-compact.S @@ -254,18 +254,7 @@ END(handle_interrupt_level1) ENTRY(EV_TLBProtV) - EXCEPTION_PROLOGUE - - mov r2, r10 ; ECR set into r10 already - lr r0, [efa] ; Faulting Data address (not part of pt_regs saved above) - - ; Exception auto-disables further Intr/exceptions. - ; Re-enable them by pretending to return from exception - ; (so rest of handler executes in pure K mode) - - FAKE_RET_FROM_EXCPN - - mov r1, sp ; Handle to pt_regs + EXCEPTION_PROLOGUE ; ECR returned in r10 ;------ (5) Type of Protection Violation? ---------- ; @@ -273,8 +262,7 @@ ENTRY(EV_TLBProtV) ; -Access Violation : 00_23_(00|01|02|03)_00 ; x r w r+w ; -Unaligned Access : 00_23_04_00 - ; - bbit1 r2, ECR_C_BIT_PROTV_MISALIG_DATA, 4f + bbit1 r10, ECR_C_BIT_PROTV_MISALIG_DATA, 4f ;========= (6a) Access Violation Processing ======== bl do_page_fault @@ -303,9 +291,6 @@ END(EV_TLBProtV) ENTRY(call_do_page_fault) EXCEPTION_PROLOGUE - lr r0, [efa] ; Faulting Data address - mov r1, sp - FAKE_RET_FROM_EXCPN mov blink, ret_from_exception b do_page_fault diff --git a/arch/arc/kernel/entry.S b/arch/arc/kernel/entry.S index 54e91df678dd..3c7e74aba679 100644 --- a/arch/arc/kernel/entry.S +++ b/arch/arc/kernel/entry.S @@ -80,11 +80,6 @@ ENTRY(instr_service) EXCEPTION_PROLOGUE - lr r0, [efa] - mov r1, sp - - FAKE_RET_FROM_EXCPN - bl do_insterror_or_kprobe b ret_from_exception END(instr_service) @@ -95,16 +90,15 @@ END(instr_service) ENTRY(EV_MachineCheck) - EXCEPTION_PROLOGUE + EXCEPTION_PROLOGUE_KEEP_AE ; ECR returned in r10 - lr r2, [ecr] lr r0, [efa] mov r1, sp - ; MC excpetions disable MMU + ; MC exceptions disable MMU ARC_MMU_REENABLE r3 - lsr r3, r2, 8 + lsr r3, r10, 8 bmsk r3, r3, 7 brne r3, ECR_C_MCHK_DUP_TLB, 1f @@ -129,11 +123,6 @@ ENTRY(EV_PrivilegeV) EXCEPTION_PROLOGUE - lr r0, [efa] - mov r1, sp - - FAKE_RET_FROM_EXCPN - bl do_privilege_fault b ret_from_exception END(EV_PrivilegeV) @@ -145,11 +134,6 @@ ENTRY(EV_Extension) EXCEPTION_PROLOGUE - lr r0, [efa] - mov r1, sp - - FAKE_RET_FROM_EXCPN - bl do_extension_fault b ret_from_exception END(EV_Extension) @@ -160,20 +144,19 @@ END(EV_Extension) ; syscall Tracing ; --------------------------------------------- tracesys: - ; save EFA in case tracer wants the PC of traced task - ; using ERET won't work since next-PC has already committed + ; safekeep EFA (r12) if syscall tracer wanted PC + ; for traps, ERET is pre-commit so points to next-PC GET_CURR_TASK_FIELD_PTR TASK_THREAD, r11 st r12, [r11, THREAD_FAULT_ADDR] ; thread.fault_address - ; PRE Sys Call Ptrace hook - mov r0, sp ; pt_regs needed - bl @syscall_trace_entry + ; PRE syscall trace hook + mov r0, sp ; pt_regs + bl @syscall_trace_enter ; Tracing code now returns the syscall num (orig or modif) mov r8, r0 ; Do the Sys Call as we normally would. - ; Validate the Sys Call number cmp r8, NR_syscalls - 1 mov.hi r0, -ENOSYS bhi tracesys_exit @@ -190,79 +173,74 @@ tracesys: ld r6, [sp, PT_r6] ld r7, [sp, PT_r7] ld.as r9, [sys_call_table, r8] - jl [r9] ; Entry into Sys Call Handler + jl [r9] tracesys_exit: - st r0, [sp, PT_r0] ; sys call return value in pt_regs + st r0, [sp, PT_r0] - ;POST Sys Call Ptrace Hook + ; POST syscall trace hook mov r0, sp ; pt_regs needed bl @syscall_trace_exit - b ret_from_exception ; NOT ret_from_system_call at is saves r0 which - ; we'd done before calling post hook above + + ; don't call ret_from_system_call as it saves r0, already done above + b ret_from_exception ; --------------------------------------------- ; Breakpoint TRAP ; --------------------------------------------- trap_with_param: mov r0, r12 ; EFA in case ptracer/gdb wants stop_pc - mov r1, sp + mov r1, sp ; pt_regs - ; Save callee regs in case gdb wants to have a look - ; SP will grow up by size of CALLEE Reg-File - ; NOTE: clobbers r12 + ; save callee regs in case tracer/gdb wants to peek SAVE_CALLEE_SAVED_USER - ; save location of saved Callee Regs @ thread_struct->pc + ; safekeep ref to callee regs GET_CURR_TASK_FIELD_PTR TASK_THREAD, r10 st sp, [r10, THREAD_CALLEE_REG] - ; Call the trap handler + ; call the non syscall trap handler bl do_non_swi_trap - ; unwind stack to discard Callee saved Regs + ; unwind stack to discard callee regs DISCARD_CALLEE_SAVED_USER b ret_from_exception ; --------------------------------------------- ; syscall TRAP -; ABI: (r0-r7) upto 8 args, (r8) syscall number +; ABI: (r0-r7) up to 8 args, (r8) syscall number ; --------------------------------------------- ENTRY(EV_Trap) - EXCEPTION_PROLOGUE + EXCEPTION_PROLOGUE_KEEP_AE lr r12, [efa] FAKE_RET_FROM_EXCPN - ;============ TRAP 1 :breakpoints - ; Check ECR for trap with arg (PROLOGUE ensures r10 has ECR) + ;============ TRAP N : breakpoints, kprobes etc bmsk.f 0, r10, 7 bnz trap_with_param - ;============ TRAP (no param): syscall top level + ;============ TRAP 0 (no param): syscall - ; If syscall tracing ongoing, invoke pre-post-hooks + ; syscall tracing ongoing, invoke pre-post-hooks around syscall GET_CURR_THR_INFO_FLAGS r10 and.f 0, r10, _TIF_SYSCALL_WORK bnz tracesys ; this never comes back ;============ Normal syscall case - ; syscall num shd not exceed the total system calls avail cmp r8, NR_syscalls - 1 mov.hi r0, -ENOSYS bhi .Lret_from_system_call - ; Offset into the syscall_table and call handler ld.as r9,[sys_call_table, r8] - jl [r9] ; Entry into Sys Call Handler + jl [r9] .Lret_from_system_call: - st r0, [sp, PT_r0] ; sys call return value in pt_regs ; fall through to ret_from_exception @@ -318,7 +296,7 @@ resume_user_mode_begin: ; tracer might call PEEKUSR(CALLEE reg) ; ; NOTE: SP will grow up by size of CALLEE Reg-File - SAVE_CALLEE_SAVED_USER ; clobbers r12 + SAVE_CALLEE_SAVED_USER ; save location of saved Callee Regs @ thread_struct->callee GET_CURR_TASK_FIELD_PTR TASK_THREAD, r10 diff --git a/arch/arc/kernel/head.S b/arch/arc/kernel/head.S index 9152782444b5..8d541f53fae3 100644 --- a/arch/arc/kernel/head.S +++ b/arch/arc/kernel/head.S @@ -165,7 +165,7 @@ ENTRY(first_lines_of_secondary) ; setup stack (fp, sp) mov fp, 0 - ; set it's stack base to tsk->thread_info bottom + ; set its stack base to tsk->thread_info bottom GET_TSK_STACK_BASE r0, sp j start_kernel_secondary diff --git a/arch/arc/kernel/intc-arcv2.c b/arch/arc/kernel/intc-arcv2.c index 5cda19d0aa91..809edc59af25 100644 --- a/arch/arc/kernel/intc-arcv2.c +++ b/arch/arc/kernel/intc-arcv2.c @@ -56,7 +56,7 @@ void arc_init_IRQ(void) WRITE_AUX(AUX_IRQ_CTRL, ictrl); /* - * ARCv2 core intc provides multiple interrupt priorities (upto 16). + * ARCv2 core intc provides multiple interrupt priorities (up to 16). * Typical builds though have only two levels (0-high, 1-low) * Linux by default uses lower prio 1 for most irqs, reserving 0 for * NMI style interrupts in future (say perf) @@ -108,7 +108,7 @@ static void arcv2_irq_unmask(struct irq_data *data) write_aux_reg(AUX_IRQ_ENABLE, 1); } -void arcv2_irq_enable(struct irq_data *data) +static void arcv2_irq_enable(struct irq_data *data) { /* set default priority */ write_aux_reg(AUX_IRQ_SELECT, data->hwirq); @@ -170,7 +170,7 @@ init_onchip_IRQ(struct device_node *intc, struct device_node *parent) if (parent) panic("DeviceTree incore intc not a root irq controller\n"); - root_domain = irq_domain_add_linear(intc, nr_cpu_irqs, &arcv2_irq_ops, NULL); + root_domain = irq_domain_create_linear(of_fwnode_handle(intc), nr_cpu_irqs, &arcv2_irq_ops, NULL); if (!root_domain) panic("root irq domain not avail\n"); @@ -178,7 +178,7 @@ init_onchip_IRQ(struct device_node *intc, struct device_node *parent) * Needed for primary domain lookup to succeed * This is a primary irqchip, and can never have a parent */ - irq_set_default_host(root_domain); + irq_set_default_domain(root_domain); #ifdef CONFIG_SMP irq_create_mapping(root_domain, IPI_IRQ); diff --git a/arch/arc/kernel/intc-compact.c b/arch/arc/kernel/intc-compact.c index 6885e422870e..1b159e9e0234 100644 --- a/arch/arc/kernel/intc-compact.c +++ b/arch/arc/kernel/intc-compact.c @@ -112,8 +112,9 @@ init_onchip_IRQ(struct device_node *intc, struct device_node *parent) if (parent) panic("DeviceTree incore intc not a root irq controller\n"); - root_domain = irq_domain_add_linear(intc, NR_CPU_IRQS, - &arc_intc_domain_ops, NULL); + root_domain = irq_domain_create_linear(of_fwnode_handle(intc), + NR_CPU_IRQS, + &arc_intc_domain_ops, NULL); if (!root_domain) panic("root irq domain not avail\n"); @@ -121,7 +122,7 @@ init_onchip_IRQ(struct device_node *intc, struct device_node *parent) * Needed for primary domain lookup to succeed * This is a primary irqchip, and can never have a parent */ - irq_set_default_host(root_domain); + irq_set_default_domain(root_domain); return 0; } diff --git a/arch/arc/kernel/kgdb.c b/arch/arc/kernel/kgdb.c index 345a0000554c..4f2b5951454f 100644 --- a/arch/arc/kernel/kgdb.c +++ b/arch/arc/kernel/kgdb.c @@ -175,7 +175,7 @@ void kgdb_trap(struct pt_regs *regs) * with trap_s 4 (compiled) breakpoints, continuation needs to * start after the breakpoint. */ - if (regs->ecr_param == 3) + if (regs->ecr.param == 3) instruction_pointer(regs) -= BREAK_INSTR_SIZE; kgdb_handle_exception(1, SIGTRAP, 0, regs); diff --git a/arch/arc/kernel/kprobes.c b/arch/arc/kernel/kprobes.c index e71d64119d71..f8e2960832d9 100644 --- a/arch/arc/kernel/kprobes.c +++ b/arch/arc/kernel/kprobes.c @@ -190,7 +190,8 @@ static void __kprobes setup_singlestep(struct kprobe *p, struct pt_regs *regs) } } -int __kprobes arc_kprobe_handler(unsigned long addr, struct pt_regs *regs) +static int +__kprobes arc_kprobe_handler(unsigned long addr, struct pt_regs *regs) { struct kprobe *p; struct kprobe_ctlblk *kcb; @@ -241,8 +242,8 @@ int __kprobes arc_kprobe_handler(unsigned long addr, struct pt_regs *regs) return 0; } -static int __kprobes arc_post_kprobe_handler(unsigned long addr, - struct pt_regs *regs) +static int +__kprobes arc_post_kprobe_handler(unsigned long addr, struct pt_regs *regs) { struct kprobe *cur = kprobe_running(); struct kprobe_ctlblk *kcb = get_kprobe_ctlblk(); diff --git a/arch/arc/kernel/mcip.c b/arch/arc/kernel/mcip.c index f9fdb557c263..02b28a9324f4 100644 --- a/arch/arc/kernel/mcip.c +++ b/arch/arc/kernel/mcip.c @@ -165,8 +165,6 @@ static void mcip_probe_n_setup(void) IS_AVAIL1(mp.idu, "IDU "), IS_AVAIL1(mp.dbg, "DEBUG "), IS_AVAIL1(mp.gfrc, "GFRC")); - - cpuinfo_arc700[0].extn.gfrc = mp.gfrc; } struct plat_smp_ops plat_smp_ops = { @@ -359,8 +357,6 @@ static void idu_cascade_isr(struct irq_desc *desc) static int idu_irq_map(struct irq_domain *d, unsigned int virq, irq_hw_number_t hwirq) { irq_set_chip_and_handler(virq, &idu_irq_chip, handle_level_irq); - irq_set_status_flags(virq, IRQ_MOVE_PCNTXT); - return 0; } @@ -395,7 +391,8 @@ idu_of_init(struct device_node *intc, struct device_node *parent) pr_info("MCIP: IDU supports %u common irqs\n", nr_irqs); - domain = irq_domain_add_linear(intc, nr_irqs, &idu_irq_ops, NULL); + domain = irq_domain_create_linear(of_fwnode_handle(intc), nr_irqs, + &idu_irq_ops, NULL); /* Parent interrupts (core-intc) are already mapped */ diff --git a/arch/arc/kernel/perf_event.c b/arch/arc/kernel/perf_event.c index adff957962da..ed6d4f0cd621 100644 --- a/arch/arc/kernel/perf_event.c +++ b/arch/arc/kernel/perf_event.c @@ -38,7 +38,7 @@ * (based on a specific RTL build) * Below is the static map between perf generic/arc specific event_id and * h/w condition names. - * At the time of probe, we loop thru each index and find it's name to + * At the time of probe, we loop thru each index and find its name to * complete the mapping of perf event_id to h/w index as latter is needed * to program the counter really */ @@ -599,10 +599,8 @@ static irqreturn_t arc_pmu_intr(int irq, void *dev) arc_perf_event_update(event, &event->hw, event->hw.idx); perf_sample_data_init(&data, 0, hwc->last_period); - if (arc_pmu_event_set_period(event)) { - if (perf_event_overflow(event, &data, regs)) - arc_pmu_stop(event, 0); - } + if (arc_pmu_event_set_period(event)) + perf_event_overflow(event, &data, regs); active_ints &= ~BIT(idx); } while (active_ints); diff --git a/arch/arc/kernel/process.c b/arch/arc/kernel/process.c index 3369f0700702..186ceab661eb 100644 --- a/arch/arc/kernel/process.c +++ b/arch/arc/kernel/process.c @@ -114,6 +114,8 @@ void arch_cpu_idle(void) "sleep %0 \n" : :"I"(arg)); /* can't be "r" has to be embedded const */ + + raw_local_irq_disable(); } #else /* ARC700 */ @@ -122,6 +124,7 @@ void arch_cpu_idle(void) { /* sleep, but enable both set E1/E2 (levels of interrupts) before committing */ __asm__ __volatile__("sleep 0x3 \n"); + raw_local_irq_disable(); } #endif @@ -138,7 +141,7 @@ asmlinkage void ret_from_fork(void); * | unused | * | | * ------------------ - * | r25 | <==== top of Stack (thread.ksp) + * | r25 | <==== top of Stack (thread_info.ksp) * ~ ~ * | --to-- | (CALLEE Regs of kernel mode) * | r13 | @@ -159,7 +162,6 @@ asmlinkage void ret_from_fork(void); * | SP | * | orig_r0 | * | event/ECR | - * | user_r25 | * ------------------ <===== END of PAGE */ int copy_thread(struct task_struct *p, const struct kernel_clone_args *args) @@ -179,14 +181,14 @@ int copy_thread(struct task_struct *p, const struct kernel_clone_args *args) c_callee = ((struct callee_regs *)childksp) - 1; /* - * __switch_to() uses thread.ksp to start unwinding stack + * __switch_to() uses thread_info.ksp to start unwinding stack * For kernel threads we don't need to create callee regs, the * stack layout nevertheless needs to remain the same. * Also, since __switch_to anyways unwinds callee regs, we use * this to populate kernel thread entry-pt/args into callee regs, * so that ret_from_kernel_thread() becomes simpler. */ - p->thread.ksp = (unsigned long)c_callee; /* THREAD_KSP */ + task_thread_info(p)->ksp = (unsigned long)c_callee; /* THREAD_INFO_KSP */ /* __switch_to expects FP(0), BLINK(return addr) at top */ childksp[0] = 0; /* fp */ @@ -240,16 +242,6 @@ int copy_thread(struct task_struct *p, const struct kernel_clone_args *args) */ c_callee->r25 = task_thread_info(p)->thr_ptr; -#ifdef CONFIG_ARC_CURR_IN_REG - /* - * setup usermode thread pointer #2: - * however for this special use of r25 in kernel, __switch_to() sets - * r25 for kernel needs and only in the final return path is usermode - * r25 setup, from pt_regs->user_r25. So set that up as well - */ - c_regs->user_r25 = c_callee->r25; -#endif - return 0; } diff --git a/arch/arc/kernel/ptrace.c b/arch/arc/kernel/ptrace.c index da7542cea0d8..e0c233c178b1 100644 --- a/arch/arc/kernel/ptrace.c +++ b/arch/arc/kernel/ptrace.c @@ -46,8 +46,7 @@ static const struct pt_regs_offset regoffset_table[] = { REG_OFFSET_NAME(r0), REG_OFFSET_NAME(sp), REG_OFFSET_NAME(orig_r0), - REG_OFFSET_NAME(event), - REG_OFFSET_NAME(user_r25), + REG_OFFSET_NAME(ecr), REG_OFFSET_END, }; @@ -55,9 +54,8 @@ static const struct pt_regs_offset regoffset_table[] = { static const struct pt_regs_offset regoffset_table[] = { REG_OFFSET_NAME(orig_r0), - REG_OFFSET_NAME(event), + REG_OFFSET_NAME(ecr), REG_OFFSET_NAME(bta), - REG_OFFSET_NAME(user_r25), REG_OFFSET_NAME(r26), REG_OFFSET_NAME(fp), REG_OFFSET_NAME(sp), @@ -185,7 +183,7 @@ static int genregs_set(struct task_struct *target, #define REG_IGNORE_ONE(LOC) \ if (!ret) \ - ret = user_regset_copyin_ignore(&pos, &count, &kbuf, &ubuf, \ + user_regset_copyin_ignore(&pos, &count, &kbuf, &ubuf, \ offsetof(struct user_regs_struct, LOC), \ offsetof(struct user_regs_struct, LOC) + 4); @@ -341,7 +339,7 @@ long arch_ptrace(struct task_struct *child, long request, return ret; } -asmlinkage int syscall_trace_entry(struct pt_regs *regs) +asmlinkage int syscall_trace_enter(struct pt_regs *regs) { if (test_thread_flag(TIF_SYSCALL_TRACE)) if (ptrace_report_syscall_entry(regs)) diff --git a/arch/arc/kernel/setup.c b/arch/arc/kernel/setup.c index 41f07b3e594e..7b6a9beba9db 100644 --- a/arch/arc/kernel/setup.c +++ b/arch/arc/kernel/setup.c @@ -29,6 +29,7 @@ #include <asm/mach_desc.h> #include <asm/smp.h> #include <asm/dsp-impl.h> +#include <soc/arc/mcip.h> #define FIX_PTR(x) __asm__ __volatile__(";" : "+r"(x)) @@ -43,19 +44,22 @@ const struct machine_desc *machine_desc; struct task_struct *_current_task[NR_CPUS]; /* For stack switching */ -struct cpuinfo_arc cpuinfo_arc700[NR_CPUS]; +struct cpuinfo_arc { + int arcver; + unsigned int t0:1, t1:1; + struct { + unsigned long base; + unsigned int sz; + } iccm, dccm; +}; + +#ifdef CONFIG_ISA_ARCV2 -static const struct id_to_str arc_legacy_rel[] = { +static const struct id_to_str arc_hs_rel[] = { /* ID.ARCVER, Release */ -#ifdef CONFIG_ISA_ARCOMPACT - { 0x34, "R4.10"}, - { 0x35, "R4.11"}, -#else { 0x51, "R2.0" }, { 0x52, "R2.1" }, { 0x53, "R3.0" }, -#endif - { 0x00, NULL } }; static const struct id_to_str arc_hs_ver54_rel[] = { @@ -66,323 +70,294 @@ static const struct id_to_str arc_hs_ver54_rel[] = { { 3, "R4.00a"}, { 0xFF, NULL } }; +#endif -static void read_decode_ccm_bcr(struct cpuinfo_arc *cpu) +static int +arcompact_mumbojumbo(int c, struct cpuinfo_arc *info, char *buf, int len) { - if (is_isa_arcompact()) { - struct bcr_iccm_arcompact iccm; - struct bcr_dccm_arcompact dccm; + int n = 0; +#ifdef CONFIG_ISA_ARCOMPACT + char *cpu_nm, *isa_nm = "ARCompact"; + struct bcr_fp_arcompact fpu_sp, fpu_dp; + int atomic = 0, be, present; + int bpu_full, bpu_cache, bpu_pred; + struct bcr_bpu_arcompact bpu; + struct bcr_iccm_arcompact iccm; + struct bcr_dccm_arcompact dccm; + struct bcr_generic isa; - READ_BCR(ARC_REG_ICCM_BUILD, iccm); - if (iccm.ver) { - cpu->iccm.sz = 4096 << iccm.sz; /* 8K to 512K */ - cpu->iccm.base_addr = iccm.base << 16; - } + READ_BCR(ARC_REG_ISA_CFG_BCR, isa); - READ_BCR(ARC_REG_DCCM_BUILD, dccm); - if (dccm.ver) { - unsigned long base; - cpu->dccm.sz = 2048 << dccm.sz; /* 2K to 256K */ + if (!isa.ver) /* ISA BCR absent, use Kconfig info */ + atomic = IS_ENABLED(CONFIG_ARC_HAS_LLSC); + else { + /* ARC700_BUILD only has 2 bits of isa info */ + atomic = isa.info & 1; + } - base = read_aux_reg(ARC_REG_DCCM_BASE_BUILD); - cpu->dccm.base_addr = base & ~0xF; - } - } else { - struct bcr_iccm_arcv2 iccm; - struct bcr_dccm_arcv2 dccm; - unsigned long region; - - READ_BCR(ARC_REG_ICCM_BUILD, iccm); - if (iccm.ver) { - cpu->iccm.sz = 256 << iccm.sz00; /* 512B to 16M */ - if (iccm.sz00 == 0xF && iccm.sz01 > 0) - cpu->iccm.sz <<= iccm.sz01; - - region = read_aux_reg(ARC_REG_AUX_ICCM); - cpu->iccm.base_addr = region & 0xF0000000; - } + be = IS_ENABLED(CONFIG_CPU_BIG_ENDIAN); - READ_BCR(ARC_REG_DCCM_BUILD, dccm); - if (dccm.ver) { - cpu->dccm.sz = 256 << dccm.sz0; - if (dccm.sz0 == 0xF && dccm.sz1 > 0) - cpu->dccm.sz <<= dccm.sz1; + if (info->arcver < 0x34) + cpu_nm = "ARC750"; + else + cpu_nm = "ARC770"; - region = read_aux_reg(ARC_REG_AUX_DCCM); - cpu->dccm.base_addr = region & 0xF0000000; - } - } -} + n += scnprintf(buf + n, len - n, "processor [%d]\t: %s (%s ISA) %s%s%s\n", + c, cpu_nm, isa_nm, + IS_AVAIL2(atomic, "atomic ", CONFIG_ARC_HAS_LLSC), + IS_AVAIL1(be, "[Big-Endian]")); -static void decode_arc_core(struct cpuinfo_arc *cpu) -{ - struct bcr_uarch_build_arcv2 uarch; - const struct id_to_str *tbl; - - if (cpu->core.family < 0x54) { /* includes arc700 */ + READ_BCR(ARC_REG_FP_BCR, fpu_sp); + READ_BCR(ARC_REG_DPFP_BCR, fpu_dp); - for (tbl = &arc_legacy_rel[0]; tbl->id != 0; tbl++) { - if (cpu->core.family == tbl->id) { - cpu->release = tbl->str; - break; - } - } + if (fpu_sp.ver | fpu_dp.ver) + n += scnprintf(buf + n, len - n, "FPU\t\t: %s%s\n", + IS_AVAIL1(fpu_sp.ver, "SP "), + IS_AVAIL1(fpu_dp.ver, "DP ")); - if (is_isa_arcompact()) - cpu->name = "ARC700"; - else if (tbl->str) - cpu->name = "HS38"; - else - cpu->name = cpu->release = "Unknown"; + READ_BCR(ARC_REG_BPU_BCR, bpu); + bpu_full = bpu.fam ? 1 : 0; + bpu_cache = 256 << (bpu.ent - 1); + bpu_pred = 256 << (bpu.ent - 1); - return; + n += scnprintf(buf + n, len - n, + "BPU\t\t: %s%s match, cache:%d, Predict Table:%d\n", + IS_AVAIL1(bpu_full, "full"), + IS_AVAIL1(!bpu_full, "partial"), + bpu_cache, bpu_pred); + + READ_BCR(ARC_REG_ICCM_BUILD, iccm); + if (iccm.ver) { + info->iccm.sz = 4096 << iccm.sz; /* 8K to 512K */ + info->iccm.base = iccm.base << 16; } - /* - * Initial HS cores bumped AUX IDENTITY.ARCVER for each release until - * ARCVER 0x54 which introduced AUX MICRO_ARCH_BUILD and subsequent - * releases only update it. - */ - READ_BCR(ARC_REG_MICRO_ARCH_BCR, uarch); - - if (uarch.prod == 4) { - cpu->name = "HS48"; - cpu->extn.dual = 1; + READ_BCR(ARC_REG_DCCM_BUILD, dccm); + if (dccm.ver) { + unsigned long base; + info->dccm.sz = 2048 << dccm.sz; /* 2K to 256K */ - } else { - cpu->name = "HS38"; + base = read_aux_reg(ARC_REG_DCCM_BASE_BUILD); + info->dccm.base = base & ~0xF; } - for (tbl = &arc_hs_ver54_rel[0]; tbl->id != 0xFF; tbl++) { - if (uarch.maj == tbl->id) { - cpu->release = tbl->str; - break; - } - } + /* ARCompact ISA specific sanity checks */ + present = fpu_dp.ver; /* SP has no arch visible regs */ + CHK_OPT_STRICT(CONFIG_ARC_FPU_SAVE_RESTORE, present); +#endif + return n; + } -static void read_arc_build_cfg_regs(void) +static int arcv2_mumbojumbo(int c, struct cpuinfo_arc *info, char *buf, int len) { - struct bcr_timer timer; - struct bcr_generic bcr; - struct cpuinfo_arc *cpu = &cpuinfo_arc700[smp_processor_id()]; + int n = 0; +#ifdef CONFIG_ISA_ARCV2 + const char *release = "", *cpu_nm = "HS38", *isa_nm = "ARCv2"; + int dual_issue = 0, dual_enb = 0, mpy_opt, present; + int bpu_full, bpu_cache, bpu_pred, bpu_ret_stk; + char mpy_nm[16], lpb_nm[32]; struct bcr_isa_arcv2 isa; - struct bcr_actionpoint ap; - - FIX_PTR(cpu); + struct bcr_mpy mpy; + struct bcr_fp_arcv2 fpu; + struct bcr_bpu_arcv2 bpu; + struct bcr_lpb lpb; + struct bcr_iccm_arcv2 iccm; + struct bcr_dccm_arcv2 dccm; + struct bcr_erp erp; - READ_BCR(AUX_IDENTITY, cpu->core); - decode_arc_core(cpu); - - READ_BCR(ARC_REG_TIMERS_BCR, timer); - cpu->extn.timer0 = timer.t0; - cpu->extn.timer1 = timer.t1; - cpu->extn.rtc = timer.rtc; - - cpu->vec_base = read_aux_reg(AUX_INTR_VEC_BASE); - - READ_BCR(ARC_REG_MUL_BCR, cpu->extn_mpy); + /* + * Initial HS cores bumped AUX IDENTITY.ARCVER for each release until + * ARCVER 0x54 which introduced AUX MICRO_ARCH_BUILD and subsequent + * releases only update it. + */ - /* Read CCM BCRs for boot reporting even if not enabled in Kconfig */ - read_decode_ccm_bcr(cpu); + if (info->arcver > 0x50 && info->arcver <= 0x53) { + release = arc_hs_rel[info->arcver - 0x51].str; + } else { + const struct id_to_str *tbl; + struct bcr_uarch_build uarch; - read_decode_mmu_bcr(); - read_decode_cache_bcr(); + READ_BCR(ARC_REG_MICRO_ARCH_BCR, uarch); - if (is_isa_arcompact()) { - struct bcr_fp_arcompact sp, dp; - struct bcr_bpu_arcompact bpu; - - READ_BCR(ARC_REG_FP_BCR, sp); - READ_BCR(ARC_REG_DPFP_BCR, dp); - cpu->extn.fpu_sp = sp.ver ? 1 : 0; - cpu->extn.fpu_dp = dp.ver ? 1 : 0; - - READ_BCR(ARC_REG_BPU_BCR, bpu); - cpu->bpu.ver = bpu.ver; - cpu->bpu.full = bpu.fam ? 1 : 0; - if (bpu.ent) { - cpu->bpu.num_cache = 256 << (bpu.ent - 1); - cpu->bpu.num_pred = 256 << (bpu.ent - 1); + for (tbl = &arc_hs_ver54_rel[0]; tbl->id != 0xFF; tbl++) { + if (uarch.maj == tbl->id) { + release = tbl->str; + break; + } } - } else { - struct bcr_fp_arcv2 spdp; - struct bcr_bpu_arcv2 bpu; - - READ_BCR(ARC_REG_FP_V2_BCR, spdp); - cpu->extn.fpu_sp = spdp.sp ? 1 : 0; - cpu->extn.fpu_dp = spdp.dp ? 1 : 0; - - READ_BCR(ARC_REG_BPU_BCR, bpu); - cpu->bpu.ver = bpu.ver; - cpu->bpu.full = bpu.ft; - cpu->bpu.num_cache = 256 << bpu.bce; - cpu->bpu.num_pred = 2048 << bpu.pte; - cpu->bpu.ret_stk = 4 << bpu.rse; - - /* if dual issue hardware, is it enabled ? */ - if (cpu->extn.dual) { + if (uarch.prod == 4) { unsigned int exec_ctrl; + cpu_nm = "HS48"; + dual_issue = 1; + /* if dual issue hardware, is it enabled ? */ READ_BCR(AUX_EXEC_CTRL, exec_ctrl); - cpu->extn.dual_enb = !(exec_ctrl & 1); + dual_enb = !(exec_ctrl & 1); } } - READ_BCR(ARC_REG_AP_BCR, ap); - if (ap.ver) { - cpu->extn.ap_num = 2 << ap.num; - cpu->extn.ap_full = !ap.min; - } - - READ_BCR(ARC_REG_SMART_BCR, bcr); - cpu->extn.smart = bcr.ver ? 1 : 0; - - READ_BCR(ARC_REG_RTT_BCR, bcr); - cpu->extn.rtt = bcr.ver ? 1 : 0; - READ_BCR(ARC_REG_ISA_CFG_BCR, isa); - /* some hacks for lack of feature BCR info in old ARC700 cores */ - if (is_isa_arcompact()) { - if (!isa.ver) /* ISA BCR absent, use Kconfig info */ - cpu->isa.atomic = IS_ENABLED(CONFIG_ARC_HAS_LLSC); - else { - /* ARC700_BUILD only has 2 bits of isa info */ - struct bcr_generic bcr = *(struct bcr_generic *)&isa; - cpu->isa.atomic = bcr.info & 1; - } - - cpu->isa.be = IS_ENABLED(CONFIG_CPU_BIG_ENDIAN); + n += scnprintf(buf + n, len - n, "processor [%d]\t: %s %s (%s ISA) %s%s%s\n", + c, cpu_nm, release, isa_nm, + IS_AVAIL1(isa.be, "[Big-Endian]"), + IS_AVAIL3(dual_issue, dual_enb, " Dual-Issue ")); + + READ_BCR(ARC_REG_MPY_BCR, mpy); + mpy_opt = 2; /* stock MPY/MPYH */ + if (mpy.dsp) /* OPT 7-9 */ + mpy_opt = mpy.dsp + 6; + + scnprintf(mpy_nm, 16, "mpy[opt %d] ", mpy_opt); + + READ_BCR(ARC_REG_FP_V2_BCR, fpu); + + n += scnprintf(buf + n, len - n, "ISA Extn\t: %s%s%s%s%s%s%s%s%s%s%s\n", + IS_AVAIL2(isa.atomic, "atomic ", CONFIG_ARC_HAS_LLSC), + IS_AVAIL2(isa.ldd, "ll64 ", CONFIG_ARC_HAS_LL64), + IS_AVAIL2(isa.unalign, "unalign ", CONFIG_ARC_USE_UNALIGNED_MEM_ACCESS), + IS_AVAIL1(mpy.ver, mpy_nm), + IS_AVAIL1(isa.div_rem, "div_rem "), + IS_AVAIL1((fpu.sp | fpu.dp), " FPU:"), + IS_AVAIL1(fpu.sp, " sp"), + IS_AVAIL1(fpu.dp, " dp")); + + READ_BCR(ARC_REG_BPU_BCR, bpu); + bpu_full = bpu.ft; + bpu_cache = 256 << bpu.bce; + bpu_pred = 2048 << bpu.pte; + bpu_ret_stk = 4 << bpu.rse; + + READ_BCR(ARC_REG_LPB_BUILD, lpb); + if (lpb.ver) { + unsigned int ctl; + ctl = read_aux_reg(ARC_REG_LPB_CTRL); + + scnprintf(lpb_nm, sizeof(lpb_nm), " Loop Buffer:%d %s", + lpb.entries, IS_DISABLED_RUN(!ctl)); + } - /* there's no direct way to distinguish 750 vs. 770 */ - if (unlikely(cpu->core.family < 0x34 || cpu->mmu.ver < 3)) - cpu->name = "ARC750"; - } else { - cpu->isa = isa; + n += scnprintf(buf + n, len - n, + "BPU\t\t: %s%s match, cache:%d, Predict Table:%d Return stk: %d%s\n", + IS_AVAIL1(bpu_full, "full"), + IS_AVAIL1(!bpu_full, "partial"), + bpu_cache, bpu_pred, bpu_ret_stk, + lpb_nm); + + READ_BCR(ARC_REG_ICCM_BUILD, iccm); + if (iccm.ver) { + unsigned long base; + info->iccm.sz = 256 << iccm.sz00; /* 512B to 16M */ + if (iccm.sz00 == 0xF && iccm.sz01 > 0) + info->iccm.sz <<= iccm.sz01; + base = read_aux_reg(ARC_REG_AUX_ICCM); + info->iccm.base = base & 0xF0000000; } -} -static char *arc_cpu_mumbojumbo(int cpu_id, char *buf, int len) -{ - struct cpuinfo_arc *cpu = &cpuinfo_arc700[cpu_id]; - struct bcr_identity *core = &cpu->core; - char mpy_opt[16]; - int n = 0; + READ_BCR(ARC_REG_DCCM_BUILD, dccm); + if (dccm.ver) { + unsigned long base; + info->dccm.sz = 256 << dccm.sz0; + if (dccm.sz0 == 0xF && dccm.sz1 > 0) + info->dccm.sz <<= dccm.sz1; + base = read_aux_reg(ARC_REG_AUX_DCCM); + info->dccm.base = base & 0xF0000000; + } - FIX_PTR(cpu); + /* Error Protection: ECC/Parity */ + READ_BCR(ARC_REG_ERP_BUILD, erp); + if (erp.ver) { + struct ctl_erp ctl; + READ_BCR(ARC_REG_ERP_CTRL, ctl); + /* inverted bits: 0 means enabled */ + n += scnprintf(buf + n, len - n, "Extn [ECC]\t: %s%s%s%s%s%s\n", + IS_AVAIL3(erp.ic, !ctl.dpi, "IC "), + IS_AVAIL3(erp.dc, !ctl.dpd, "DC "), + IS_AVAIL3(erp.mmu, !ctl.mpd, "MMU ")); + } - n += scnprintf(buf + n, len - n, - "\nIDENTITY\t: ARCVER [%#02x] ARCNUM [%#02x] CHIPID [%#4x]\n", - core->family, core->cpu_id, core->chip_id); + /* ARCv2 ISA specific sanity checks */ + present = fpu.sp | fpu.dp | mpy.dsp; /* DSP and/or FPU */ + CHK_OPT_STRICT(CONFIG_ARC_HAS_ACCL_REGS, present); - n += scnprintf(buf + n, len - n, "processor [%d]\t: %s %s (%s ISA) %s%s%s\n", - cpu_id, cpu->name, cpu->release, - is_isa_arcompact() ? "ARCompact" : "ARCv2", - IS_AVAIL1(cpu->isa.be, "[Big-Endian]"), - IS_AVAIL3(cpu->extn.dual, cpu->extn.dual_enb, " Dual-Issue ")); + dsp_config_check(); +#endif + return n; +} - n += scnprintf(buf + n, len - n, "Timers\t\t: %s%s%s%s%s%s\nISA Extn\t: ", - IS_AVAIL1(cpu->extn.timer0, "Timer0 "), - IS_AVAIL1(cpu->extn.timer1, "Timer1 "), - IS_AVAIL2(cpu->extn.rtc, "RTC [UP 64-bit] ", CONFIG_ARC_TIMERS_64BIT), - IS_AVAIL2(cpu->extn.gfrc, "GFRC [SMP 64-bit] ", CONFIG_ARC_TIMERS_64BIT)); +static char *arc_cpu_mumbojumbo(int c, struct cpuinfo_arc *info, char *buf, int len) +{ + struct bcr_identity ident; + struct bcr_timer timer; + struct bcr_generic bcr; + struct mcip_bcr mp; + struct bcr_actionpoint ap; + unsigned long vec_base; + int ap_num, ap_full, smart, rtt, n; - if (cpu->extn_mpy.ver) { - if (is_isa_arcompact()) { - scnprintf(mpy_opt, 16, "mpy"); - } else { + memset(info, 0, sizeof(struct cpuinfo_arc)); - int opt = 2; /* stock MPY/MPYH */ + READ_BCR(AUX_IDENTITY, ident); + info->arcver = ident.family; - if (cpu->extn_mpy.dsp) /* OPT 7-9 */ - opt = cpu->extn_mpy.dsp + 6; + n = scnprintf(buf, len, + "\nIDENTITY\t: ARCVER [%#02x] ARCNUM [%#02x] CHIPID [%#4x]\n", + ident.family, ident.cpu_id, ident.chip_id); - scnprintf(mpy_opt, 16, "mpy[opt %d] ", opt); - } + if (is_isa_arcompact()) { + n += arcompact_mumbojumbo(c, info, buf + n, len - n); + } else if (is_isa_arcv2()){ + n += arcv2_mumbojumbo(c, info, buf + n, len - n); } - n += scnprintf(buf + n, len - n, "%s%s%s%s%s%s%s%s\n", - IS_AVAIL2(cpu->isa.atomic, "atomic ", CONFIG_ARC_HAS_LLSC), - IS_AVAIL2(cpu->isa.ldd, "ll64 ", CONFIG_ARC_HAS_LL64), - IS_AVAIL2(cpu->isa.unalign, "unalign ", CONFIG_ARC_USE_UNALIGNED_MEM_ACCESS), - IS_AVAIL1(cpu->extn_mpy.ver, mpy_opt), - IS_AVAIL1(cpu->isa.div_rem, "div_rem ")); + n += arc_mmu_mumbojumbo(c, buf + n, len - n); + n += arc_cache_mumbojumbo(c, buf + n, len - n); - if (cpu->bpu.ver) { - n += scnprintf(buf + n, len - n, - "BPU\t\t: %s%s match, cache:%d, Predict Table:%d Return stk: %d", - IS_AVAIL1(cpu->bpu.full, "full"), - IS_AVAIL1(!cpu->bpu.full, "partial"), - cpu->bpu.num_cache, cpu->bpu.num_pred, cpu->bpu.ret_stk); - - if (is_isa_arcv2()) { - struct bcr_lpb lpb; - - READ_BCR(ARC_REG_LPB_BUILD, lpb); - if (lpb.ver) { - unsigned int ctl; - ctl = read_aux_reg(ARC_REG_LPB_CTRL); - - n += scnprintf(buf + n, len - n, " Loop Buffer:%d %s", - lpb.entries, - IS_DISABLED_RUN(!ctl)); - } - } - n += scnprintf(buf + n, len - n, "\n"); - } + READ_BCR(ARC_REG_TIMERS_BCR, timer); + info->t0 = timer.t0; + info->t1 = timer.t1; - return buf; -} + READ_BCR(ARC_REG_MCIP_BCR, mp); + vec_base = read_aux_reg(AUX_INTR_VEC_BASE); -static char *arc_extn_mumbojumbo(int cpu_id, char *buf, int len) -{ - int n = 0; - struct cpuinfo_arc *cpu = &cpuinfo_arc700[cpu_id]; + n += scnprintf(buf + n, len - n, + "Timers\t\t: %s%s%s%s%s%s\nVector Table\t: %#lx\n", + IS_AVAIL1(timer.t0, "Timer0 "), + IS_AVAIL1(timer.t1, "Timer1 "), + IS_AVAIL2(timer.rtc, "RTC [UP 64-bit] ", CONFIG_ARC_TIMERS_64BIT), + IS_AVAIL2(mp.gfrc, "GFRC [SMP 64-bit] ", CONFIG_ARC_TIMERS_64BIT), + vec_base); - FIX_PTR(cpu); + READ_BCR(ARC_REG_AP_BCR, ap); + if (ap.ver) { + ap_num = 2 << ap.num; + ap_full = !ap.min; + } - n += scnprintf(buf + n, len - n, "Vector Table\t: %#x\n", cpu->vec_base); + READ_BCR(ARC_REG_SMART_BCR, bcr); + smart = bcr.ver ? 1 : 0; - if (cpu->extn.fpu_sp || cpu->extn.fpu_dp) - n += scnprintf(buf + n, len - n, "FPU\t\t: %s%s\n", - IS_AVAIL1(cpu->extn.fpu_sp, "SP "), - IS_AVAIL1(cpu->extn.fpu_dp, "DP ")); + READ_BCR(ARC_REG_RTT_BCR, bcr); + rtt = bcr.ver ? 1 : 0; - if (cpu->extn.ap_num | cpu->extn.smart | cpu->extn.rtt) { + if (ap.ver | smart | rtt) { n += scnprintf(buf + n, len - n, "DEBUG\t\t: %s%s", - IS_AVAIL1(cpu->extn.smart, "smaRT "), - IS_AVAIL1(cpu->extn.rtt, "RTT ")); - if (cpu->extn.ap_num) { + IS_AVAIL1(smart, "smaRT "), + IS_AVAIL1(rtt, "RTT ")); + if (ap.ver) { n += scnprintf(buf + n, len - n, "ActionPoint %d/%s", - cpu->extn.ap_num, - cpu->extn.ap_full ? "full":"min"); + ap_num, + ap_full ? "full":"min"); } n += scnprintf(buf + n, len - n, "\n"); } - if (cpu->dccm.sz || cpu->iccm.sz) - n += scnprintf(buf + n, len - n, "Extn [CCM]\t: DCCM @ %x, %d KB / ICCM: @ %x, %d KB\n", - cpu->dccm.base_addr, TO_KB(cpu->dccm.sz), - cpu->iccm.base_addr, TO_KB(cpu->iccm.sz)); - - if (is_isa_arcv2()) { - - /* Error Protection: ECC/Parity */ - struct bcr_erp erp; - READ_BCR(ARC_REG_ERP_BUILD, erp); - - if (erp.ver) { - struct ctl_erp ctl; - READ_BCR(ARC_REG_ERP_CTRL, ctl); - - /* inverted bits: 0 means enabled */ - n += scnprintf(buf + n, len - n, "Extn [ECC]\t: %s%s%s%s%s%s\n", - IS_AVAIL3(erp.ic, !ctl.dpi, "IC "), - IS_AVAIL3(erp.dc, !ctl.dpd, "DC "), - IS_AVAIL3(erp.mmu, !ctl.mpd, "MMU ")); - } - } + if (info->dccm.sz || info->iccm.sz) + n += scnprintf(buf + n, len - n, + "Extn [CCM]\t: DCCM @ %lx, %d KB / ICCM: @ %lx, %d KB\n", + info->dccm.base, TO_KB(info->dccm.sz), + info->iccm.base, TO_KB(info->iccm.sz)); return buf; } @@ -401,51 +376,33 @@ void chk_opt_weak(char *opt_name, bool hw_exists, bool opt_ena) panic("Disable %s, hardware NOT present\n", opt_name); } -static void arc_chk_core_config(void) +/* + * ISA agnostic sanity checks + */ +static void arc_chk_core_config(struct cpuinfo_arc *info) { - struct cpuinfo_arc *cpu = &cpuinfo_arc700[smp_processor_id()]; - int present = 0; - - if (!cpu->extn.timer0) + if (!info->t0) panic("Timer0 is not present!\n"); - if (!cpu->extn.timer1) + if (!info->t1) panic("Timer1 is not present!\n"); #ifdef CONFIG_ARC_HAS_DCCM /* * DCCM can be arbit placed in hardware. - * Make sure it's placement/sz matches what Linux is built with + * Make sure its placement/sz matches what Linux is built with */ - if ((unsigned int)__arc_dccm_base != cpu->dccm.base_addr) + if ((unsigned int)__arc_dccm_base != info->dccm.base) panic("Linux built with incorrect DCCM Base address\n"); - if (CONFIG_ARC_DCCM_SZ * SZ_1K != cpu->dccm.sz) + if (CONFIG_ARC_DCCM_SZ * SZ_1K != info->dccm.sz) panic("Linux built with incorrect DCCM Size\n"); #endif #ifdef CONFIG_ARC_HAS_ICCM - if (CONFIG_ARC_ICCM_SZ * SZ_1K != cpu->iccm.sz) + if (CONFIG_ARC_ICCM_SZ * SZ_1K != info->iccm.sz) panic("Linux built with incorrect ICCM Size\n"); #endif - - /* - * FP hardware/software config sanity - * -If hardware present, kernel needs to save/restore FPU state - * -If not, it will crash trying to save/restore the non-existant regs - */ - - if (is_isa_arcompact()) { - /* only DPDP checked since SP has no arch visible regs */ - present = cpu->extn.fpu_dp; - CHK_OPT_STRICT(CONFIG_ARC_FPU_SAVE_RESTORE, present); - } else { - /* Accumulator Low:High pair (r58:59) present if DSP MPY or FPU */ - present = cpu->extn_mpy.dsp | cpu->extn.fpu_sp | cpu->extn.fpu_dp; - CHK_OPT_STRICT(CONFIG_ARC_HAS_ACCL_REGS, present); - - dsp_config_check(); - } } /* @@ -456,21 +413,19 @@ static void arc_chk_core_config(void) void setup_processor(void) { + struct cpuinfo_arc info; + int c = smp_processor_id(); char str[512]; - int cpu_id = smp_processor_id(); - read_arc_build_cfg_regs(); - arc_init_IRQ(); + pr_info("%s", arc_cpu_mumbojumbo(c, &info, str, sizeof(str))); + pr_info("%s", arc_platform_smp_cpuinfo()); - pr_info("%s", arc_cpu_mumbojumbo(cpu_id, str, sizeof(str))); + arc_chk_core_config(&info); + arc_init_IRQ(); arc_mmu_init(); arc_cache_init(); - pr_info("%s", arc_extn_mumbojumbo(cpu_id, str, sizeof(str))); - pr_info("%s", arc_platform_smp_cpuinfo()); - - arc_chk_core_config(); } static inline bool uboot_arg_invalid(unsigned long addr) @@ -617,6 +572,7 @@ static int show_cpuinfo(struct seq_file *m, void *v) char *str; int cpu_id = ptr_to_cpu(v); struct device *cpu_dev = get_cpu_device(cpu_id); + struct cpuinfo_arc info; struct clk *cpu_clk; unsigned long freq = 0; @@ -629,7 +585,7 @@ static int show_cpuinfo(struct seq_file *m, void *v) if (!str) goto done; - seq_printf(m, arc_cpu_mumbojumbo(cpu_id, str, PAGE_SIZE)); + seq_printf(m, arc_cpu_mumbojumbo(cpu_id, &info, str, PAGE_SIZE)); cpu_clk = clk_get(cpu_dev, NULL); if (IS_ERR(cpu_clk)) { @@ -646,9 +602,6 @@ static int show_cpuinfo(struct seq_file *m, void *v) loops_per_jiffy / (500000 / HZ), (loops_per_jiffy / (5000 / HZ)) % 100); - seq_printf(m, arc_mmu_mumbojumbo(cpu_id, str, PAGE_SIZE)); - seq_printf(m, arc_cache_mumbojumbo(cpu_id, str, PAGE_SIZE)); - seq_printf(m, arc_extn_mumbojumbo(cpu_id, str, PAGE_SIZE)); seq_printf(m, arc_platform_smp_cpuinfo()); free_page((unsigned long)str); diff --git a/arch/arc/kernel/signal.c b/arch/arc/kernel/signal.c index 3c1590c27fae..fefa705a8638 100644 --- a/arch/arc/kernel/signal.c +++ b/arch/arc/kernel/signal.c @@ -8,15 +8,16 @@ * * vineetg: Nov 2009 (Everything needed for TIF_RESTORE_SIGMASK) * -do_signal() supports TIF_RESTORE_SIGMASK - * -do_signal() no loner needs oldset, required by OLD sys_sigsuspend - * -sys_rt_sigsuspend() now comes from generic code, so discard arch implemen + * -do_signal() no longer needs oldset, required by OLD sys_sigsuspend + * -sys_rt_sigsuspend() now comes from generic code, so discard arch + * implementation * -sys_sigsuspend() no longer needs to fudge ptregs, hence that arg removed * -sys_sigsuspend() no longer loops for do_signal(), sets TIF_xxx and leaves * the job to do_signal() * * vineetg: July 2009 * -Modified Code to support the uClibc provided userland sigreturn stub - * to avoid kernel synthesing it on user stack at runtime, costing TLB + * to avoid kernel synthesizing it on user stack at runtime, costing TLB * probes and Cache line flushes. * * vineetg: July 2009 @@ -53,6 +54,7 @@ #include <linux/sched/task_stack.h> #include <asm/ucontext.h> +#include <asm/entry.h> struct rt_sigframe { struct siginfo info; @@ -61,7 +63,7 @@ struct rt_sigframe { unsigned int sigret_magic; }; -static int save_arcv2_regs(struct sigcontext *mctx, struct pt_regs *regs) +static int save_arcv2_regs(struct sigcontext __user *mctx, struct pt_regs *regs) { int err = 0; #ifndef CONFIG_ISA_ARCOMPACT @@ -74,12 +76,12 @@ static int save_arcv2_regs(struct sigcontext *mctx, struct pt_regs *regs) #else v2abi.r58 = v2abi.r59 = 0; #endif - err = __copy_to_user(&mctx->v2abi, &v2abi, sizeof(v2abi)); + err = __copy_to_user(&mctx->v2abi, (void const *)&v2abi, sizeof(v2abi)); #endif return err; } -static int restore_arcv2_regs(struct sigcontext *mctx, struct pt_regs *regs) +static int restore_arcv2_regs(struct sigcontext __user *mctx, struct pt_regs *regs) { int err = 0; #ifndef CONFIG_ISA_ARCOMPACT diff --git a/arch/arc/kernel/smp.c b/arch/arc/kernel/smp.c index d947473f1e6d..b2f2c59279a6 100644 --- a/arch/arc/kernel/smp.c +++ b/arch/arc/kernel/smp.c @@ -23,9 +23,10 @@ #include <linux/export.h> #include <linux/of_fdt.h> -#include <asm/processor.h> -#include <asm/setup.h> #include <asm/mach_desc.h> +#include <asm/setup.h> +#include <asm/smp.h> +#include <asm/processor.h> #ifndef CONFIG_ARC_HAS_LLSC arch_spinlock_t smp_atomic_ops_lock = __ARCH_SPIN_LOCK_UNLOCKED; @@ -38,11 +39,6 @@ struct plat_smp_ops __weak plat_smp_ops; /* XXX: per cpu ? Only needed once in early secondary boot */ struct task_struct *secondary_idle_tsk; -/* Called from start_kernel */ -void __init smp_prepare_boot_cpu(void) -{ -} - static int __init arc_get_cpu_map(const char *name, struct cpumask *cpumask) { unsigned long dt_root = of_get_flat_dt_root(); @@ -232,14 +228,6 @@ int __cpu_up(unsigned int cpu, struct task_struct *idle) return 0; } -/* - * not supported here - */ -int setup_profiling_timer(unsigned int multiplier) -{ - return -EINVAL; -} - /*****************************************************************************/ /* Inter Processor Interrupt Handling */ /*****************************************************************************/ @@ -300,7 +288,7 @@ static void ipi_send_msg(const struct cpumask *callmap, enum ipi_msg_type msg) ipi_send_msg_one(cpu, msg); } -void smp_send_reschedule(int cpu) +void arch_smp_send_reschedule(int cpu) { ipi_send_msg_one(cpu, IPI_RESCHEDULE); } @@ -359,7 +347,7 @@ static inline int __do_IPI(unsigned long msg) * arch-common ISR to handle for inter-processor interrupts * Has hooks for platform specific IPI */ -irqreturn_t do_IPI(int irq, void *dev_id) +static irqreturn_t do_IPI(int irq, void *dev_id) { unsigned long pending; unsigned long __maybe_unused copy; @@ -393,7 +381,7 @@ irqreturn_t do_IPI(int irq, void *dev_id) * API called by platform code to hookup arch-common ISR to their IPI IRQ * * Note: If IPI is provided by platform (vs. say ARC MCIP), their intc setup/map - * function needs to call call irq_set_percpu_devid() for IPI IRQ, otherwise + * function needs to call irq_set_percpu_devid() for IPI IRQ, otherwise * request_percpu_irq() below will fail */ static DEFINE_PER_CPU(int, ipi_dev); diff --git a/arch/arc/kernel/stacktrace.c b/arch/arc/kernel/stacktrace.c index 5372dc04e784..ea99c066ef25 100644 --- a/arch/arc/kernel/stacktrace.c +++ b/arch/arc/kernel/stacktrace.c @@ -29,6 +29,7 @@ #include <asm/arcregs.h> #include <asm/unwind.h> +#include <asm/stacktrace.h> #include <asm/switch_to.h> /*------------------------------------------------------------------------- diff --git a/arch/arc/kernel/sys.c b/arch/arc/kernel/sys.c index 1069446bdc58..36a2a95c083b 100644 --- a/arch/arc/kernel/sys.c +++ b/arch/arc/kernel/sys.c @@ -8,11 +8,12 @@ #define sys_clone sys_clone_wrapper #define sys_clone3 sys_clone3_wrapper +#define sys_mmap2 sys_mmap_pgoff -#undef __SYSCALL #define __SYSCALL(nr, call) [nr] = (call), +#define __SYSCALL_WITH_COMPAT(nr, native, compat) __SYSCALL(nr, native) void *sys_call_table[NR_syscalls] = { [0 ... NR_syscalls-1] = sys_ni_syscall, -#include <asm/unistd.h> +#include <asm/syscall_table_32.h> }; diff --git a/arch/arc/kernel/traps.c b/arch/arc/kernel/traps.c index 6b83e3f2b41c..8d2ea2cbd98b 100644 --- a/arch/arc/kernel/traps.c +++ b/arch/arc/kernel/traps.c @@ -16,9 +16,11 @@ #include <linux/ptrace.h> #include <linux/kprobes.h> #include <linux/kgdb.h> +#include <asm/entry.h> #include <asm/setup.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <asm/kprobes.h> +#include "unaligned.h" void die(const char *str, struct pt_regs *regs, unsigned long address) { @@ -88,7 +90,7 @@ int do_misaligned_access(unsigned long address, struct pt_regs *regs, /* * Entry point for miscll errors such as Nested Exceptions - * -Duplicate TLB entry is handled seperately though + * -Duplicate TLB entry is handled separately though */ void do_machine_check_fault(unsigned long address, struct pt_regs *regs) { @@ -109,9 +111,7 @@ void do_machine_check_fault(unsigned long address, struct pt_regs *regs) */ void do_non_swi_trap(unsigned long address, struct pt_regs *regs) { - unsigned int param = regs->ecr_param; - - switch (param) { + switch (regs->ecr.param) { case 1: trap_is_brkpt(address, regs); break; diff --git a/arch/arc/kernel/troubleshoot.c b/arch/arc/kernel/troubleshoot.c index 7654c2e42dc0..c380d8c30704 100644 --- a/arch/arc/kernel/troubleshoot.c +++ b/arch/arc/kernel/troubleshoot.c @@ -90,10 +90,12 @@ static void show_faulting_vma(unsigned long address) */ if (vma) { char buf[ARC_PATH_MAX]; - char *nm = "?"; + char *nm = "anon"; if (vma->vm_file) { - nm = file_path(vma->vm_file, buf, ARC_PATH_MAX-1); + /* XXX: can we use %pD below and get rid of buf? */ + nm = d_path(file_user_path(vma->vm_file), buf, + ARC_PATH_MAX-1); if (IS_ERR(nm)) nm = "?"; } @@ -115,8 +117,8 @@ static void show_ecr_verbose(struct pt_regs *regs) /* For Data fault, this is data address not instruction addr */ address = current->thread.fault_address; - vec = regs->ecr_vec; - cause_code = regs->ecr_cause; + vec = regs->ecr.vec; + cause_code = regs->ecr.cause; /* For DTLB Miss or ProtV, display the memory involved too */ if (vec == ECR_V_DTLB_MISS) { @@ -154,7 +156,7 @@ static void show_ecr_verbose(struct pt_regs *regs) pr_cont("Misaligned r/w from 0x%08lx\n", address); #endif } else if (vec == ECR_V_TRAP) { - if (regs->ecr_param == 5) + if (regs->ecr.param == 5) pr_cont("gcc generated __builtin_trap\n"); } else { pr_cont("Check Programmer's Manual\n"); @@ -184,9 +186,10 @@ void show_regs(struct pt_regs *regs) if (user_mode(regs)) show_faulting_vma(regs->ret); /* faulting code, not data */ - pr_info("ECR: 0x%08lx EFA: 0x%08lx ERET: 0x%08lx\nSTAT: 0x%08lx", - regs->event, current->thread.fault_address, regs->ret, - regs->status32); + pr_info("ECR: 0x%08lx EFA: 0x%08lx ERET: 0x%08lx\n", + regs->ecr.full, current->thread.fault_address, regs->ret); + + pr_info("STAT32: 0x%08lx", regs->status32); #define STS_BIT(r, bit) r->status32 & STATUS_##bit##_MASK ? #bit" " : "" diff --git a/arch/arc/kernel/unaligned.c b/arch/arc/kernel/unaligned.c index 99a9b92ed98d..3b2d8b1bd271 100644 --- a/arch/arc/kernel/unaligned.c +++ b/arch/arc/kernel/unaligned.c @@ -12,6 +12,7 @@ #include <linux/ptrace.h> #include <linux/uaccess.h> #include <asm/disasm.h> +#include "unaligned.h" #ifdef CONFIG_CPU_BIG_ENDIAN #define BE 1 @@ -199,7 +200,6 @@ int misaligned_fixup(unsigned long address, struct pt_regs *regs, struct callee_regs *cregs) { struct disasm_state state; - char buf[TASK_COMM_LEN]; /* handle user mode only and only if enabled by sysadmin */ if (!user_mode(regs) || !unaligned_enabled) @@ -211,11 +211,11 @@ int misaligned_fixup(unsigned long address, struct pt_regs *regs, " performance significantly\n. To enable further" " logging of such instances, please \n" " echo 0 > /proc/sys/kernel/ignore-unaligned-usertrap\n", - get_task_comm(buf, current), task_pid_nr(current)); + current->comm, task_pid_nr(current)); } else { /* Add rate limiting if it gets down to it */ pr_warn("%s(%d): unaligned access to/from 0x%lx by PC: 0x%lx\n", - get_task_comm(buf, current), task_pid_nr(current), + current->comm, task_pid_nr(current), address, regs->ret); } diff --git a/arch/arc/kernel/unaligned.h b/arch/arc/kernel/unaligned.h new file mode 100644 index 000000000000..5244453bb85f --- /dev/null +++ b/arch/arc/kernel/unaligned.h @@ -0,0 +1,16 @@ +struct pt_regs; +struct callee_regs; + +#ifdef CONFIG_ARC_EMUL_UNALIGNED +int misaligned_fixup(unsigned long address, struct pt_regs *regs, + struct callee_regs *cregs); +#else +static inline int +misaligned_fixup(unsigned long address, struct pt_regs *regs, + struct callee_regs *cregs) +{ + /* Not fixed */ + return 1; +} +#endif + diff --git a/arch/arc/kernel/unwind.c b/arch/arc/kernel/unwind.c index 200270a94558..789cfb9ea14e 100644 --- a/arch/arc/kernel/unwind.c +++ b/arch/arc/kernel/unwind.c @@ -19,7 +19,7 @@ #include <linux/uaccess.h> #include <linux/ptrace.h> #include <asm/sections.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <asm/unwind.h> extern char __start_unwind[], __end_unwind[]; @@ -241,15 +241,6 @@ static int cmp_eh_frame_hdr_table_entries(const void *p1, const void *p2) return (e1->start > e2->start) - (e1->start < e2->start); } -static void swap_eh_frame_hdr_table_entries(void *p1, void *p2, int size) -{ - struct eh_frame_hdr_table_entry *e1 = p1; - struct eh_frame_hdr_table_entry *e2 = p2; - - swap(e1->start, e2->start); - swap(e1->fde, e2->fde); -} - static void init_unwind_hdr(struct unwind_table *table, void *(*alloc) (unsigned long)) { @@ -345,7 +336,7 @@ static void init_unwind_hdr(struct unwind_table *table, sort(header->table, n, sizeof(*header->table), - cmp_eh_frame_hdr_table_entries, swap_eh_frame_hdr_table_entries); + cmp_eh_frame_hdr_table_entries, NULL); table->hdrsz = hdrSize; smp_wmb(); @@ -369,6 +360,8 @@ void *unwind_add_table(struct module *module, const void *table_start, unsigned long table_size) { struct unwind_table *table; + struct module_memory *core_text; + struct module_memory *init_text; if (table_size <= 0) return NULL; @@ -377,11 +370,11 @@ void *unwind_add_table(struct module *module, const void *table_start, if (!table) return NULL; - init_unwind_table(table, module->name, - module->core_layout.base, module->core_layout.size, - module->init_layout.base, module->init_layout.size, - table_start, table_size, - NULL, 0); + core_text = &module->mem[MOD_TEXT]; + init_text = &module->mem[MOD_INIT_TEXT]; + + init_unwind_table(table, module->name, core_text->base, core_text->size, + init_text->base, init_text->size, table_start, table_size, NULL, 0); init_unwind_hdr(table, unw_hdr_alloc); diff --git a/arch/arc/kernel/vmlinux.lds.S b/arch/arc/kernel/vmlinux.lds.S index 529ae50f9fe2..61a1b2b96e1d 100644 --- a/arch/arc/kernel/vmlinux.lds.S +++ b/arch/arc/kernel/vmlinux.lds.S @@ -41,8 +41,8 @@ SECTIONS #endif /* - * The reason for having a seperate subsection .init.ramfs is to - * prevent objump from including it in kernel dumps + * The reason for having a separate subsection .init.ramfs is to + * prevent objdump from including it in kernel dumps * * Reason for having .init.ramfs above .init is to make sure that the * binary blob is tucked away to one side, reducing the displacement @@ -85,7 +85,6 @@ SECTIONS _stext = .; TEXT_TEXT SCHED_TEXT - CPUIDLE_TEXT LOCK_TEXT KPROBES_TEXT IRQENTRY_TEXT |