diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2009-12-15 12:00:19 -0500 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2009-12-15 12:00:19 -0500 |
| commit | 17c330f98383629cfd359ee62b3adde1d2a3ff7c (patch) | |
| tree | 876bed8fc7de7d404fae579035a948c46a7f05d4 /arch/sparc/kernel | |
| parent | 48e902f0a3aea4b6b3a73e9d277b92024a493e6d (diff) | |
| parent | 7466bd3caab6bd1d0095de957affbacd02ca58a7 (diff) | |
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/sparc-2.6
* git://git.kernel.org/pub/scm/linux/kernel/git/davem/sparc-2.6:
sparc64: Fix clock event multiplier printf format.
sparc64: Use clock{source,events}_calc_mult_shift().
sparc64: Use free_bootmem_late() in mdesc_lmb_free().
sparc: Add alignment and emulation fault perf events.
sparc64: Add syscall tracepoint support.
sparc: Stop trying to be so fancy and use __builtin_{memcpy,memset}()
sparc: Use __builtin_object_size() to validate the buffer size for copy_from_user()
sparc64: Add some missing __kprobes annotations to kernel fault paths.
sparc64: Use kprobes_built_in() to avoid ifdefs in fault_64.c
sparc: Validate that kprobe address is 4-byte aligned.
sparc64: Don't specify IRQF_SHARED for LDC interrupts.
sparc64: Fix stack debugging IRQ stack regression.
sparc64: Fix overly strict range type matching for PCI devices.
Diffstat (limited to 'arch/sparc/kernel')
| -rw-r--r-- | arch/sparc/kernel/entry.S | 2 | ||||
| -rw-r--r-- | arch/sparc/kernel/ftrace.c | 11 | ||||
| -rw-r--r-- | arch/sparc/kernel/kprobes.c | 3 | ||||
| -rw-r--r-- | arch/sparc/kernel/ldc.c | 4 | ||||
| -rw-r--r-- | arch/sparc/kernel/mdesc.c | 21 | ||||
| -rw-r--r-- | arch/sparc/kernel/of_device_64.c | 14 | ||||
| -rw-r--r-- | arch/sparc/kernel/ptrace_64.c | 10 | ||||
| -rw-r--r-- | arch/sparc/kernel/syscalls.S | 14 | ||||
| -rw-r--r-- | arch/sparc/kernel/time_64.c | 26 | ||||
| -rw-r--r-- | arch/sparc/kernel/unaligned_32.c | 15 | ||||
| -rw-r--r-- | arch/sparc/kernel/unaligned_64.c | 23 | ||||
| -rw-r--r-- | arch/sparc/kernel/visemul.c | 3 |
12 files changed, 70 insertions, 76 deletions
diff --git a/arch/sparc/kernel/entry.S b/arch/sparc/kernel/entry.S index ec9c7bc67d21..1504df8ddf70 100644 --- a/arch/sparc/kernel/entry.S +++ b/arch/sparc/kernel/entry.S | |||
| @@ -1294,7 +1294,7 @@ linux_sparc_syscall: | |||
| 1294 | sethi %hi(PSR_SYSCALL), %l4 | 1294 | sethi %hi(PSR_SYSCALL), %l4 |
| 1295 | or %l0, %l4, %l0 | 1295 | or %l0, %l4, %l0 |
| 1296 | /* Direct access to user regs, must faster. */ | 1296 | /* Direct access to user regs, must faster. */ |
| 1297 | cmp %g1, NR_SYSCALLS | 1297 | cmp %g1, NR_syscalls |
| 1298 | bgeu linux_sparc_ni_syscall | 1298 | bgeu linux_sparc_ni_syscall |
| 1299 | sll %g1, 2, %l4 | 1299 | sll %g1, 2, %l4 |
| 1300 | ld [%l7 + %l4], %l7 | 1300 | ld [%l7 + %l4], %l7 |
diff --git a/arch/sparc/kernel/ftrace.c b/arch/sparc/kernel/ftrace.c index d3b1a3076569..29973daa9930 100644 --- a/arch/sparc/kernel/ftrace.c +++ b/arch/sparc/kernel/ftrace.c | |||
| @@ -4,6 +4,7 @@ | |||
| 4 | #include <linux/percpu.h> | 4 | #include <linux/percpu.h> |
| 5 | #include <linux/init.h> | 5 | #include <linux/init.h> |
| 6 | #include <linux/list.h> | 6 | #include <linux/list.h> |
| 7 | #include <trace/syscall.h> | ||
| 7 | 8 | ||
| 8 | #include <asm/ftrace.h> | 9 | #include <asm/ftrace.h> |
| 9 | 10 | ||
| @@ -91,3 +92,13 @@ int __init ftrace_dyn_arch_init(void *data) | |||
| 91 | } | 92 | } |
| 92 | #endif | 93 | #endif |
| 93 | 94 | ||
| 95 | #ifdef CONFIG_FTRACE_SYSCALLS | ||
| 96 | |||
| 97 | extern unsigned int sys_call_table[]; | ||
| 98 | |||
| 99 | unsigned long __init arch_syscall_addr(int nr) | ||
| 100 | { | ||
| 101 | return (unsigned long)sys_call_table[nr]; | ||
| 102 | } | ||
| 103 | |||
| 104 | #endif | ||
diff --git a/arch/sparc/kernel/kprobes.c b/arch/sparc/kernel/kprobes.c index 3bc6527c95af..6716584e48ab 100644 --- a/arch/sparc/kernel/kprobes.c +++ b/arch/sparc/kernel/kprobes.c | |||
| @@ -46,6 +46,9 @@ struct kretprobe_blackpoint kretprobe_blacklist[] = {{NULL, NULL}}; | |||
| 46 | 46 | ||
| 47 | int __kprobes arch_prepare_kprobe(struct kprobe *p) | 47 | int __kprobes arch_prepare_kprobe(struct kprobe *p) |
| 48 | { | 48 | { |
| 49 | if ((unsigned long) p->addr & 0x3UL) | ||
| 50 | return -EILSEQ; | ||
| 51 | |||
| 49 | p->ainsn.insn[0] = *p->addr; | 52 | p->ainsn.insn[0] = *p->addr; |
| 50 | flushi(&p->ainsn.insn[0]); | 53 | flushi(&p->ainsn.insn[0]); |
| 51 | 54 | ||
diff --git a/arch/sparc/kernel/ldc.c b/arch/sparc/kernel/ldc.c index cb3c72c45aab..e0ba898e30cf 100644 --- a/arch/sparc/kernel/ldc.c +++ b/arch/sparc/kernel/ldc.c | |||
| @@ -1242,13 +1242,13 @@ int ldc_bind(struct ldc_channel *lp, const char *name) | |||
| 1242 | snprintf(lp->tx_irq_name, LDC_IRQ_NAME_MAX, "%s TX", name); | 1242 | snprintf(lp->tx_irq_name, LDC_IRQ_NAME_MAX, "%s TX", name); |
| 1243 | 1243 | ||
| 1244 | err = request_irq(lp->cfg.rx_irq, ldc_rx, | 1244 | err = request_irq(lp->cfg.rx_irq, ldc_rx, |
| 1245 | IRQF_SAMPLE_RANDOM | IRQF_DISABLED | IRQF_SHARED, | 1245 | IRQF_SAMPLE_RANDOM | IRQF_DISABLED, |
| 1246 | lp->rx_irq_name, lp); | 1246 | lp->rx_irq_name, lp); |
| 1247 | if (err) | 1247 | if (err) |
| 1248 | return err; | 1248 | return err; |
| 1249 | 1249 | ||
| 1250 | err = request_irq(lp->cfg.tx_irq, ldc_tx, | 1250 | err = request_irq(lp->cfg.tx_irq, ldc_tx, |
| 1251 | IRQF_SAMPLE_RANDOM | IRQF_DISABLED | IRQF_SHARED, | 1251 | IRQF_SAMPLE_RANDOM | IRQF_DISABLED, |
| 1252 | lp->tx_irq_name, lp); | 1252 | lp->tx_irq_name, lp); |
| 1253 | if (err) { | 1253 | if (err) { |
| 1254 | free_irq(lp->cfg.rx_irq, lp); | 1254 | free_irq(lp->cfg.rx_irq, lp); |
diff --git a/arch/sparc/kernel/mdesc.c b/arch/sparc/kernel/mdesc.c index 938da19dc065..cdc91d919e93 100644 --- a/arch/sparc/kernel/mdesc.c +++ b/arch/sparc/kernel/mdesc.c | |||
| @@ -10,6 +10,7 @@ | |||
| 10 | #include <linux/slab.h> | 10 | #include <linux/slab.h> |
| 11 | #include <linux/mm.h> | 11 | #include <linux/mm.h> |
| 12 | #include <linux/miscdevice.h> | 12 | #include <linux/miscdevice.h> |
| 13 | #include <linux/bootmem.h> | ||
| 13 | 14 | ||
| 14 | #include <asm/cpudata.h> | 15 | #include <asm/cpudata.h> |
| 15 | #include <asm/hypervisor.h> | 16 | #include <asm/hypervisor.h> |
| @@ -108,25 +109,15 @@ static struct mdesc_handle * __init mdesc_lmb_alloc(unsigned int mdesc_size) | |||
| 108 | 109 | ||
| 109 | static void mdesc_lmb_free(struct mdesc_handle *hp) | 110 | static void mdesc_lmb_free(struct mdesc_handle *hp) |
| 110 | { | 111 | { |
| 111 | unsigned int alloc_size, handle_size = hp->handle_size; | 112 | unsigned int alloc_size; |
| 112 | unsigned long start, end; | 113 | unsigned long start; |
| 113 | 114 | ||
| 114 | BUG_ON(atomic_read(&hp->refcnt) != 0); | 115 | BUG_ON(atomic_read(&hp->refcnt) != 0); |
| 115 | BUG_ON(!list_empty(&hp->list)); | 116 | BUG_ON(!list_empty(&hp->list)); |
| 116 | 117 | ||
| 117 | alloc_size = PAGE_ALIGN(handle_size); | 118 | alloc_size = PAGE_ALIGN(hp->handle_size); |
| 118 | 119 | start = __pa(hp); | |
| 119 | start = (unsigned long) hp; | 120 | free_bootmem_late(start, alloc_size); |
| 120 | end = start + alloc_size; | ||
| 121 | |||
| 122 | while (start < end) { | ||
| 123 | struct page *p; | ||
| 124 | |||
| 125 | p = virt_to_page(start); | ||
| 126 | ClearPageReserved(p); | ||
| 127 | __free_page(p); | ||
| 128 | start += PAGE_SIZE; | ||
| 129 | } | ||
| 130 | } | 121 | } |
| 131 | 122 | ||
| 132 | static struct mdesc_mem_ops lmb_mdesc_ops = { | 123 | static struct mdesc_mem_ops lmb_mdesc_ops = { |
diff --git a/arch/sparc/kernel/of_device_64.c b/arch/sparc/kernel/of_device_64.c index 881947e59e95..0a6f2d1798d1 100644 --- a/arch/sparc/kernel/of_device_64.c +++ b/arch/sparc/kernel/of_device_64.c | |||
| @@ -104,9 +104,19 @@ static int of_bus_pci_map(u32 *addr, const u32 *range, | |||
| 104 | int i; | 104 | int i; |
| 105 | 105 | ||
| 106 | /* Check address type match */ | 106 | /* Check address type match */ |
| 107 | if ((addr[0] ^ range[0]) & 0x03000000) | 107 | if (!((addr[0] ^ range[0]) & 0x03000000)) |
| 108 | return -EINVAL; | 108 | goto type_match; |
| 109 | |||
| 110 | /* Special exception, we can map a 64-bit address into | ||
| 111 | * a 32-bit range. | ||
| 112 | */ | ||
| 113 | if ((addr[0] & 0x03000000) == 0x03000000 && | ||
| 114 | (range[0] & 0x03000000) == 0x02000000) | ||
| 115 | goto type_match; | ||
| 116 | |||
| 117 | return -EINVAL; | ||
| 109 | 118 | ||
| 119 | type_match: | ||
| 110 | if (of_out_of_range(addr + 1, range + 1, range + na + pna, | 120 | if (of_out_of_range(addr + 1, range + 1, range + na + pna, |
| 111 | na - 1, ns)) | 121 | na - 1, ns)) |
| 112 | return -EINVAL; | 122 | return -EINVAL; |
diff --git a/arch/sparc/kernel/ptrace_64.c b/arch/sparc/kernel/ptrace_64.c index 4ae91dc2feb9..2f6524d1a817 100644 --- a/arch/sparc/kernel/ptrace_64.c +++ b/arch/sparc/kernel/ptrace_64.c | |||
| @@ -23,6 +23,7 @@ | |||
| 23 | #include <linux/signal.h> | 23 | #include <linux/signal.h> |
| 24 | #include <linux/regset.h> | 24 | #include <linux/regset.h> |
| 25 | #include <linux/tracehook.h> | 25 | #include <linux/tracehook.h> |
| 26 | #include <trace/syscall.h> | ||
| 26 | #include <linux/compat.h> | 27 | #include <linux/compat.h> |
| 27 | #include <linux/elf.h> | 28 | #include <linux/elf.h> |
| 28 | 29 | ||
| @@ -37,6 +38,9 @@ | |||
| 37 | #include <asm/cpudata.h> | 38 | #include <asm/cpudata.h> |
| 38 | #include <asm/cacheflush.h> | 39 | #include <asm/cacheflush.h> |
| 39 | 40 | ||
| 41 | #define CREATE_TRACE_POINTS | ||
| 42 | #include <trace/events/syscalls.h> | ||
| 43 | |||
| 40 | #include "entry.h" | 44 | #include "entry.h" |
| 41 | 45 | ||
| 42 | /* #define ALLOW_INIT_TRACING */ | 46 | /* #define ALLOW_INIT_TRACING */ |
| @@ -1059,6 +1063,9 @@ asmlinkage int syscall_trace_enter(struct pt_regs *regs) | |||
| 1059 | if (test_thread_flag(TIF_SYSCALL_TRACE)) | 1063 | if (test_thread_flag(TIF_SYSCALL_TRACE)) |
| 1060 | ret = tracehook_report_syscall_entry(regs); | 1064 | ret = tracehook_report_syscall_entry(regs); |
| 1061 | 1065 | ||
| 1066 | if (unlikely(test_thread_flag(TIF_SYSCALL_TRACEPOINT))) | ||
| 1067 | trace_sys_enter(regs, regs->u_regs[UREG_G1]); | ||
| 1068 | |||
| 1062 | if (unlikely(current->audit_context) && !ret) | 1069 | if (unlikely(current->audit_context) && !ret) |
| 1063 | audit_syscall_entry((test_thread_flag(TIF_32BIT) ? | 1070 | audit_syscall_entry((test_thread_flag(TIF_32BIT) ? |
| 1064 | AUDIT_ARCH_SPARC : | 1071 | AUDIT_ARCH_SPARC : |
| @@ -1084,6 +1091,9 @@ asmlinkage void syscall_trace_leave(struct pt_regs *regs) | |||
| 1084 | audit_syscall_exit(result, regs->u_regs[UREG_I0]); | 1091 | audit_syscall_exit(result, regs->u_regs[UREG_I0]); |
| 1085 | } | 1092 | } |
| 1086 | 1093 | ||
| 1094 | if (unlikely(test_thread_flag(TIF_SYSCALL_TRACEPOINT))) | ||
| 1095 | trace_sys_exit(regs, regs->u_regs[UREG_G1]); | ||
| 1096 | |||
| 1087 | if (test_thread_flag(TIF_SYSCALL_TRACE)) | 1097 | if (test_thread_flag(TIF_SYSCALL_TRACE)) |
| 1088 | tracehook_report_syscall_exit(regs, 0); | 1098 | tracehook_report_syscall_exit(regs, 0); |
| 1089 | } | 1099 | } |
diff --git a/arch/sparc/kernel/syscalls.S b/arch/sparc/kernel/syscalls.S index d150c2aa98d2..dc4a458f74dc 100644 --- a/arch/sparc/kernel/syscalls.S +++ b/arch/sparc/kernel/syscalls.S | |||
| @@ -62,7 +62,7 @@ sys32_rt_sigreturn: | |||
| 62 | #endif | 62 | #endif |
| 63 | .align 32 | 63 | .align 32 |
| 64 | 1: ldx [%g6 + TI_FLAGS], %l5 | 64 | 1: ldx [%g6 + TI_FLAGS], %l5 |
| 65 | andcc %l5, (_TIF_SYSCALL_TRACE|_TIF_SECCOMP|_TIF_SYSCALL_AUDIT), %g0 | 65 | andcc %l5, (_TIF_SYSCALL_TRACE|_TIF_SECCOMP|_TIF_SYSCALL_AUDIT|_TIF_SYSCALL_TRACEPOINT), %g0 |
| 66 | be,pt %icc, rtrap | 66 | be,pt %icc, rtrap |
| 67 | nop | 67 | nop |
| 68 | call syscall_trace_leave | 68 | call syscall_trace_leave |
| @@ -187,7 +187,7 @@ linux_syscall_trace: | |||
| 187 | .globl linux_sparc_syscall32 | 187 | .globl linux_sparc_syscall32 |
| 188 | linux_sparc_syscall32: | 188 | linux_sparc_syscall32: |
| 189 | /* Direct access to user regs, much faster. */ | 189 | /* Direct access to user regs, much faster. */ |
| 190 | cmp %g1, NR_SYSCALLS ! IEU1 Group | 190 | cmp %g1, NR_syscalls ! IEU1 Group |
| 191 | bgeu,pn %xcc, linux_sparc_ni_syscall ! CTI | 191 | bgeu,pn %xcc, linux_sparc_ni_syscall ! CTI |
| 192 | srl %i0, 0, %o0 ! IEU0 | 192 | srl %i0, 0, %o0 ! IEU0 |
| 193 | sll %g1, 2, %l4 ! IEU0 Group | 193 | sll %g1, 2, %l4 ! IEU0 Group |
| @@ -198,7 +198,7 @@ linux_sparc_syscall32: | |||
| 198 | 198 | ||
| 199 | srl %i5, 0, %o5 ! IEU1 | 199 | srl %i5, 0, %o5 ! IEU1 |
| 200 | srl %i2, 0, %o2 ! IEU0 Group | 200 | srl %i2, 0, %o2 ! IEU0 Group |
| 201 | andcc %l0, (_TIF_SYSCALL_TRACE|_TIF_SECCOMP|_TIF_SYSCALL_AUDIT), %g0 | 201 | andcc %l0, (_TIF_SYSCALL_TRACE|_TIF_SECCOMP|_TIF_SYSCALL_AUDIT|_TIF_SYSCALL_TRACEPOINT), %g0 |
| 202 | bne,pn %icc, linux_syscall_trace32 ! CTI | 202 | bne,pn %icc, linux_syscall_trace32 ! CTI |
| 203 | mov %i0, %l5 ! IEU1 | 203 | mov %i0, %l5 ! IEU1 |
| 204 | call %l7 ! CTI Group brk forced | 204 | call %l7 ! CTI Group brk forced |
| @@ -210,7 +210,7 @@ linux_sparc_syscall32: | |||
| 210 | .globl linux_sparc_syscall | 210 | .globl linux_sparc_syscall |
| 211 | linux_sparc_syscall: | 211 | linux_sparc_syscall: |
| 212 | /* Direct access to user regs, much faster. */ | 212 | /* Direct access to user regs, much faster. */ |
| 213 | cmp %g1, NR_SYSCALLS ! IEU1 Group | 213 | cmp %g1, NR_syscalls ! IEU1 Group |
| 214 | bgeu,pn %xcc, linux_sparc_ni_syscall ! CTI | 214 | bgeu,pn %xcc, linux_sparc_ni_syscall ! CTI |
| 215 | mov %i0, %o0 ! IEU0 | 215 | mov %i0, %o0 ! IEU0 |
| 216 | sll %g1, 2, %l4 ! IEU0 Group | 216 | sll %g1, 2, %l4 ! IEU0 Group |
| @@ -221,7 +221,7 @@ linux_sparc_syscall: | |||
| 221 | 221 | ||
| 222 | mov %i3, %o3 ! IEU1 | 222 | mov %i3, %o3 ! IEU1 |
| 223 | mov %i4, %o4 ! IEU0 Group | 223 | mov %i4, %o4 ! IEU0 Group |
| 224 | andcc %l0, (_TIF_SYSCALL_TRACE|_TIF_SECCOMP|_TIF_SYSCALL_AUDIT), %g0 | 224 | andcc %l0, (_TIF_SYSCALL_TRACE|_TIF_SECCOMP|_TIF_SYSCALL_AUDIT|_TIF_SYSCALL_TRACEPOINT), %g0 |
| 225 | bne,pn %icc, linux_syscall_trace ! CTI Group | 225 | bne,pn %icc, linux_syscall_trace ! CTI Group |
| 226 | mov %i0, %l5 ! IEU0 | 226 | mov %i0, %l5 ! IEU0 |
| 227 | 2: call %l7 ! CTI Group brk forced | 227 | 2: call %l7 ! CTI Group brk forced |
| @@ -245,7 +245,7 @@ ret_sys_call: | |||
| 245 | 245 | ||
| 246 | cmp %o0, -ERESTART_RESTARTBLOCK | 246 | cmp %o0, -ERESTART_RESTARTBLOCK |
| 247 | bgeu,pn %xcc, 1f | 247 | bgeu,pn %xcc, 1f |
| 248 | andcc %l0, (_TIF_SYSCALL_TRACE|_TIF_SECCOMP|_TIF_SYSCALL_AUDIT), %l6 | 248 | andcc %l0, (_TIF_SYSCALL_TRACE|_TIF_SECCOMP|_TIF_SYSCALL_AUDIT|_TIF_SYSCALL_TRACEPOINT), %l6 |
| 249 | 80: | 249 | 80: |
| 250 | /* System call success, clear Carry condition code. */ | 250 | /* System call success, clear Carry condition code. */ |
| 251 | andn %g3, %g2, %g3 | 251 | andn %g3, %g2, %g3 |
| @@ -260,7 +260,7 @@ ret_sys_call: | |||
| 260 | /* System call failure, set Carry condition code. | 260 | /* System call failure, set Carry condition code. |
| 261 | * Also, get abs(errno) to return to the process. | 261 | * Also, get abs(errno) to return to the process. |
| 262 | */ | 262 | */ |
| 263 | andcc %l0, (_TIF_SYSCALL_TRACE|_TIF_SECCOMP|_TIF_SYSCALL_AUDIT), %l6 | 263 | andcc %l0, (_TIF_SYSCALL_TRACE|_TIF_SECCOMP|_TIF_SYSCALL_AUDIT|_TIF_SYSCALL_TRACEPOINT), %l6 |
| 264 | sub %g0, %o0, %o0 | 264 | sub %g0, %o0, %o0 |
| 265 | or %g3, %g2, %g3 | 265 | or %g3, %g2, %g3 |
| 266 | stx %o0, [%sp + PTREGS_OFF + PT_V9_I0] | 266 | stx %o0, [%sp + PTREGS_OFF + PT_V9_I0] |
diff --git a/arch/sparc/kernel/time_64.c b/arch/sparc/kernel/time_64.c index 63f73ae8a892..67e165102885 100644 --- a/arch/sparc/kernel/time_64.c +++ b/arch/sparc/kernel/time_64.c | |||
| @@ -774,26 +774,9 @@ void __devinit setup_sparc64_timer(void) | |||
| 774 | static struct clocksource clocksource_tick = { | 774 | static struct clocksource clocksource_tick = { |
| 775 | .rating = 100, | 775 | .rating = 100, |
| 776 | .mask = CLOCKSOURCE_MASK(64), | 776 | .mask = CLOCKSOURCE_MASK(64), |
| 777 | .shift = 16, | ||
| 778 | .flags = CLOCK_SOURCE_IS_CONTINUOUS, | 777 | .flags = CLOCK_SOURCE_IS_CONTINUOUS, |
| 779 | }; | 778 | }; |
| 780 | 779 | ||
| 781 | static void __init setup_clockevent_multiplier(unsigned long hz) | ||
| 782 | { | ||
| 783 | unsigned long mult, shift = 32; | ||
| 784 | |||
| 785 | while (1) { | ||
| 786 | mult = div_sc(hz, NSEC_PER_SEC, shift); | ||
| 787 | if (mult && (mult >> 32UL) == 0UL) | ||
| 788 | break; | ||
| 789 | |||
| 790 | shift--; | ||
| 791 | } | ||
| 792 | |||
| 793 | sparc64_clockevent.shift = shift; | ||
| 794 | sparc64_clockevent.mult = mult; | ||
| 795 | } | ||
| 796 | |||
| 797 | static unsigned long tb_ticks_per_usec __read_mostly; | 780 | static unsigned long tb_ticks_per_usec __read_mostly; |
| 798 | 781 | ||
| 799 | void __delay(unsigned long loops) | 782 | void __delay(unsigned long loops) |
| @@ -828,9 +811,7 @@ void __init time_init(void) | |||
| 828 | clocksource_hz2mult(freq, SPARC64_NSEC_PER_CYC_SHIFT); | 811 | clocksource_hz2mult(freq, SPARC64_NSEC_PER_CYC_SHIFT); |
| 829 | 812 | ||
| 830 | clocksource_tick.name = tick_ops->name; | 813 | clocksource_tick.name = tick_ops->name; |
| 831 | clocksource_tick.mult = | 814 | clocksource_calc_mult_shift(&clocksource_tick, freq, 4); |
| 832 | clocksource_hz2mult(freq, | ||
| 833 | clocksource_tick.shift); | ||
| 834 | clocksource_tick.read = clocksource_tick_read; | 815 | clocksource_tick.read = clocksource_tick_read; |
| 835 | 816 | ||
| 836 | printk("clocksource: mult[%x] shift[%d]\n", | 817 | printk("clocksource: mult[%x] shift[%d]\n", |
| @@ -839,15 +820,14 @@ void __init time_init(void) | |||
| 839 | clocksource_register(&clocksource_tick); | 820 | clocksource_register(&clocksource_tick); |
| 840 | 821 | ||
| 841 | sparc64_clockevent.name = tick_ops->name; | 822 | sparc64_clockevent.name = tick_ops->name; |
| 842 | 823 | clockevents_calc_mult_shift(&sparc64_clockevent, freq, 4); | |
| 843 | setup_clockevent_multiplier(freq); | ||
| 844 | 824 | ||
| 845 | sparc64_clockevent.max_delta_ns = | 825 | sparc64_clockevent.max_delta_ns = |
| 846 | clockevent_delta2ns(0x7fffffffffffffffUL, &sparc64_clockevent); | 826 | clockevent_delta2ns(0x7fffffffffffffffUL, &sparc64_clockevent); |
| 847 | sparc64_clockevent.min_delta_ns = | 827 | sparc64_clockevent.min_delta_ns = |
| 848 | clockevent_delta2ns(0xF, &sparc64_clockevent); | 828 | clockevent_delta2ns(0xF, &sparc64_clockevent); |
| 849 | 829 | ||
| 850 | printk("clockevent: mult[%ux] shift[%d]\n", | 830 | printk("clockevent: mult[%x] shift[%d]\n", |
| 851 | sparc64_clockevent.mult, sparc64_clockevent.shift); | 831 | sparc64_clockevent.mult, sparc64_clockevent.shift); |
| 852 | 832 | ||
| 853 | setup_sparc64_timer(); | 833 | setup_sparc64_timer(); |
diff --git a/arch/sparc/kernel/unaligned_32.c b/arch/sparc/kernel/unaligned_32.c index 6b1e6cde6fff..f8514e291e15 100644 --- a/arch/sparc/kernel/unaligned_32.c +++ b/arch/sparc/kernel/unaligned_32.c | |||
| @@ -17,8 +17,7 @@ | |||
| 17 | #include <asm/uaccess.h> | 17 | #include <asm/uaccess.h> |
| 18 | #include <linux/smp.h> | 18 | #include <linux/smp.h> |
| 19 | #include <linux/smp_lock.h> | 19 | #include <linux/smp_lock.h> |
| 20 | 20 | #include <linux/perf_event.h> | |
| 21 | /* #define DEBUG_MNA */ | ||
| 22 | 21 | ||
| 23 | enum direction { | 22 | enum direction { |
| 24 | load, /* ld, ldd, ldh, ldsh */ | 23 | load, /* ld, ldd, ldh, ldsh */ |
| @@ -29,12 +28,6 @@ enum direction { | |||
| 29 | invalid, | 28 | invalid, |
| 30 | }; | 29 | }; |
| 31 | 30 | ||
| 32 | #ifdef DEBUG_MNA | ||
| 33 | static char *dirstrings[] = { | ||
| 34 | "load", "store", "both", "fpload", "fpstore", "invalid" | ||
| 35 | }; | ||
| 36 | #endif | ||
| 37 | |||
| 38 | static inline enum direction decode_direction(unsigned int insn) | 31 | static inline enum direction decode_direction(unsigned int insn) |
| 39 | { | 32 | { |
| 40 | unsigned long tmp = (insn >> 21) & 1; | 33 | unsigned long tmp = (insn >> 21) & 1; |
| @@ -255,10 +248,7 @@ asmlinkage void kernel_unaligned_trap(struct pt_regs *regs, unsigned int insn) | |||
| 255 | unsigned long addr = compute_effective_address(regs, insn); | 248 | unsigned long addr = compute_effective_address(regs, insn); |
| 256 | int err; | 249 | int err; |
| 257 | 250 | ||
| 258 | #ifdef DEBUG_MNA | 251 | perf_sw_event(PERF_COUNT_SW_ALIGNMENT_FAULTS, 1, 0, regs, addr); |
| 259 | printk("KMNA: pc=%08lx [dir=%s addr=%08lx size=%d] retpc[%08lx]\n", | ||
| 260 | regs->pc, dirstrings[dir], addr, size, regs->u_regs[UREG_RETPC]); | ||
| 261 | #endif | ||
| 262 | switch (dir) { | 252 | switch (dir) { |
| 263 | case load: | 253 | case load: |
| 264 | err = do_int_load(fetch_reg_addr(((insn>>25)&0x1f), | 254 | err = do_int_load(fetch_reg_addr(((insn>>25)&0x1f), |
| @@ -350,6 +340,7 @@ asmlinkage void user_unaligned_trap(struct pt_regs *regs, unsigned int insn) | |||
| 350 | } | 340 | } |
| 351 | 341 | ||
| 352 | addr = compute_effective_address(regs, insn); | 342 | addr = compute_effective_address(regs, insn); |
| 343 | perf_sw_event(PERF_COUNT_SW_ALIGNMENT_FAULTS, 1, 0, regs, addr); | ||
| 353 | switch(dir) { | 344 | switch(dir) { |
| 354 | case load: | 345 | case load: |
| 355 | err = do_int_load(fetch_reg_addr(((insn>>25)&0x1f), | 346 | err = do_int_load(fetch_reg_addr(((insn>>25)&0x1f), |
diff --git a/arch/sparc/kernel/unaligned_64.c b/arch/sparc/kernel/unaligned_64.c index 379209982a07..378ca82b9ccc 100644 --- a/arch/sparc/kernel/unaligned_64.c +++ b/arch/sparc/kernel/unaligned_64.c | |||
| @@ -20,10 +20,9 @@ | |||
| 20 | #include <asm/uaccess.h> | 20 | #include <asm/uaccess.h> |
| 21 | #include <linux/smp.h> | 21 | #include <linux/smp.h> |
| 22 | #include <linux/bitops.h> | 22 | #include <linux/bitops.h> |
| 23 | #include <linux/perf_event.h> | ||
| 23 | #include <asm/fpumacro.h> | 24 | #include <asm/fpumacro.h> |
| 24 | 25 | ||
| 25 | /* #define DEBUG_MNA */ | ||
| 26 | |||
| 27 | enum direction { | 26 | enum direction { |
| 28 | load, /* ld, ldd, ldh, ldsh */ | 27 | load, /* ld, ldd, ldh, ldsh */ |
| 29 | store, /* st, std, sth, stsh */ | 28 | store, /* st, std, sth, stsh */ |
| @@ -33,12 +32,6 @@ enum direction { | |||
| 33 | invalid, | 32 | invalid, |
| 34 | }; | 33 | }; |
| 35 | 34 | ||
| 36 | #ifdef DEBUG_MNA | ||
| 37 | static char *dirstrings[] = { | ||
| 38 | "load", "store", "both", "fpload", "fpstore", "invalid" | ||
| 39 | }; | ||
| 40 | #endif | ||
| 41 | |||
| 42 | static inline enum direction decode_direction(unsigned int insn) | 35 | static inline enum direction decode_direction(unsigned int insn) |
| 43 | { | 36 | { |
| 44 | unsigned long tmp = (insn >> 21) & 1; | 37 | unsigned long tmp = (insn >> 21) & 1; |
| @@ -327,12 +320,7 @@ asmlinkage void kernel_unaligned_trap(struct pt_regs *regs, unsigned int insn) | |||
| 327 | 320 | ||
| 328 | addr = compute_effective_address(regs, insn, | 321 | addr = compute_effective_address(regs, insn, |
| 329 | ((insn >> 25) & 0x1f)); | 322 | ((insn >> 25) & 0x1f)); |
| 330 | #ifdef DEBUG_MNA | 323 | perf_sw_event(PERF_COUNT_SW_ALIGNMENT_FAULTS, 1, 0, regs, addr); |
| 331 | printk("KMNA: pc=%016lx [dir=%s addr=%016lx size=%d] " | ||
| 332 | "retpc[%016lx]\n", | ||
| 333 | regs->tpc, dirstrings[dir], addr, size, | ||
| 334 | regs->u_regs[UREG_RETPC]); | ||
| 335 | #endif | ||
| 336 | switch (asi) { | 324 | switch (asi) { |
| 337 | case ASI_NL: | 325 | case ASI_NL: |
| 338 | case ASI_AIUPL: | 326 | case ASI_AIUPL: |
| @@ -399,6 +387,7 @@ int handle_popc(u32 insn, struct pt_regs *regs) | |||
| 399 | int ret, i, rd = ((insn >> 25) & 0x1f); | 387 | int ret, i, rd = ((insn >> 25) & 0x1f); |
| 400 | int from_kernel = (regs->tstate & TSTATE_PRIV) != 0; | 388 | int from_kernel = (regs->tstate & TSTATE_PRIV) != 0; |
| 401 | 389 | ||
| 390 | perf_sw_event(PERF_COUNT_SW_EMULATION_FAULTS, 1, 0, regs, 0); | ||
| 402 | if (insn & 0x2000) { | 391 | if (insn & 0x2000) { |
| 403 | maybe_flush_windows(0, 0, rd, from_kernel); | 392 | maybe_flush_windows(0, 0, rd, from_kernel); |
| 404 | value = sign_extend_imm13(insn); | 393 | value = sign_extend_imm13(insn); |
| @@ -445,6 +434,8 @@ int handle_ldf_stq(u32 insn, struct pt_regs *regs) | |||
| 445 | int asi = decode_asi(insn, regs); | 434 | int asi = decode_asi(insn, regs); |
| 446 | int flag = (freg < 32) ? FPRS_DL : FPRS_DU; | 435 | int flag = (freg < 32) ? FPRS_DL : FPRS_DU; |
| 447 | 436 | ||
| 437 | perf_sw_event(PERF_COUNT_SW_EMULATION_FAULTS, 1, 0, regs, 0); | ||
| 438 | |||
| 448 | save_and_clear_fpu(); | 439 | save_and_clear_fpu(); |
| 449 | current_thread_info()->xfsr[0] &= ~0x1c000; | 440 | current_thread_info()->xfsr[0] &= ~0x1c000; |
| 450 | if (freg & 3) { | 441 | if (freg & 3) { |
| @@ -566,6 +557,8 @@ void handle_ld_nf(u32 insn, struct pt_regs *regs) | |||
| 566 | int from_kernel = (regs->tstate & TSTATE_PRIV) != 0; | 557 | int from_kernel = (regs->tstate & TSTATE_PRIV) != 0; |
| 567 | unsigned long *reg; | 558 | unsigned long *reg; |
| 568 | 559 | ||
| 560 | perf_sw_event(PERF_COUNT_SW_EMULATION_FAULTS, 1, 0, regs, 0); | ||
| 561 | |||
| 569 | maybe_flush_windows(0, 0, rd, from_kernel); | 562 | maybe_flush_windows(0, 0, rd, from_kernel); |
| 570 | reg = fetch_reg_addr(rd, regs); | 563 | reg = fetch_reg_addr(rd, regs); |
| 571 | if (from_kernel || rd < 16) { | 564 | if (from_kernel || rd < 16) { |
| @@ -596,6 +589,7 @@ void handle_lddfmna(struct pt_regs *regs, unsigned long sfar, unsigned long sfsr | |||
| 596 | 589 | ||
| 597 | if (tstate & TSTATE_PRIV) | 590 | if (tstate & TSTATE_PRIV) |
| 598 | die_if_kernel("lddfmna from kernel", regs); | 591 | die_if_kernel("lddfmna from kernel", regs); |
| 592 | perf_sw_event(PERF_COUNT_SW_ALIGNMENT_FAULTS, 1, 0, regs, sfar); | ||
| 599 | if (test_thread_flag(TIF_32BIT)) | 593 | if (test_thread_flag(TIF_32BIT)) |
| 600 | pc = (u32)pc; | 594 | pc = (u32)pc; |
| 601 | if (get_user(insn, (u32 __user *) pc) != -EFAULT) { | 595 | if (get_user(insn, (u32 __user *) pc) != -EFAULT) { |
| @@ -657,6 +651,7 @@ void handle_stdfmna(struct pt_regs *regs, unsigned long sfar, unsigned long sfsr | |||
| 657 | 651 | ||
| 658 | if (tstate & TSTATE_PRIV) | 652 | if (tstate & TSTATE_PRIV) |
| 659 | die_if_kernel("stdfmna from kernel", regs); | 653 | die_if_kernel("stdfmna from kernel", regs); |
| 654 | perf_sw_event(PERF_COUNT_SW_ALIGNMENT_FAULTS, 1, 0, regs, sfar); | ||
| 660 | if (test_thread_flag(TIF_32BIT)) | 655 | if (test_thread_flag(TIF_32BIT)) |
| 661 | pc = (u32)pc; | 656 | pc = (u32)pc; |
| 662 | if (get_user(insn, (u32 __user *) pc) != -EFAULT) { | 657 | if (get_user(insn, (u32 __user *) pc) != -EFAULT) { |
diff --git a/arch/sparc/kernel/visemul.c b/arch/sparc/kernel/visemul.c index d231cbd5c526..9dfd2ebcb157 100644 --- a/arch/sparc/kernel/visemul.c +++ b/arch/sparc/kernel/visemul.c | |||
| @@ -5,6 +5,7 @@ | |||
| 5 | #include <linux/kernel.h> | 5 | #include <linux/kernel.h> |
| 6 | #include <linux/errno.h> | 6 | #include <linux/errno.h> |
| 7 | #include <linux/thread_info.h> | 7 | #include <linux/thread_info.h> |
| 8 | #include <linux/perf_event.h> | ||
| 8 | 9 | ||
| 9 | #include <asm/ptrace.h> | 10 | #include <asm/ptrace.h> |
| 10 | #include <asm/pstate.h> | 11 | #include <asm/pstate.h> |
| @@ -801,6 +802,8 @@ int vis_emul(struct pt_regs *regs, unsigned int insn) | |||
| 801 | 802 | ||
| 802 | BUG_ON(regs->tstate & TSTATE_PRIV); | 803 | BUG_ON(regs->tstate & TSTATE_PRIV); |
| 803 | 804 | ||
| 805 | perf_sw_event(PERF_COUNT_SW_EMULATION_FAULTS, 1, 0, regs, 0); | ||
| 806 | |||
| 804 | if (test_thread_flag(TIF_32BIT)) | 807 | if (test_thread_flag(TIF_32BIT)) |
| 805 | pc = (u32)pc; | 808 | pc = (u32)pc; |
| 806 | 809 | ||
