diff options
Diffstat (limited to 'arch/arm/kernel')
-rw-r--r-- | arch/arm/kernel/asm-offsets.c | 2 | ||||
-rw-r--r-- | arch/arm/kernel/calls.S | 1 | ||||
-rw-r--r-- | arch/arm/kernel/entry-common.S | 9 | ||||
-rw-r--r-- | arch/arm/kernel/hw_breakpoint.c | 62 | ||||
-rw-r--r-- | arch/arm/kernel/machine_kexec.c | 29 | ||||
-rw-r--r-- | arch/arm/kernel/ptrace.c | 19 | ||||
-rw-r--r-- | arch/arm/kernel/sched_clock.c | 8 | ||||
-rw-r--r-- | arch/arm/kernel/smp.c | 13 | ||||
-rw-r--r-- | arch/arm/kernel/smp_twd.c | 48 | ||||
-rw-r--r-- | arch/arm/kernel/traps.c | 11 |
10 files changed, 167 insertions, 35 deletions
diff --git a/arch/arm/kernel/asm-offsets.c b/arch/arm/kernel/asm-offsets.c index 1429d8989fb9..c985b481192c 100644 --- a/arch/arm/kernel/asm-offsets.c +++ b/arch/arm/kernel/asm-offsets.c | |||
@@ -59,10 +59,12 @@ int main(void) | |||
59 | DEFINE(TI_USED_CP, offsetof(struct thread_info, used_cp)); | 59 | DEFINE(TI_USED_CP, offsetof(struct thread_info, used_cp)); |
60 | DEFINE(TI_TP_VALUE, offsetof(struct thread_info, tp_value)); | 60 | DEFINE(TI_TP_VALUE, offsetof(struct thread_info, tp_value)); |
61 | DEFINE(TI_FPSTATE, offsetof(struct thread_info, fpstate)); | 61 | DEFINE(TI_FPSTATE, offsetof(struct thread_info, fpstate)); |
62 | #ifdef CONFIG_VFP | ||
62 | DEFINE(TI_VFPSTATE, offsetof(struct thread_info, vfpstate)); | 63 | DEFINE(TI_VFPSTATE, offsetof(struct thread_info, vfpstate)); |
63 | #ifdef CONFIG_SMP | 64 | #ifdef CONFIG_SMP |
64 | DEFINE(VFP_CPU, offsetof(union vfp_state, hard.cpu)); | 65 | DEFINE(VFP_CPU, offsetof(union vfp_state, hard.cpu)); |
65 | #endif | 66 | #endif |
67 | #endif | ||
66 | #ifdef CONFIG_ARM_THUMBEE | 68 | #ifdef CONFIG_ARM_THUMBEE |
67 | DEFINE(TI_THUMBEE_STATE, offsetof(struct thread_info, thumbee_state)); | 69 | DEFINE(TI_THUMBEE_STATE, offsetof(struct thread_info, thumbee_state)); |
68 | #endif | 70 | #endif |
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/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? */ | ||
163 | static 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. */ |
163 | static int get_num_wrp_resources(void) | 169 | static 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 | |||
634 | out: | 658 | out: |
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 | ||
33 | int machine_kexec_prepare(struct kimage *image) | 35 | int 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 | ||
942 | asmlinkage int syscall_trace_enter(struct pt_regs *regs, int scno) | 945 | asmlinkage 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 | ||
950 | asmlinkage int syscall_trace_exit(struct pt_regs *regs, int scno) | 955 | asmlinkage 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 f4515393248d..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> |
@@ -27,6 +28,9 @@ struct clock_data { | |||
27 | 28 | ||
28 | static void sched_clock_poll(unsigned long wrap_ticks); | 29 | static void sched_clock_poll(unsigned long wrap_ticks); |
29 | static DEFINE_TIMER(sched_clock_timer, sched_clock_poll, 0, 0); | 30 | static DEFINE_TIMER(sched_clock_timer, sched_clock_poll, 0, 0); |
31 | static int irqtime = -1; | ||
32 | |||
33 | core_param(irqtime, irqtime, int, 0400); | ||
30 | 34 | ||
31 | static struct clock_data cd = { | 35 | static struct clock_data cd = { |
32 | .mult = NSEC_PER_SEC / HZ, | 36 | .mult = NSEC_PER_SEC / HZ, |
@@ -157,6 +161,10 @@ void __init setup_sched_clock(u32 (*read)(void), int bits, unsigned long rate) | |||
157 | */ | 161 | */ |
158 | cd.epoch_ns = 0; | 162 | cd.epoch_ns = 0; |
159 | 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 | |||
160 | pr_debug("Registered %pF as sched_clock source\n", read); | 168 | pr_debug("Registered %pF as sched_clock source\n", read); |
161 | } | 169 | } |
162 | 170 | ||
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 @@ | |||
51 | struct secondary_data secondary_data; | 51 | struct secondary_data secondary_data; |
52 | 52 | ||
53 | enum ipi_msg_type { | 53 | enum 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 | ||
349 | static const char *ipi_types[NR_IPI] = { | 350 | static 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 | */ | ||
104 | static 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 | |||
111 | static 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 | |||
128 | static struct notifier_block twd_clk_nb = { | ||
129 | .notifier_call = twd_rate_change, | ||
130 | }; | ||
131 | |||
132 | static 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 | } | ||
139 | core_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/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 | ||
439 | die_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", |