diff options
Diffstat (limited to 'arch/arm/kernel')
-rw-r--r-- | arch/arm/kernel/Makefile | 2 | ||||
-rw-r--r-- | arch/arm/kernel/atags.h | 5 | ||||
-rw-r--r-- | arch/arm/kernel/atags_parse.c | 6 | ||||
-rw-r--r-- | arch/arm/kernel/devtree.c | 6 | ||||
-rw-r--r-- | arch/arm/kernel/entry-common.S | 4 | ||||
-rw-r--r-- | arch/arm/kernel/module.c | 8 | ||||
-rw-r--r-- | arch/arm/kernel/perf_event_cpu.c | 3 | ||||
-rw-r--r-- | arch/arm/kernel/setup.c | 21 | ||||
-rw-r--r-- | arch/arm/kernel/smp.c | 13 | ||||
-rw-r--r-- | arch/arm/kernel/smp_tlb.c | 10 | ||||
-rw-r--r-- | arch/arm/kernel/traps.c | 66 | ||||
-rw-r--r-- | arch/arm/kernel/v7m.c | 19 |
12 files changed, 105 insertions, 58 deletions
diff --git a/arch/arm/kernel/Makefile b/arch/arm/kernel/Makefile index 86d10dd47dc4..5140df5f23aa 100644 --- a/arch/arm/kernel/Makefile +++ b/arch/arm/kernel/Makefile @@ -24,7 +24,7 @@ obj-$(CONFIG_ATAGS_PROC) += atags_proc.o obj-$(CONFIG_DEPRECATED_PARAM_STRUCT) += atags_compat.o ifeq ($(CONFIG_CPU_V7M),y) -obj-y += entry-v7m.o +obj-y += entry-v7m.o v7m.o else obj-y += entry-armv.o endif diff --git a/arch/arm/kernel/atags.h b/arch/arm/kernel/atags.h index 9edc9692332d..ec4164da6e30 100644 --- a/arch/arm/kernel/atags.h +++ b/arch/arm/kernel/atags.h @@ -7,9 +7,10 @@ static inline void save_atags(struct tag *tags) { } void convert_to_tag_list(struct tag *tags); #ifdef CONFIG_ATAGS -struct machine_desc *setup_machine_tags(phys_addr_t __atags_pointer, unsigned int machine_nr); +const struct machine_desc *setup_machine_tags(phys_addr_t __atags_pointer, + unsigned int machine_nr); #else -static inline struct machine_desc * +static inline const struct machine_desc * setup_machine_tags(phys_addr_t __atags_pointer, unsigned int machine_nr) { early_print("no ATAGS support: can't continue\n"); diff --git a/arch/arm/kernel/atags_parse.c b/arch/arm/kernel/atags_parse.c index 14512e6931d8..8c14de8180c0 100644 --- a/arch/arm/kernel/atags_parse.c +++ b/arch/arm/kernel/atags_parse.c @@ -178,11 +178,11 @@ static void __init squash_mem_tags(struct tag *tag) tag->hdr.tag = ATAG_NONE; } -struct machine_desc * __init setup_machine_tags(phys_addr_t __atags_pointer, - unsigned int machine_nr) +const struct machine_desc * __init +setup_machine_tags(phys_addr_t __atags_pointer, unsigned int machine_nr) { struct tag *tags = (struct tag *)&default_tags; - struct machine_desc *mdesc = NULL, *p; + const struct machine_desc *mdesc = NULL, *p; char *from = default_command_line; default_tags.mem.start = PHYS_OFFSET; diff --git a/arch/arm/kernel/devtree.c b/arch/arm/kernel/devtree.c index 5859c8bc727c..eae1976f859d 100644 --- a/arch/arm/kernel/devtree.c +++ b/arch/arm/kernel/devtree.c @@ -176,10 +176,10 @@ void __init arm_dt_init_cpu_maps(void) * If a dtb was passed to the kernel in r2, then use it to choose the * correct machine_desc and to setup the system. */ -struct machine_desc * __init setup_machine_fdt(unsigned int dt_phys) +const struct machine_desc * __init setup_machine_fdt(unsigned int dt_phys) { struct boot_param_header *devtree; - struct machine_desc *mdesc, *mdesc_best = NULL; + const struct machine_desc *mdesc, *mdesc_best = NULL; unsigned int score, mdesc_score = ~1; unsigned long dt_root; const char *model; @@ -188,7 +188,7 @@ struct machine_desc * __init setup_machine_fdt(unsigned int dt_phys) DT_MACHINE_START(GENERIC_DT, "Generic DT based system") MACHINE_END - mdesc_best = (struct machine_desc *)&__mach_desc_GENERIC_DT; + mdesc_best = &__mach_desc_GENERIC_DT; #endif if (!dt_phys) diff --git a/arch/arm/kernel/entry-common.S b/arch/arm/kernel/entry-common.S index 94104bf69719..74ad15d1a065 100644 --- a/arch/arm/kernel/entry-common.S +++ b/arch/arm/kernel/entry-common.S @@ -442,10 +442,10 @@ local_restart: ldrcc pc, [tbl, scno, lsl #2] @ call sys_* routine add r1, sp, #S_OFF -2: mov why, #0 @ no longer a real syscall cmp scno, #(__ARM_NR_BASE - __NR_SYSCALL_BASE) eor r0, scno, #__NR_SYSCALL_BASE @ put OS number back - bcs arm_syscall + bcs arm_syscall +2: mov why, #0 @ no longer a real syscall b sys_ni_syscall @ not private func #if defined(CONFIG_OABI_COMPAT) || !defined(CONFIG_AEABI) diff --git a/arch/arm/kernel/module.c b/arch/arm/kernel/module.c index 85c3fb6c93c2..084dc8896986 100644 --- a/arch/arm/kernel/module.c +++ b/arch/arm/kernel/module.c @@ -292,12 +292,20 @@ int module_finalize(const Elf32_Ehdr *hdr, const Elf_Shdr *sechdrs, maps[ARM_SEC_CORE].unw_sec = s; else if (strcmp(".ARM.exidx.exit.text", secname) == 0) maps[ARM_SEC_EXIT].unw_sec = s; + else if (strcmp(".ARM.exidx.text.unlikely", secname) == 0) + maps[ARM_SEC_UNLIKELY].unw_sec = s; + else if (strcmp(".ARM.exidx.text.hot", secname) == 0) + maps[ARM_SEC_HOT].unw_sec = s; else if (strcmp(".init.text", secname) == 0) maps[ARM_SEC_INIT].txt_sec = s; else if (strcmp(".text", secname) == 0) maps[ARM_SEC_CORE].txt_sec = s; else if (strcmp(".exit.text", secname) == 0) maps[ARM_SEC_EXIT].txt_sec = s; + else if (strcmp(".text.unlikely", secname) == 0) + maps[ARM_SEC_UNLIKELY].txt_sec = s; + else if (strcmp(".text.hot", secname) == 0) + maps[ARM_SEC_HOT].txt_sec = s; } for (i = 0; i < ARM_SEC_MAX; i++) diff --git a/arch/arm/kernel/perf_event_cpu.c b/arch/arm/kernel/perf_event_cpu.c index aebe0e99c153..8d6147b2001f 100644 --- a/arch/arm/kernel/perf_event_cpu.c +++ b/arch/arm/kernel/perf_event_cpu.c @@ -118,7 +118,8 @@ static int cpu_pmu_request_irq(struct arm_pmu *cpu_pmu, irq_handler_t handler) continue; } - err = request_irq(irq, handler, IRQF_NOBALANCING, "arm-pmu", + err = request_irq(irq, handler, + IRQF_NOBALANCING | IRQF_NO_THREAD, "arm-pmu", cpu_pmu); if (err) { pr_err("unable to request IRQ%d for ARM PMU counters\n", diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c index afc2489ee13b..0e1e2b3afa45 100644 --- a/arch/arm/kernel/setup.c +++ b/arch/arm/kernel/setup.c @@ -72,10 +72,10 @@ static int __init fpe_setup(char *line) __setup("fpe=", fpe_setup); #endif -extern void paging_init(struct machine_desc *desc); +extern void paging_init(const struct machine_desc *desc); extern void sanity_check_meminfo(void); extern enum reboot_mode reboot_mode; -extern void setup_dma_zone(struct machine_desc *desc); +extern void setup_dma_zone(const struct machine_desc *desc); unsigned int processor_id; EXPORT_SYMBOL(processor_id); @@ -139,7 +139,7 @@ EXPORT_SYMBOL(elf_platform); static const char *cpu_name; static const char *machine_name; static char __initdata cmd_line[COMMAND_LINE_SIZE]; -struct machine_desc *machine_desc __initdata; +const struct machine_desc *machine_desc __initdata; static union { char c[4]; unsigned long l; } endian_test __initdata = { { 'l', '?', '?', 'b' } }; #define ENDIANNESS ((char)endian_test.l) @@ -607,7 +607,7 @@ static void __init setup_processor(void) void __init dump_machine_table(void) { - struct machine_desc *p; + const struct machine_desc *p; early_print("Available machine support:\n\nID (hex)\tNAME\n"); for_each_machine_desc(p) @@ -694,7 +694,7 @@ static int __init early_mem(char *p) } early_param("mem", early_mem); -static void __init request_standard_resources(struct machine_desc *mdesc) +static void __init request_standard_resources(const struct machine_desc *mdesc) { struct memblock_region *region; struct resource *res; @@ -852,7 +852,7 @@ void __init hyp_mode_check(void) void __init setup_arch(char **cmdline_p) { - struct machine_desc *mdesc; + const struct machine_desc *mdesc; setup_processor(); mdesc = setup_machine_fdt(__atags_pointer); @@ -994,15 +994,6 @@ static int c_show(struct seq_file *m, void *v) seq_printf(m, "model name\t: %s rev %d (%s)\n", cpu_name, cpuid & 15, elf_platform); -#if defined(CONFIG_SMP) - seq_printf(m, "BogoMIPS\t: %lu.%02lu\n", - per_cpu(cpu_data, i).loops_per_jiffy / (500000UL/HZ), - (per_cpu(cpu_data, i).loops_per_jiffy / (5000UL/HZ)) % 100); -#else - seq_printf(m, "BogoMIPS\t: %lu.%02lu\n", - loops_per_jiffy / (500000/HZ), - (loops_per_jiffy / (5000/HZ)) % 100); -#endif /* dump out the processor features */ seq_puts(m, "Features\t: "); diff --git a/arch/arm/kernel/smp.c b/arch/arm/kernel/smp.c index 2dc19349eb19..92d10e503746 100644 --- a/arch/arm/kernel/smp.c +++ b/arch/arm/kernel/smp.c @@ -398,17 +398,8 @@ asmlinkage void secondary_start_kernel(void) void __init smp_cpus_done(unsigned int max_cpus) { - int cpu; - unsigned long bogosum = 0; - - for_each_online_cpu(cpu) - bogosum += per_cpu(cpu_data, cpu).loops_per_jiffy; - - printk(KERN_INFO "SMP: Total of %d processors activated " - "(%lu.%02lu BogoMIPS).\n", - num_online_cpus(), - bogosum / (500000/HZ), - (bogosum / (5000/HZ)) % 100); + printk(KERN_INFO "SMP: Total of %d processors activated.\n", + num_online_cpus()); hyp_mode_check(); } diff --git a/arch/arm/kernel/smp_tlb.c b/arch/arm/kernel/smp_tlb.c index c2edfff573c2..83ccca303df8 100644 --- a/arch/arm/kernel/smp_tlb.c +++ b/arch/arm/kernel/smp_tlb.c @@ -104,7 +104,7 @@ void flush_tlb_all(void) if (tlb_ops_need_broadcast()) on_each_cpu(ipi_flush_tlb_all, NULL, 1); else - local_flush_tlb_all(); + __flush_tlb_all(); broadcast_tlb_a15_erratum(); } @@ -113,7 +113,7 @@ void flush_tlb_mm(struct mm_struct *mm) if (tlb_ops_need_broadcast()) on_each_cpu_mask(mm_cpumask(mm), ipi_flush_tlb_mm, mm, 1); else - local_flush_tlb_mm(mm); + __flush_tlb_mm(mm); broadcast_tlb_mm_a15_erratum(mm); } @@ -126,7 +126,7 @@ void flush_tlb_page(struct vm_area_struct *vma, unsigned long uaddr) on_each_cpu_mask(mm_cpumask(vma->vm_mm), ipi_flush_tlb_page, &ta, 1); } else - local_flush_tlb_page(vma, uaddr); + __flush_tlb_page(vma, uaddr); broadcast_tlb_mm_a15_erratum(vma->vm_mm); } @@ -137,7 +137,7 @@ void flush_tlb_kernel_page(unsigned long kaddr) ta.ta_start = kaddr; on_each_cpu(ipi_flush_tlb_kernel_page, &ta, 1); } else - local_flush_tlb_kernel_page(kaddr); + __flush_tlb_kernel_page(kaddr); broadcast_tlb_a15_erratum(); } @@ -173,5 +173,5 @@ void flush_bp_all(void) if (tlb_ops_need_broadcast()) on_each_cpu(ipi_flush_bp_all, NULL, 1); else - local_flush_bp_all(); + __flush_bp_all(); } diff --git a/arch/arm/kernel/traps.c b/arch/arm/kernel/traps.c index ab517fcce21b..8fcda140358d 100644 --- a/arch/arm/kernel/traps.c +++ b/arch/arm/kernel/traps.c @@ -497,28 +497,64 @@ static int bad_syscall(int n, struct pt_regs *regs) return regs->ARM_r0; } +static long do_cache_op_restart(struct restart_block *); + 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; + unsigned long chunk = PAGE_SIZE; + + do { + if (signal_pending(current)) { + struct thread_info *ti = current_thread_info(); + + ti->restart_block = (struct restart_block) { + .fn = do_cache_op_restart, + }; + + ti->arm_restart_block = (struct arm_restart_block) { + { + .cache = { + .start = start, + .end = end, + }, + }, + }; + + return -ERESTART_RESTARTBLOCK; + } + + ret = flush_cache_user_range(start, start + chunk); + if (ret) + return ret; + cond_resched(); + start += chunk; + } while (start < end); + + return 0; +} + +static long do_cache_op_restart(struct restart_block *unused) +{ + struct arm_restart_block *restart_block; + + restart_block = ¤t_thread_info()->arm_restart_block; + return __do_cache_op(restart_block->cache.start, + restart_block->cache.end); +} + +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); } /* diff --git a/arch/arm/kernel/v7m.c b/arch/arm/kernel/v7m.c new file mode 100644 index 000000000000..4d2cba94f5cc --- /dev/null +++ b/arch/arm/kernel/v7m.c @@ -0,0 +1,19 @@ +/* + * Copyright (C) 2013 Uwe Kleine-Koenig for Pengutronix + * + * This program is free software; you can redistribute it and/or modify it under + * the terms of the GNU General Public License version 2 as published by the + * Free Software Foundation. + */ +#include <linux/io.h> +#include <linux/reboot.h> +#include <asm/barrier.h> +#include <asm/v7m.h> + +void armv7m_restart(enum reboot_mode mode, const char *cmd) +{ + dsb(); + __raw_writel(V7M_SCB_AIRCR_VECTKEY | V7M_SCB_AIRCR_SYSRESETREQ, + BASEADDR_V7M_SCB + V7M_SCB_AIRCR); + dsb(); +} |