aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/kernel
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/kernel')
-rw-r--r--arch/arm/kernel/Makefile5
-rw-r--r--arch/arm/kernel/atags.h14
-rw-r--r--arch/arm/kernel/atags_compat.c (renamed from arch/arm/kernel/compat.c)4
-rw-r--r--arch/arm/kernel/atags_parse.c238
-rw-r--r--arch/arm/kernel/atags_proc.c (renamed from arch/arm/kernel/atags.c)0
-rw-r--r--arch/arm/kernel/calls.S1
-rw-r--r--arch/arm/kernel/compat.h11
-rw-r--r--arch/arm/kernel/entry-common.S9
-rw-r--r--arch/arm/kernel/hw_breakpoint.c62
-rw-r--r--arch/arm/kernel/machine_kexec.c29
-rw-r--r--arch/arm/kernel/ptrace.c19
-rw-r--r--arch/arm/kernel/sched_clock.c32
-rw-r--r--arch/arm/kernel/setup.c236
-rw-r--r--arch/arm/kernel/smp.c13
-rw-r--r--arch/arm/kernel/smp_twd.c48
-rw-r--r--arch/arm/kernel/topology.c2
-rw-r--r--arch/arm/kernel/traps.c11
17 files changed, 448 insertions, 286 deletions
diff --git a/arch/arm/kernel/Makefile b/arch/arm/kernel/Makefile
index 7ad2d5cf7008..79e346a5d78b 100644
--- a/arch/arm/kernel/Makefile
+++ b/arch/arm/kernel/Makefile
@@ -19,7 +19,9 @@ obj-y := elf.o entry-armv.o entry-common.o irq.o opcodes.o \
19 process.o ptrace.o return_address.o sched_clock.o \ 19 process.o ptrace.o return_address.o sched_clock.o \
20 setup.o signal.o stacktrace.o sys_arm.o time.o traps.o 20 setup.o signal.o stacktrace.o sys_arm.o time.o traps.o
21 21
22obj-$(CONFIG_DEPRECATED_PARAM_STRUCT) += compat.o 22obj-$(CONFIG_ATAGS) += atags_parse.o
23obj-$(CONFIG_ATAGS_PROC) += atags_proc.o
24obj-$(CONFIG_DEPRECATED_PARAM_STRUCT) += atags_compat.o
23 25
24obj-$(CONFIG_LEDS) += leds.o 26obj-$(CONFIG_LEDS) += leds.o
25obj-$(CONFIG_OC_ETM) += etm.o 27obj-$(CONFIG_OC_ETM) += etm.o
@@ -52,7 +54,6 @@ test-kprobes-objs += kprobes-test-thumb.o
52else 54else
53test-kprobes-objs += kprobes-test-arm.o 55test-kprobes-objs += kprobes-test-arm.o
54endif 56endif
55obj-$(CONFIG_ATAGS_PROC) += atags.o
56obj-$(CONFIG_OABI_COMPAT) += sys_oabi-compat.o 57obj-$(CONFIG_OABI_COMPAT) += sys_oabi-compat.o
57obj-$(CONFIG_ARM_THUMBEE) += thumbee.o 58obj-$(CONFIG_ARM_THUMBEE) += thumbee.o
58obj-$(CONFIG_KGDB) += kgdb.o 59obj-$(CONFIG_KGDB) += kgdb.o
diff --git a/arch/arm/kernel/atags.h b/arch/arm/kernel/atags.h
index e5f028d214a1..9edc9692332d 100644
--- a/arch/arm/kernel/atags.h
+++ b/arch/arm/kernel/atags.h
@@ -3,3 +3,17 @@ extern void save_atags(struct tag *tags);
3#else 3#else
4static inline void save_atags(struct tag *tags) { } 4static inline void save_atags(struct tag *tags) { }
5#endif 5#endif
6
7void convert_to_tag_list(struct tag *tags);
8
9#ifdef CONFIG_ATAGS
10struct machine_desc *setup_machine_tags(phys_addr_t __atags_pointer, unsigned int machine_nr);
11#else
12static inline struct machine_desc *
13setup_machine_tags(phys_addr_t __atags_pointer, unsigned int machine_nr)
14{
15 early_print("no ATAGS support: can't continue\n");
16 while (true);
17 unreachable();
18}
19#endif
diff --git a/arch/arm/kernel/compat.c b/arch/arm/kernel/atags_compat.c
index 925652318b8b..5236ad38f417 100644
--- a/arch/arm/kernel/compat.c
+++ b/arch/arm/kernel/atags_compat.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * linux/arch/arm/kernel/compat.c 2 * linux/arch/arm/kernel/atags_compat.c
3 * 3 *
4 * Copyright (C) 2001 Russell King 4 * Copyright (C) 2001 Russell King
5 * 5 *
@@ -26,7 +26,7 @@
26 26
27#include <asm/mach/arch.h> 27#include <asm/mach/arch.h>
28 28
29#include "compat.h" 29#include "atags.h"
30 30
31/* 31/*
32 * Usage: 32 * Usage:
diff --git a/arch/arm/kernel/atags_parse.c b/arch/arm/kernel/atags_parse.c
new file mode 100644
index 000000000000..14512e6931d8
--- /dev/null
+++ b/arch/arm/kernel/atags_parse.c
@@ -0,0 +1,238 @@
1/*
2 * Tag parsing.
3 *
4 * Copyright (C) 1995-2001 Russell King
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 */
10
11/*
12 * This is the traditional way of passing data to the kernel at boot time. Rather
13 * than passing a fixed inflexible structure to the kernel, we pass a list
14 * of variable-sized tags to the kernel. The first tag must be a ATAG_CORE
15 * tag for the list to be recognised (to distinguish the tagged list from
16 * a param_struct). The list is terminated with a zero-length tag (this tag
17 * is not parsed in any way).
18 */
19
20#include <linux/init.h>
21#include <linux/kernel.h>
22#include <linux/fs.h>
23#include <linux/root_dev.h>
24#include <linux/screen_info.h>
25
26#include <asm/setup.h>
27#include <asm/system_info.h>
28#include <asm/page.h>
29#include <asm/mach/arch.h>
30
31#include "atags.h"
32
33static char default_command_line[COMMAND_LINE_SIZE] __initdata = CONFIG_CMDLINE;
34
35#ifndef MEM_SIZE
36#define MEM_SIZE (16*1024*1024)
37#endif
38
39static struct {
40 struct tag_header hdr1;
41 struct tag_core core;
42 struct tag_header hdr2;
43 struct tag_mem32 mem;
44 struct tag_header hdr3;
45} default_tags __initdata = {
46 { tag_size(tag_core), ATAG_CORE },
47 { 1, PAGE_SIZE, 0xff },
48 { tag_size(tag_mem32), ATAG_MEM },
49 { MEM_SIZE },
50 { 0, ATAG_NONE }
51};
52
53static int __init parse_tag_core(const struct tag *tag)
54{
55 if (tag->hdr.size > 2) {
56 if ((tag->u.core.flags & 1) == 0)
57 root_mountflags &= ~MS_RDONLY;
58 ROOT_DEV = old_decode_dev(tag->u.core.rootdev);
59 }
60 return 0;
61}
62
63__tagtable(ATAG_CORE, parse_tag_core);
64
65static int __init parse_tag_mem32(const struct tag *tag)
66{
67 return arm_add_memory(tag->u.mem.start, tag->u.mem.size);
68}
69
70__tagtable(ATAG_MEM, parse_tag_mem32);
71
72#if defined(CONFIG_VGA_CONSOLE) || defined(CONFIG_DUMMY_CONSOLE)
73static int __init parse_tag_videotext(const struct tag *tag)
74{
75 screen_info.orig_x = tag->u.videotext.x;
76 screen_info.orig_y = tag->u.videotext.y;
77 screen_info.orig_video_page = tag->u.videotext.video_page;
78 screen_info.orig_video_mode = tag->u.videotext.video_mode;
79 screen_info.orig_video_cols = tag->u.videotext.video_cols;
80 screen_info.orig_video_ega_bx = tag->u.videotext.video_ega_bx;
81 screen_info.orig_video_lines = tag->u.videotext.video_lines;
82 screen_info.orig_video_isVGA = tag->u.videotext.video_isvga;
83 screen_info.orig_video_points = tag->u.videotext.video_points;
84 return 0;
85}
86
87__tagtable(ATAG_VIDEOTEXT, parse_tag_videotext);
88#endif
89
90#ifdef CONFIG_BLK_DEV_RAM
91static int __init parse_tag_ramdisk(const struct tag *tag)
92{
93 extern int rd_size, rd_image_start, rd_prompt, rd_doload;
94
95 rd_image_start = tag->u.ramdisk.start;
96 rd_doload = (tag->u.ramdisk.flags & 1) == 0;
97 rd_prompt = (tag->u.ramdisk.flags & 2) == 0;
98
99 if (tag->u.ramdisk.size)
100 rd_size = tag->u.ramdisk.size;
101
102 return 0;
103}
104
105__tagtable(ATAG_RAMDISK, parse_tag_ramdisk);
106#endif
107
108static int __init parse_tag_serialnr(const struct tag *tag)
109{
110 system_serial_low = tag->u.serialnr.low;
111 system_serial_high = tag->u.serialnr.high;
112 return 0;
113}
114
115__tagtable(ATAG_SERIAL, parse_tag_serialnr);
116
117static int __init parse_tag_revision(const struct tag *tag)
118{
119 system_rev = tag->u.revision.rev;
120 return 0;
121}
122
123__tagtable(ATAG_REVISION, parse_tag_revision);
124
125static int __init parse_tag_cmdline(const struct tag *tag)
126{
127#if defined(CONFIG_CMDLINE_EXTEND)
128 strlcat(default_command_line, " ", COMMAND_LINE_SIZE);
129 strlcat(default_command_line, tag->u.cmdline.cmdline,
130 COMMAND_LINE_SIZE);
131#elif defined(CONFIG_CMDLINE_FORCE)
132 pr_warning("Ignoring tag cmdline (using the default kernel command line)\n");
133#else
134 strlcpy(default_command_line, tag->u.cmdline.cmdline,
135 COMMAND_LINE_SIZE);
136#endif
137 return 0;
138}
139
140__tagtable(ATAG_CMDLINE, parse_tag_cmdline);
141
142/*
143 * Scan the tag table for this tag, and call its parse function.
144 * The tag table is built by the linker from all the __tagtable
145 * declarations.
146 */
147static int __init parse_tag(const struct tag *tag)
148{
149 extern struct tagtable __tagtable_begin, __tagtable_end;
150 struct tagtable *t;
151
152 for (t = &__tagtable_begin; t < &__tagtable_end; t++)
153 if (tag->hdr.tag == t->tag) {
154 t->parse(tag);
155 break;
156 }
157
158 return t < &__tagtable_end;
159}
160
161/*
162 * Parse all tags in the list, checking both the global and architecture
163 * specific tag tables.
164 */
165static void __init parse_tags(const struct tag *t)
166{
167 for (; t->hdr.size; t = tag_next(t))
168 if (!parse_tag(t))
169 printk(KERN_WARNING
170 "Ignoring unrecognised tag 0x%08x\n",
171 t->hdr.tag);
172}
173
174static void __init squash_mem_tags(struct tag *tag)
175{
176 for (; tag->hdr.size; tag = tag_next(tag))
177 if (tag->hdr.tag == ATAG_MEM)
178 tag->hdr.tag = ATAG_NONE;
179}
180
181struct machine_desc * __init setup_machine_tags(phys_addr_t __atags_pointer,
182 unsigned int machine_nr)
183{
184 struct tag *tags = (struct tag *)&default_tags;
185 struct machine_desc *mdesc = NULL, *p;
186 char *from = default_command_line;
187
188 default_tags.mem.start = PHYS_OFFSET;
189
190 /*
191 * locate machine in the list of supported machines.
192 */
193 for_each_machine_desc(p)
194 if (machine_nr == p->nr) {
195 printk("Machine: %s\n", p->name);
196 mdesc = p;
197 break;
198 }
199
200 if (!mdesc) {
201 early_print("\nError: unrecognized/unsupported machine ID"
202 " (r1 = 0x%08x).\n\n", machine_nr);
203 dump_machine_table(); /* does not return */
204 }
205
206 if (__atags_pointer)
207 tags = phys_to_virt(__atags_pointer);
208 else if (mdesc->atag_offset)
209 tags = (void *)(PAGE_OFFSET + mdesc->atag_offset);
210
211#if defined(CONFIG_DEPRECATED_PARAM_STRUCT)
212 /*
213 * If we have the old style parameters, convert them to
214 * a tag list.
215 */
216 if (tags->hdr.tag != ATAG_CORE)
217 convert_to_tag_list(tags);
218#endif
219 if (tags->hdr.tag != ATAG_CORE) {
220 early_print("Warning: Neither atags nor dtb found\n");
221 tags = (struct tag *)&default_tags;
222 }
223
224 if (mdesc->fixup)
225 mdesc->fixup(tags, &from, &meminfo);
226
227 if (tags->hdr.tag == ATAG_CORE) {
228 if (meminfo.nr_banks != 0)
229 squash_mem_tags(tags);
230 save_atags(tags);
231 parse_tags(tags);
232 }
233
234 /* parse_early_param needs a boot_command_line */
235 strlcpy(boot_command_line, from, COMMAND_LINE_SIZE);
236
237 return mdesc;
238}
diff --git a/arch/arm/kernel/atags.c b/arch/arm/kernel/atags_proc.c
index 42a1a1415fa6..42a1a1415fa6 100644
--- a/arch/arm/kernel/atags.c
+++ b/arch/arm/kernel/atags_proc.c
diff --git a/arch/arm/kernel/calls.S b/arch/arm/kernel/calls.S
index 463ff4a0ec8a..e337879595e5 100644
--- a/arch/arm/kernel/calls.S
+++ b/arch/arm/kernel/calls.S
@@ -387,6 +387,7 @@
387/* 375 */ CALL(sys_setns) 387/* 375 */ CALL(sys_setns)
388 CALL(sys_process_vm_readv) 388 CALL(sys_process_vm_readv)
389 CALL(sys_process_vm_writev) 389 CALL(sys_process_vm_writev)
390 CALL(sys_ni_syscall) /* reserved for sys_kcmp */
390#ifndef syscalls_counted 391#ifndef syscalls_counted
391.equ syscalls_padding, ((NR_syscalls + 3) & ~3) - NR_syscalls 392.equ syscalls_padding, ((NR_syscalls + 3) & ~3) - NR_syscalls
392#define syscalls_counted 393#define syscalls_counted
diff --git a/arch/arm/kernel/compat.h b/arch/arm/kernel/compat.h
deleted file mode 100644
index 39264ab1b9c6..000000000000
--- a/arch/arm/kernel/compat.h
+++ /dev/null
@@ -1,11 +0,0 @@
1/*
2 * linux/arch/arm/kernel/compat.h
3 *
4 * Copyright (C) 2001 Russell King
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9*/
10
11extern void convert_to_tag_list(struct tag *tags);
diff --git a/arch/arm/kernel/entry-common.S b/arch/arm/kernel/entry-common.S
index 978eac57e04a..f45987037bf1 100644
--- a/arch/arm/kernel/entry-common.S
+++ b/arch/arm/kernel/entry-common.S
@@ -94,6 +94,15 @@ ENDPROC(ret_from_fork)
94 .equ NR_syscalls,0 94 .equ NR_syscalls,0
95#define CALL(x) .equ NR_syscalls,NR_syscalls+1 95#define CALL(x) .equ NR_syscalls,NR_syscalls+1
96#include "calls.S" 96#include "calls.S"
97
98/*
99 * Ensure that the system call table is equal to __NR_syscalls,
100 * which is the value the rest of the system sees
101 */
102.ifne NR_syscalls - __NR_syscalls
103.error "__NR_syscalls is not equal to the size of the syscall table"
104.endif
105
97#undef CALL 106#undef CALL
98#define CALL(x) .long x 107#define CALL(x) .long x
99 108
diff --git a/arch/arm/kernel/hw_breakpoint.c b/arch/arm/kernel/hw_breakpoint.c
index ba386bd94107..281bf3301241 100644
--- a/arch/arm/kernel/hw_breakpoint.c
+++ b/arch/arm/kernel/hw_breakpoint.c
@@ -159,6 +159,12 @@ static int debug_arch_supported(void)
159 arch >= ARM_DEBUG_ARCH_V7_1; 159 arch >= ARM_DEBUG_ARCH_V7_1;
160} 160}
161 161
162/* Can we determine the watchpoint access type from the fsr? */
163static int debug_exception_updates_fsr(void)
164{
165 return 0;
166}
167
162/* Determine number of WRP registers available. */ 168/* Determine number of WRP registers available. */
163static int get_num_wrp_resources(void) 169static int get_num_wrp_resources(void)
164{ 170{
@@ -604,13 +610,14 @@ int arch_validate_hwbkpt_settings(struct perf_event *bp)
604 /* Aligned */ 610 /* Aligned */
605 break; 611 break;
606 case 1: 612 case 1:
607 /* Allow single byte watchpoint. */
608 if (info->ctrl.len == ARM_BREAKPOINT_LEN_1)
609 break;
610 case 2: 613 case 2:
611 /* Allow halfword watchpoints and breakpoints. */ 614 /* Allow halfword watchpoints and breakpoints. */
612 if (info->ctrl.len == ARM_BREAKPOINT_LEN_2) 615 if (info->ctrl.len == ARM_BREAKPOINT_LEN_2)
613 break; 616 break;
617 case 3:
618 /* Allow single byte watchpoint. */
619 if (info->ctrl.len == ARM_BREAKPOINT_LEN_1)
620 break;
614 default: 621 default:
615 ret = -EINVAL; 622 ret = -EINVAL;
616 goto out; 623 goto out;
@@ -619,18 +626,35 @@ int arch_validate_hwbkpt_settings(struct perf_event *bp)
619 info->address &= ~alignment_mask; 626 info->address &= ~alignment_mask;
620 info->ctrl.len <<= offset; 627 info->ctrl.len <<= offset;
621 628
622 /* 629 if (!bp->overflow_handler) {
623 * Currently we rely on an overflow handler to take 630 /*
624 * care of single-stepping the breakpoint when it fires. 631 * Mismatch breakpoints are required for single-stepping
625 * In the case of userspace breakpoints on a core with V7 debug, 632 * breakpoints.
626 * we can use the mismatch feature as a poor-man's hardware 633 */
627 * single-step, but this only works for per-task breakpoints. 634 if (!core_has_mismatch_brps())
628 */ 635 return -EINVAL;
629 if (!bp->overflow_handler && (arch_check_bp_in_kernelspace(bp) || 636
630 !core_has_mismatch_brps() || !bp->hw.bp_target)) { 637 /* We don't allow mismatch breakpoints in kernel space. */
631 pr_warning("overflow handler required but none found\n"); 638 if (arch_check_bp_in_kernelspace(bp))
632 ret = -EINVAL; 639 return -EPERM;
640
641 /*
642 * Per-cpu breakpoints are not supported by our stepping
643 * mechanism.
644 */
645 if (!bp->hw.bp_target)
646 return -EINVAL;
647
648 /*
649 * We only support specific access types if the fsr
650 * reports them.
651 */
652 if (!debug_exception_updates_fsr() &&
653 (info->ctrl.type == ARM_BREAKPOINT_LOAD ||
654 info->ctrl.type == ARM_BREAKPOINT_STORE))
655 return -EINVAL;
633 } 656 }
657
634out: 658out:
635 return ret; 659 return ret;
636} 660}
@@ -706,10 +730,12 @@ static void watchpoint_handler(unsigned long addr, unsigned int fsr,
706 goto unlock; 730 goto unlock;
707 731
708 /* Check that the access type matches. */ 732 /* Check that the access type matches. */
709 access = (fsr & ARM_FSR_ACCESS_MASK) ? HW_BREAKPOINT_W : 733 if (debug_exception_updates_fsr()) {
710 HW_BREAKPOINT_R; 734 access = (fsr & ARM_FSR_ACCESS_MASK) ?
711 if (!(access & hw_breakpoint_type(wp))) 735 HW_BREAKPOINT_W : HW_BREAKPOINT_R;
712 goto unlock; 736 if (!(access & hw_breakpoint_type(wp)))
737 goto unlock;
738 }
713 739
714 /* We have a winner. */ 740 /* We have a winner. */
715 info->trigger = addr; 741 info->trigger = addr;
diff --git a/arch/arm/kernel/machine_kexec.c b/arch/arm/kernel/machine_kexec.c
index dfcdb9f7c126..e29c3337ca81 100644
--- a/arch/arm/kernel/machine_kexec.c
+++ b/arch/arm/kernel/machine_kexec.c
@@ -8,7 +8,9 @@
8#include <linux/reboot.h> 8#include <linux/reboot.h>
9#include <linux/io.h> 9#include <linux/io.h>
10#include <linux/irq.h> 10#include <linux/irq.h>
11#include <linux/memblock.h>
11#include <asm/pgtable.h> 12#include <asm/pgtable.h>
13#include <linux/of_fdt.h>
12#include <asm/pgalloc.h> 14#include <asm/pgalloc.h>
13#include <asm/mmu_context.h> 15#include <asm/mmu_context.h>
14#include <asm/cacheflush.h> 16#include <asm/cacheflush.h>
@@ -32,6 +34,29 @@ static atomic_t waiting_for_crash_ipi;
32 34
33int machine_kexec_prepare(struct kimage *image) 35int machine_kexec_prepare(struct kimage *image)
34{ 36{
37 struct kexec_segment *current_segment;
38 __be32 header;
39 int i, err;
40
41 /*
42 * No segment at default ATAGs address. try to locate
43 * a dtb using magic.
44 */
45 for (i = 0; i < image->nr_segments; i++) {
46 current_segment = &image->segment[i];
47
48 err = memblock_is_region_memory(current_segment->mem,
49 current_segment->memsz);
50 if (err)
51 return - EINVAL;
52
53 err = get_user(header, (__be32*)current_segment->buf);
54 if (err)
55 return err;
56
57 if (be32_to_cpu(header) == OF_DT_HEADER)
58 kexec_boot_atags = current_segment->mem;
59 }
35 return 0; 60 return 0;
36} 61}
37 62
@@ -122,7 +147,9 @@ void machine_kexec(struct kimage *image)
122 kexec_start_address = image->start; 147 kexec_start_address = image->start;
123 kexec_indirection_page = page_list; 148 kexec_indirection_page = page_list;
124 kexec_mach_type = machine_arch_type; 149 kexec_mach_type = machine_arch_type;
125 kexec_boot_atags = image->start - KEXEC_ARM_ZIMAGE_OFFSET + KEXEC_ARM_ATAGS_OFFSET; 150 if (!kexec_boot_atags)
151 kexec_boot_atags = image->start - KEXEC_ARM_ZIMAGE_OFFSET + KEXEC_ARM_ATAGS_OFFSET;
152
126 153
127 /* copy our kernel relocation code to the control code page */ 154 /* copy our kernel relocation code to the control code page */
128 memcpy(reboot_code_buffer, 155 memcpy(reboot_code_buffer,
diff --git a/arch/arm/kernel/ptrace.c b/arch/arm/kernel/ptrace.c
index 3e0fc5f7ed4b..739db3a1b2d2 100644
--- a/arch/arm/kernel/ptrace.c
+++ b/arch/arm/kernel/ptrace.c
@@ -30,6 +30,9 @@
30#include <asm/pgtable.h> 30#include <asm/pgtable.h>
31#include <asm/traps.h> 31#include <asm/traps.h>
32 32
33#define CREATE_TRACE_POINTS
34#include <trace/events/syscalls.h>
35
33#define REG_PC 15 36#define REG_PC 15
34#define REG_PSR 16 37#define REG_PSR 16
35/* 38/*
@@ -918,11 +921,11 @@ static int ptrace_syscall_trace(struct pt_regs *regs, int scno,
918{ 921{
919 unsigned long ip; 922 unsigned long ip;
920 923
924 current_thread_info()->syscall = scno;
925
921 if (!test_thread_flag(TIF_SYSCALL_TRACE)) 926 if (!test_thread_flag(TIF_SYSCALL_TRACE))
922 return scno; 927 return scno;
923 928
924 current_thread_info()->syscall = scno;
925
926 /* 929 /*
927 * IP is used to denote syscall entry/exit: 930 * IP is used to denote syscall entry/exit:
928 * IP = 0 -> entry, =1 -> exit 931 * IP = 0 -> entry, =1 -> exit
@@ -941,15 +944,19 @@ static int ptrace_syscall_trace(struct pt_regs *regs, int scno,
941 944
942asmlinkage int syscall_trace_enter(struct pt_regs *regs, int scno) 945asmlinkage int syscall_trace_enter(struct pt_regs *regs, int scno)
943{ 946{
944 int ret = ptrace_syscall_trace(regs, scno, PTRACE_SYSCALL_ENTER); 947 scno = ptrace_syscall_trace(regs, scno, PTRACE_SYSCALL_ENTER);
948 if (test_thread_flag(TIF_SYSCALL_TRACEPOINT))
949 trace_sys_enter(regs, scno);
945 audit_syscall_entry(AUDIT_ARCH_ARM, scno, regs->ARM_r0, regs->ARM_r1, 950 audit_syscall_entry(AUDIT_ARCH_ARM, scno, regs->ARM_r0, regs->ARM_r1,
946 regs->ARM_r2, regs->ARM_r3); 951 regs->ARM_r2, regs->ARM_r3);
947 return ret; 952 return scno;
948} 953}
949 954
950asmlinkage int syscall_trace_exit(struct pt_regs *regs, int scno) 955asmlinkage int syscall_trace_exit(struct pt_regs *regs, int scno)
951{ 956{
952 int ret = ptrace_syscall_trace(regs, scno, PTRACE_SYSCALL_EXIT); 957 scno = ptrace_syscall_trace(regs, scno, PTRACE_SYSCALL_EXIT);
958 if (test_thread_flag(TIF_SYSCALL_TRACEPOINT))
959 trace_sys_exit(regs, scno);
953 audit_syscall_exit(regs); 960 audit_syscall_exit(regs);
954 return ret; 961 return scno;
955} 962}
diff --git a/arch/arm/kernel/sched_clock.c b/arch/arm/kernel/sched_clock.c
index 27d186abbc06..e21bac20d90d 100644
--- a/arch/arm/kernel/sched_clock.c
+++ b/arch/arm/kernel/sched_clock.c
@@ -9,6 +9,7 @@
9#include <linux/init.h> 9#include <linux/init.h>
10#include <linux/jiffies.h> 10#include <linux/jiffies.h>
11#include <linux/kernel.h> 11#include <linux/kernel.h>
12#include <linux/moduleparam.h>
12#include <linux/sched.h> 13#include <linux/sched.h>
13#include <linux/syscore_ops.h> 14#include <linux/syscore_ops.h>
14#include <linux/timer.h> 15#include <linux/timer.h>
@@ -21,10 +22,15 @@ struct clock_data {
21 u32 epoch_cyc_copy; 22 u32 epoch_cyc_copy;
22 u32 mult; 23 u32 mult;
23 u32 shift; 24 u32 shift;
25 bool suspended;
26 bool needs_suspend;
24}; 27};
25 28
26static void sched_clock_poll(unsigned long wrap_ticks); 29static void sched_clock_poll(unsigned long wrap_ticks);
27static DEFINE_TIMER(sched_clock_timer, sched_clock_poll, 0, 0); 30static DEFINE_TIMER(sched_clock_timer, sched_clock_poll, 0, 0);
31static int irqtime = -1;
32
33core_param(irqtime, irqtime, int, 0400);
28 34
29static struct clock_data cd = { 35static struct clock_data cd = {
30 .mult = NSEC_PER_SEC / HZ, 36 .mult = NSEC_PER_SEC / HZ,
@@ -49,6 +55,9 @@ static unsigned long long cyc_to_sched_clock(u32 cyc, u32 mask)
49 u64 epoch_ns; 55 u64 epoch_ns;
50 u32 epoch_cyc; 56 u32 epoch_cyc;
51 57
58 if (cd.suspended)
59 return cd.epoch_ns;
60
52 /* 61 /*
53 * Load the epoch_cyc and epoch_ns atomically. We do this by 62 * Load the epoch_cyc and epoch_ns atomically. We do this by
54 * ensuring that we always write epoch_cyc, epoch_ns and 63 * ensuring that we always write epoch_cyc, epoch_ns and
@@ -98,6 +107,13 @@ static void sched_clock_poll(unsigned long wrap_ticks)
98 update_sched_clock(); 107 update_sched_clock();
99} 108}
100 109
110void __init setup_sched_clock_needs_suspend(u32 (*read)(void), int bits,
111 unsigned long rate)
112{
113 setup_sched_clock(read, bits, rate);
114 cd.needs_suspend = true;
115}
116
101void __init setup_sched_clock(u32 (*read)(void), int bits, unsigned long rate) 117void __init setup_sched_clock(u32 (*read)(void), int bits, unsigned long rate)
102{ 118{
103 unsigned long r, w; 119 unsigned long r, w;
@@ -145,6 +161,10 @@ void __init setup_sched_clock(u32 (*read)(void), int bits, unsigned long rate)
145 */ 161 */
146 cd.epoch_ns = 0; 162 cd.epoch_ns = 0;
147 163
164 /* Enable IRQ time accounting if we have a fast enough sched_clock */
165 if (irqtime > 0 || (irqtime == -1 && rate >= 1000000))
166 enable_sched_clock_irqtime();
167
148 pr_debug("Registered %pF as sched_clock source\n", read); 168 pr_debug("Registered %pF as sched_clock source\n", read);
149} 169}
150 170
@@ -169,11 +189,23 @@ void __init sched_clock_postinit(void)
169static int sched_clock_suspend(void) 189static int sched_clock_suspend(void)
170{ 190{
171 sched_clock_poll(sched_clock_timer.data); 191 sched_clock_poll(sched_clock_timer.data);
192 if (cd.needs_suspend)
193 cd.suspended = true;
172 return 0; 194 return 0;
173} 195}
174 196
197static void sched_clock_resume(void)
198{
199 if (cd.needs_suspend) {
200 cd.epoch_cyc = read_sched_clock();
201 cd.epoch_cyc_copy = cd.epoch_cyc;
202 cd.suspended = false;
203 }
204}
205
175static struct syscore_ops sched_clock_ops = { 206static struct syscore_ops sched_clock_ops = {
176 .suspend = sched_clock_suspend, 207 .suspend = sched_clock_suspend,
208 .resume = sched_clock_resume,
177}; 209};
178 210
179static int __init sched_clock_syscore_init(void) 211static int __init sched_clock_syscore_init(void)
diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c
index a81dcecc7343..0785472460a8 100644
--- a/arch/arm/kernel/setup.c
+++ b/arch/arm/kernel/setup.c
@@ -21,11 +21,9 @@
21#include <linux/init.h> 21#include <linux/init.h>
22#include <linux/kexec.h> 22#include <linux/kexec.h>
23#include <linux/of_fdt.h> 23#include <linux/of_fdt.h>
24#include <linux/root_dev.h>
25#include <linux/cpu.h> 24#include <linux/cpu.h>
26#include <linux/interrupt.h> 25#include <linux/interrupt.h>
27#include <linux/smp.h> 26#include <linux/smp.h>
28#include <linux/fs.h>
29#include <linux/proc_fs.h> 27#include <linux/proc_fs.h>
30#include <linux/memblock.h> 28#include <linux/memblock.h>
31#include <linux/bug.h> 29#include <linux/bug.h>
@@ -56,15 +54,9 @@
56#include <asm/unwind.h> 54#include <asm/unwind.h>
57#include <asm/memblock.h> 55#include <asm/memblock.h>
58 56
59#if defined(CONFIG_DEPRECATED_PARAM_STRUCT)
60#include "compat.h"
61#endif
62#include "atags.h" 57#include "atags.h"
63#include "tcm.h" 58#include "tcm.h"
64 59
65#ifndef MEM_SIZE
66#define MEM_SIZE (16*1024*1024)
67#endif
68 60
69#if defined(CONFIG_FPE_NWFPE) || defined(CONFIG_FPE_FASTFPE) 61#if defined(CONFIG_FPE_NWFPE) || defined(CONFIG_FPE_FASTFPE)
70char fpe_type[8]; 62char fpe_type[8];
@@ -145,7 +137,6 @@ static const char *machine_name;
145static char __initdata cmd_line[COMMAND_LINE_SIZE]; 137static char __initdata cmd_line[COMMAND_LINE_SIZE];
146struct machine_desc *machine_desc __initdata; 138struct machine_desc *machine_desc __initdata;
147 139
148static char default_command_line[COMMAND_LINE_SIZE] __initdata = CONFIG_CMDLINE;
149static union { char c[4]; unsigned long l; } endian_test __initdata = { { 'l', '?', '?', 'b' } }; 140static union { char c[4]; unsigned long l; } endian_test __initdata = { { 'l', '?', '?', 'b' } };
150#define ENDIANNESS ((char)endian_test.l) 141#define ENDIANNESS ((char)endian_test.l)
151 142
@@ -583,21 +574,6 @@ static int __init early_mem(char *p)
583} 574}
584early_param("mem", early_mem); 575early_param("mem", early_mem);
585 576
586static void __init
587setup_ramdisk(int doload, int prompt, int image_start, unsigned int rd_sz)
588{
589#ifdef CONFIG_BLK_DEV_RAM
590 extern int rd_size, rd_image_start, rd_prompt, rd_doload;
591
592 rd_image_start = image_start;
593 rd_prompt = prompt;
594 rd_doload = doload;
595
596 if (rd_sz)
597 rd_size = rd_sz;
598#endif
599}
600
601static void __init request_standard_resources(struct machine_desc *mdesc) 577static void __init request_standard_resources(struct machine_desc *mdesc)
602{ 578{
603 struct memblock_region *region; 579 struct memblock_region *region;
@@ -643,35 +619,6 @@ static void __init request_standard_resources(struct machine_desc *mdesc)
643 request_resource(&ioport_resource, &lp2); 619 request_resource(&ioport_resource, &lp2);
644} 620}
645 621
646/*
647 * Tag parsing.
648 *
649 * This is the new way of passing data to the kernel at boot time. Rather
650 * than passing a fixed inflexible structure to the kernel, we pass a list
651 * of variable-sized tags to the kernel. The first tag must be a ATAG_CORE
652 * tag for the list to be recognised (to distinguish the tagged list from
653 * a param_struct). The list is terminated with a zero-length tag (this tag
654 * is not parsed in any way).
655 */
656static int __init parse_tag_core(const struct tag *tag)
657{
658 if (tag->hdr.size > 2) {
659 if ((tag->u.core.flags & 1) == 0)
660 root_mountflags &= ~MS_RDONLY;
661 ROOT_DEV = old_decode_dev(tag->u.core.rootdev);
662 }
663 return 0;
664}
665
666__tagtable(ATAG_CORE, parse_tag_core);
667
668static int __init parse_tag_mem32(const struct tag *tag)
669{
670 return arm_add_memory(tag->u.mem.start, tag->u.mem.size);
671}
672
673__tagtable(ATAG_MEM, parse_tag_mem32);
674
675#if defined(CONFIG_VGA_CONSOLE) || defined(CONFIG_DUMMY_CONSOLE) 622#if defined(CONFIG_VGA_CONSOLE) || defined(CONFIG_DUMMY_CONSOLE)
676struct screen_info screen_info = { 623struct screen_info screen_info = {
677 .orig_video_lines = 30, 624 .orig_video_lines = 30,
@@ -681,117 +628,8 @@ struct screen_info screen_info = {
681 .orig_video_isVGA = 1, 628 .orig_video_isVGA = 1,
682 .orig_video_points = 8 629 .orig_video_points = 8
683}; 630};
684
685static int __init parse_tag_videotext(const struct tag *tag)
686{
687 screen_info.orig_x = tag->u.videotext.x;
688 screen_info.orig_y = tag->u.videotext.y;
689 screen_info.orig_video_page = tag->u.videotext.video_page;
690 screen_info.orig_video_mode = tag->u.videotext.video_mode;
691 screen_info.orig_video_cols = tag->u.videotext.video_cols;
692 screen_info.orig_video_ega_bx = tag->u.videotext.video_ega_bx;
693 screen_info.orig_video_lines = tag->u.videotext.video_lines;
694 screen_info.orig_video_isVGA = tag->u.videotext.video_isvga;
695 screen_info.orig_video_points = tag->u.videotext.video_points;
696 return 0;
697}
698
699__tagtable(ATAG_VIDEOTEXT, parse_tag_videotext);
700#endif 631#endif
701 632
702static int __init parse_tag_ramdisk(const struct tag *tag)
703{
704 setup_ramdisk((tag->u.ramdisk.flags & 1) == 0,
705 (tag->u.ramdisk.flags & 2) == 0,
706 tag->u.ramdisk.start, tag->u.ramdisk.size);
707 return 0;
708}
709
710__tagtable(ATAG_RAMDISK, parse_tag_ramdisk);
711
712static int __init parse_tag_serialnr(const struct tag *tag)
713{
714 system_serial_low = tag->u.serialnr.low;
715 system_serial_high = tag->u.serialnr.high;
716 return 0;
717}
718
719__tagtable(ATAG_SERIAL, parse_tag_serialnr);
720
721static int __init parse_tag_revision(const struct tag *tag)
722{
723 system_rev = tag->u.revision.rev;
724 return 0;
725}
726
727__tagtable(ATAG_REVISION, parse_tag_revision);
728
729static int __init parse_tag_cmdline(const struct tag *tag)
730{
731#if defined(CONFIG_CMDLINE_EXTEND)
732 strlcat(default_command_line, " ", COMMAND_LINE_SIZE);
733 strlcat(default_command_line, tag->u.cmdline.cmdline,
734 COMMAND_LINE_SIZE);
735#elif defined(CONFIG_CMDLINE_FORCE)
736 pr_warning("Ignoring tag cmdline (using the default kernel command line)\n");
737#else
738 strlcpy(default_command_line, tag->u.cmdline.cmdline,
739 COMMAND_LINE_SIZE);
740#endif
741 return 0;
742}
743
744__tagtable(ATAG_CMDLINE, parse_tag_cmdline);
745
746/*
747 * Scan the tag table for this tag, and call its parse function.
748 * The tag table is built by the linker from all the __tagtable
749 * declarations.
750 */
751static int __init parse_tag(const struct tag *tag)
752{
753 extern struct tagtable __tagtable_begin, __tagtable_end;
754 struct tagtable *t;
755
756 for (t = &__tagtable_begin; t < &__tagtable_end; t++)
757 if (tag->hdr.tag == t->tag) {
758 t->parse(tag);
759 break;
760 }
761
762 return t < &__tagtable_end;
763}
764
765/*
766 * Parse all tags in the list, checking both the global and architecture
767 * specific tag tables.
768 */
769static void __init parse_tags(const struct tag *t)
770{
771 for (; t->hdr.size; t = tag_next(t))
772 if (!parse_tag(t))
773 printk(KERN_WARNING
774 "Ignoring unrecognised tag 0x%08x\n",
775 t->hdr.tag);
776}
777
778/*
779 * This holds our defaults.
780 */
781static struct init_tags {
782 struct tag_header hdr1;
783 struct tag_core core;
784 struct tag_header hdr2;
785 struct tag_mem32 mem;
786 struct tag_header hdr3;
787} init_tags __initdata = {
788 { tag_size(tag_core), ATAG_CORE },
789 { 1, PAGE_SIZE, 0xff },
790 { tag_size(tag_mem32), ATAG_MEM },
791 { MEM_SIZE },
792 { 0, ATAG_NONE }
793};
794
795static int __init customize_machine(void) 633static int __init customize_machine(void)
796{ 634{
797 /* customizes platform devices, or adds new ones */ 635 /* customizes platform devices, or adds new ones */
@@ -858,78 +696,6 @@ static void __init reserve_crashkernel(void)
858static inline void reserve_crashkernel(void) {} 696static inline void reserve_crashkernel(void) {}
859#endif /* CONFIG_KEXEC */ 697#endif /* CONFIG_KEXEC */
860 698
861static void __init squash_mem_tags(struct tag *tag)
862{
863 for (; tag->hdr.size; tag = tag_next(tag))
864 if (tag->hdr.tag == ATAG_MEM)
865 tag->hdr.tag = ATAG_NONE;
866}
867
868static struct machine_desc * __init setup_machine_tags(unsigned int nr)
869{
870 struct tag *tags = (struct tag *)&init_tags;
871 struct machine_desc *mdesc = NULL, *p;
872 char *from = default_command_line;
873
874 init_tags.mem.start = PHYS_OFFSET;
875
876 /*
877 * locate machine in the list of supported machines.
878 */
879 for_each_machine_desc(p)
880 if (nr == p->nr) {
881 printk("Machine: %s\n", p->name);
882 mdesc = p;
883 break;
884 }
885
886 if (!mdesc) {
887 early_print("\nError: unrecognized/unsupported machine ID"
888 " (r1 = 0x%08x).\n\n", nr);
889 dump_machine_table(); /* does not return */
890 }
891
892 if (__atags_pointer)
893 tags = phys_to_virt(__atags_pointer);
894 else if (mdesc->atag_offset)
895 tags = (void *)(PAGE_OFFSET + mdesc->atag_offset);
896
897#if defined(CONFIG_DEPRECATED_PARAM_STRUCT)
898 /*
899 * If we have the old style parameters, convert them to
900 * a tag list.
901 */
902 if (tags->hdr.tag != ATAG_CORE)
903 convert_to_tag_list(tags);
904#endif
905
906 if (tags->hdr.tag != ATAG_CORE) {
907#if defined(CONFIG_OF)
908 /*
909 * If CONFIG_OF is set, then assume this is a reasonably
910 * modern system that should pass boot parameters
911 */
912 early_print("Warning: Neither atags nor dtb found\n");
913#endif
914 tags = (struct tag *)&init_tags;
915 }
916
917 if (mdesc->fixup)
918 mdesc->fixup(tags, &from, &meminfo);
919
920 if (tags->hdr.tag == ATAG_CORE) {
921 if (meminfo.nr_banks != 0)
922 squash_mem_tags(tags);
923 save_atags(tags);
924 parse_tags(tags);
925 }
926
927 /* parse_early_param needs a boot_command_line */
928 strlcpy(boot_command_line, from, COMMAND_LINE_SIZE);
929
930 return mdesc;
931}
932
933static int __init meminfo_cmp(const void *_a, const void *_b) 699static int __init meminfo_cmp(const void *_a, const void *_b)
934{ 700{
935 const struct membank *a = _a, *b = _b; 701 const struct membank *a = _a, *b = _b;
@@ -944,7 +710,7 @@ void __init setup_arch(char **cmdline_p)
944 setup_processor(); 710 setup_processor();
945 mdesc = setup_machine_fdt(__atags_pointer); 711 mdesc = setup_machine_fdt(__atags_pointer);
946 if (!mdesc) 712 if (!mdesc)
947 mdesc = setup_machine_tags(machine_arch_type); 713 mdesc = setup_machine_tags(__atags_pointer, machine_arch_type);
948 machine_desc = mdesc; 714 machine_desc = mdesc;
949 machine_name = mdesc->name; 715 machine_name = mdesc->name;
950 716
diff --git a/arch/arm/kernel/smp.c b/arch/arm/kernel/smp.c
index ebd8ad274d76..d98c37e97d9d 100644
--- a/arch/arm/kernel/smp.c
+++ b/arch/arm/kernel/smp.c
@@ -51,7 +51,8 @@
51struct secondary_data secondary_data; 51struct secondary_data secondary_data;
52 52
53enum ipi_msg_type { 53enum ipi_msg_type {
54 IPI_TIMER = 2, 54 IPI_WAKEUP,
55 IPI_TIMER,
55 IPI_RESCHEDULE, 56 IPI_RESCHEDULE,
56 IPI_CALL_FUNC, 57 IPI_CALL_FUNC,
57 IPI_CALL_FUNC_SINGLE, 58 IPI_CALL_FUNC_SINGLE,
@@ -347,7 +348,8 @@ void arch_send_call_function_single_ipi(int cpu)
347} 348}
348 349
349static const char *ipi_types[NR_IPI] = { 350static const char *ipi_types[NR_IPI] = {
350#define S(x,s) [x - IPI_TIMER] = s 351#define S(x,s) [x] = s
352 S(IPI_WAKEUP, "CPU wakeup interrupts"),
351 S(IPI_TIMER, "Timer broadcast interrupts"), 353 S(IPI_TIMER, "Timer broadcast interrupts"),
352 S(IPI_RESCHEDULE, "Rescheduling interrupts"), 354 S(IPI_RESCHEDULE, "Rescheduling interrupts"),
353 S(IPI_CALL_FUNC, "Function call interrupts"), 355 S(IPI_CALL_FUNC, "Function call interrupts"),
@@ -500,10 +502,13 @@ void handle_IPI(int ipinr, struct pt_regs *regs)
500 unsigned int cpu = smp_processor_id(); 502 unsigned int cpu = smp_processor_id();
501 struct pt_regs *old_regs = set_irq_regs(regs); 503 struct pt_regs *old_regs = set_irq_regs(regs);
502 504
503 if (ipinr >= IPI_TIMER && ipinr < IPI_TIMER + NR_IPI) 505 if (ipinr < NR_IPI)
504 __inc_irq_stat(cpu, ipi_irqs[ipinr - IPI_TIMER]); 506 __inc_irq_stat(cpu, ipi_irqs[ipinr]);
505 507
506 switch (ipinr) { 508 switch (ipinr) {
509 case IPI_WAKEUP:
510 break;
511
507 case IPI_TIMER: 512 case IPI_TIMER:
508 irq_enter(); 513 irq_enter();
509 ipi_timer(); 514 ipi_timer();
diff --git a/arch/arm/kernel/smp_twd.c b/arch/arm/kernel/smp_twd.c
index fef42b21cecb..e1f906989bb8 100644
--- a/arch/arm/kernel/smp_twd.c
+++ b/arch/arm/kernel/smp_twd.c
@@ -11,7 +11,6 @@
11#include <linux/init.h> 11#include <linux/init.h>
12#include <linux/kernel.h> 12#include <linux/kernel.h>
13#include <linux/clk.h> 13#include <linux/clk.h>
14#include <linux/cpufreq.h>
15#include <linux/delay.h> 14#include <linux/delay.h>
16#include <linux/device.h> 15#include <linux/device.h>
17#include <linux/err.h> 16#include <linux/err.h>
@@ -96,7 +95,52 @@ static void twd_timer_stop(struct clock_event_device *clk)
96 disable_percpu_irq(clk->irq); 95 disable_percpu_irq(clk->irq);
97} 96}
98 97
99#ifdef CONFIG_CPU_FREQ 98#ifdef CONFIG_COMMON_CLK
99
100/*
101 * Updates clockevent frequency when the cpu frequency changes.
102 * Called on the cpu that is changing frequency with interrupts disabled.
103 */
104static void twd_update_frequency(void *new_rate)
105{
106 twd_timer_rate = *((unsigned long *) new_rate);
107
108 clockevents_update_freq(*__this_cpu_ptr(twd_evt), twd_timer_rate);
109}
110
111static int twd_rate_change(struct notifier_block *nb,
112 unsigned long flags, void *data)
113{
114 struct clk_notifier_data *cnd = data;
115
116 /*
117 * The twd clock events must be reprogrammed to account for the new
118 * frequency. The timer is local to a cpu, so cross-call to the
119 * changing cpu.
120 */
121 if (flags == POST_RATE_CHANGE)
122 smp_call_function(twd_update_frequency,
123 (void *)&cnd->new_rate, 1);
124
125 return NOTIFY_OK;
126}
127
128static struct notifier_block twd_clk_nb = {
129 .notifier_call = twd_rate_change,
130};
131
132static int twd_clk_init(void)
133{
134 if (twd_evt && *__this_cpu_ptr(twd_evt) && !IS_ERR(twd_clk))
135 return clk_notifier_register(twd_clk, &twd_clk_nb);
136
137 return 0;
138}
139core_initcall(twd_clk_init);
140
141#elif defined (CONFIG_CPU_FREQ)
142
143#include <linux/cpufreq.h>
100 144
101/* 145/*
102 * Updates clockevent frequency when the cpu frequency changes. 146 * Updates clockevent frequency when the cpu frequency changes.
diff --git a/arch/arm/kernel/topology.c b/arch/arm/kernel/topology.c
index 198b08456e90..26c12c6440fc 100644
--- a/arch/arm/kernel/topology.c
+++ b/arch/arm/kernel/topology.c
@@ -321,7 +321,7 @@ void store_cpu_topology(unsigned int cpuid)
321 * init_cpu_topology is called at boot when only one cpu is running 321 * init_cpu_topology is called at boot when only one cpu is running
322 * which prevent simultaneous write access to cpu_topology array 322 * which prevent simultaneous write access to cpu_topology array
323 */ 323 */
324void init_cpu_topology(void) 324void __init init_cpu_topology(void)
325{ 325{
326 unsigned int cpu; 326 unsigned int cpu;
327 327
diff --git a/arch/arm/kernel/traps.c b/arch/arm/kernel/traps.c
index f7945218b8c6..b0179b89a04c 100644
--- a/arch/arm/kernel/traps.c
+++ b/arch/arm/kernel/traps.c
@@ -420,20 +420,23 @@ asmlinkage void __exception do_undefinstr(struct pt_regs *regs)
420#endif 420#endif
421 instr = *(u32 *) pc; 421 instr = *(u32 *) pc;
422 } else if (thumb_mode(regs)) { 422 } else if (thumb_mode(regs)) {
423 get_user(instr, (u16 __user *)pc); 423 if (get_user(instr, (u16 __user *)pc))
424 goto die_sig;
424 if (is_wide_instruction(instr)) { 425 if (is_wide_instruction(instr)) {
425 unsigned int instr2; 426 unsigned int instr2;
426 get_user(instr2, (u16 __user *)pc+1); 427 if (get_user(instr2, (u16 __user *)pc+1))
428 goto die_sig;
427 instr <<= 16; 429 instr <<= 16;
428 instr |= instr2; 430 instr |= instr2;
429 } 431 }
430 } else { 432 } else if (get_user(instr, (u32 __user *)pc)) {
431 get_user(instr, (u32 __user *)pc); 433 goto die_sig;
432 } 434 }
433 435
434 if (call_undef_hook(regs, instr) == 0) 436 if (call_undef_hook(regs, instr) == 0)
435 return; 437 return;
436 438
439die_sig:
437#ifdef CONFIG_DEBUG_USER 440#ifdef CONFIG_DEBUG_USER
438 if (user_debug & UDBG_UNDEFINED) { 441 if (user_debug & UDBG_UNDEFINED) {
439 printk(KERN_INFO "%s (%d): undefined instruction: pc=%p\n", 442 printk(KERN_INFO "%s (%d): undefined instruction: pc=%p\n",