diff options
Diffstat (limited to 'arch/arc/kernel')
-rw-r--r-- | arch/arc/kernel/arcksyms.c | 2 | ||||
-rw-r--r-- | arch/arc/kernel/ctx_sw_asm.S | 3 | ||||
-rw-r--r-- | arch/arc/kernel/entry-compact.S | 18 | ||||
-rw-r--r-- | arch/arc/kernel/entry.S | 24 | ||||
-rw-r--r-- | arch/arc/kernel/intc-arcv2.c | 2 | ||||
-rw-r--r-- | arch/arc/kernel/intc-compact.c | 6 | ||||
-rw-r--r-- | arch/arc/kernel/module.c | 19 | ||||
-rw-r--r-- | arch/arc/kernel/perf_event.c | 8 | ||||
-rw-r--r-- | arch/arc/kernel/process.c | 2 | ||||
-rw-r--r-- | arch/arc/kernel/setup.c | 21 | ||||
-rw-r--r-- | arch/arc/kernel/signal.c | 10 | ||||
-rw-r--r-- | arch/arc/kernel/stacktrace.c | 2 | ||||
-rw-r--r-- | arch/arc/kernel/time.c | 99 | ||||
-rw-r--r-- | arch/arc/kernel/troubleshoot.c | 2 | ||||
-rw-r--r-- | arch/arc/kernel/unwind.c | 24 | ||||
-rw-r--r-- | arch/arc/kernel/vmlinux.lds.S | 22 |
16 files changed, 117 insertions, 147 deletions
diff --git a/arch/arc/kernel/arcksyms.c b/arch/arc/kernel/arcksyms.c index 4d9e77724bed..000dd041ab42 100644 --- a/arch/arc/kernel/arcksyms.c +++ b/arch/arc/kernel/arcksyms.c @@ -28,6 +28,7 @@ extern void __muldf3(void); extern void __divdf3(void); extern void __floatunsidf(void); extern void __floatunsisf(void); +extern void __udivdi3(void); EXPORT_SYMBOL(__ashldi3); EXPORT_SYMBOL(__ashrdi3); @@ -45,6 +46,7 @@ EXPORT_SYMBOL(__muldf3); EXPORT_SYMBOL(__divdf3); EXPORT_SYMBOL(__floatunsidf); EXPORT_SYMBOL(__floatunsisf); +EXPORT_SYMBOL(__udivdi3); /* ARC optimised assembler routines */ EXPORT_SYMBOL(memset); diff --git a/arch/arc/kernel/ctx_sw_asm.S b/arch/arc/kernel/ctx_sw_asm.S index e6890b1f8650..7c1f365ef3d2 100644 --- a/arch/arc/kernel/ctx_sw_asm.S +++ b/arch/arc/kernel/ctx_sw_asm.S @@ -23,6 +23,7 @@ .global __switch_to .type __switch_to, @function __switch_to: + CFI_STARTPROC /* Save regs on kernel mode stack of task */ st.a blink, [sp, -4] @@ -59,4 +60,4 @@ __switch_to: ld.ab blink, [sp, 4] j [blink] -END(__switch_to) +END_CFI(__switch_to) diff --git a/arch/arc/kernel/entry-compact.S b/arch/arc/kernel/entry-compact.S index 0cb0abaa0479..98812c1248df 100644 --- a/arch/arc/kernel/entry-compact.S +++ b/arch/arc/kernel/entry-compact.S @@ -91,27 +91,13 @@ VECTOR mem_service ; 0x8, Mem exception (0x1) VECTOR instr_service ; 0x10, Instrn Error (0x2) ; ******************** Device ISRs ********************** -#ifdef CONFIG_ARC_IRQ3_LV2 -VECTOR handle_interrupt_level2 -#else -VECTOR handle_interrupt_level1 -#endif - -VECTOR handle_interrupt_level1 - -#ifdef CONFIG_ARC_IRQ5_LV2 -VECTOR handle_interrupt_level2 -#else -VECTOR handle_interrupt_level1 -#endif - -#ifdef CONFIG_ARC_IRQ6_LV2 +#ifdef CONFIG_ARC_COMPACT_IRQ_LEVELS VECTOR handle_interrupt_level2 #else VECTOR handle_interrupt_level1 #endif -.rept 25 +.rept 28 VECTOR handle_interrupt_level1 ; Other devices .endr diff --git a/arch/arc/kernel/entry.S b/arch/arc/kernel/entry.S index 2efb0625331d..1eea99beecc3 100644 --- a/arch/arc/kernel/entry.S +++ b/arch/arc/kernel/entry.S @@ -35,7 +35,7 @@ ENTRY(sys_clone_wrapper) btst r10, TIF_SYSCALL_TRACE bnz tracesys_exit - b ret_from_system_call + b .Lret_from_system_call END(sys_clone_wrapper) ENTRY(ret_from_fork) @@ -61,18 +61,6 @@ ENTRY(ret_from_fork) b ret_from_exception END(ret_from_fork) -#ifdef CONFIG_ARC_DW2_UNWIND -; Workaround for bug 94179 (STAR ): -; Despite -fasynchronous-unwind-tables, linker is not making dwarf2 unwinder -; section (.debug_frame) as loadable. So we force it here. -; This also fixes STAR 9000487933 where the prev-workaround (objcopy --setflag) -; would not work after a clean build due to kernel build system dependencies. -.section .debug_frame, "wa",@progbits - -; Reset to .text as this file is included in entry-<isa>.S -.section .text, "ax",@progbits -#endif - ;################### Non TLB Exception Handling ############################# ; --------------------------------------------- @@ -260,20 +248,18 @@ ENTRY(EV_Trap) ; syscall num shd not exceed the total system calls avail cmp r8, NR_syscalls mov.hi r0, -ENOSYS - bhi ret_from_system_call + 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 - ; fall through to ret_from_system_call -END(EV_Trap) - -ENTRY(ret_from_system_call) +.Lret_from_system_call: st r0, [sp, PT_r0] ; sys call return value in pt_regs - ; fall through yet again to ret_from_exception + ; fall through to ret_from_exception +END(EV_Trap) ;############# Return from Intr/Excp/Trap (Linux Specifics) ############## ; diff --git a/arch/arc/kernel/intc-arcv2.c b/arch/arc/kernel/intc-arcv2.c index 6c24faf48b16..62b59409a5d9 100644 --- a/arch/arc/kernel/intc-arcv2.c +++ b/arch/arc/kernel/intc-arcv2.c @@ -74,7 +74,7 @@ void arc_init_IRQ(void) tmp = read_aux_reg(0xa); tmp |= STATUS_AD_MASK | (irq_prio << 1); tmp &= ~STATUS_IE_MASK; - asm volatile("flag %0 \n"::"r"(tmp)); + asm volatile("kflag %0 \n"::"r"(tmp)); } static void arcv2_irq_mask(struct irq_data *data) diff --git a/arch/arc/kernel/intc-compact.c b/arch/arc/kernel/intc-compact.c index c5cceca36118..ce9deb953ca9 100644 --- a/arch/arc/kernel/intc-compact.c +++ b/arch/arc/kernel/intc-compact.c @@ -28,10 +28,8 @@ void arc_init_IRQ(void) { int level_mask = 0; - /* setup any high priority Interrupts (Level2 in ARCompact jargon) */ - level_mask |= IS_ENABLED(CONFIG_ARC_IRQ3_LV2) << 3; - level_mask |= IS_ENABLED(CONFIG_ARC_IRQ5_LV2) << 5; - level_mask |= IS_ENABLED(CONFIG_ARC_IRQ6_LV2) << 6; + /* Is timer high priority Interrupt (Level2 in ARCompact jargon) */ + level_mask |= IS_ENABLED(CONFIG_ARC_COMPACT_IRQ_LEVELS) << TIMER0_IRQ; /* * Write to register, even if no LV2 IRQs configured to reset it diff --git a/arch/arc/kernel/module.c b/arch/arc/kernel/module.c index 376e04622962..9a2849756022 100644 --- a/arch/arc/kernel/module.c +++ b/arch/arc/kernel/module.c @@ -22,13 +22,9 @@ static inline void arc_write_me(unsigned short *addr, unsigned long value) *(addr + 1) = (value & 0xffff); } -/* ARC specific section quirks - before relocation loop in generic loader - * - * For dwarf unwinding out of modules, this needs to - * 1. Ensure the .debug_frame is allocatable (ARC Linker bug: despite - * -fasynchronous-unwind-tables it doesn't). - * 2. Since we are iterating thru sec hdr tbl anyways, make a note of - * the exact section index, for later use. +/* + * This gets called before relocation loop in generic loader + * Make a note of the section index of unwinding section */ int module_frob_arch_sections(Elf_Ehdr *hdr, Elf_Shdr *sechdrs, char *secstr, struct module *mod) @@ -40,8 +36,7 @@ int module_frob_arch_sections(Elf_Ehdr *hdr, Elf_Shdr *sechdrs, mod->arch.unw_info = NULL; for (i = 1; i < hdr->e_shnum; i++) { - if (strcmp(secstr+sechdrs[i].sh_name, ".debug_frame") == 0) { - sechdrs[i].sh_flags |= SHF_ALLOC; + if (strcmp(secstr+sechdrs[i].sh_name, ".eh_frame") == 0) { mod->arch.unw_sec_idx = i; break; } @@ -106,10 +101,12 @@ int apply_relocate_add(Elf32_Shdr *sechdrs, */ relo_type = ELF32_R_TYPE(rel_entry[i].r_info); - if (likely(R_ARC_32_ME == relo_type)) + if (likely(R_ARC_32_ME == relo_type)) /* ME ( S + A ) */ arc_write_me((unsigned short *)location, relocation); - else if (R_ARC_32 == relo_type) + else if (R_ARC_32 == relo_type) /* ( S + A ) */ *((Elf32_Addr *) location) = relocation; + else if (R_ARC_32_PCREL == relo_type) /* ( S + A ) - PDATA ) */ + *((Elf32_Addr *) location) = relocation - location; else goto relo_err; diff --git a/arch/arc/kernel/perf_event.c b/arch/arc/kernel/perf_event.c index 6fd48021324b..2ce24e74f879 100644 --- a/arch/arc/kernel/perf_event.c +++ b/arch/arc/kernel/perf_event.c @@ -108,7 +108,7 @@ static void arc_perf_event_update(struct perf_event *event, int64_t delta = new_raw_count - prev_raw_count; /* - * We don't afaraid of hwc->prev_count changing beneath our feet + * We aren't afraid of hwc->prev_count changing beneath our feet * because there's no way for us to re-enter this function anytime. */ local64_set(&hwc->prev_count, new_raw_count); @@ -179,8 +179,8 @@ static int arc_pmu_event_init(struct perf_event *event) if (arc_pmu->ev_hw_idx[event->attr.config] < 0) return -ENOENT; hwc->config |= arc_pmu->ev_hw_idx[event->attr.config]; - pr_debug("init event %d with h/w %d \'%s\'\n", - (int) event->attr.config, (int) hwc->config, + pr_debug("init event %d with h/w %08x \'%s\'\n", + (int)event->attr.config, (int)hwc->config, arc_pmu_ev_hw_map[event->attr.config]); return 0; @@ -189,6 +189,8 @@ static int arc_pmu_event_init(struct perf_event *event) if (ret < 0) return ret; hwc->config |= arc_pmu->ev_hw_idx[ret]; + pr_debug("init cache event with h/w %08x \'%s\'\n", + (int)hwc->config, arc_pmu_ev_hw_map[ret]); return 0; default: return -ENOENT; diff --git a/arch/arc/kernel/process.c b/arch/arc/kernel/process.c index b5db9e7fd649..be1972bd2729 100644 --- a/arch/arc/kernel/process.c +++ b/arch/arc/kernel/process.c @@ -199,7 +199,7 @@ int elf_check_arch(const struct elf32_hdr *x) } eflags = x->e_flags; - if ((eflags & EF_ARC_OSABI_MSK) < EF_ARC_OSABI_CURRENT) { + if ((eflags & EF_ARC_OSABI_MSK) != EF_ARC_OSABI_CURRENT) { pr_err("ABI mismatch - you need newer toolchain\n"); force_sigsegv(SIGSEGV, current); return 0; diff --git a/arch/arc/kernel/setup.c b/arch/arc/kernel/setup.c index f63b8bfefb0c..3df7f9c72f42 100644 --- a/arch/arc/kernel/setup.c +++ b/arch/arc/kernel/setup.c @@ -14,7 +14,7 @@ #include <linux/module.h> #include <linux/cpu.h> #include <linux/of_fdt.h> -#include <linux/of_platform.h> +#include <linux/of.h> #include <linux/cache.h> #include <asm/sections.h> #include <asm/arcregs.h> @@ -171,6 +171,7 @@ static const struct cpuinfo_data arc_cpu_tbl[] = { #else { {0x50, "ARC HS38 R2.0"}, 0x51}, { {0x52, "ARC HS38 R2.1"}, 0x52}, + { {0x53, "ARC HS38 R3.0"}, 0x53}, #endif { {0x00, NULL } } }; @@ -272,8 +273,8 @@ static char *arc_extn_mumbojumbo(int cpu_id, char *buf, int len) FIX_PTR(cpu); n += scnprintf(buf + n, len - n, - "Vector Table\t: %#x\nUncached Base\t: %#lx\n", - cpu->vec_base, perip_base); + "Vector Table\t: %#x\nPeripherals\t: %#lx:%#lx\n", + cpu->vec_base, perip_base, perip_end); if (cpu->extn.fpu_sp || cpu->extn.fpu_dp) n += scnprintf(buf + n, len - n, "FPU\t\t: %s%s\n", @@ -291,8 +292,10 @@ static char *arc_extn_mumbojumbo(int cpu_id, char *buf, int len) cpu->dccm.base_addr, TO_KB(cpu->dccm.sz), cpu->iccm.base_addr, TO_KB(cpu->iccm.sz)); - n += scnprintf(buf + n, len - n, - "OS ABI [v3]\t: no-legacy-syscalls\n"); + n += scnprintf(buf + n, len - n, "OS ABI [v%d]\t: %s\n", + EF_ARC_OSABI_CURRENT >> 8, + EF_ARC_OSABI_CURRENT == EF_ARC_OSABI_V3 ? + "no-legacy-syscalls" : "64-bit data any register aligned"); return buf; } @@ -392,7 +395,7 @@ void __init setup_arch(char **cmdline_p) /* * If we are here, it is established that @uboot_arg didn't * point to DT blob. Instead if u-boot says it is cmdline, - * Appent to embedded DT cmdline. + * append to embedded DT cmdline. * setup_machine_fdt() would have populated @boot_command_line */ if (uboot_tag == 1) { @@ -435,12 +438,6 @@ void __init setup_arch(char **cmdline_p) static int __init customize_machine(void) { - /* - * Traverses flattened DeviceTree - registering platform devices - * (if any) complete with their resources - */ - of_platform_default_populate(NULL, NULL, NULL); - if (machine_desc->init_machine) machine_desc->init_machine(); diff --git a/arch/arc/kernel/signal.c b/arch/arc/kernel/signal.c index 004b7f0bc76c..d347bbc086fe 100644 --- a/arch/arc/kernel/signal.c +++ b/arch/arc/kernel/signal.c @@ -34,7 +34,7 @@ * -ViXS were still seeing crashes when using insmod to load drivers. * It turned out that the code to change Execute permssions for TLB entries * of user was not guarded for interrupts (mod_tlb_permission) - * This was cauing TLB entries to be overwritten on unrelated indexes + * This was causing TLB entries to be overwritten on unrelated indexes * * Vineetg: July 15th 2008: Bug #94183 * -Exception happens in Delay slot of a JMP, and before user space resumes, @@ -107,13 +107,13 @@ static int restore_usr_regs(struct pt_regs *regs, struct rt_sigframe __user *sf) struct user_regs_struct uregs; err = __copy_from_user(&set, &sf->uc.uc_sigmask, sizeof(set)); - if (!err) - set_current_blocked(&set); - err |= __copy_from_user(&uregs.scratch, &(sf->uc.uc_mcontext.regs.scratch), sizeof(sf->uc.uc_mcontext.regs.scratch)); + if (err) + return err; + set_current_blocked(&set); regs->bta = uregs.scratch.bta; regs->lp_start = uregs.scratch.lp_start; regs->lp_end = uregs.scratch.lp_end; @@ -138,7 +138,7 @@ static int restore_usr_regs(struct pt_regs *regs, struct rt_sigframe __user *sf) regs->r0 = uregs.scratch.r0; regs->sp = uregs.scratch.sp; - return err; + return 0; } static inline int is_do_ss_needed(unsigned int magic) diff --git a/arch/arc/kernel/stacktrace.c b/arch/arc/kernel/stacktrace.c index e0efff15a5ae..b9192a653b7e 100644 --- a/arch/arc/kernel/stacktrace.c +++ b/arch/arc/kernel/stacktrace.c @@ -142,7 +142,7 @@ arc_unwind_core(struct task_struct *tsk, struct pt_regs *regs, * prelogue is setup (callee regs saved and then fp set and not other * way around */ - pr_warn("CONFIG_ARC_DW2_UNWIND needs to be enabled\n"); + pr_warn_once("CONFIG_ARC_DW2_UNWIND needs to be enabled\n"); return 0; #endif diff --git a/arch/arc/kernel/time.c b/arch/arc/kernel/time.c index 4549ab255dd1..f927b8dc6edd 100644 --- a/arch/arc/kernel/time.c +++ b/arch/arc/kernel/time.c @@ -116,19 +116,19 @@ static struct clocksource arc_counter_gfrc = { .flags = CLOCK_SOURCE_IS_CONTINUOUS, }; -static void __init arc_cs_setup_gfrc(struct device_node *node) +static int __init arc_cs_setup_gfrc(struct device_node *node) { int exists = cpuinfo_arc700[0].extn.gfrc; int ret; if (WARN(!exists, "Global-64-bit-Ctr clocksource not detected")) - return; + return -ENXIO; ret = arc_get_timer_clk(node); if (ret) - return; + return ret; - clocksource_register_hz(&arc_counter_gfrc, arc_timer_freq); + return clocksource_register_hz(&arc_counter_gfrc, arc_timer_freq); } CLOCKSOURCE_OF_DECLARE(arc_gfrc, "snps,archs-timer-gfrc", arc_cs_setup_gfrc); @@ -172,25 +172,25 @@ static struct clocksource arc_counter_rtc = { .flags = CLOCK_SOURCE_IS_CONTINUOUS, }; -static void __init arc_cs_setup_rtc(struct device_node *node) +static int __init arc_cs_setup_rtc(struct device_node *node) { int exists = cpuinfo_arc700[smp_processor_id()].extn.rtc; int ret; if (WARN(!exists, "Local-64-bit-Ctr clocksource not detected")) - return; + return -ENXIO; /* Local to CPU hence not usable in SMP */ if (WARN(IS_ENABLED(CONFIG_SMP), "Local-64-bit-Ctr not usable in SMP")) - return; + return -EINVAL; ret = arc_get_timer_clk(node); if (ret) - return; + return ret; write_aux_reg(AUX_RTC_CTRL, 1); - clocksource_register_hz(&arc_counter_rtc, arc_timer_freq); + return clocksource_register_hz(&arc_counter_rtc, arc_timer_freq); } CLOCKSOURCE_OF_DECLARE(arc_rtc, "snps,archs-timer-rtc", arc_cs_setup_rtc); @@ -213,23 +213,23 @@ static struct clocksource arc_counter_timer1 = { .flags = CLOCK_SOURCE_IS_CONTINUOUS, }; -static void __init arc_cs_setup_timer1(struct device_node *node) +static int __init arc_cs_setup_timer1(struct device_node *node) { int ret; /* Local to CPU hence not usable in SMP */ if (IS_ENABLED(CONFIG_SMP)) - return; + return -EINVAL; ret = arc_get_timer_clk(node); if (ret) - return; + return ret; write_aux_reg(ARC_REG_TIMER1_LIMIT, ARC_TIMER_MAX); write_aux_reg(ARC_REG_TIMER1_CNT, 0); write_aux_reg(ARC_REG_TIMER1_CTRL, TIMER_CTRL_NH); - clocksource_register_hz(&arc_counter_timer1, arc_timer_freq); + return clocksource_register_hz(&arc_counter_timer1, arc_timer_freq); } /********** Clock Event Device *********/ @@ -296,73 +296,76 @@ static irqreturn_t timer_irq_handler(int irq, void *dev_id) return IRQ_HANDLED; } -static int arc_timer_cpu_notify(struct notifier_block *self, - unsigned long action, void *hcpu) + +static int arc_timer_starting_cpu(unsigned int cpu) { struct clock_event_device *evt = this_cpu_ptr(&arc_clockevent_device); evt->cpumask = cpumask_of(smp_processor_id()); - switch (action & ~CPU_TASKS_FROZEN) { - case CPU_STARTING: - clockevents_config_and_register(evt, arc_timer_freq, - 0, ULONG_MAX); - enable_percpu_irq(arc_timer_irq, 0); - break; - case CPU_DYING: - disable_percpu_irq(arc_timer_irq); - break; - } - - return NOTIFY_OK; + clockevents_config_and_register(evt, arc_timer_freq, 0, ARC_TIMER_MAX); + enable_percpu_irq(arc_timer_irq, 0); + return 0; } -static struct notifier_block arc_timer_cpu_nb = { - .notifier_call = arc_timer_cpu_notify, -}; +static int arc_timer_dying_cpu(unsigned int cpu) +{ + disable_percpu_irq(arc_timer_irq); + return 0; +} /* * clockevent setup for boot CPU */ -static void __init arc_clockevent_setup(struct device_node *node) +static int __init arc_clockevent_setup(struct device_node *node) { struct clock_event_device *evt = this_cpu_ptr(&arc_clockevent_device); int ret; - register_cpu_notifier(&arc_timer_cpu_nb); - arc_timer_irq = irq_of_parse_and_map(node, 0); - if (arc_timer_irq <= 0) - panic("clockevent: missing irq"); + if (arc_timer_irq <= 0) { + pr_err("clockevent: missing irq"); + return -EINVAL; + } ret = arc_get_timer_clk(node); - if (ret) - panic("clockevent: missing clk"); - - evt->irq = arc_timer_irq; - evt->cpumask = cpumask_of(smp_processor_id()); - clockevents_config_and_register(evt, arc_timer_freq, - 0, ARC_TIMER_MAX); + if (ret) { + pr_err("clockevent: missing clk"); + return ret; + } /* Needs apriori irq_set_percpu_devid() done in intc map function */ ret = request_percpu_irq(arc_timer_irq, timer_irq_handler, "Timer0 (per-cpu-tick)", evt); - if (ret) - panic("clockevent: unable to request irq\n"); + if (ret) { + pr_err("clockevent: unable to request irq\n"); + return ret; + } - enable_percpu_irq(arc_timer_irq, 0); + ret = cpuhp_setup_state(CPUHP_AP_ARC_TIMER_STARTING, + "AP_ARC_TIMER_STARTING", + arc_timer_starting_cpu, + arc_timer_dying_cpu); + if (ret) { + pr_err("Failed to setup hotplug state"); + return ret; + } + return 0; } -static void __init arc_of_timer_init(struct device_node *np) +static int __init arc_of_timer_init(struct device_node *np) { static int init_count = 0; + int ret; if (!init_count) { init_count = 1; - arc_clockevent_setup(np); + ret = arc_clockevent_setup(np); } else { - arc_cs_setup_timer1(np); + ret = arc_cs_setup_timer1(np); } + + return ret; } CLOCKSOURCE_OF_DECLARE(arc_clkevt, "snps,arc-timer", arc_of_timer_init); diff --git a/arch/arc/kernel/troubleshoot.c b/arch/arc/kernel/troubleshoot.c index a6f91e88ce36..934150e7ac48 100644 --- a/arch/arc/kernel/troubleshoot.c +++ b/arch/arc/kernel/troubleshoot.c @@ -276,7 +276,7 @@ static int tlb_stats_open(struct inode *inode, struct file *file) return 0; } -/* called on user read(): display the couters */ +/* called on user read(): display the counters */ static ssize_t tlb_stats_output(struct file *file, /* file descriptor */ char __user *user_buf, /* user buffer */ size_t len, /* length of buffer */ diff --git a/arch/arc/kernel/unwind.c b/arch/arc/kernel/unwind.c index 0587bf121d11..61fd1ce63c56 100644 --- a/arch/arc/kernel/unwind.c +++ b/arch/arc/kernel/unwind.c @@ -111,6 +111,8 @@ UNW_REGISTER_INFO}; #define DW_EH_PE_indirect 0x80 #define DW_EH_PE_omit 0xff +#define CIE_ID 0 + typedef unsigned long uleb128_t; typedef signed long sleb128_t; @@ -232,6 +234,7 @@ void __init arc_unwind_init(void) static const u32 bad_cie, not_fde; static const u32 *cie_for_fde(const u32 *fde, const struct unwind_table *); +static const u32 *__cie_for_fde(const u32 *fde); static signed fde_pointer_type(const u32 *cie); struct eh_frame_hdr_table_entry { @@ -338,10 +341,9 @@ static void init_unwind_hdr(struct unwind_table *table, for (fde = table->address, tableSize = table->size, n = 0; tableSize; tableSize -= sizeof(*fde) + *fde, fde += 1 + *fde / sizeof(*fde)) { - /* const u32 *cie = fde + 1 - fde[1] / sizeof(*fde); */ - const u32 *cie = (const u32 *)(fde[1]); + const u32 *cie = __cie_for_fde(fde); - if (fde[1] == 0xffffffff) + if (fde[1] == CIE_ID) continue; /* this is a CIE */ ptr = (const u8 *)(fde + 2); header->table[n].start = read_pointer(&ptr, @@ -504,6 +506,15 @@ static sleb128_t get_sleb128(const u8 **pcur, const u8 *end) return value; } +static const u32 *__cie_for_fde(const u32 *fde) +{ + const u32 *cie; + + cie = fde + 1 - fde[1] / sizeof(*fde); + + return cie; +} + static const u32 *cie_for_fde(const u32 *fde, const struct unwind_table *table) { const u32 *cie; @@ -511,19 +522,18 @@ static const u32 *cie_for_fde(const u32 *fde, const struct unwind_table *table) if (!*fde || (*fde & (sizeof(*fde) - 1))) return &bad_cie; - if (fde[1] == 0xffffffff) + if (fde[1] == CIE_ID) return ¬_fde; /* this is a CIE */ if ((fde[1] & (sizeof(*fde) - 1))) /* || fde[1] > (unsigned long)(fde + 1) - (unsigned long)table->address) */ return NULL; /* this is not a valid FDE */ - /* cie = fde + 1 - fde[1] / sizeof(*fde); */ - cie = (u32 *) fde[1]; + cie = __cie_for_fde(fde); if (*cie <= sizeof(*cie) + 4 || *cie >= fde[1] - sizeof(*fde) || (*cie & (sizeof(*cie) - 1)) - || (cie[1] != 0xffffffff)) + || (cie[1] != CIE_ID)) return NULL; /* this is not a (valid) CIE */ return cie; } diff --git a/arch/arc/kernel/vmlinux.lds.S b/arch/arc/kernel/vmlinux.lds.S index 894e696bddaa..f35ed578e007 100644 --- a/arch/arc/kernel/vmlinux.lds.S +++ b/arch/arc/kernel/vmlinux.lds.S @@ -82,14 +82,6 @@ SECTIONS PERCPU_SECTION(L1_CACHE_BYTES) - /* - * .exit.text is discard at runtime, not link time, to deal with - * references from .debug_frame - * It will be init freed, being inside [__init_start : __init_end] - */ - .exit.text : { EXIT_TEXT } - .exit.data : { EXIT_DATA } - . = ALIGN(PAGE_SIZE); __init_end = .; @@ -97,6 +89,7 @@ SECTIONS _text = .; TEXT_TEXT SCHED_TEXT + CPUIDLE_TEXT LOCK_TEXT KPROBES_TEXT *(.fixup) @@ -120,18 +113,13 @@ SECTIONS #ifdef CONFIG_ARC_DW2_UNWIND . = ALIGN(PAGE_SIZE); - .debug_frame : { + .eh_frame : { __start_unwind = .; - *(.debug_frame) + *(.eh_frame) __end_unwind = .; } - /* - * gcc 4.8 generates this for -fasynchonous-unwind-tables, - * while we still use the .debug_frame based unwinder - */ - /DISCARD/ : { *(.eh_frame) } #else - /DISCARD/ : { *(.debug_frame) } + /DISCARD/ : { *(.eh_frame) } #endif NOTES @@ -148,7 +136,7 @@ SECTIONS } #ifndef CONFIG_DEBUG_INFO - /* open-coded because we need .debug_frame seperately for unwinding */ + /DISCARD/ : { *(.debug_frame) } /DISCARD/ : { *(.debug_aranges) } /DISCARD/ : { *(.debug_pubnames) } /DISCARD/ : { *(.debug_info) } |