summaryrefslogtreecommitdiffstats
path: root/arch/arm/kernel
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/kernel')
-rw-r--r--arch/arm/kernel/entry-armv.S18
-rw-r--r--arch/arm/kernel/entry-common.S11
-rw-r--r--arch/arm/kernel/head-common.S4
-rw-r--r--arch/arm/kernel/smp.c13
-rw-r--r--arch/arm/kernel/smp_twd.c4
-rw-r--r--arch/arm/kernel/time.c1
-rw-r--r--arch/arm/kernel/traps.c81
7 files changed, 64 insertions, 68 deletions
diff --git a/arch/arm/kernel/entry-armv.S b/arch/arm/kernel/entry-armv.S
index 0a2ba51cf35d..322410be573c 100644
--- a/arch/arm/kernel/entry-armv.S
+++ b/arch/arm/kernel/entry-armv.S
@@ -311,22 +311,16 @@ __pabt_svc:
tst r3, #PSR_I_BIT
biceq r9, r9, #PSR_I_BIT
- @
- @ set args, then call main handler
- @
- @ r0 - address of faulting instruction
- @ r1 - pointer to registers on stack
- @
-#ifdef MULTI_PABORT
mov r0, r2 @ pass address of aborted instruction.
+#ifdef MULTI_PABORT
ldr r4, .LCprocfns
mov lr, pc
ldr pc, [r4, #PROCESSOR_PABT_FUNC]
#else
- CPU_PABORT_HANDLER(r0, r2)
+ bl CPU_PABORT_HANDLER
#endif
msr cpsr_c, r9 @ Maybe enable interrupts
- mov r1, sp @ regs
+ mov r2, sp @ regs
bl do_PrefetchAbort @ call abort handler
@
@@ -701,16 +695,16 @@ ENDPROC(__und_usr_unknown)
__pabt_usr:
usr_entry
-#ifdef MULTI_PABORT
mov r0, r2 @ pass address of aborted instruction.
+#ifdef MULTI_PABORT
ldr r4, .LCprocfns
mov lr, pc
ldr pc, [r4, #PROCESSOR_PABT_FUNC]
#else
- CPU_PABORT_HANDLER(r0, r2)
+ bl CPU_PABORT_HANDLER
#endif
enable_irq @ Enable interrupts
- mov r1, sp @ regs
+ mov r2, sp @ regs
bl do_PrefetchAbort @ call abort handler
UNWIND(.fnend )
/* fall through */
diff --git a/arch/arm/kernel/entry-common.S b/arch/arm/kernel/entry-common.S
index 807cfebb0f44..f0fe95b7085d 100644
--- a/arch/arm/kernel/entry-common.S
+++ b/arch/arm/kernel/entry-common.S
@@ -126,7 +126,7 @@ ENTRY(__gnu_mcount_nc)
cmp r0, r2
bne gnu_trace
ldmia sp!, {r0-r3, ip, lr}
- bx ip
+ mov pc, ip
gnu_trace:
ldr r1, [sp, #20] @ lr of instrumented routine
@@ -135,7 +135,7 @@ gnu_trace:
mov lr, pc
mov pc, r2
ldmia sp!, {r0-r3, ip, lr}
- bx ip
+ mov pc, ip
ENTRY(mcount)
stmdb sp!, {r0-r3, lr}
@@ -425,13 +425,6 @@ sys_mmap2:
#endif
ENDPROC(sys_mmap2)
-ENTRY(pabort_ifar)
- mrc p15, 0, r0, cr6, cr0, 2
-ENTRY(pabort_noifar)
- mov pc, lr
-ENDPROC(pabort_ifar)
-ENDPROC(pabort_noifar)
-
#ifdef CONFIG_OABI_COMPAT
/*
diff --git a/arch/arm/kernel/head-common.S b/arch/arm/kernel/head-common.S
index 93ad576b2d74..885a7214418d 100644
--- a/arch/arm/kernel/head-common.S
+++ b/arch/arm/kernel/head-common.S
@@ -13,6 +13,7 @@
#define ATAG_CORE 0x54410001
#define ATAG_CORE_SIZE ((2*4 + 3*4) >> 2)
+#define ATAG_CORE_SIZE_EMPTY ((2*4) >> 2)
.align 2
.type __switch_data, %object
@@ -251,7 +252,8 @@ __vet_atags:
bne 1f
ldr r5, [r2, #0] @ is first tag ATAG_CORE?
- subs r5, r5, #ATAG_CORE_SIZE
+ cmp r5, #ATAG_CORE_SIZE
+ cmpne r5, #ATAG_CORE_SIZE_EMPTY
bne 1f
ldr r5, [r2, #4]
ldr r6, =ATAG_CORE
diff --git a/arch/arm/kernel/smp.c b/arch/arm/kernel/smp.c
index e0d32770bb3d..57162af53dc9 100644
--- a/arch/arm/kernel/smp.c
+++ b/arch/arm/kernel/smp.c
@@ -36,6 +36,7 @@
#include <asm/tlbflush.h>
#include <asm/ptrace.h>
#include <asm/localtimer.h>
+#include <asm/smp_plat.h>
/*
* as from 2.5, kernels no longer have an init_tasks structure
@@ -153,7 +154,7 @@ int __cpuinit __cpu_up(unsigned int cpu)
/*
* __cpu_disable runs on the processor to be shutdown.
*/
-int __cpuexit __cpu_disable(void)
+int __cpu_disable(void)
{
unsigned int cpu = smp_processor_id();
struct task_struct *p;
@@ -200,7 +201,7 @@ int __cpuexit __cpu_disable(void)
* called on the thread which is asking for a CPU to be shutdown -
* waits until shutdown has completed, or it is timed out.
*/
-void __cpuexit __cpu_die(unsigned int cpu)
+void __cpu_die(unsigned int cpu)
{
if (!platform_cpu_kill(cpu))
printk("CPU%u: unable to kill\n", cpu);
@@ -214,7 +215,7 @@ void __cpuexit __cpu_die(unsigned int cpu)
* of the other hotplug-cpu capable cores, so presumably coming
* out of idle fixes this.
*/
-void __cpuexit cpu_die(void)
+void __ref cpu_die(void)
{
unsigned int cpu = smp_processor_id();
@@ -586,12 +587,6 @@ struct tlb_args {
unsigned long ta_end;
};
-/* all SMP configurations have the extended CPUID registers */
-static inline int tlb_ops_need_broadcast(void)
-{
- return ((read_cpuid_ext(CPUID_EXT_MMFR3) >> 12) & 0xf) < 2;
-}
-
static inline void ipi_flush_tlb_all(void *ignored)
{
local_flush_tlb_all();
diff --git a/arch/arm/kernel/smp_twd.c b/arch/arm/kernel/smp_twd.c
index d8c88c633c6f..a73a34dccf2a 100644
--- a/arch/arm/kernel/smp_twd.c
+++ b/arch/arm/kernel/smp_twd.c
@@ -166,10 +166,12 @@ void __cpuinit twd_timer_setup(struct clock_event_device *clk)
clockevents_register_device(clk);
}
+#ifdef CONFIG_HOTPLUG_CPU
/*
* take a local timer down
*/
-void __cpuexit twd_timer_stop(void)
+void twd_timer_stop(void)
{
__raw_writel(0, twd_base + TWD_TIMER_CONTROL);
}
+#endif
diff --git a/arch/arm/kernel/time.c b/arch/arm/kernel/time.c
index 4cdc4a0bd02d..d38cdf2c8276 100644
--- a/arch/arm/kernel/time.c
+++ b/arch/arm/kernel/time.c
@@ -21,6 +21,7 @@
#include <linux/interrupt.h>
#include <linux/time.h>
#include <linux/init.h>
+#include <linux/sched.h>
#include <linux/smp.h>
#include <linux/timex.h>
#include <linux/errno.h>
diff --git a/arch/arm/kernel/traps.c b/arch/arm/kernel/traps.c
index 57eb0f6f6005..f838f36eb702 100644
--- a/arch/arm/kernel/traps.c
+++ b/arch/arm/kernel/traps.c
@@ -45,21 +45,21 @@ static int __init user_debug_setup(char *str)
__setup("user_debug=", user_debug_setup);
#endif
-static void dump_mem(const char *str, unsigned long bottom, unsigned long top);
+static void dump_mem(const char *, const char *, unsigned long, unsigned long);
void dump_backtrace_entry(unsigned long where, unsigned long from, unsigned long frame)
{
#ifdef CONFIG_KALLSYMS
- printk("[<%08lx>] ", where);
- print_symbol("(%s) ", where);
- printk("from [<%08lx>] ", from);
- print_symbol("(%s)\n", from);
+ char sym1[KSYM_SYMBOL_LEN], sym2[KSYM_SYMBOL_LEN];
+ sprint_symbol(sym1, where);
+ sprint_symbol(sym2, from);
+ printk("[<%08lx>] (%s) from [<%08lx>] (%s)\n", where, sym1, from, sym2);
#else
printk("Function entered at [<%08lx>] from [<%08lx>]\n", where, from);
#endif
if (in_exception_text(where))
- dump_mem("Exception stack", frame + 4, frame + 4 + sizeof(struct pt_regs));
+ dump_mem("", "Exception stack", frame + 4, frame + 4 + sizeof(struct pt_regs));
}
#ifndef CONFIG_ARM_UNWIND
@@ -81,9 +81,10 @@ static int verify_stack(unsigned long sp)
/*
* Dump out the contents of some memory nicely...
*/
-static void dump_mem(const char *str, unsigned long bottom, unsigned long top)
+static void dump_mem(const char *lvl, const char *str, unsigned long bottom,
+ unsigned long top)
{
- unsigned long p = bottom & ~31;
+ unsigned long first;
mm_segment_t fs;
int i;
@@ -95,33 +96,37 @@ static void dump_mem(const char *str, unsigned long bottom, unsigned long top)
fs = get_fs();
set_fs(KERNEL_DS);
- printk("%s(0x%08lx to 0x%08lx)\n", str, bottom, top);
+ printk("%s%s(0x%08lx to 0x%08lx)\n", lvl, str, bottom, top);
- for (p = bottom & ~31; p < top;) {
- printk("%04lx: ", p & 0xffff);
+ for (first = bottom & ~31; first < top; first += 32) {
+ unsigned long p;
+ char str[sizeof(" 12345678") * 8 + 1];
- for (i = 0; i < 8; i++, p += 4) {
- unsigned int val;
+ memset(str, ' ', sizeof(str));
+ str[sizeof(str) - 1] = '\0';
- if (p < bottom || p >= top)
- printk(" ");
- else {
- __get_user(val, (unsigned long *)p);
- printk("%08x ", val);
+ for (p = first, i = 0; i < 8 && p < top; i++, p += 4) {
+ if (p >= bottom && p < top) {
+ unsigned long val;
+ if (__get_user(val, (unsigned long *)p) == 0)
+ sprintf(str + i * 9, " %08lx", val);
+ else
+ sprintf(str + i * 9, " ????????");
}
}
- printk ("\n");
+ printk("%s%04lx:%s\n", lvl, first & 0xffff, str);
}
set_fs(fs);
}
-static void dump_instr(struct pt_regs *regs)
+static void dump_instr(const char *lvl, struct pt_regs *regs)
{
unsigned long addr = instruction_pointer(regs);
const int thumb = thumb_mode(regs);
const int width = thumb ? 4 : 8;
mm_segment_t fs;
+ char str[sizeof("00000000 ") * 5 + 2 + 1], *p = str;
int i;
/*
@@ -132,7 +137,6 @@ static void dump_instr(struct pt_regs *regs)
fs = get_fs();
set_fs(KERNEL_DS);
- printk("Code: ");
for (i = -4; i < 1; i++) {
unsigned int val, bad;
@@ -142,13 +146,14 @@ static void dump_instr(struct pt_regs *regs)
bad = __get_user(val, &((u32 *)addr)[i]);
if (!bad)
- printk(i == 0 ? "(%0*x) " : "%0*x ", width, val);
+ p += sprintf(p, i == 0 ? "(%0*x) " : "%0*x ",
+ width, val);
else {
- printk("bad PC value.");
+ p += sprintf(p, "bad PC value");
break;
}
}
- printk("\n");
+ printk("%sCode: %s\n", lvl, str);
set_fs(fs);
}
@@ -224,18 +229,19 @@ static void __die(const char *str, int err, struct thread_info *thread, struct p
struct task_struct *tsk = thread->task;
static int die_counter;
- printk("Internal error: %s: %x [#%d]" S_PREEMPT S_SMP "\n",
+ printk(KERN_EMERG "Internal error: %s: %x [#%d]" S_PREEMPT S_SMP "\n",
str, err, ++die_counter);
+ sysfs_printk_last_file();
print_modules();
__show_regs(regs);
- printk("Process %s (pid: %d, stack limit = 0x%p)\n",
- tsk->comm, task_pid_nr(tsk), thread + 1);
+ printk(KERN_EMERG "Process %.*s (pid: %d, stack limit = 0x%p)\n",
+ TASK_COMM_LEN, tsk->comm, task_pid_nr(tsk), thread + 1);
if (!user_mode(regs) || in_interrupt()) {
- dump_mem("Stack: ", regs->ARM_sp,
+ dump_mem(KERN_EMERG, "Stack: ", regs->ARM_sp,
THREAD_SIZE + (unsigned long)task_stack_page(tsk));
dump_backtrace(regs, tsk);
- dump_instr(regs);
+ dump_instr(KERN_EMERG, regs);
}
}
@@ -250,13 +256,14 @@ NORET_TYPE void die(const char *str, struct pt_regs *regs, int err)
oops_enter();
- console_verbose();
spin_lock_irq(&die_lock);
+ console_verbose();
bust_spinlocks(1);
__die(str, err, thread, regs);
bust_spinlocks(0);
add_taint(TAINT_DIE);
spin_unlock_irq(&die_lock);
+ oops_exit();
if (in_interrupt())
panic("Fatal exception in interrupt");
@@ -264,7 +271,6 @@ NORET_TYPE void die(const char *str, struct pt_regs *regs, int err)
if (panic_on_oops)
panic("Fatal exception");
- oops_exit();
do_exit(SIGSEGV);
}
@@ -349,7 +355,7 @@ asmlinkage void __exception do_undefinstr(struct pt_regs *regs)
if (user_debug & UDBG_UNDEFINED) {
printk(KERN_INFO "%s (%d): undefined instruction: pc=%p\n",
current->comm, task_pid_nr(current), pc);
- dump_instr(regs);
+ dump_instr(KERN_INFO, regs);
}
#endif
@@ -400,7 +406,7 @@ static int bad_syscall(int n, struct pt_regs *regs)
if (user_debug & UDBG_SYSCALL) {
printk(KERN_ERR "[%d] %s: obsolete system call %08x.\n",
task_pid_nr(current), current->comm, n);
- dump_instr(regs);
+ dump_instr(KERN_ERR, regs);
}
#endif
@@ -418,12 +424,14 @@ static int bad_syscall(int n, struct pt_regs *regs)
static inline void
do_cache_op(unsigned long start, unsigned long end, int flags)
{
+ struct mm_struct *mm = current->active_mm;
struct vm_area_struct *vma;
if (end < start || flags)
return;
- vma = find_vma(current->active_mm, start);
+ 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;
@@ -432,6 +440,7 @@ do_cache_op(unsigned long start, unsigned long end, int flags)
flush_cache_user_range(vma, start, end);
}
+ up_read(&mm->mmap_sem);
}
/*
@@ -576,7 +585,7 @@ asmlinkage int arm_syscall(int no, struct pt_regs *regs)
if (user_debug & UDBG_SYSCALL) {
printk("[%d] %s: arm syscall %d\n",
task_pid_nr(current), current->comm, no);
- dump_instr(regs);
+ dump_instr("", regs);
if (user_mode(regs)) {
__show_regs(regs);
c_backtrace(regs->ARM_fp, processor_mode(regs));
@@ -653,7 +662,7 @@ baddataabort(int code, unsigned long instr, struct pt_regs *regs)
if (user_debug & UDBG_BADABORT) {
printk(KERN_ERR "[%d] %s: bad data abort: code %d instr 0x%08lx\n",
task_pid_nr(current), current->comm, code, instr);
- dump_instr(regs);
+ dump_instr(KERN_ERR, regs);
show_pte(current->mm, addr);
}
#endif