aboutsummaryrefslogtreecommitdiffstats
path: root/arch/sparc/kernel
diff options
context:
space:
mode:
Diffstat (limited to 'arch/sparc/kernel')
-rw-r--r--arch/sparc/kernel/Makefile2
-rw-r--r--arch/sparc/kernel/central.c2
-rw-r--r--arch/sparc/kernel/cpu.c51
-rw-r--r--arch/sparc/kernel/head_64.S31
-rw-r--r--arch/sparc/kernel/irq_64.c70
-rw-r--r--arch/sparc/kernel/kernel.h1
-rw-r--r--arch/sparc/kernel/nmi.c225
-rw-r--r--arch/sparc/kernel/pcr.c158
-rw-r--r--arch/sparc/kernel/process_64.c5
-rw-r--r--arch/sparc/kernel/setup_64.c2
-rw-r--r--arch/sparc/kernel/sys_sparc_64.c48
-rw-r--r--arch/sparc/kernel/syscalls.S2
-rw-r--r--arch/sparc/kernel/systbls.h3
-rw-r--r--arch/sparc/kernel/systbls_64.S16
-rw-r--r--arch/sparc/kernel/time_64.c2
-rw-r--r--arch/sparc/kernel/traps_64.c17
-rw-r--r--arch/sparc/kernel/ttable.S3
17 files changed, 516 insertions, 122 deletions
diff --git a/arch/sparc/kernel/Makefile b/arch/sparc/kernel/Makefile
index 53adcaa0348b..54742e58831c 100644
--- a/arch/sparc/kernel/Makefile
+++ b/arch/sparc/kernel/Makefile
@@ -52,6 +52,8 @@ obj-$(CONFIG_SPARC64) += visemul.o
52obj-$(CONFIG_SPARC64) += hvapi.o 52obj-$(CONFIG_SPARC64) += hvapi.o
53obj-$(CONFIG_SPARC64) += sstate.o 53obj-$(CONFIG_SPARC64) += sstate.o
54obj-$(CONFIG_SPARC64) += mdesc.o 54obj-$(CONFIG_SPARC64) += mdesc.o
55obj-$(CONFIG_SPARC64) += pcr.o
56obj-$(CONFIG_SPARC64) += nmi.o
55 57
56# sparc32 do not use GENERIC_HARDIRQS but uses the generic devres implementation 58# sparc32 do not use GENERIC_HARDIRQS but uses the generic devres implementation
57obj-$(CONFIG_SPARC32) += devres.o 59obj-$(CONFIG_SPARC32) += devres.o
diff --git a/arch/sparc/kernel/central.c b/arch/sparc/kernel/central.c
index 05f1c916db06..f3b5466c389c 100644
--- a/arch/sparc/kernel/central.c
+++ b/arch/sparc/kernel/central.c
@@ -103,6 +103,7 @@ static int __devinit clock_board_probe(struct of_device *op,
103 p->leds_resource.name = "leds"; 103 p->leds_resource.name = "leds";
104 104
105 p->leds_pdev.name = "sunfire-clockboard-leds"; 105 p->leds_pdev.name = "sunfire-clockboard-leds";
106 p->leds_pdev.id = -1;
106 p->leds_pdev.resource = &p->leds_resource; 107 p->leds_pdev.resource = &p->leds_resource;
107 p->leds_pdev.num_resources = 1; 108 p->leds_pdev.num_resources = 1;
108 p->leds_pdev.dev.parent = &op->dev; 109 p->leds_pdev.dev.parent = &op->dev;
@@ -197,6 +198,7 @@ static int __devinit fhc_probe(struct of_device *op,
197 p->leds_resource.name = "leds"; 198 p->leds_resource.name = "leds";
198 199
199 p->leds_pdev.name = "sunfire-fhc-leds"; 200 p->leds_pdev.name = "sunfire-fhc-leds";
201 p->leds_pdev.id = p->board_num;
200 p->leds_pdev.resource = &p->leds_resource; 202 p->leds_pdev.resource = &p->leds_resource;
201 p->leds_pdev.num_resources = 1; 203 p->leds_pdev.num_resources = 1;
202 p->leds_pdev.dev.parent = &op->dev; 204 p->leds_pdev.dev.parent = &op->dev;
diff --git a/arch/sparc/kernel/cpu.c b/arch/sparc/kernel/cpu.c
index f0b825505da5..d85c3dc4953a 100644
--- a/arch/sparc/kernel/cpu.c
+++ b/arch/sparc/kernel/cpu.c
@@ -26,6 +26,7 @@ EXPORT_PER_CPU_SYMBOL(__cpu_data);
26struct cpu_info { 26struct cpu_info {
27 int psr_vers; 27 int psr_vers;
28 const char *name; 28 const char *name;
29 const char *pmu_name;
29}; 30};
30 31
31struct fpu_info { 32struct fpu_info {
@@ -45,6 +46,9 @@ struct manufacturer_info {
45#define CPU(ver, _name) \ 46#define CPU(ver, _name) \
46{ .psr_vers = ver, .name = _name } 47{ .psr_vers = ver, .name = _name }
47 48
49#define CPU_PMU(ver, _name, _pmu_name) \
50{ .psr_vers = ver, .name = _name, .pmu_name = _pmu_name }
51
48#define FPU(ver, _name) \ 52#define FPU(ver, _name) \
49{ .fp_vers = ver, .name = _name } 53{ .fp_vers = ver, .name = _name }
50 54
@@ -183,10 +187,10 @@ static const struct manufacturer_info __initconst manufacturer_info[] = {
183},{ 187},{
184 0x17, 188 0x17,
185 .cpu_info = { 189 .cpu_info = {
186 CPU(0x10, "TI UltraSparc I (SpitFire)"), 190 CPU_PMU(0x10, "TI UltraSparc I (SpitFire)", "ultra12"),
187 CPU(0x11, "TI UltraSparc II (BlackBird)"), 191 CPU_PMU(0x11, "TI UltraSparc II (BlackBird)", "ultra12"),
188 CPU(0x12, "TI UltraSparc IIi (Sabre)"), 192 CPU_PMU(0x12, "TI UltraSparc IIi (Sabre)", "ultra12"),
189 CPU(0x13, "TI UltraSparc IIe (Hummingbird)"), 193 CPU_PMU(0x13, "TI UltraSparc IIe (Hummingbird)", "ultra12"),
190 CPU(-1, NULL) 194 CPU(-1, NULL)
191 }, 195 },
192 .fpu_info = { 196 .fpu_info = {
@@ -199,7 +203,7 @@ static const struct manufacturer_info __initconst manufacturer_info[] = {
199},{ 203},{
200 0x22, 204 0x22,
201 .cpu_info = { 205 .cpu_info = {
202 CPU(0x10, "TI UltraSparc I (SpitFire)"), 206 CPU_PMU(0x10, "TI UltraSparc I (SpitFire)", "ultra12"),
203 CPU(-1, NULL) 207 CPU(-1, NULL)
204 }, 208 },
205 .fpu_info = { 209 .fpu_info = {
@@ -209,12 +213,12 @@ static const struct manufacturer_info __initconst manufacturer_info[] = {
209},{ 213},{
210 0x3e, 214 0x3e,
211 .cpu_info = { 215 .cpu_info = {
212 CPU(0x14, "TI UltraSparc III (Cheetah)"), 216 CPU_PMU(0x14, "TI UltraSparc III (Cheetah)", "ultra3"),
213 CPU(0x15, "TI UltraSparc III+ (Cheetah+)"), 217 CPU_PMU(0x15, "TI UltraSparc III+ (Cheetah+)", "ultra3+"),
214 CPU(0x16, "TI UltraSparc IIIi (Jalapeno)"), 218 CPU_PMU(0x16, "TI UltraSparc IIIi (Jalapeno)", "ultra3i"),
215 CPU(0x18, "TI UltraSparc IV (Jaguar)"), 219 CPU_PMU(0x18, "TI UltraSparc IV (Jaguar)", "ultra3+"),
216 CPU(0x19, "TI UltraSparc IV+ (Panther)"), 220 CPU_PMU(0x19, "TI UltraSparc IV+ (Panther)", "ultra4+"),
217 CPU(0x22, "TI UltraSparc IIIi+ (Serrano)"), 221 CPU_PMU(0x22, "TI UltraSparc IIIi+ (Serrano)", "ultra3i"),
218 CPU(-1, NULL) 222 CPU(-1, NULL)
219 }, 223 },
220 .fpu_info = { 224 .fpu_info = {
@@ -234,29 +238,44 @@ static const struct manufacturer_info __initconst manufacturer_info[] = {
234 238
235const char *sparc_cpu_type; 239const char *sparc_cpu_type;
236const char *sparc_fpu_type; 240const char *sparc_fpu_type;
241const char *sparc_pmu_type;
237 242
238unsigned int fsr_storage; 243unsigned int fsr_storage;
239 244
240static void set_cpu_and_fpu(int psr_impl, int psr_vers, int fpu_vers) 245static void set_cpu_and_fpu(int psr_impl, int psr_vers, int fpu_vers)
241{ 246{
247 const struct manufacturer_info *manuf;
248 int i;
249
242 sparc_cpu_type = NULL; 250 sparc_cpu_type = NULL;
243 sparc_fpu_type = NULL; 251 sparc_fpu_type = NULL;
244 if (psr_impl < ARRAY_SIZE(manufacturer_info)) 252 sparc_pmu_type = NULL;
253 manuf = NULL;
254
255 for (i = 0; i < ARRAY_SIZE(manufacturer_info); i++)
256 {
257 if (psr_impl == manufacturer_info[i].psr_impl) {
258 manuf = &manufacturer_info[i];
259 break;
260 }
261 }
262 if (manuf != NULL)
245 { 263 {
246 const struct cpu_info *cpu; 264 const struct cpu_info *cpu;
247 const struct fpu_info *fpu; 265 const struct fpu_info *fpu;
248 266
249 cpu = &manufacturer_info[psr_impl].cpu_info[0]; 267 cpu = &manuf->cpu_info[0];
250 while (cpu->psr_vers != -1) 268 while (cpu->psr_vers != -1)
251 { 269 {
252 if (cpu->psr_vers == psr_vers) { 270 if (cpu->psr_vers == psr_vers) {
253 sparc_cpu_type = cpu->name; 271 sparc_cpu_type = cpu->name;
272 sparc_pmu_type = cpu->pmu_name;
254 sparc_fpu_type = "No FPU"; 273 sparc_fpu_type = "No FPU";
255 break; 274 break;
256 } 275 }
257 cpu++; 276 cpu++;
258 } 277 }
259 fpu = &manufacturer_info[psr_impl].fpu_info[0]; 278 fpu = &manuf->fpu_info[0];
260 while (fpu->fp_vers != -1) 279 while (fpu->fp_vers != -1)
261 { 280 {
262 if (fpu->fp_vers == fpu_vers) { 281 if (fpu->fp_vers == fpu_vers) {
@@ -278,6 +297,8 @@ static void set_cpu_and_fpu(int psr_impl, int psr_vers, int fpu_vers)
278 psr_impl, fpu_vers); 297 psr_impl, fpu_vers);
279 sparc_fpu_type = "Unknown FPU"; 298 sparc_fpu_type = "Unknown FPU";
280 } 299 }
300 if (sparc_pmu_type == NULL)
301 sparc_pmu_type = "Unknown PMU";
281} 302}
282 303
283#ifdef CONFIG_SPARC32 304#ifdef CONFIG_SPARC32
@@ -303,11 +324,13 @@ static void __init sun4v_cpu_probe(void)
303 case SUN4V_CHIP_NIAGARA1: 324 case SUN4V_CHIP_NIAGARA1:
304 sparc_cpu_type = "UltraSparc T1 (Niagara)"; 325 sparc_cpu_type = "UltraSparc T1 (Niagara)";
305 sparc_fpu_type = "UltraSparc T1 integrated FPU"; 326 sparc_fpu_type = "UltraSparc T1 integrated FPU";
327 sparc_pmu_type = "niagara";
306 break; 328 break;
307 329
308 case SUN4V_CHIP_NIAGARA2: 330 case SUN4V_CHIP_NIAGARA2:
309 sparc_cpu_type = "UltraSparc T2 (Niagara2)"; 331 sparc_cpu_type = "UltraSparc T2 (Niagara2)";
310 sparc_fpu_type = "UltraSparc T2 integrated FPU"; 332 sparc_fpu_type = "UltraSparc T2 integrated FPU";
333 sparc_pmu_type = "niagara2";
311 break; 334 break;
312 335
313 default: 336 default:
diff --git a/arch/sparc/kernel/head_64.S b/arch/sparc/kernel/head_64.S
index 8ffee714f932..a46c3a21e26d 100644
--- a/arch/sparc/kernel/head_64.S
+++ b/arch/sparc/kernel/head_64.S
@@ -891,10 +891,35 @@ prom_tba: .xword 0
891tlb_type: .word 0 /* Must NOT end up in BSS */ 891tlb_type: .word 0 /* Must NOT end up in BSS */
892 .section ".fixup",#alloc,#execinstr 892 .section ".fixup",#alloc,#execinstr
893 893
894 .globl __ret_efault, __retl_efault 894 .globl __ret_efault, __retl_efault, __ret_one, __retl_one
895__ret_efault: 895ENTRY(__ret_efault)
896 ret 896 ret
897 restore %g0, -EFAULT, %o0 897 restore %g0, -EFAULT, %o0
898__retl_efault: 898ENDPROC(__ret_efault)
899
900ENTRY(__retl_efault)
899 retl 901 retl
900 mov -EFAULT, %o0 902 mov -EFAULT, %o0
903ENDPROC(__retl_efault)
904
905ENTRY(__retl_one)
906 retl
907 mov 1, %o0
908ENDPROC(__retl_one)
909
910ENTRY(__ret_one_asi)
911 wr %g0, ASI_AIUS, %asi
912 ret
913 restore %g0, 1, %o0
914ENDPROC(__ret_one_asi)
915
916ENTRY(__retl_one_asi)
917 wr %g0, ASI_AIUS, %asi
918 retl
919 mov 1, %o0
920ENDPROC(__retl_one_asi)
921
922ENTRY(__retl_o1)
923 retl
924 mov %o1, %o0
925ENDPROC(__retl_o1)
diff --git a/arch/sparc/kernel/irq_64.c b/arch/sparc/kernel/irq_64.c
index cab8e0286871..e53138365490 100644
--- a/arch/sparc/kernel/irq_64.c
+++ b/arch/sparc/kernel/irq_64.c
@@ -185,7 +185,7 @@ int show_interrupts(struct seq_file *p, void *v)
185 seq_printf(p, "%10u ", kstat_irqs(i)); 185 seq_printf(p, "%10u ", kstat_irqs(i));
186#else 186#else
187 for_each_online_cpu(j) 187 for_each_online_cpu(j)
188 seq_printf(p, "%10u ", kstat_cpu(j).irqs[i]); 188 seq_printf(p, "%10u ", kstat_irqs_cpu(i, j));
189#endif 189#endif
190 seq_printf(p, " %9s", irq_desc[i].chip->typename); 190 seq_printf(p, " %9s", irq_desc[i].chip->typename);
191 seq_printf(p, " %s", action->name); 191 seq_printf(p, " %s", action->name);
@@ -196,6 +196,11 @@ int show_interrupts(struct seq_file *p, void *v)
196 seq_putc(p, '\n'); 196 seq_putc(p, '\n');
197skip: 197skip:
198 spin_unlock_irqrestore(&irq_desc[i].lock, flags); 198 spin_unlock_irqrestore(&irq_desc[i].lock, flags);
199 } else if (i == NR_IRQS) {
200 seq_printf(p, "NMI: ");
201 for_each_online_cpu(j)
202 seq_printf(p, "%10u ", cpu_data(j).__nmi_count);
203 seq_printf(p, " Non-maskable interrupts\n");
199 } 204 }
200 return 0; 205 return 0;
201} 206}
@@ -778,69 +783,6 @@ void do_softirq(void)
778 local_irq_restore(flags); 783 local_irq_restore(flags);
779} 784}
780 785
781static void unhandled_perf_irq(struct pt_regs *regs)
782{
783 unsigned long pcr, pic;
784
785 read_pcr(pcr);
786 read_pic(pic);
787
788 write_pcr(0);
789
790 printk(KERN_EMERG "CPU %d: Got unexpected perf counter IRQ.\n",
791 smp_processor_id());
792 printk(KERN_EMERG "CPU %d: PCR[%016lx] PIC[%016lx]\n",
793 smp_processor_id(), pcr, pic);
794}
795
796/* Almost a direct copy of the powerpc PMC code. */
797static DEFINE_SPINLOCK(perf_irq_lock);
798static void *perf_irq_owner_caller; /* mostly for debugging */
799static void (*perf_irq)(struct pt_regs *regs) = unhandled_perf_irq;
800
801/* Invoked from level 15 PIL handler in trap table. */
802void perfctr_irq(int irq, struct pt_regs *regs)
803{
804 clear_softint(1 << irq);
805 perf_irq(regs);
806}
807
808int register_perfctr_intr(void (*handler)(struct pt_regs *))
809{
810 int ret;
811
812 if (!handler)
813 return -EINVAL;
814
815 spin_lock(&perf_irq_lock);
816 if (perf_irq != unhandled_perf_irq) {
817 printk(KERN_WARNING "register_perfctr_intr: "
818 "perf IRQ busy (reserved by caller %p)\n",
819 perf_irq_owner_caller);
820 ret = -EBUSY;
821 goto out;
822 }
823
824 perf_irq_owner_caller = __builtin_return_address(0);
825 perf_irq = handler;
826
827 ret = 0;
828out:
829 spin_unlock(&perf_irq_lock);
830
831 return ret;
832}
833EXPORT_SYMBOL_GPL(register_perfctr_intr);
834
835void release_perfctr_intr(void (*handler)(struct pt_regs *))
836{
837 spin_lock(&perf_irq_lock);
838 perf_irq_owner_caller = NULL;
839 perf_irq = unhandled_perf_irq;
840 spin_unlock(&perf_irq_lock);
841}
842EXPORT_SYMBOL_GPL(release_perfctr_intr);
843
844#ifdef CONFIG_HOTPLUG_CPU 786#ifdef CONFIG_HOTPLUG_CPU
845void fixup_irqs(void) 787void fixup_irqs(void)
846{ 788{
diff --git a/arch/sparc/kernel/kernel.h b/arch/sparc/kernel/kernel.h
index 81a972e8d8ea..15d8a3f645c9 100644
--- a/arch/sparc/kernel/kernel.h
+++ b/arch/sparc/kernel/kernel.h
@@ -5,6 +5,7 @@
5 5
6/* cpu.c */ 6/* cpu.c */
7extern const char *sparc_cpu_type; 7extern const char *sparc_cpu_type;
8extern const char *sparc_pmu_type;
8extern const char *sparc_fpu_type; 9extern const char *sparc_fpu_type;
9 10
10extern unsigned int fsr_storage; 11extern unsigned int fsr_storage;
diff --git a/arch/sparc/kernel/nmi.c b/arch/sparc/kernel/nmi.c
new file mode 100644
index 000000000000..f3577223c863
--- /dev/null
+++ b/arch/sparc/kernel/nmi.c
@@ -0,0 +1,225 @@
1/* Pseudo NMI support on sparc64 systems.
2 *
3 * Copyright (C) 2009 David S. Miller <davem@davemloft.net>
4 *
5 * The NMI watchdog support and infrastructure is based almost
6 * entirely upon the x86 NMI support code.
7 */
8#include <linux/kernel.h>
9#include <linux/param.h>
10#include <linux/init.h>
11#include <linux/percpu.h>
12#include <linux/nmi.h>
13#include <linux/module.h>
14#include <linux/kprobes.h>
15#include <linux/kernel_stat.h>
16#include <linux/slab.h>
17#include <linux/kdebug.h>
18#include <linux/delay.h>
19#include <linux/smp.h>
20
21#include <asm/ptrace.h>
22#include <asm/local.h>
23#include <asm/pcr.h>
24
25/* We don't have a real NMI on sparc64, but we can fake one
26 * up using profiling counter overflow interrupts and interrupt
27 * levels.
28 *
29 * The profile overflow interrupts at level 15, so we use
30 * level 14 as our IRQ off level.
31 */
32
33static int nmi_watchdog_active;
34static int panic_on_timeout;
35
36int nmi_usable;
37EXPORT_SYMBOL_GPL(nmi_usable);
38
39static unsigned int nmi_hz = HZ;
40
41static DEFINE_PER_CPU(unsigned int, last_irq_sum);
42static DEFINE_PER_CPU(local_t, alert_counter);
43static DEFINE_PER_CPU(int, nmi_touch);
44
45void touch_nmi_watchdog(void)
46{
47 if (nmi_watchdog_active) {
48 int cpu;
49
50 for_each_present_cpu(cpu) {
51 if (per_cpu(nmi_touch, cpu) != 1)
52 per_cpu(nmi_touch, cpu) = 1;
53 }
54 }
55
56 touch_softlockup_watchdog();
57}
58EXPORT_SYMBOL(touch_nmi_watchdog);
59
60static void die_nmi(const char *str, struct pt_regs *regs, int do_panic)
61{
62 if (notify_die(DIE_NMIWATCHDOG, str, regs, 0,
63 pt_regs_trap_type(regs), SIGINT) == NOTIFY_STOP)
64 return;
65
66 console_verbose();
67 bust_spinlocks(1);
68
69 printk(KERN_EMERG "%s", str);
70 printk(" on CPU%d, ip %08lx, registers:\n",
71 smp_processor_id(), regs->tpc);
72 show_regs(regs);
73 dump_stack();
74
75 bust_spinlocks(0);
76
77 if (do_panic || panic_on_oops)
78 panic("Non maskable interrupt");
79
80 local_irq_enable();
81 do_exit(SIGBUS);
82}
83
84notrace __kprobes void perfctr_irq(int irq, struct pt_regs *regs)
85{
86 unsigned int sum, touched = 0;
87 int cpu = smp_processor_id();
88
89 clear_softint(1 << irq);
90 pcr_ops->write(PCR_PIC_PRIV);
91
92 local_cpu_data().__nmi_count++;
93
94 if (notify_die(DIE_NMI, "nmi", regs, 0,
95 pt_regs_trap_type(regs), SIGINT) == NOTIFY_STOP)
96 touched = 1;
97
98 sum = kstat_irqs_cpu(0, cpu);
99 if (__get_cpu_var(nmi_touch)) {
100 __get_cpu_var(nmi_touch) = 0;
101 touched = 1;
102 }
103 if (!touched && __get_cpu_var(last_irq_sum) == sum) {
104 local_inc(&__get_cpu_var(alert_counter));
105 if (local_read(&__get_cpu_var(alert_counter)) == 5 * nmi_hz)
106 die_nmi("BUG: NMI Watchdog detected LOCKUP",
107 regs, panic_on_timeout);
108 } else {
109 __get_cpu_var(last_irq_sum) = sum;
110 local_set(&__get_cpu_var(alert_counter), 0);
111 }
112 if (nmi_usable) {
113 write_pic(picl_value(nmi_hz));
114 pcr_ops->write(pcr_enable);
115 }
116}
117
118static inline unsigned int get_nmi_count(int cpu)
119{
120 return cpu_data(cpu).__nmi_count;
121}
122
123static int endflag __initdata;
124
125static __init void nmi_cpu_busy(void *data)
126{
127 local_irq_enable_in_hardirq();
128 while (endflag == 0)
129 mb();
130}
131
132static void report_broken_nmi(int cpu, int *prev_nmi_count)
133{
134 printk(KERN_CONT "\n");
135
136 printk(KERN_WARNING
137 "WARNING: CPU#%d: NMI appears to be stuck (%d->%d)!\n",
138 cpu, prev_nmi_count[cpu], get_nmi_count(cpu));
139
140 printk(KERN_WARNING
141 "Please report this to bugzilla.kernel.org,\n");
142 printk(KERN_WARNING
143 "and attach the output of the 'dmesg' command.\n");
144
145 nmi_usable = 0;
146}
147
148static void stop_watchdog(void *unused)
149{
150 pcr_ops->write(PCR_PIC_PRIV);
151}
152
153static int __init check_nmi_watchdog(void)
154{
155 unsigned int *prev_nmi_count;
156 int cpu, err;
157
158 prev_nmi_count = kmalloc(nr_cpu_ids * sizeof(unsigned int), GFP_KERNEL);
159 if (!prev_nmi_count) {
160 err = -ENOMEM;
161 goto error;
162 }
163
164 printk(KERN_INFO "Testing NMI watchdog ... ");
165
166 smp_call_function(nmi_cpu_busy, (void *)&endflag, 0);
167
168 for_each_possible_cpu(cpu)
169 prev_nmi_count[cpu] = get_nmi_count(cpu);
170 local_irq_enable();
171 mdelay((20 * 1000) / nmi_hz); /* wait 20 ticks */
172
173 for_each_online_cpu(cpu) {
174 if (get_nmi_count(cpu) - prev_nmi_count[cpu] <= 5)
175 report_broken_nmi(cpu, prev_nmi_count);
176 }
177 endflag = 1;
178 if (!nmi_usable) {
179 kfree(prev_nmi_count);
180 err = -ENODEV;
181 goto error;
182 }
183 printk("OK.\n");
184
185 nmi_hz = 1;
186
187 kfree(prev_nmi_count);
188 return 0;
189error:
190 on_each_cpu(stop_watchdog, NULL, 1);
191 return err;
192}
193
194static void start_watchdog(void *unused)
195{
196 pcr_ops->write(PCR_PIC_PRIV);
197 write_pic(picl_value(nmi_hz));
198
199 pcr_ops->write(pcr_enable);
200}
201
202void nmi_adjust_hz(unsigned int new_hz)
203{
204 nmi_hz = new_hz;
205 on_each_cpu(start_watchdog, NULL, 1);
206}
207EXPORT_SYMBOL_GPL(nmi_adjust_hz);
208
209int __init nmi_init(void)
210{
211 nmi_usable = 1;
212
213 on_each_cpu(start_watchdog, NULL, 1);
214
215 return check_nmi_watchdog();
216}
217
218static int __init setup_nmi_watchdog(char *str)
219{
220 if (!strncmp(str, "panic", 5))
221 panic_on_timeout = 1;
222
223 return 0;
224}
225__setup("nmi_watchdog=", setup_nmi_watchdog);
diff --git a/arch/sparc/kernel/pcr.c b/arch/sparc/kernel/pcr.c
new file mode 100644
index 000000000000..1ae8cdd7e703
--- /dev/null
+++ b/arch/sparc/kernel/pcr.c
@@ -0,0 +1,158 @@
1/* pcr.c: Generic sparc64 performance counter infrastructure.
2 *
3 * Copyright (C) 2009 David S. Miller (davem@davemloft.net)
4 */
5#include <linux/kernel.h>
6#include <linux/module.h>
7#include <linux/init.h>
8#include <linux/irq.h>
9
10#include <asm/pil.h>
11#include <asm/pcr.h>
12#include <asm/nmi.h>
13
14/* This code is shared between various users of the performance
15 * counters. Users will be oprofile, pseudo-NMI watchdog, and the
16 * perf_counter support layer.
17 */
18
19#define PCR_SUN4U_ENABLE (PCR_PIC_PRIV | PCR_STRACE | PCR_UTRACE)
20#define PCR_N2_ENABLE (PCR_PIC_PRIV | PCR_STRACE | PCR_UTRACE | \
21 PCR_N2_TOE_OV1 | \
22 (2 << PCR_N2_SL1_SHIFT) | \
23 (0xff << PCR_N2_MASK1_SHIFT))
24
25u64 pcr_enable;
26unsigned int picl_shift;
27
28/* Performance counter interrupts run unmasked at PIL level 15.
29 * Therefore we can't do things like wakeups and other work
30 * that expects IRQ disabling to be adhered to in locking etc.
31 *
32 * Therefore in such situations we defer the work by signalling
33 * a lower level cpu IRQ.
34 */
35void deferred_pcr_work_irq(int irq, struct pt_regs *regs)
36{
37 clear_softint(1 << PIL_DEFERRED_PCR_WORK);
38}
39
40void schedule_deferred_pcr_work(void)
41{
42 set_softint(1 << PIL_DEFERRED_PCR_WORK);
43}
44
45const struct pcr_ops *pcr_ops;
46EXPORT_SYMBOL_GPL(pcr_ops);
47
48static u64 direct_pcr_read(void)
49{
50 u64 val;
51
52 read_pcr(val);
53 return val;
54}
55
56static void direct_pcr_write(u64 val)
57{
58 write_pcr(val);
59}
60
61static const struct pcr_ops direct_pcr_ops = {
62 .read = direct_pcr_read,
63 .write = direct_pcr_write,
64};
65
66static void n2_pcr_write(u64 val)
67{
68 unsigned long ret;
69
70 ret = sun4v_niagara2_setperf(HV_N2_PERF_SPARC_CTL, val);
71 if (val != HV_EOK)
72 write_pcr(val);
73}
74
75static const struct pcr_ops n2_pcr_ops = {
76 .read = direct_pcr_read,
77 .write = n2_pcr_write,
78};
79
80static unsigned long perf_hsvc_group;
81static unsigned long perf_hsvc_major;
82static unsigned long perf_hsvc_minor;
83
84static int __init register_perf_hsvc(void)
85{
86 if (tlb_type == hypervisor) {
87 switch (sun4v_chip_type) {
88 case SUN4V_CHIP_NIAGARA1:
89 perf_hsvc_group = HV_GRP_NIAG_PERF;
90 break;
91
92 case SUN4V_CHIP_NIAGARA2:
93 perf_hsvc_group = HV_GRP_N2_CPU;
94 break;
95
96 default:
97 return -ENODEV;
98 }
99
100
101 perf_hsvc_major = 1;
102 perf_hsvc_minor = 0;
103 if (sun4v_hvapi_register(perf_hsvc_group,
104 perf_hsvc_major,
105 &perf_hsvc_minor)) {
106 printk("perfmon: Could not register hvapi.\n");
107 return -ENODEV;
108 }
109 }
110 return 0;
111}
112
113static void __init unregister_perf_hsvc(void)
114{
115 if (tlb_type != hypervisor)
116 return;
117 sun4v_hvapi_unregister(perf_hsvc_group);
118}
119
120int __init pcr_arch_init(void)
121{
122 int err = register_perf_hsvc();
123
124 if (err)
125 return err;
126
127 switch (tlb_type) {
128 case hypervisor:
129 pcr_ops = &n2_pcr_ops;
130 pcr_enable = PCR_N2_ENABLE;
131 picl_shift = 2;
132 break;
133
134 case cheetah:
135 case cheetah_plus:
136 pcr_ops = &direct_pcr_ops;
137 pcr_enable = PCR_SUN4U_ENABLE;
138 break;
139
140 case spitfire:
141 /* UltraSPARC-I/II and derivatives lack a profile
142 * counter overflow interrupt so we can't make use of
143 * their hardware currently.
144 */
145 /* fallthrough */
146 default:
147 err = -ENODEV;
148 goto out_unregister;
149 }
150
151 return nmi_init();
152
153out_unregister:
154 unregister_perf_hsvc();
155 return err;
156}
157
158arch_initcall(pcr_arch_init);
diff --git a/arch/sparc/kernel/process_64.c b/arch/sparc/kernel/process_64.c
index cc8b5604442c..a73954b87f0a 100644
--- a/arch/sparc/kernel/process_64.c
+++ b/arch/sparc/kernel/process_64.c
@@ -29,6 +29,7 @@
29#include <linux/cpu.h> 29#include <linux/cpu.h>
30#include <linux/elfcore.h> 30#include <linux/elfcore.h>
31#include <linux/sysrq.h> 31#include <linux/sysrq.h>
32#include <linux/nmi.h>
32 33
33#include <asm/uaccess.h> 34#include <asm/uaccess.h>
34#include <asm/system.h> 35#include <asm/system.h>
@@ -52,8 +53,10 @@
52 53
53static void sparc64_yield(int cpu) 54static void sparc64_yield(int cpu)
54{ 55{
55 if (tlb_type != hypervisor) 56 if (tlb_type != hypervisor) {
57 touch_nmi_watchdog();
56 return; 58 return;
59 }
57 60
58 clear_thread_flag(TIF_POLLING_NRFLAG); 61 clear_thread_flag(TIF_POLLING_NRFLAG);
59 smp_mb__after_clear_bit(); 62 smp_mb__after_clear_bit();
diff --git a/arch/sparc/kernel/setup_64.c b/arch/sparc/kernel/setup_64.c
index 49d061f4ae9d..f2bcfd2967d7 100644
--- a/arch/sparc/kernel/setup_64.c
+++ b/arch/sparc/kernel/setup_64.c
@@ -354,6 +354,7 @@ static int show_cpuinfo(struct seq_file *m, void *__unused)
354 seq_printf(m, 354 seq_printf(m,
355 "cpu\t\t: %s\n" 355 "cpu\t\t: %s\n"
356 "fpu\t\t: %s\n" 356 "fpu\t\t: %s\n"
357 "pmu\t\t: %s\n"
357 "prom\t\t: %s\n" 358 "prom\t\t: %s\n"
358 "type\t\t: %s\n" 359 "type\t\t: %s\n"
359 "ncpus probed\t: %d\n" 360 "ncpus probed\t: %d\n"
@@ -366,6 +367,7 @@ static int show_cpuinfo(struct seq_file *m, void *__unused)
366 , 367 ,
367 sparc_cpu_type, 368 sparc_cpu_type,
368 sparc_fpu_type, 369 sparc_fpu_type,
370 sparc_pmu_type,
369 prom_version, 371 prom_version,
370 ((tlb_type == hypervisor) ? 372 ((tlb_type == hypervisor) ?
371 "sun4v" : 373 "sun4v" :
diff --git a/arch/sparc/kernel/sys_sparc_64.c b/arch/sparc/kernel/sys_sparc_64.c
index 09058fc39e73..e2d102447a43 100644
--- a/arch/sparc/kernel/sys_sparc_64.c
+++ b/arch/sparc/kernel/sys_sparc_64.c
@@ -399,7 +399,7 @@ void arch_pick_mmap_layout(struct mm_struct *mm)
399 } 399 }
400} 400}
401 401
402asmlinkage unsigned long sparc_brk(unsigned long brk) 402SYSCALL_DEFINE1(sparc_brk, unsigned long, brk)
403{ 403{
404 /* People could try to be nasty and use ta 0x6d in 32bit programs */ 404 /* People could try to be nasty and use ta 0x6d in 32bit programs */
405 if (test_thread_flag(TIF_32BIT) && brk >= STACK_TOP32) 405 if (test_thread_flag(TIF_32BIT) && brk >= STACK_TOP32)
@@ -415,7 +415,7 @@ asmlinkage unsigned long sparc_brk(unsigned long brk)
415 * sys_pipe() is the normal C calling standard for creating 415 * sys_pipe() is the normal C calling standard for creating
416 * a pipe. It's not the way unix traditionally does this, though. 416 * a pipe. It's not the way unix traditionally does this, though.
417 */ 417 */
418asmlinkage long sparc_pipe(struct pt_regs *regs) 418SYSCALL_DEFINE1(sparc_pipe_real, struct pt_regs *, regs)
419{ 419{
420 int fd[2]; 420 int fd[2];
421 int error; 421 int error;
@@ -435,8 +435,8 @@ out:
435 * This is really horribly ugly. 435 * This is really horribly ugly.
436 */ 436 */
437 437
438asmlinkage long sys_ipc(unsigned int call, int first, unsigned long second, 438SYSCALL_DEFINE6(ipc, unsigned int, call, int, first, unsigned long, second,
439 unsigned long third, void __user *ptr, long fifth) 439 unsigned long, third, void __user *, ptr, long, fifth)
440{ 440{
441 long err; 441 long err;
442 442
@@ -519,7 +519,7 @@ out:
519 return err; 519 return err;
520} 520}
521 521
522asmlinkage long sparc64_newuname(struct new_utsname __user *name) 522SYSCALL_DEFINE1(sparc64_newuname, struct new_utsname __user *, name)
523{ 523{
524 int ret = sys_newuname(name); 524 int ret = sys_newuname(name);
525 525
@@ -530,7 +530,7 @@ asmlinkage long sparc64_newuname(struct new_utsname __user *name)
530 return ret; 530 return ret;
531} 531}
532 532
533asmlinkage long sparc64_personality(unsigned long personality) 533SYSCALL_DEFINE1(sparc64_personality, unsigned long, personality)
534{ 534{
535 int ret; 535 int ret;
536 536
@@ -564,9 +564,9 @@ int sparc_mmap_check(unsigned long addr, unsigned long len)
564} 564}
565 565
566/* Linux version of mmap */ 566/* Linux version of mmap */
567asmlinkage unsigned long sys_mmap(unsigned long addr, unsigned long len, 567SYSCALL_DEFINE6(mmap, unsigned long, addr, unsigned long, len,
568 unsigned long prot, unsigned long flags, unsigned long fd, 568 unsigned long, prot, unsigned long, flags, unsigned long, fd,
569 unsigned long off) 569 unsigned long, off)
570{ 570{
571 struct file * file = NULL; 571 struct file * file = NULL;
572 unsigned long retval = -EBADF; 572 unsigned long retval = -EBADF;
@@ -589,7 +589,7 @@ out:
589 return retval; 589 return retval;
590} 590}
591 591
592asmlinkage long sys64_munmap(unsigned long addr, size_t len) 592SYSCALL_DEFINE2(64_munmap, unsigned long, addr, size_t, len)
593{ 593{
594 long ret; 594 long ret;
595 595
@@ -606,9 +606,9 @@ extern unsigned long do_mremap(unsigned long addr,
606 unsigned long old_len, unsigned long new_len, 606 unsigned long old_len, unsigned long new_len,
607 unsigned long flags, unsigned long new_addr); 607 unsigned long flags, unsigned long new_addr);
608 608
609asmlinkage unsigned long sys64_mremap(unsigned long addr, 609SYSCALL_DEFINE5(64_mremap, unsigned long, addr, unsigned long, old_len,
610 unsigned long old_len, unsigned long new_len, 610 unsigned long, new_len, unsigned long, flags,
611 unsigned long flags, unsigned long new_addr) 611 unsigned long, new_addr)
612{ 612{
613 unsigned long ret = -EINVAL; 613 unsigned long ret = -EINVAL;
614 614
@@ -671,7 +671,7 @@ asmlinkage void sparc_breakpoint(struct pt_regs *regs)
671 671
672extern void check_pending(int signum); 672extern void check_pending(int signum);
673 673
674asmlinkage long sys_getdomainname(char __user *name, int len) 674SYSCALL_DEFINE2(getdomainname, char __user *, name, int, len)
675{ 675{
676 int nlen, err; 676 int nlen, err;
677 677
@@ -694,11 +694,10 @@ out:
694 return err; 694 return err;
695} 695}
696 696
697asmlinkage long sys_utrap_install(utrap_entry_t type, 697SYSCALL_DEFINE5(utrap_install, utrap_entry_t, type,
698 utrap_handler_t new_p, 698 utrap_handler_t, new_p, utrap_handler_t, new_d,
699 utrap_handler_t new_d, 699 utrap_handler_t __user *, old_p,
700 utrap_handler_t __user *old_p, 700 utrap_handler_t __user *, old_d)
701 utrap_handler_t __user *old_d)
702{ 701{
703 if (type < UT_INSTRUCTION_EXCEPTION || type > UT_TRAP_INSTRUCTION_31) 702 if (type < UT_INSTRUCTION_EXCEPTION || type > UT_TRAP_INSTRUCTION_31)
704 return -EINVAL; 703 return -EINVAL;
@@ -764,11 +763,9 @@ asmlinkage long sparc_memory_ordering(unsigned long model,
764 return 0; 763 return 0;
765} 764}
766 765
767asmlinkage long sys_rt_sigaction(int sig, 766SYSCALL_DEFINE5(rt_sigaction, int, sig, const struct sigaction __user *, act,
768 const struct sigaction __user *act, 767 struct sigaction __user *, oact, void __user *, restorer,
769 struct sigaction __user *oact, 768 size_t, sigsetsize)
770 void __user *restorer,
771 size_t sigsetsize)
772{ 769{
773 struct k_sigaction new_ka, old_ka; 770 struct k_sigaction new_ka, old_ka;
774 int ret; 771 int ret;
@@ -808,7 +805,8 @@ asmlinkage void update_perfctrs(void)
808 reset_pic(); 805 reset_pic();
809} 806}
810 807
811asmlinkage long sys_perfctr(int opcode, unsigned long arg0, unsigned long arg1, unsigned long arg2) 808SYSCALL_DEFINE4(perfctr, int, opcode, unsigned long, arg0,
809 unsigned long, arg1, unsigned long, arg2)
812{ 810{
813 int err = 0; 811 int err = 0;
814 812
diff --git a/arch/sparc/kernel/syscalls.S b/arch/sparc/kernel/syscalls.S
index 87f5a3b8a253..d150c2aa98d2 100644
--- a/arch/sparc/kernel/syscalls.S
+++ b/arch/sparc/kernel/syscalls.S
@@ -21,7 +21,7 @@ execve_merge:
21 21
22 .align 32 22 .align 32
23sys_sparc_pipe: 23sys_sparc_pipe:
24 ba,pt %xcc, sparc_pipe 24 ba,pt %xcc, sys_sparc_pipe_real
25 add %sp, PTREGS_OFF, %o0 25 add %sp, PTREGS_OFF, %o0
26sys_nis_syscall: 26sys_nis_syscall:
27 ba,pt %xcc, c_sys_nis_syscall 27 ba,pt %xcc, c_sys_nis_syscall
diff --git a/arch/sparc/kernel/systbls.h b/arch/sparc/kernel/systbls.h
index bc9f5dac4069..15c2d752b2bc 100644
--- a/arch/sparc/kernel/systbls.h
+++ b/arch/sparc/kernel/systbls.h
@@ -16,9 +16,6 @@ extern asmlinkage long sys_ipc(unsigned int call, int first,
16 void __user *ptr, long fifth); 16 void __user *ptr, long fifth);
17extern asmlinkage long sparc64_newuname(struct new_utsname __user *name); 17extern asmlinkage long sparc64_newuname(struct new_utsname __user *name);
18extern asmlinkage long sparc64_personality(unsigned long personality); 18extern asmlinkage long sparc64_personality(unsigned long personality);
19extern asmlinkage unsigned long sys_mmap(unsigned long addr, unsigned long len,
20 unsigned long prot, unsigned long flags,
21 unsigned long fd, unsigned long off);
22extern asmlinkage long sys64_munmap(unsigned long addr, size_t len); 19extern asmlinkage long sys64_munmap(unsigned long addr, size_t len);
23extern asmlinkage unsigned long sys64_mremap(unsigned long addr, 20extern asmlinkage unsigned long sys64_mremap(unsigned long addr,
24 unsigned long old_len, 21 unsigned long old_len,
diff --git a/arch/sparc/kernel/systbls_64.S b/arch/sparc/kernel/systbls_64.S
index e6007bb37046..f93c42a2b522 100644
--- a/arch/sparc/kernel/systbls_64.S
+++ b/arch/sparc/kernel/systbls_64.S
@@ -21,7 +21,7 @@ sys_call_table32:
21/*0*/ .word sys_restart_syscall, sys32_exit, sys_fork, sys_read, sys_write 21/*0*/ .word sys_restart_syscall, sys32_exit, sys_fork, sys_read, sys_write
22/*5*/ .word sys32_open, sys_close, sys32_wait4, sys32_creat, sys_link 22/*5*/ .word sys32_open, sys_close, sys32_wait4, sys32_creat, sys_link
23/*10*/ .word sys_unlink, sunos_execv, sys_chdir, sys_chown16, sys32_mknod 23/*10*/ .word sys_unlink, sunos_execv, sys_chdir, sys_chown16, sys32_mknod
24/*15*/ .word sys_chmod, sys_lchown16, sparc_brk, sys32_perfctr, sys32_lseek 24/*15*/ .word sys_chmod, sys_lchown16, sys_sparc_brk, sys32_perfctr, sys32_lseek
25/*20*/ .word sys_getpid, sys_capget, sys_capset, sys_setuid16, sys_getuid16 25/*20*/ .word sys_getpid, sys_capget, sys_capset, sys_setuid16, sys_getuid16
26/*25*/ .word sys32_vmsplice, compat_sys_ptrace, sys_alarm, sys32_sigaltstack, sys_pause 26/*25*/ .word sys32_vmsplice, compat_sys_ptrace, sys_alarm, sys32_sigaltstack, sys_pause
27/*30*/ .word compat_sys_utime, sys_lchown, sys_fchown, sys32_access, sys32_nice 27/*30*/ .word compat_sys_utime, sys_lchown, sys_fchown, sys32_access, sys32_nice
@@ -55,8 +55,8 @@ sys_call_table32:
55/*170*/ .word sys32_lsetxattr, sys32_fsetxattr, sys_getxattr, sys_lgetxattr, compat_sys_getdents 55/*170*/ .word sys32_lsetxattr, sys32_fsetxattr, sys_getxattr, sys_lgetxattr, compat_sys_getdents
56 .word sys_setsid, sys_fchdir, sys32_fgetxattr, sys_listxattr, sys_llistxattr 56 .word sys_setsid, sys_fchdir, sys32_fgetxattr, sys_listxattr, sys_llistxattr
57/*180*/ .word sys32_flistxattr, sys_removexattr, sys_lremovexattr, compat_sys_sigpending, sys_ni_syscall 57/*180*/ .word sys32_flistxattr, sys_removexattr, sys_lremovexattr, compat_sys_sigpending, sys_ni_syscall
58 .word sys32_setpgid, sys32_fremovexattr, sys32_tkill, sys32_exit_group, sparc64_newuname 58 .word sys32_setpgid, sys32_fremovexattr, sys32_tkill, sys32_exit_group, sys_sparc64_newuname
59/*190*/ .word sys32_init_module, sparc64_personality, sys_remap_file_pages, sys32_epoll_create, sys32_epoll_ctl 59/*190*/ .word sys32_init_module, sys_sparc64_personality, sys_remap_file_pages, sys32_epoll_create, sys32_epoll_ctl
60 .word sys32_epoll_wait, sys32_ioprio_set, sys_getppid, sys32_sigaction, sys_sgetmask 60 .word sys32_epoll_wait, sys32_ioprio_set, sys_getppid, sys32_sigaction, sys_sgetmask
61/*200*/ .word sys32_ssetmask, sys_sigsuspend, compat_sys_newlstat, sys_uselib, compat_sys_old_readdir 61/*200*/ .word sys32_ssetmask, sys_sigsuspend, compat_sys_newlstat, sys_uselib, compat_sys_old_readdir
62 .word sys32_readahead, sys32_socketcall, sys32_syslog, sys32_lookup_dcookie, sys32_fadvise64 62 .word sys32_readahead, sys32_socketcall, sys32_syslog, sys32_lookup_dcookie, sys32_fadvise64
@@ -95,7 +95,7 @@ sys_call_table:
95/*0*/ .word sys_restart_syscall, sparc_exit, sys_fork, sys_read, sys_write 95/*0*/ .word sys_restart_syscall, sparc_exit, sys_fork, sys_read, sys_write
96/*5*/ .word sys_open, sys_close, sys_wait4, sys_creat, sys_link 96/*5*/ .word sys_open, sys_close, sys_wait4, sys_creat, sys_link
97/*10*/ .word sys_unlink, sys_nis_syscall, sys_chdir, sys_chown, sys_mknod 97/*10*/ .word sys_unlink, sys_nis_syscall, sys_chdir, sys_chown, sys_mknod
98/*15*/ .word sys_chmod, sys_lchown, sparc_brk, sys_perfctr, sys_lseek 98/*15*/ .word sys_chmod, sys_lchown, sys_sparc_brk, sys_perfctr, sys_lseek
99/*20*/ .word sys_getpid, sys_capget, sys_capset, sys_setuid, sys_getuid 99/*20*/ .word sys_getpid, sys_capget, sys_capset, sys_setuid, sys_getuid
100/*25*/ .word sys_vmsplice, sys_ptrace, sys_alarm, sys_sigaltstack, sys_nis_syscall 100/*25*/ .word sys_vmsplice, sys_ptrace, sys_alarm, sys_sigaltstack, sys_nis_syscall
101/*30*/ .word sys_utime, sys_nis_syscall, sys_nis_syscall, sys_access, sys_nice 101/*30*/ .word sys_utime, sys_nis_syscall, sys_nis_syscall, sys_access, sys_nice
@@ -106,7 +106,7 @@ sys_call_table:
106 .word sys_reboot, sys_nis_syscall, sys_symlink, sys_readlink, sys_execve 106 .word sys_reboot, sys_nis_syscall, sys_symlink, sys_readlink, sys_execve
107/*60*/ .word sys_umask, sys_chroot, sys_newfstat, sys_fstat64, sys_getpagesize 107/*60*/ .word sys_umask, sys_chroot, sys_newfstat, sys_fstat64, sys_getpagesize
108 .word sys_msync, sys_vfork, sys_pread64, sys_pwrite64, sys_nis_syscall 108 .word sys_msync, sys_vfork, sys_pread64, sys_pwrite64, sys_nis_syscall
109/*70*/ .word sys_nis_syscall, sys_mmap, sys_nis_syscall, sys64_munmap, sys_mprotect 109/*70*/ .word sys_nis_syscall, sys_mmap, sys_nis_syscall, sys_64_munmap, sys_mprotect
110 .word sys_madvise, sys_vhangup, sys_nis_syscall, sys_mincore, sys_getgroups 110 .word sys_madvise, sys_vhangup, sys_nis_syscall, sys_mincore, sys_getgroups
111/*80*/ .word sys_setgroups, sys_getpgrp, sys_nis_syscall, sys_setitimer, sys_nis_syscall 111/*80*/ .word sys_setgroups, sys_getpgrp, sys_nis_syscall, sys_setitimer, sys_nis_syscall
112 .word sys_swapon, sys_getitimer, sys_nis_syscall, sys_sethostname, sys_nis_syscall 112 .word sys_swapon, sys_getitimer, sys_nis_syscall, sys_sethostname, sys_nis_syscall
@@ -129,8 +129,8 @@ sys_call_table:
129/*170*/ .word sys_lsetxattr, sys_fsetxattr, sys_getxattr, sys_lgetxattr, sys_getdents 129/*170*/ .word sys_lsetxattr, sys_fsetxattr, sys_getxattr, sys_lgetxattr, sys_getdents
130 .word sys_setsid, sys_fchdir, sys_fgetxattr, sys_listxattr, sys_llistxattr 130 .word sys_setsid, sys_fchdir, sys_fgetxattr, sys_listxattr, sys_llistxattr
131/*180*/ .word sys_flistxattr, sys_removexattr, sys_lremovexattr, sys_nis_syscall, sys_ni_syscall 131/*180*/ .word sys_flistxattr, sys_removexattr, sys_lremovexattr, sys_nis_syscall, sys_ni_syscall
132 .word sys_setpgid, sys_fremovexattr, sys_tkill, sys_exit_group, sparc64_newuname 132 .word sys_setpgid, sys_fremovexattr, sys_tkill, sys_exit_group, sys_sparc64_newuname
133/*190*/ .word sys_init_module, sparc64_personality, sys_remap_file_pages, sys_epoll_create, sys_epoll_ctl 133/*190*/ .word sys_init_module, sys_sparc64_personality, sys_remap_file_pages, sys_epoll_create, sys_epoll_ctl
134 .word sys_epoll_wait, sys_ioprio_set, sys_getppid, sys_nis_syscall, sys_sgetmask 134 .word sys_epoll_wait, sys_ioprio_set, sys_getppid, sys_nis_syscall, sys_sgetmask
135/*200*/ .word sys_ssetmask, sys_nis_syscall, sys_newlstat, sys_uselib, sys_nis_syscall 135/*200*/ .word sys_ssetmask, sys_nis_syscall, sys_newlstat, sys_uselib, sys_nis_syscall
136 .word sys_readahead, sys_socketcall, sys_syslog, sys_lookup_dcookie, sys_fadvise64 136 .word sys_readahead, sys_socketcall, sys_syslog, sys_lookup_dcookie, sys_fadvise64
@@ -142,7 +142,7 @@ sys_call_table:
142 .word sys_fstatfs64, sys_llseek, sys_mlock, sys_munlock, sys_mlockall 142 .word sys_fstatfs64, sys_llseek, sys_mlock, sys_munlock, sys_mlockall
143/*240*/ .word sys_munlockall, sys_sched_setparam, sys_sched_getparam, sys_sched_setscheduler, sys_sched_getscheduler 143/*240*/ .word sys_munlockall, sys_sched_setparam, sys_sched_getparam, sys_sched_setscheduler, sys_sched_getscheduler
144 .word sys_sched_yield, sys_sched_get_priority_max, sys_sched_get_priority_min, sys_sched_rr_get_interval, sys_nanosleep 144 .word sys_sched_yield, sys_sched_get_priority_max, sys_sched_get_priority_min, sys_sched_rr_get_interval, sys_nanosleep
145/*250*/ .word sys64_mremap, sys_sysctl, sys_getsid, sys_fdatasync, sys_nfsservctl 145/*250*/ .word sys_64_mremap, sys_sysctl, sys_getsid, sys_fdatasync, sys_nfsservctl
146 .word sys_sync_file_range, sys_clock_settime, sys_clock_gettime, sys_clock_getres, sys_clock_nanosleep 146 .word sys_sync_file_range, sys_clock_settime, sys_clock_gettime, sys_clock_getres, sys_clock_nanosleep
147/*260*/ .word sys_sched_getaffinity, sys_sched_setaffinity, sys_timer_settime, sys_timer_gettime, sys_timer_getoverrun 147/*260*/ .word sys_sched_getaffinity, sys_sched_setaffinity, sys_timer_settime, sys_timer_gettime, sys_timer_getoverrun
148 .word sys_timer_delete, sys_timer_create, sys_ni_syscall, sys_io_setup, sys_io_destroy 148 .word sys_timer_delete, sys_timer_create, sys_ni_syscall, sys_io_setup, sys_io_destroy
diff --git a/arch/sparc/kernel/time_64.c b/arch/sparc/kernel/time_64.c
index 2db3c2229b95..642562d83ec4 100644
--- a/arch/sparc/kernel/time_64.c
+++ b/arch/sparc/kernel/time_64.c
@@ -36,10 +36,10 @@
36#include <linux/clocksource.h> 36#include <linux/clocksource.h>
37#include <linux/of_device.h> 37#include <linux/of_device.h>
38#include <linux/platform_device.h> 38#include <linux/platform_device.h>
39#include <linux/irq.h>
39 40
40#include <asm/oplib.h> 41#include <asm/oplib.h>
41#include <asm/timer.h> 42#include <asm/timer.h>
42#include <asm/irq.h>
43#include <asm/io.h> 43#include <asm/io.h>
44#include <asm/prom.h> 44#include <asm/prom.h>
45#include <asm/starfire.h> 45#include <asm/starfire.h>
diff --git a/arch/sparc/kernel/traps_64.c b/arch/sparc/kernel/traps_64.c
index c2d153d46586..d809c4ebb48f 100644
--- a/arch/sparc/kernel/traps_64.c
+++ b/arch/sparc/kernel/traps_64.c
@@ -1,6 +1,6 @@
1/* arch/sparc64/kernel/traps.c 1/* arch/sparc64/kernel/traps.c
2 * 2 *
3 * Copyright (C) 1995,1997,2008 David S. Miller (davem@davemloft.net) 3 * Copyright (C) 1995,1997,2008,2009 David S. Miller (davem@davemloft.net)
4 * Copyright (C) 1997,1999,2000 Jakub Jelinek (jakub@redhat.com) 4 * Copyright (C) 1997,1999,2000 Jakub Jelinek (jakub@redhat.com)
5 */ 5 */
6 6
@@ -314,6 +314,21 @@ void sun4v_data_access_exception(struct pt_regs *regs, unsigned long addr, unsig
314 return; 314 return;
315 315
316 if (regs->tstate & TSTATE_PRIV) { 316 if (regs->tstate & TSTATE_PRIV) {
317 /* Test if this comes from uaccess places. */
318 const struct exception_table_entry *entry;
319
320 entry = search_exception_tables(regs->tpc);
321 if (entry) {
322 /* Ouch, somebody is trying VM hole tricks on us... */
323#ifdef DEBUG_EXCEPTIONS
324 printk("Exception: PC<%016lx> faddr<UNKNOWN>\n", regs->tpc);
325 printk("EX_TABLE: insn<%016lx> fixup<%016lx>\n",
326 regs->tpc, entry->fixup);
327#endif
328 regs->tpc = entry->fixup;
329 regs->tnpc = regs->tpc + 4;
330 return;
331 }
317 printk("sun4v_data_access_exception: ADDR[%016lx] " 332 printk("sun4v_data_access_exception: ADDR[%016lx] "
318 "CTX[%04x] TYPE[%04x], going.\n", 333 "CTX[%04x] TYPE[%04x], going.\n",
319 addr, ctx, type); 334 addr, ctx, type);
diff --git a/arch/sparc/kernel/ttable.S b/arch/sparc/kernel/ttable.S
index ea925503b42e..d9bdfb9d5c18 100644
--- a/arch/sparc/kernel/ttable.S
+++ b/arch/sparc/kernel/ttable.S
@@ -63,7 +63,8 @@ tl0_irq6: TRAP_IRQ(smp_call_function_single_client, 6)
63#else 63#else
64tl0_irq6: BTRAP(0x46) 64tl0_irq6: BTRAP(0x46)
65#endif 65#endif
66tl0_irq7: BTRAP(0x47) BTRAP(0x48) BTRAP(0x49) 66tl0_irq7: TRAP_IRQ(deferred_pcr_work_irq, 7)
67tl0_irq8: BTRAP(0x48) BTRAP(0x49)
67tl0_irq10: BTRAP(0x4a) BTRAP(0x4b) BTRAP(0x4c) BTRAP(0x4d) 68tl0_irq10: BTRAP(0x4a) BTRAP(0x4b) BTRAP(0x4c) BTRAP(0x4d)
68tl0_irq14: TRAP_IRQ(timer_interrupt, 14) 69tl0_irq14: TRAP_IRQ(timer_interrupt, 14)
69tl0_irq15: TRAP_NMI_IRQ(perfctr_irq, 15) 70tl0_irq15: TRAP_NMI_IRQ(perfctr_irq, 15)