diff options
author | Ingo Molnar <mingo@elte.hu> | 2008-07-18 13:53:16 -0400 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2008-07-18 13:53:16 -0400 |
commit | 9b610fda0df5d0f0b0c64242e37441ad1b384aac (patch) | |
tree | 0ea14b15f2e6546f37fe18d8ac3dc83077ec0e55 /arch/sparc64/kernel | |
parent | b8f8c3cf0a4ac0632ec3f0e15e9dc0c29de917af (diff) | |
parent | 5b664cb235e97afbf34db9c4d77f08ebd725335e (diff) |
Merge branch 'linus' into timers/nohz
Diffstat (limited to 'arch/sparc64/kernel')
-rw-r--r-- | arch/sparc64/kernel/Makefile | 1 | ||||
-rw-r--r-- | arch/sparc64/kernel/ftrace.c | 94 | ||||
-rw-r--r-- | arch/sparc64/kernel/pci.c | 2 | ||||
-rw-r--r-- | arch/sparc64/kernel/smp.c | 13 | ||||
-rw-r--r-- | arch/sparc64/kernel/sparc64_ksyms.c | 4 | ||||
-rw-r--r-- | arch/sparc64/kernel/stacktrace.c | 2 | ||||
-rw-r--r-- | arch/sparc64/kernel/time.c | 7 |
7 files changed, 111 insertions, 12 deletions
diff --git a/arch/sparc64/kernel/Makefile b/arch/sparc64/kernel/Makefile index ec4f5ebb1ca6..418b5782096e 100644 --- a/arch/sparc64/kernel/Makefile +++ b/arch/sparc64/kernel/Makefile | |||
@@ -14,6 +14,7 @@ obj-y := process.o setup.o cpu.o idprom.o \ | |||
14 | power.o sbus.o sparc64_ksyms.o chmc.o \ | 14 | power.o sbus.o sparc64_ksyms.o chmc.o \ |
15 | visemul.o prom.o of_device.o hvapi.o sstate.o mdesc.o | 15 | visemul.o prom.o of_device.o hvapi.o sstate.o mdesc.o |
16 | 16 | ||
17 | obj-$(CONFIG_DYNAMIC_FTRACE) += ftrace.o | ||
17 | obj-$(CONFIG_STACKTRACE) += stacktrace.o | 18 | obj-$(CONFIG_STACKTRACE) += stacktrace.o |
18 | obj-$(CONFIG_PCI) += ebus.o pci_common.o \ | 19 | obj-$(CONFIG_PCI) += ebus.o pci_common.o \ |
19 | pci_psycho.o pci_sabre.o pci_schizo.o \ | 20 | pci_psycho.o pci_sabre.o pci_schizo.o \ |
diff --git a/arch/sparc64/kernel/ftrace.c b/arch/sparc64/kernel/ftrace.c new file mode 100644 index 000000000000..4298d0aee713 --- /dev/null +++ b/arch/sparc64/kernel/ftrace.c | |||
@@ -0,0 +1,94 @@ | |||
1 | #include <linux/spinlock.h> | ||
2 | #include <linux/hardirq.h> | ||
3 | #include <linux/ftrace.h> | ||
4 | #include <linux/percpu.h> | ||
5 | #include <linux/init.h> | ||
6 | #include <linux/list.h> | ||
7 | |||
8 | #include <asm/ftrace.h> | ||
9 | |||
10 | static const u32 ftrace_nop = 0x01000000; | ||
11 | |||
12 | notrace unsigned char *ftrace_nop_replace(void) | ||
13 | { | ||
14 | return (char *)&ftrace_nop; | ||
15 | } | ||
16 | |||
17 | notrace unsigned char *ftrace_call_replace(unsigned long ip, unsigned long addr) | ||
18 | { | ||
19 | static u32 call; | ||
20 | s32 off; | ||
21 | |||
22 | off = ((s32)addr - (s32)ip); | ||
23 | call = 0x40000000 | ((u32)off >> 2); | ||
24 | |||
25 | return (unsigned char *) &call; | ||
26 | } | ||
27 | |||
28 | notrace int | ||
29 | ftrace_modify_code(unsigned long ip, unsigned char *old_code, | ||
30 | unsigned char *new_code) | ||
31 | { | ||
32 | u32 old = *(u32 *)old_code; | ||
33 | u32 new = *(u32 *)new_code; | ||
34 | u32 replaced; | ||
35 | int faulted; | ||
36 | |||
37 | __asm__ __volatile__( | ||
38 | "1: cas [%[ip]], %[old], %[new]\n" | ||
39 | " flush %[ip]\n" | ||
40 | " mov 0, %[faulted]\n" | ||
41 | "2:\n" | ||
42 | " .section .fixup,#alloc,#execinstr\n" | ||
43 | " .align 4\n" | ||
44 | "3: sethi %%hi(2b), %[faulted]\n" | ||
45 | " jmpl %[faulted] + %%lo(2b), %%g0\n" | ||
46 | " mov 1, %[faulted]\n" | ||
47 | " .previous\n" | ||
48 | " .section __ex_table,\"a\"\n" | ||
49 | " .align 4\n" | ||
50 | " .word 1b, 3b\n" | ||
51 | " .previous\n" | ||
52 | : "=r" (replaced), [faulted] "=r" (faulted) | ||
53 | : [new] "0" (new), [old] "r" (old), [ip] "r" (ip) | ||
54 | : "memory"); | ||
55 | |||
56 | if (replaced != old && replaced != new) | ||
57 | faulted = 2; | ||
58 | |||
59 | return faulted; | ||
60 | } | ||
61 | |||
62 | notrace int ftrace_update_ftrace_func(ftrace_func_t func) | ||
63 | { | ||
64 | unsigned long ip = (unsigned long)(&ftrace_call); | ||
65 | unsigned char old[MCOUNT_INSN_SIZE], *new; | ||
66 | |||
67 | memcpy(old, &ftrace_call, MCOUNT_INSN_SIZE); | ||
68 | new = ftrace_call_replace(ip, (unsigned long)func); | ||
69 | return ftrace_modify_code(ip, old, new); | ||
70 | } | ||
71 | |||
72 | notrace int ftrace_mcount_set(unsigned long *data) | ||
73 | { | ||
74 | unsigned long ip = (long)(&mcount_call); | ||
75 | unsigned long *addr = data; | ||
76 | unsigned char old[MCOUNT_INSN_SIZE], *new; | ||
77 | |||
78 | /* | ||
79 | * Replace the mcount stub with a pointer to the | ||
80 | * ip recorder function. | ||
81 | */ | ||
82 | memcpy(old, &mcount_call, MCOUNT_INSN_SIZE); | ||
83 | new = ftrace_call_replace(ip, *addr); | ||
84 | *addr = ftrace_modify_code(ip, old, new); | ||
85 | |||
86 | return 0; | ||
87 | } | ||
88 | |||
89 | |||
90 | int __init ftrace_dyn_arch_init(void *data) | ||
91 | { | ||
92 | ftrace_mcount_set(data); | ||
93 | return 0; | ||
94 | } | ||
diff --git a/arch/sparc64/kernel/pci.c b/arch/sparc64/kernel/pci.c index 112b09f16f36..d00a3656c287 100644 --- a/arch/sparc64/kernel/pci.c +++ b/arch/sparc64/kernel/pci.c | |||
@@ -408,7 +408,7 @@ struct pci_dev *of_create_pci_dev(struct pci_pbm_info *pbm, | |||
408 | dev->class = class >> 8; | 408 | dev->class = class >> 8; |
409 | dev->revision = class & 0xff; | 409 | dev->revision = class & 0xff; |
410 | 410 | ||
411 | sprintf(pci_name(dev), "%04x:%02x:%02x.%d", pci_domain_nr(bus), | 411 | sprintf(dev->dev.bus_id, "%04x:%02x:%02x.%d", pci_domain_nr(bus), |
412 | dev->bus->number, PCI_SLOT(devfn), PCI_FUNC(devfn)); | 412 | dev->bus->number, PCI_SLOT(devfn), PCI_FUNC(devfn)); |
413 | 413 | ||
414 | if (ofpci_verbose) | 414 | if (ofpci_verbose) |
diff --git a/arch/sparc64/kernel/smp.c b/arch/sparc64/kernel/smp.c index fa63c68a1819..c099d96f1239 100644 --- a/arch/sparc64/kernel/smp.c +++ b/arch/sparc64/kernel/smp.c | |||
@@ -807,7 +807,6 @@ extern unsigned long xcall_call_function; | |||
807 | * smp_call_function(): Run a function on all other CPUs. | 807 | * smp_call_function(): Run a function on all other CPUs. |
808 | * @func: The function to run. This must be fast and non-blocking. | 808 | * @func: The function to run. This must be fast and non-blocking. |
809 | * @info: An arbitrary pointer to pass to the function. | 809 | * @info: An arbitrary pointer to pass to the function. |
810 | * @nonatomic: currently unused. | ||
811 | * @wait: If true, wait (atomically) until function has completed on other CPUs. | 810 | * @wait: If true, wait (atomically) until function has completed on other CPUs. |
812 | * | 811 | * |
813 | * Returns 0 on success, else a negative status code. Does not return until | 812 | * Returns 0 on success, else a negative status code. Does not return until |
@@ -816,8 +815,8 @@ extern unsigned long xcall_call_function; | |||
816 | * You must not call this function with disabled interrupts or from a | 815 | * You must not call this function with disabled interrupts or from a |
817 | * hardware interrupt handler or from a bottom half handler. | 816 | * hardware interrupt handler or from a bottom half handler. |
818 | */ | 817 | */ |
819 | static int smp_call_function_mask(void (*func)(void *info), void *info, | 818 | static int sparc64_smp_call_function_mask(void (*func)(void *info), void *info, |
820 | int nonatomic, int wait, cpumask_t mask) | 819 | int wait, cpumask_t mask) |
821 | { | 820 | { |
822 | struct call_data_struct data; | 821 | struct call_data_struct data; |
823 | int cpus; | 822 | int cpus; |
@@ -852,11 +851,9 @@ out_unlock: | |||
852 | return 0; | 851 | return 0; |
853 | } | 852 | } |
854 | 853 | ||
855 | int smp_call_function(void (*func)(void *info), void *info, | 854 | int smp_call_function(void (*func)(void *info), void *info, int wait) |
856 | int nonatomic, int wait) | ||
857 | { | 855 | { |
858 | return smp_call_function_mask(func, info, nonatomic, wait, | 856 | return sparc64_smp_call_function_mask(func, info, wait, cpu_online_map); |
859 | cpu_online_map); | ||
860 | } | 857 | } |
861 | 858 | ||
862 | void smp_call_function_client(int irq, struct pt_regs *regs) | 859 | void smp_call_function_client(int irq, struct pt_regs *regs) |
@@ -893,7 +890,7 @@ static void tsb_sync(void *info) | |||
893 | 890 | ||
894 | void smp_tsb_sync(struct mm_struct *mm) | 891 | void smp_tsb_sync(struct mm_struct *mm) |
895 | { | 892 | { |
896 | smp_call_function_mask(tsb_sync, mm, 0, 1, mm->cpu_vm_mask); | 893 | sparc64_smp_call_function_mask(tsb_sync, mm, 1, mm->cpu_vm_mask); |
897 | } | 894 | } |
898 | 895 | ||
899 | extern unsigned long xcall_flush_tlb_mm; | 896 | extern unsigned long xcall_flush_tlb_mm; |
diff --git a/arch/sparc64/kernel/sparc64_ksyms.c b/arch/sparc64/kernel/sparc64_ksyms.c index 8ac0b99f2c55..49d3ea50c247 100644 --- a/arch/sparc64/kernel/sparc64_ksyms.c +++ b/arch/sparc64/kernel/sparc64_ksyms.c | |||
@@ -53,6 +53,7 @@ | |||
53 | #include <asm/ns87303.h> | 53 | #include <asm/ns87303.h> |
54 | #include <asm/timer.h> | 54 | #include <asm/timer.h> |
55 | #include <asm/cpudata.h> | 55 | #include <asm/cpudata.h> |
56 | #include <asm/ftrace.h> | ||
56 | 57 | ||
57 | struct poll { | 58 | struct poll { |
58 | int fd; | 59 | int fd; |
@@ -111,8 +112,7 @@ EXPORT_SYMBOL(__write_trylock); | |||
111 | EXPORT_SYMBOL(smp_call_function); | 112 | EXPORT_SYMBOL(smp_call_function); |
112 | #endif /* CONFIG_SMP */ | 113 | #endif /* CONFIG_SMP */ |
113 | 114 | ||
114 | #if defined(CONFIG_MCOUNT) | 115 | #ifdef CONFIG_MCOUNT |
115 | extern void _mcount(void); | ||
116 | EXPORT_SYMBOL(_mcount); | 116 | EXPORT_SYMBOL(_mcount); |
117 | #endif | 117 | #endif |
118 | 118 | ||
diff --git a/arch/sparc64/kernel/stacktrace.c b/arch/sparc64/kernel/stacktrace.c index c73ce3f4197e..b3e3737750d8 100644 --- a/arch/sparc64/kernel/stacktrace.c +++ b/arch/sparc64/kernel/stacktrace.c | |||
@@ -1,6 +1,7 @@ | |||
1 | #include <linux/sched.h> | 1 | #include <linux/sched.h> |
2 | #include <linux/stacktrace.h> | 2 | #include <linux/stacktrace.h> |
3 | #include <linux/thread_info.h> | 3 | #include <linux/thread_info.h> |
4 | #include <linux/module.h> | ||
4 | #include <asm/ptrace.h> | 5 | #include <asm/ptrace.h> |
5 | #include <asm/stacktrace.h> | 6 | #include <asm/stacktrace.h> |
6 | 7 | ||
@@ -47,3 +48,4 @@ void save_stack_trace(struct stack_trace *trace) | |||
47 | trace->entries[trace->nr_entries++] = pc; | 48 | trace->entries[trace->nr_entries++] = pc; |
48 | } while (trace->nr_entries < trace->max_entries); | 49 | } while (trace->nr_entries < trace->max_entries); |
49 | } | 50 | } |
51 | EXPORT_SYMBOL_GPL(save_stack_trace); | ||
diff --git a/arch/sparc64/kernel/time.c b/arch/sparc64/kernel/time.c index e5d238970c7e..bedc4c159b1c 100644 --- a/arch/sparc64/kernel/time.c +++ b/arch/sparc64/kernel/time.c | |||
@@ -11,6 +11,7 @@ | |||
11 | #include <linux/errno.h> | 11 | #include <linux/errno.h> |
12 | #include <linux/module.h> | 12 | #include <linux/module.h> |
13 | #include <linux/sched.h> | 13 | #include <linux/sched.h> |
14 | #include <linux/smp_lock.h> | ||
14 | #include <linux/kernel.h> | 15 | #include <linux/kernel.h> |
15 | #include <linux/param.h> | 16 | #include <linux/param.h> |
16 | #include <linux/string.h> | 17 | #include <linux/string.h> |
@@ -1659,10 +1660,14 @@ static int mini_rtc_ioctl(struct inode *inode, struct file *file, | |||
1659 | 1660 | ||
1660 | static int mini_rtc_open(struct inode *inode, struct file *file) | 1661 | static int mini_rtc_open(struct inode *inode, struct file *file) |
1661 | { | 1662 | { |
1662 | if (mini_rtc_status & RTC_IS_OPEN) | 1663 | lock_kernel(); |
1664 | if (mini_rtc_status & RTC_IS_OPEN) { | ||
1665 | unlock_kernel(); | ||
1663 | return -EBUSY; | 1666 | return -EBUSY; |
1667 | } | ||
1664 | 1668 | ||
1665 | mini_rtc_status |= RTC_IS_OPEN; | 1669 | mini_rtc_status |= RTC_IS_OPEN; |
1670 | unlock_kernel(); | ||
1666 | 1671 | ||
1667 | return 0; | 1672 | return 0; |
1668 | } | 1673 | } |