aboutsummaryrefslogtreecommitdiffstats
path: root/arch/sparc
diff options
context:
space:
mode:
authorAl Viro <viro@zeniv.linux.org.uk>2012-11-16 20:48:13 -0500
committerAl Viro <viro@zeniv.linux.org.uk>2012-11-16 20:49:06 -0500
commit85910c202bb869edd2bb9a6c217a658c83f06f1e (patch)
treefcf4bf1ba2ebfcb6dec395a10ed6b33e7d33217e /arch/sparc
parentf7200d4c504a385b1b70f3bab379f99745f7ef6a (diff)
parent517ffce4e1a03aea979fe3a18a3dd1761a24fafb (diff)
Merge commit '517ffce4e1a03aea979fe3a18a3dd1761a24fafb' into arch-sparc
Backmerge from the point in mainline where a trivial conflict had been introduced (arch/sparc/kernel/sys_sparc_64.c had grown sys_kern_features() right after where kernel_execve() used to be) Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'arch/sparc')
-rw-r--r--arch/sparc/include/asm/compat.h5
-rw-r--r--arch/sparc/include/asm/ptrace.h13
-rw-r--r--arch/sparc/include/asm/smp_64.h2
-rw-r--r--arch/sparc/include/asm/thread_info_64.h5
-rw-r--r--arch/sparc/include/asm/ttable.h24
-rw-r--r--arch/sparc/include/uapi/asm/sigcontext.h4
-rw-r--r--arch/sparc/include/uapi/asm/unistd.h6
-rw-r--r--arch/sparc/kernel/perf_event.c37
-rw-r--r--arch/sparc/kernel/process_64.c162
-rw-r--r--arch/sparc/kernel/ptrace_64.c4
-rw-r--r--arch/sparc/kernel/smp_64.c11
-rw-r--r--arch/sparc/kernel/sys_sparc_64.c5
-rw-r--r--arch/sparc/kernel/systbls_64.S2
-rw-r--r--arch/sparc/kernel/unaligned_64.c36
-rw-r--r--arch/sparc/kernel/visemul.c23
-rw-r--r--arch/sparc/kernel/winfixup.S2
-rw-r--r--arch/sparc/math-emu/math_64.c2
-rw-r--r--arch/sparc/mm/ultra.S64
18 files changed, 317 insertions, 90 deletions
diff --git a/arch/sparc/include/asm/compat.h b/arch/sparc/include/asm/compat.h
index cef99fbc0a21..830502fe62b4 100644
--- a/arch/sparc/include/asm/compat.h
+++ b/arch/sparc/include/asm/compat.h
@@ -232,9 +232,10 @@ static inline void __user *arch_compat_alloc_user_space(long len)
232 struct pt_regs *regs = current_thread_info()->kregs; 232 struct pt_regs *regs = current_thread_info()->kregs;
233 unsigned long usp = regs->u_regs[UREG_I6]; 233 unsigned long usp = regs->u_regs[UREG_I6];
234 234
235 if (!(test_thread_flag(TIF_32BIT))) 235 if (test_thread_64bit_stack(usp))
236 usp += STACK_BIAS; 236 usp += STACK_BIAS;
237 else 237
238 if (test_thread_flag(TIF_32BIT))
238 usp &= 0xffffffffUL; 239 usp &= 0xffffffffUL;
239 240
240 usp -= len; 241 usp -= len;
diff --git a/arch/sparc/include/asm/ptrace.h b/arch/sparc/include/asm/ptrace.h
index 1e8b81802263..bdfafd7af46f 100644
--- a/arch/sparc/include/asm/ptrace.h
+++ b/arch/sparc/include/asm/ptrace.h
@@ -45,7 +45,18 @@ struct global_reg_snapshot {
45 struct thread_info *thread; 45 struct thread_info *thread;
46 unsigned long pad1; 46 unsigned long pad1;
47}; 47};
48extern struct global_reg_snapshot global_reg_snapshot[NR_CPUS]; 48
49struct global_pmu_snapshot {
50 unsigned long pcr[4];
51 unsigned long pic[4];
52};
53
54union global_cpu_snapshot {
55 struct global_reg_snapshot reg;
56 struct global_pmu_snapshot pmu;
57};
58
59extern union global_cpu_snapshot global_cpu_snapshot[NR_CPUS];
49 60
50#define force_successful_syscall_return() set_thread_noerror(1) 61#define force_successful_syscall_return() set_thread_noerror(1)
51#define user_mode(regs) (!((regs)->tstate & TSTATE_PRIV)) 62#define user_mode(regs) (!((regs)->tstate & TSTATE_PRIV))
diff --git a/arch/sparc/include/asm/smp_64.h b/arch/sparc/include/asm/smp_64.h
index 29862a9e9065..dd3bef4b9896 100644
--- a/arch/sparc/include/asm/smp_64.h
+++ b/arch/sparc/include/asm/smp_64.h
@@ -48,6 +48,7 @@ extern void smp_fill_in_sib_core_maps(void);
48extern void cpu_play_dead(void); 48extern void cpu_play_dead(void);
49 49
50extern void smp_fetch_global_regs(void); 50extern void smp_fetch_global_regs(void);
51extern void smp_fetch_global_pmu(void);
51 52
52struct seq_file; 53struct seq_file;
53void smp_bogo(struct seq_file *); 54void smp_bogo(struct seq_file *);
@@ -65,6 +66,7 @@ extern void __cpu_die(unsigned int cpu);
65#define hard_smp_processor_id() 0 66#define hard_smp_processor_id() 0
66#define smp_fill_in_sib_core_maps() do { } while (0) 67#define smp_fill_in_sib_core_maps() do { } while (0)
67#define smp_fetch_global_regs() do { } while (0) 68#define smp_fetch_global_regs() do { } while (0)
69#define smp_fetch_global_pmu() do { } while (0)
68 70
69#endif /* !(CONFIG_SMP) */ 71#endif /* !(CONFIG_SMP) */
70 72
diff --git a/arch/sparc/include/asm/thread_info_64.h b/arch/sparc/include/asm/thread_info_64.h
index ea2ba22d595a..269bd92313df 100644
--- a/arch/sparc/include/asm/thread_info_64.h
+++ b/arch/sparc/include/asm/thread_info_64.h
@@ -258,6 +258,11 @@ static inline bool test_and_clear_restore_sigmask(void)
258 258
259#define tsk_is_polling(t) test_tsk_thread_flag(t, TIF_POLLING_NRFLAG) 259#define tsk_is_polling(t) test_tsk_thread_flag(t, TIF_POLLING_NRFLAG)
260 260
261#define thread32_stack_is_64bit(__SP) (((__SP) & 0x1) != 0)
262#define test_thread_64bit_stack(__SP) \
263 ((test_thread_flag(TIF_32BIT) && !thread32_stack_is_64bit(__SP)) ? \
264 false : true)
265
261#endif /* !__ASSEMBLY__ */ 266#endif /* !__ASSEMBLY__ */
262 267
263#endif /* __KERNEL__ */ 268#endif /* __KERNEL__ */
diff --git a/arch/sparc/include/asm/ttable.h b/arch/sparc/include/asm/ttable.h
index 48f2807d3265..71b5a67522ab 100644
--- a/arch/sparc/include/asm/ttable.h
+++ b/arch/sparc/include/asm/ttable.h
@@ -372,7 +372,9 @@ etrap_spill_fixup_64bit: \
372 372
373/* Normal 32bit spill */ 373/* Normal 32bit spill */
374#define SPILL_2_GENERIC(ASI) \ 374#define SPILL_2_GENERIC(ASI) \
375 srl %sp, 0, %sp; \ 375 and %sp, 1, %g3; \
376 brnz,pn %g3, (. - (128 + 4)); \
377 srl %sp, 0, %sp; \
376 stwa %l0, [%sp + %g0] ASI; \ 378 stwa %l0, [%sp + %g0] ASI; \
377 mov 0x04, %g3; \ 379 mov 0x04, %g3; \
378 stwa %l1, [%sp + %g3] ASI; \ 380 stwa %l1, [%sp + %g3] ASI; \
@@ -398,14 +400,16 @@ etrap_spill_fixup_64bit: \
398 stwa %i6, [%g1 + %g0] ASI; \ 400 stwa %i6, [%g1 + %g0] ASI; \
399 stwa %i7, [%g1 + %g3] ASI; \ 401 stwa %i7, [%g1 + %g3] ASI; \
400 saved; \ 402 saved; \
401 retry; nop; nop; \ 403 retry; \
402 b,a,pt %xcc, spill_fixup_dax; \ 404 b,a,pt %xcc, spill_fixup_dax; \
403 b,a,pt %xcc, spill_fixup_mna; \ 405 b,a,pt %xcc, spill_fixup_mna; \
404 b,a,pt %xcc, spill_fixup; 406 b,a,pt %xcc, spill_fixup;
405 407
406#define SPILL_2_GENERIC_ETRAP \ 408#define SPILL_2_GENERIC_ETRAP \
407etrap_user_spill_32bit: \ 409etrap_user_spill_32bit: \
408 srl %sp, 0, %sp; \ 410 and %sp, 1, %g3; \
411 brnz,pn %g3, etrap_user_spill_64bit; \
412 srl %sp, 0, %sp; \
409 stwa %l0, [%sp + 0x00] %asi; \ 413 stwa %l0, [%sp + 0x00] %asi; \
410 stwa %l1, [%sp + 0x04] %asi; \ 414 stwa %l1, [%sp + 0x04] %asi; \
411 stwa %l2, [%sp + 0x08] %asi; \ 415 stwa %l2, [%sp + 0x08] %asi; \
@@ -427,7 +431,7 @@ etrap_user_spill_32bit: \
427 ba,pt %xcc, etrap_save; \ 431 ba,pt %xcc, etrap_save; \
428 wrpr %g1, %cwp; \ 432 wrpr %g1, %cwp; \
429 nop; nop; nop; nop; \ 433 nop; nop; nop; nop; \
430 nop; nop; nop; nop; \ 434 nop; nop; \
431 ba,a,pt %xcc, etrap_spill_fixup_32bit; \ 435 ba,a,pt %xcc, etrap_spill_fixup_32bit; \
432 ba,a,pt %xcc, etrap_spill_fixup_32bit; \ 436 ba,a,pt %xcc, etrap_spill_fixup_32bit; \
433 ba,a,pt %xcc, etrap_spill_fixup_32bit; 437 ba,a,pt %xcc, etrap_spill_fixup_32bit;
@@ -592,7 +596,9 @@ user_rtt_fill_64bit: \
592 596
593/* Normal 32bit fill */ 597/* Normal 32bit fill */
594#define FILL_2_GENERIC(ASI) \ 598#define FILL_2_GENERIC(ASI) \
595 srl %sp, 0, %sp; \ 599 and %sp, 1, %g3; \
600 brnz,pn %g3, (. - (128 + 4)); \
601 srl %sp, 0, %sp; \
596 lduwa [%sp + %g0] ASI, %l0; \ 602 lduwa [%sp + %g0] ASI, %l0; \
597 mov 0x04, %g2; \ 603 mov 0x04, %g2; \
598 mov 0x08, %g3; \ 604 mov 0x08, %g3; \
@@ -616,14 +622,16 @@ user_rtt_fill_64bit: \
616 lduwa [%g1 + %g3] ASI, %i6; \ 622 lduwa [%g1 + %g3] ASI, %i6; \
617 lduwa [%g1 + %g5] ASI, %i7; \ 623 lduwa [%g1 + %g5] ASI, %i7; \
618 restored; \ 624 restored; \
619 retry; nop; nop; nop; nop; \ 625 retry; nop; nop; \
620 b,a,pt %xcc, fill_fixup_dax; \ 626 b,a,pt %xcc, fill_fixup_dax; \
621 b,a,pt %xcc, fill_fixup_mna; \ 627 b,a,pt %xcc, fill_fixup_mna; \
622 b,a,pt %xcc, fill_fixup; 628 b,a,pt %xcc, fill_fixup;
623 629
624#define FILL_2_GENERIC_RTRAP \ 630#define FILL_2_GENERIC_RTRAP \
625user_rtt_fill_32bit: \ 631user_rtt_fill_32bit: \
626 srl %sp, 0, %sp; \ 632 and %sp, 1, %g3; \
633 brnz,pn %g3, user_rtt_fill_64bit; \
634 srl %sp, 0, %sp; \
627 lduwa [%sp + 0x00] %asi, %l0; \ 635 lduwa [%sp + 0x00] %asi, %l0; \
628 lduwa [%sp + 0x04] %asi, %l1; \ 636 lduwa [%sp + 0x04] %asi, %l1; \
629 lduwa [%sp + 0x08] %asi, %l2; \ 637 lduwa [%sp + 0x08] %asi, %l2; \
@@ -643,7 +651,7 @@ user_rtt_fill_32bit: \
643 ba,pt %xcc, user_rtt_pre_restore; \ 651 ba,pt %xcc, user_rtt_pre_restore; \
644 restored; \ 652 restored; \
645 nop; nop; nop; nop; nop; \ 653 nop; nop; nop; nop; nop; \
646 nop; nop; nop; nop; nop; \ 654 nop; nop; nop; \
647 ba,a,pt %xcc, user_rtt_fill_fixup; \ 655 ba,a,pt %xcc, user_rtt_fill_fixup; \
648 ba,a,pt %xcc, user_rtt_fill_fixup; \ 656 ba,a,pt %xcc, user_rtt_fill_fixup; \
649 ba,a,pt %xcc, user_rtt_fill_fixup; 657 ba,a,pt %xcc, user_rtt_fill_fixup;
diff --git a/arch/sparc/include/uapi/asm/sigcontext.h b/arch/sparc/include/uapi/asm/sigcontext.h
index e69de29bb2d1..ae5704fa77ad 100644
--- a/arch/sparc/include/uapi/asm/sigcontext.h
+++ b/arch/sparc/include/uapi/asm/sigcontext.h
@@ -0,0 +1,4 @@
1/*
2 * There isn't anything here anymore, but the file must not be empty or patch
3 * will delete it.
4 */
diff --git a/arch/sparc/include/uapi/asm/unistd.h b/arch/sparc/include/uapi/asm/unistd.h
index 8974ef7ae920..bed86a820d09 100644
--- a/arch/sparc/include/uapi/asm/unistd.h
+++ b/arch/sparc/include/uapi/asm/unistd.h
@@ -405,8 +405,12 @@
405#define __NR_setns 337 405#define __NR_setns 337
406#define __NR_process_vm_readv 338 406#define __NR_process_vm_readv 338
407#define __NR_process_vm_writev 339 407#define __NR_process_vm_writev 339
408#define __NR_kern_features 340
408 409
409#define NR_syscalls 340 410#define NR_syscalls 341
411
412/* Bitmask values returned from kern_features system call. */
413#define KERN_FEATURE_MIXED_MODE_STACK 0x00000001
410 414
411#ifdef __32bit_syscall_numbers__ 415#ifdef __32bit_syscall_numbers__
412/* Sparc 32-bit only has the "setresuid32", "getresuid32" variants, 416/* Sparc 32-bit only has the "setresuid32", "getresuid32" variants,
diff --git a/arch/sparc/kernel/perf_event.c b/arch/sparc/kernel/perf_event.c
index e48651dace1b..b5c38faa4ead 100644
--- a/arch/sparc/kernel/perf_event.c
+++ b/arch/sparc/kernel/perf_event.c
@@ -817,15 +817,17 @@ static u64 nop_for_index(int idx)
817 817
818static inline void sparc_pmu_enable_event(struct cpu_hw_events *cpuc, struct hw_perf_event *hwc, int idx) 818static inline void sparc_pmu_enable_event(struct cpu_hw_events *cpuc, struct hw_perf_event *hwc, int idx)
819{ 819{
820 u64 val, mask = mask_for_index(idx); 820 u64 enc, val, mask = mask_for_index(idx);
821 int pcr_index = 0; 821 int pcr_index = 0;
822 822
823 if (sparc_pmu->num_pcrs > 1) 823 if (sparc_pmu->num_pcrs > 1)
824 pcr_index = idx; 824 pcr_index = idx;
825 825
826 enc = perf_event_get_enc(cpuc->events[idx]);
827
826 val = cpuc->pcr[pcr_index]; 828 val = cpuc->pcr[pcr_index];
827 val &= ~mask; 829 val &= ~mask;
828 val |= hwc->config; 830 val |= event_encoding(enc, idx);
829 cpuc->pcr[pcr_index] = val; 831 cpuc->pcr[pcr_index] = val;
830 832
831 pcr_ops->write_pcr(pcr_index, cpuc->pcr[pcr_index]); 833 pcr_ops->write_pcr(pcr_index, cpuc->pcr[pcr_index]);
@@ -1738,8 +1740,6 @@ static void perf_callchain_user_64(struct perf_callchain_entry *entry,
1738{ 1740{
1739 unsigned long ufp; 1741 unsigned long ufp;
1740 1742
1741 perf_callchain_store(entry, regs->tpc);
1742
1743 ufp = regs->u_regs[UREG_I6] + STACK_BIAS; 1743 ufp = regs->u_regs[UREG_I6] + STACK_BIAS;
1744 do { 1744 do {
1745 struct sparc_stackf *usf, sf; 1745 struct sparc_stackf *usf, sf;
@@ -1760,19 +1760,27 @@ static void perf_callchain_user_32(struct perf_callchain_entry *entry,
1760{ 1760{
1761 unsigned long ufp; 1761 unsigned long ufp;
1762 1762
1763 perf_callchain_store(entry, regs->tpc);
1764
1765 ufp = regs->u_regs[UREG_I6] & 0xffffffffUL; 1763 ufp = regs->u_regs[UREG_I6] & 0xffffffffUL;
1766 do { 1764 do {
1767 struct sparc_stackf32 *usf, sf;
1768 unsigned long pc; 1765 unsigned long pc;
1769 1766
1770 usf = (struct sparc_stackf32 *) ufp; 1767 if (thread32_stack_is_64bit(ufp)) {
1771 if (__copy_from_user_inatomic(&sf, usf, sizeof(sf))) 1768 struct sparc_stackf *usf, sf;
1772 break;
1773 1769
1774 pc = sf.callers_pc; 1770 ufp += STACK_BIAS;
1775 ufp = (unsigned long)sf.fp; 1771 usf = (struct sparc_stackf *) ufp;
1772 if (__copy_from_user_inatomic(&sf, usf, sizeof(sf)))
1773 break;
1774 pc = sf.callers_pc & 0xffffffff;
1775 ufp = ((unsigned long) sf.fp) & 0xffffffff;
1776 } else {
1777 struct sparc_stackf32 *usf, sf;
1778 usf = (struct sparc_stackf32 *) ufp;
1779 if (__copy_from_user_inatomic(&sf, usf, sizeof(sf)))
1780 break;
1781 pc = sf.callers_pc;
1782 ufp = (unsigned long)sf.fp;
1783 }
1776 perf_callchain_store(entry, pc); 1784 perf_callchain_store(entry, pc);
1777 } while (entry->nr < PERF_MAX_STACK_DEPTH); 1785 } while (entry->nr < PERF_MAX_STACK_DEPTH);
1778} 1786}
@@ -1780,6 +1788,11 @@ static void perf_callchain_user_32(struct perf_callchain_entry *entry,
1780void 1788void
1781perf_callchain_user(struct perf_callchain_entry *entry, struct pt_regs *regs) 1789perf_callchain_user(struct perf_callchain_entry *entry, struct pt_regs *regs)
1782{ 1790{
1791 perf_callchain_store(entry, regs->tpc);
1792
1793 if (!current->mm)
1794 return;
1795
1783 flushw_user(); 1796 flushw_user();
1784 if (test_thread_flag(TIF_32BIT)) 1797 if (test_thread_flag(TIF_32BIT))
1785 perf_callchain_user_32(entry, regs); 1798 perf_callchain_user_32(entry, regs);
diff --git a/arch/sparc/kernel/process_64.c b/arch/sparc/kernel/process_64.c
index 6b36e879b2a0..dff54f46728d 100644
--- a/arch/sparc/kernel/process_64.c
+++ b/arch/sparc/kernel/process_64.c
@@ -27,6 +27,7 @@
27#include <linux/tick.h> 27#include <linux/tick.h>
28#include <linux/init.h> 28#include <linux/init.h>
29#include <linux/cpu.h> 29#include <linux/cpu.h>
30#include <linux/perf_event.h>
30#include <linux/elfcore.h> 31#include <linux/elfcore.h>
31#include <linux/sysrq.h> 32#include <linux/sysrq.h>
32#include <linux/nmi.h> 33#include <linux/nmi.h>
@@ -47,6 +48,7 @@
47#include <asm/syscalls.h> 48#include <asm/syscalls.h>
48#include <asm/irq_regs.h> 49#include <asm/irq_regs.h>
49#include <asm/smp.h> 50#include <asm/smp.h>
51#include <asm/pcr.h>
50 52
51#include "kstack.h" 53#include "kstack.h"
52 54
@@ -204,18 +206,22 @@ void show_regs(struct pt_regs *regs)
204 show_stack(current, (unsigned long *) regs->u_regs[UREG_FP]); 206 show_stack(current, (unsigned long *) regs->u_regs[UREG_FP]);
205} 207}
206 208
207struct global_reg_snapshot global_reg_snapshot[NR_CPUS]; 209union global_cpu_snapshot global_cpu_snapshot[NR_CPUS];
208static DEFINE_SPINLOCK(global_reg_snapshot_lock); 210static DEFINE_SPINLOCK(global_cpu_snapshot_lock);
209 211
210static void __global_reg_self(struct thread_info *tp, struct pt_regs *regs, 212static void __global_reg_self(struct thread_info *tp, struct pt_regs *regs,
211 int this_cpu) 213 int this_cpu)
212{ 214{
215 struct global_reg_snapshot *rp;
216
213 flushw_all(); 217 flushw_all();
214 218
215 global_reg_snapshot[this_cpu].tstate = regs->tstate; 219 rp = &global_cpu_snapshot[this_cpu].reg;
216 global_reg_snapshot[this_cpu].tpc = regs->tpc; 220
217 global_reg_snapshot[this_cpu].tnpc = regs->tnpc; 221 rp->tstate = regs->tstate;
218 global_reg_snapshot[this_cpu].o7 = regs->u_regs[UREG_I7]; 222 rp->tpc = regs->tpc;
223 rp->tnpc = regs->tnpc;
224 rp->o7 = regs->u_regs[UREG_I7];
219 225
220 if (regs->tstate & TSTATE_PRIV) { 226 if (regs->tstate & TSTATE_PRIV) {
221 struct reg_window *rw; 227 struct reg_window *rw;
@@ -223,17 +229,17 @@ static void __global_reg_self(struct thread_info *tp, struct pt_regs *regs,
223 rw = (struct reg_window *) 229 rw = (struct reg_window *)
224 (regs->u_regs[UREG_FP] + STACK_BIAS); 230 (regs->u_regs[UREG_FP] + STACK_BIAS);
225 if (kstack_valid(tp, (unsigned long) rw)) { 231 if (kstack_valid(tp, (unsigned long) rw)) {
226 global_reg_snapshot[this_cpu].i7 = rw->ins[7]; 232 rp->i7 = rw->ins[7];
227 rw = (struct reg_window *) 233 rw = (struct reg_window *)
228 (rw->ins[6] + STACK_BIAS); 234 (rw->ins[6] + STACK_BIAS);
229 if (kstack_valid(tp, (unsigned long) rw)) 235 if (kstack_valid(tp, (unsigned long) rw))
230 global_reg_snapshot[this_cpu].rpc = rw->ins[7]; 236 rp->rpc = rw->ins[7];
231 } 237 }
232 } else { 238 } else {
233 global_reg_snapshot[this_cpu].i7 = 0; 239 rp->i7 = 0;
234 global_reg_snapshot[this_cpu].rpc = 0; 240 rp->rpc = 0;
235 } 241 }
236 global_reg_snapshot[this_cpu].thread = tp; 242 rp->thread = tp;
237} 243}
238 244
239/* In order to avoid hangs we do not try to synchronize with the 245/* In order to avoid hangs we do not try to synchronize with the
@@ -261,9 +267,9 @@ void arch_trigger_all_cpu_backtrace(void)
261 if (!regs) 267 if (!regs)
262 regs = tp->kregs; 268 regs = tp->kregs;
263 269
264 spin_lock_irqsave(&global_reg_snapshot_lock, flags); 270 spin_lock_irqsave(&global_cpu_snapshot_lock, flags);
265 271
266 memset(global_reg_snapshot, 0, sizeof(global_reg_snapshot)); 272 memset(global_cpu_snapshot, 0, sizeof(global_cpu_snapshot));
267 273
268 this_cpu = raw_smp_processor_id(); 274 this_cpu = raw_smp_processor_id();
269 275
@@ -272,7 +278,7 @@ void arch_trigger_all_cpu_backtrace(void)
272 smp_fetch_global_regs(); 278 smp_fetch_global_regs();
273 279
274 for_each_online_cpu(cpu) { 280 for_each_online_cpu(cpu) {
275 struct global_reg_snapshot *gp = &global_reg_snapshot[cpu]; 281 struct global_reg_snapshot *gp = &global_cpu_snapshot[cpu].reg;
276 282
277 __global_reg_poll(gp); 283 __global_reg_poll(gp);
278 284
@@ -295,9 +301,9 @@ void arch_trigger_all_cpu_backtrace(void)
295 } 301 }
296 } 302 }
297 303
298 memset(global_reg_snapshot, 0, sizeof(global_reg_snapshot)); 304 memset(global_cpu_snapshot, 0, sizeof(global_cpu_snapshot));
299 305
300 spin_unlock_irqrestore(&global_reg_snapshot_lock, flags); 306 spin_unlock_irqrestore(&global_cpu_snapshot_lock, flags);
301} 307}
302 308
303#ifdef CONFIG_MAGIC_SYSRQ 309#ifdef CONFIG_MAGIC_SYSRQ
@@ -309,16 +315,90 @@ static void sysrq_handle_globreg(int key)
309 315
310static struct sysrq_key_op sparc_globalreg_op = { 316static struct sysrq_key_op sparc_globalreg_op = {
311 .handler = sysrq_handle_globreg, 317 .handler = sysrq_handle_globreg,
312 .help_msg = "Globalregs", 318 .help_msg = "global-regs(Y)",
313 .action_msg = "Show Global CPU Regs", 319 .action_msg = "Show Global CPU Regs",
314}; 320};
315 321
316static int __init sparc_globreg_init(void) 322static void __global_pmu_self(int this_cpu)
317{ 323{
318 return register_sysrq_key('y', &sparc_globalreg_op); 324 struct global_pmu_snapshot *pp;
325 int i, num;
326
327 pp = &global_cpu_snapshot[this_cpu].pmu;
328
329 num = 1;
330 if (tlb_type == hypervisor &&
331 sun4v_chip_type >= SUN4V_CHIP_NIAGARA4)
332 num = 4;
333
334 for (i = 0; i < num; i++) {
335 pp->pcr[i] = pcr_ops->read_pcr(i);
336 pp->pic[i] = pcr_ops->read_pic(i);
337 }
319} 338}
320 339
321core_initcall(sparc_globreg_init); 340static void __global_pmu_poll(struct global_pmu_snapshot *pp)
341{
342 int limit = 0;
343
344 while (!pp->pcr[0] && ++limit < 100) {
345 barrier();
346 udelay(1);
347 }
348}
349
350static void pmu_snapshot_all_cpus(void)
351{
352 unsigned long flags;
353 int this_cpu, cpu;
354
355 spin_lock_irqsave(&global_cpu_snapshot_lock, flags);
356
357 memset(global_cpu_snapshot, 0, sizeof(global_cpu_snapshot));
358
359 this_cpu = raw_smp_processor_id();
360
361 __global_pmu_self(this_cpu);
362
363 smp_fetch_global_pmu();
364
365 for_each_online_cpu(cpu) {
366 struct global_pmu_snapshot *pp = &global_cpu_snapshot[cpu].pmu;
367
368 __global_pmu_poll(pp);
369
370 printk("%c CPU[%3d]: PCR[%08lx:%08lx:%08lx:%08lx] PIC[%08lx:%08lx:%08lx:%08lx]\n",
371 (cpu == this_cpu ? '*' : ' '), cpu,
372 pp->pcr[0], pp->pcr[1], pp->pcr[2], pp->pcr[3],
373 pp->pic[0], pp->pic[1], pp->pic[2], pp->pic[3]);
374 }
375
376 memset(global_cpu_snapshot, 0, sizeof(global_cpu_snapshot));
377
378 spin_unlock_irqrestore(&global_cpu_snapshot_lock, flags);
379}
380
381static void sysrq_handle_globpmu(int key)
382{
383 pmu_snapshot_all_cpus();
384}
385
386static struct sysrq_key_op sparc_globalpmu_op = {
387 .handler = sysrq_handle_globpmu,
388 .help_msg = "global-pmu(X)",
389 .action_msg = "Show Global PMU Regs",
390};
391
392static int __init sparc_sysrq_init(void)
393{
394 int ret = register_sysrq_key('y', &sparc_globalreg_op);
395
396 if (!ret)
397 ret = register_sysrq_key('x', &sparc_globalpmu_op);
398 return ret;
399}
400
401core_initcall(sparc_sysrq_init);
322 402
323#endif 403#endif
324 404
@@ -372,13 +452,16 @@ void flush_thread(void)
372/* It's a bit more tricky when 64-bit tasks are involved... */ 452/* It's a bit more tricky when 64-bit tasks are involved... */
373static unsigned long clone_stackframe(unsigned long csp, unsigned long psp) 453static unsigned long clone_stackframe(unsigned long csp, unsigned long psp)
374{ 454{
455 bool stack_64bit = test_thread_64bit_stack(psp);
375 unsigned long fp, distance, rval; 456 unsigned long fp, distance, rval;
376 457
377 if (!(test_thread_flag(TIF_32BIT))) { 458 if (stack_64bit) {
378 csp += STACK_BIAS; 459 csp += STACK_BIAS;
379 psp += STACK_BIAS; 460 psp += STACK_BIAS;
380 __get_user(fp, &(((struct reg_window __user *)psp)->ins[6])); 461 __get_user(fp, &(((struct reg_window __user *)psp)->ins[6]));
381 fp += STACK_BIAS; 462 fp += STACK_BIAS;
463 if (test_thread_flag(TIF_32BIT))
464 fp &= 0xffffffff;
382 } else 465 } else
383 __get_user(fp, &(((struct reg_window32 __user *)psp)->ins[6])); 466 __get_user(fp, &(((struct reg_window32 __user *)psp)->ins[6]));
384 467
@@ -392,7 +475,7 @@ static unsigned long clone_stackframe(unsigned long csp, unsigned long psp)
392 rval = (csp - distance); 475 rval = (csp - distance);
393 if (copy_in_user((void __user *) rval, (void __user *) psp, distance)) 476 if (copy_in_user((void __user *) rval, (void __user *) psp, distance))
394 rval = 0; 477 rval = 0;
395 else if (test_thread_flag(TIF_32BIT)) { 478 else if (!stack_64bit) {
396 if (put_user(((u32)csp), 479 if (put_user(((u32)csp),
397 &(((struct reg_window32 __user *)rval)->ins[6]))) 480 &(((struct reg_window32 __user *)rval)->ins[6])))
398 rval = 0; 481 rval = 0;
@@ -427,18 +510,18 @@ void synchronize_user_stack(void)
427 510
428 flush_user_windows(); 511 flush_user_windows();
429 if ((window = get_thread_wsaved()) != 0) { 512 if ((window = get_thread_wsaved()) != 0) {
430 int winsize = sizeof(struct reg_window);
431 int bias = 0;
432
433 if (test_thread_flag(TIF_32BIT))
434 winsize = sizeof(struct reg_window32);
435 else
436 bias = STACK_BIAS;
437
438 window -= 1; 513 window -= 1;
439 do { 514 do {
440 unsigned long sp = (t->rwbuf_stkptrs[window] + bias);
441 struct reg_window *rwin = &t->reg_window[window]; 515 struct reg_window *rwin = &t->reg_window[window];
516 int winsize = sizeof(struct reg_window);
517 unsigned long sp;
518
519 sp = t->rwbuf_stkptrs[window];
520
521 if (test_thread_64bit_stack(sp))
522 sp += STACK_BIAS;
523 else
524 winsize = sizeof(struct reg_window32);
442 525
443 if (!copy_to_user((char __user *)sp, rwin, winsize)) { 526 if (!copy_to_user((char __user *)sp, rwin, winsize)) {
444 shift_window_buffer(window, get_thread_wsaved() - 1, t); 527 shift_window_buffer(window, get_thread_wsaved() - 1, t);
@@ -464,13 +547,6 @@ void fault_in_user_windows(void)
464{ 547{
465 struct thread_info *t = current_thread_info(); 548 struct thread_info *t = current_thread_info();
466 unsigned long window; 549 unsigned long window;
467 int winsize = sizeof(struct reg_window);
468 int bias = 0;
469
470 if (test_thread_flag(TIF_32BIT))
471 winsize = sizeof(struct reg_window32);
472 else
473 bias = STACK_BIAS;
474 550
475 flush_user_windows(); 551 flush_user_windows();
476 window = get_thread_wsaved(); 552 window = get_thread_wsaved();
@@ -478,8 +554,16 @@ void fault_in_user_windows(void)
478 if (likely(window != 0)) { 554 if (likely(window != 0)) {
479 window -= 1; 555 window -= 1;
480 do { 556 do {
481 unsigned long sp = (t->rwbuf_stkptrs[window] + bias);
482 struct reg_window *rwin = &t->reg_window[window]; 557 struct reg_window *rwin = &t->reg_window[window];
558 int winsize = sizeof(struct reg_window);
559 unsigned long sp;
560
561 sp = t->rwbuf_stkptrs[window];
562
563 if (test_thread_64bit_stack(sp))
564 sp += STACK_BIAS;
565 else
566 winsize = sizeof(struct reg_window32);
483 567
484 if (unlikely(sp & 0x7UL)) 568 if (unlikely(sp & 0x7UL))
485 stack_unaligned(sp); 569 stack_unaligned(sp);
diff --git a/arch/sparc/kernel/ptrace_64.c b/arch/sparc/kernel/ptrace_64.c
index 484dabac7045..7ff45e4ba681 100644
--- a/arch/sparc/kernel/ptrace_64.c
+++ b/arch/sparc/kernel/ptrace_64.c
@@ -151,7 +151,7 @@ static int regwindow64_get(struct task_struct *target,
151{ 151{
152 unsigned long rw_addr = regs->u_regs[UREG_I6]; 152 unsigned long rw_addr = regs->u_regs[UREG_I6];
153 153
154 if (test_tsk_thread_flag(current, TIF_32BIT)) { 154 if (!test_thread_64bit_stack(rw_addr)) {
155 struct reg_window32 win32; 155 struct reg_window32 win32;
156 int i; 156 int i;
157 157
@@ -176,7 +176,7 @@ static int regwindow64_set(struct task_struct *target,
176{ 176{
177 unsigned long rw_addr = regs->u_regs[UREG_I6]; 177 unsigned long rw_addr = regs->u_regs[UREG_I6];
178 178
179 if (test_tsk_thread_flag(current, TIF_32BIT)) { 179 if (!test_thread_64bit_stack(rw_addr)) {
180 struct reg_window32 win32; 180 struct reg_window32 win32;
181 int i; 181 int i;
182 182
diff --git a/arch/sparc/kernel/smp_64.c b/arch/sparc/kernel/smp_64.c
index 781bcb10b8bd..d94b878577b7 100644
--- a/arch/sparc/kernel/smp_64.c
+++ b/arch/sparc/kernel/smp_64.c
@@ -852,6 +852,8 @@ extern unsigned long xcall_flush_tlb_mm;
852extern unsigned long xcall_flush_tlb_pending; 852extern unsigned long xcall_flush_tlb_pending;
853extern unsigned long xcall_flush_tlb_kernel_range; 853extern unsigned long xcall_flush_tlb_kernel_range;
854extern unsigned long xcall_fetch_glob_regs; 854extern unsigned long xcall_fetch_glob_regs;
855extern unsigned long xcall_fetch_glob_pmu;
856extern unsigned long xcall_fetch_glob_pmu_n4;
855extern unsigned long xcall_receive_signal; 857extern unsigned long xcall_receive_signal;
856extern unsigned long xcall_new_mmu_context_version; 858extern unsigned long xcall_new_mmu_context_version;
857#ifdef CONFIG_KGDB 859#ifdef CONFIG_KGDB
@@ -1000,6 +1002,15 @@ void smp_fetch_global_regs(void)
1000 smp_cross_call(&xcall_fetch_glob_regs, 0, 0, 0); 1002 smp_cross_call(&xcall_fetch_glob_regs, 0, 0, 0);
1001} 1003}
1002 1004
1005void smp_fetch_global_pmu(void)
1006{
1007 if (tlb_type == hypervisor &&
1008 sun4v_chip_type >= SUN4V_CHIP_NIAGARA4)
1009 smp_cross_call(&xcall_fetch_glob_pmu_n4, 0, 0, 0);
1010 else
1011 smp_cross_call(&xcall_fetch_glob_pmu, 0, 0, 0);
1012}
1013
1003/* We know that the window frames of the user have been flushed 1014/* We know that the window frames of the user have been flushed
1004 * to the stack before we get here because all callers of us 1015 * to the stack before we get here because all callers of us
1005 * are flush_tlb_*() routines, and these run after flush_cache_*() 1016 * are flush_tlb_*() routines, and these run after flush_cache_*()
diff --git a/arch/sparc/kernel/sys_sparc_64.c b/arch/sparc/kernel/sys_sparc_64.c
index adfe60ece05f..51b85feb8b97 100644
--- a/arch/sparc/kernel/sys_sparc_64.c
+++ b/arch/sparc/kernel/sys_sparc_64.c
@@ -729,3 +729,8 @@ SYSCALL_DEFINE5(rt_sigaction, int, sig, const struct sigaction __user *, act,
729 729
730 return ret; 730 return ret;
731} 731}
732
733asmlinkage long sys_kern_features(void)
734{
735 return KERN_FEATURE_MIXED_MODE_STACK;
736}
diff --git a/arch/sparc/kernel/systbls_64.S b/arch/sparc/kernel/systbls_64.S
index acad343667d0..d8b22b3266d0 100644
--- a/arch/sparc/kernel/systbls_64.S
+++ b/arch/sparc/kernel/systbls_64.S
@@ -86,6 +86,7 @@ sys_call_table32:
86 .word compat_sys_pwritev, compat_sys_rt_tgsigqueueinfo, sys_perf_event_open, compat_sys_recvmmsg, sys_fanotify_init 86 .word compat_sys_pwritev, compat_sys_rt_tgsigqueueinfo, sys_perf_event_open, compat_sys_recvmmsg, sys_fanotify_init
87/*330*/ .word sys32_fanotify_mark, sys_prlimit64, sys_name_to_handle_at, compat_sys_open_by_handle_at, compat_sys_clock_adjtime 87/*330*/ .word sys32_fanotify_mark, sys_prlimit64, sys_name_to_handle_at, compat_sys_open_by_handle_at, compat_sys_clock_adjtime
88 .word sys_syncfs, compat_sys_sendmmsg, sys_setns, compat_sys_process_vm_readv, compat_sys_process_vm_writev 88 .word sys_syncfs, compat_sys_sendmmsg, sys_setns, compat_sys_process_vm_readv, compat_sys_process_vm_writev
89/*340*/ .word sys_kern_features
89 90
90#endif /* CONFIG_COMPAT */ 91#endif /* CONFIG_COMPAT */
91 92
@@ -163,3 +164,4 @@ sys_call_table:
163 .word sys_pwritev, sys_rt_tgsigqueueinfo, sys_perf_event_open, sys_recvmmsg, sys_fanotify_init 164 .word sys_pwritev, sys_rt_tgsigqueueinfo, sys_perf_event_open, sys_recvmmsg, sys_fanotify_init
164/*330*/ .word sys_fanotify_mark, sys_prlimit64, sys_name_to_handle_at, sys_open_by_handle_at, sys_clock_adjtime 165/*330*/ .word sys_fanotify_mark, sys_prlimit64, sys_name_to_handle_at, sys_open_by_handle_at, sys_clock_adjtime
165 .word sys_syncfs, sys_sendmmsg, sys_setns, sys_process_vm_readv, sys_process_vm_writev 166 .word sys_syncfs, sys_sendmmsg, sys_setns, sys_process_vm_readv, sys_process_vm_writev
167/*340*/ .word sys_kern_features
diff --git a/arch/sparc/kernel/unaligned_64.c b/arch/sparc/kernel/unaligned_64.c
index f81d038f7340..8201c25e7669 100644
--- a/arch/sparc/kernel/unaligned_64.c
+++ b/arch/sparc/kernel/unaligned_64.c
@@ -113,21 +113,24 @@ static inline long sign_extend_imm13(long imm)
113 113
114static unsigned long fetch_reg(unsigned int reg, struct pt_regs *regs) 114static unsigned long fetch_reg(unsigned int reg, struct pt_regs *regs)
115{ 115{
116 unsigned long value; 116 unsigned long value, fp;
117 117
118 if (reg < 16) 118 if (reg < 16)
119 return (!reg ? 0 : regs->u_regs[reg]); 119 return (!reg ? 0 : regs->u_regs[reg]);
120
121 fp = regs->u_regs[UREG_FP];
122
120 if (regs->tstate & TSTATE_PRIV) { 123 if (regs->tstate & TSTATE_PRIV) {
121 struct reg_window *win; 124 struct reg_window *win;
122 win = (struct reg_window *)(regs->u_regs[UREG_FP] + STACK_BIAS); 125 win = (struct reg_window *)(fp + STACK_BIAS);
123 value = win->locals[reg - 16]; 126 value = win->locals[reg - 16];
124 } else if (test_thread_flag(TIF_32BIT)) { 127 } else if (!test_thread_64bit_stack(fp)) {
125 struct reg_window32 __user *win32; 128 struct reg_window32 __user *win32;
126 win32 = (struct reg_window32 __user *)((unsigned long)((u32)regs->u_regs[UREG_FP])); 129 win32 = (struct reg_window32 __user *)((unsigned long)((u32)fp));
127 get_user(value, &win32->locals[reg - 16]); 130 get_user(value, &win32->locals[reg - 16]);
128 } else { 131 } else {
129 struct reg_window __user *win; 132 struct reg_window __user *win;
130 win = (struct reg_window __user *)(regs->u_regs[UREG_FP] + STACK_BIAS); 133 win = (struct reg_window __user *)(fp + STACK_BIAS);
131 get_user(value, &win->locals[reg - 16]); 134 get_user(value, &win->locals[reg - 16]);
132 } 135 }
133 return value; 136 return value;
@@ -135,19 +138,24 @@ static unsigned long fetch_reg(unsigned int reg, struct pt_regs *regs)
135 138
136static unsigned long *fetch_reg_addr(unsigned int reg, struct pt_regs *regs) 139static unsigned long *fetch_reg_addr(unsigned int reg, struct pt_regs *regs)
137{ 140{
141 unsigned long fp;
142
138 if (reg < 16) 143 if (reg < 16)
139 return &regs->u_regs[reg]; 144 return &regs->u_regs[reg];
145
146 fp = regs->u_regs[UREG_FP];
147
140 if (regs->tstate & TSTATE_PRIV) { 148 if (regs->tstate & TSTATE_PRIV) {
141 struct reg_window *win; 149 struct reg_window *win;
142 win = (struct reg_window *)(regs->u_regs[UREG_FP] + STACK_BIAS); 150 win = (struct reg_window *)(fp + STACK_BIAS);
143 return &win->locals[reg - 16]; 151 return &win->locals[reg - 16];
144 } else if (test_thread_flag(TIF_32BIT)) { 152 } else if (!test_thread_64bit_stack(fp)) {
145 struct reg_window32 *win32; 153 struct reg_window32 *win32;
146 win32 = (struct reg_window32 *)((unsigned long)((u32)regs->u_regs[UREG_FP])); 154 win32 = (struct reg_window32 *)((unsigned long)((u32)fp));
147 return (unsigned long *)&win32->locals[reg - 16]; 155 return (unsigned long *)&win32->locals[reg - 16];
148 } else { 156 } else {
149 struct reg_window *win; 157 struct reg_window *win;
150 win = (struct reg_window *)(regs->u_regs[UREG_FP] + STACK_BIAS); 158 win = (struct reg_window *)(fp + STACK_BIAS);
151 return &win->locals[reg - 16]; 159 return &win->locals[reg - 16];
152 } 160 }
153} 161}
@@ -392,13 +400,15 @@ int handle_popc(u32 insn, struct pt_regs *regs)
392 if (rd) 400 if (rd)
393 regs->u_regs[rd] = ret; 401 regs->u_regs[rd] = ret;
394 } else { 402 } else {
395 if (test_thread_flag(TIF_32BIT)) { 403 unsigned long fp = regs->u_regs[UREG_FP];
404
405 if (!test_thread_64bit_stack(fp)) {
396 struct reg_window32 __user *win32; 406 struct reg_window32 __user *win32;
397 win32 = (struct reg_window32 __user *)((unsigned long)((u32)regs->u_regs[UREG_FP])); 407 win32 = (struct reg_window32 __user *)((unsigned long)((u32)fp));
398 put_user(ret, &win32->locals[rd - 16]); 408 put_user(ret, &win32->locals[rd - 16]);
399 } else { 409 } else {
400 struct reg_window __user *win; 410 struct reg_window __user *win;
401 win = (struct reg_window __user *)(regs->u_regs[UREG_FP] + STACK_BIAS); 411 win = (struct reg_window __user *)(fp + STACK_BIAS);
402 put_user(ret, &win->locals[rd - 16]); 412 put_user(ret, &win->locals[rd - 16]);
403 } 413 }
404 } 414 }
@@ -554,7 +564,7 @@ void handle_ld_nf(u32 insn, struct pt_regs *regs)
554 reg[0] = 0; 564 reg[0] = 0;
555 if ((insn & 0x780000) == 0x180000) 565 if ((insn & 0x780000) == 0x180000)
556 reg[1] = 0; 566 reg[1] = 0;
557 } else if (test_thread_flag(TIF_32BIT)) { 567 } else if (!test_thread_64bit_stack(regs->u_regs[UREG_FP])) {
558 put_user(0, (int __user *) reg); 568 put_user(0, (int __user *) reg);
559 if ((insn & 0x780000) == 0x180000) 569 if ((insn & 0x780000) == 0x180000)
560 put_user(0, ((int __user *) reg) + 1); 570 put_user(0, ((int __user *) reg) + 1);
diff --git a/arch/sparc/kernel/visemul.c b/arch/sparc/kernel/visemul.c
index 08e074b7eb6a..c096c624ac4d 100644
--- a/arch/sparc/kernel/visemul.c
+++ b/arch/sparc/kernel/visemul.c
@@ -149,21 +149,24 @@ static inline void maybe_flush_windows(unsigned int rs1, unsigned int rs2,
149 149
150static unsigned long fetch_reg(unsigned int reg, struct pt_regs *regs) 150static unsigned long fetch_reg(unsigned int reg, struct pt_regs *regs)
151{ 151{
152 unsigned long value; 152 unsigned long value, fp;
153 153
154 if (reg < 16) 154 if (reg < 16)
155 return (!reg ? 0 : regs->u_regs[reg]); 155 return (!reg ? 0 : regs->u_regs[reg]);
156
157 fp = regs->u_regs[UREG_FP];
158
156 if (regs->tstate & TSTATE_PRIV) { 159 if (regs->tstate & TSTATE_PRIV) {
157 struct reg_window *win; 160 struct reg_window *win;
158 win = (struct reg_window *)(regs->u_regs[UREG_FP] + STACK_BIAS); 161 win = (struct reg_window *)(fp + STACK_BIAS);
159 value = win->locals[reg - 16]; 162 value = win->locals[reg - 16];
160 } else if (test_thread_flag(TIF_32BIT)) { 163 } else if (!test_thread_64bit_stack(fp)) {
161 struct reg_window32 __user *win32; 164 struct reg_window32 __user *win32;
162 win32 = (struct reg_window32 __user *)((unsigned long)((u32)regs->u_regs[UREG_FP])); 165 win32 = (struct reg_window32 __user *)((unsigned long)((u32)fp));
163 get_user(value, &win32->locals[reg - 16]); 166 get_user(value, &win32->locals[reg - 16]);
164 } else { 167 } else {
165 struct reg_window __user *win; 168 struct reg_window __user *win;
166 win = (struct reg_window __user *)(regs->u_regs[UREG_FP] + STACK_BIAS); 169 win = (struct reg_window __user *)(fp + STACK_BIAS);
167 get_user(value, &win->locals[reg - 16]); 170 get_user(value, &win->locals[reg - 16]);
168 } 171 }
169 return value; 172 return value;
@@ -172,16 +175,18 @@ static unsigned long fetch_reg(unsigned int reg, struct pt_regs *regs)
172static inline unsigned long __user *__fetch_reg_addr_user(unsigned int reg, 175static inline unsigned long __user *__fetch_reg_addr_user(unsigned int reg,
173 struct pt_regs *regs) 176 struct pt_regs *regs)
174{ 177{
178 unsigned long fp = regs->u_regs[UREG_FP];
179
175 BUG_ON(reg < 16); 180 BUG_ON(reg < 16);
176 BUG_ON(regs->tstate & TSTATE_PRIV); 181 BUG_ON(regs->tstate & TSTATE_PRIV);
177 182
178 if (test_thread_flag(TIF_32BIT)) { 183 if (!test_thread_64bit_stack(fp)) {
179 struct reg_window32 __user *win32; 184 struct reg_window32 __user *win32;
180 win32 = (struct reg_window32 __user *)((unsigned long)((u32)regs->u_regs[UREG_FP])); 185 win32 = (struct reg_window32 __user *)((unsigned long)((u32)fp));
181 return (unsigned long __user *)&win32->locals[reg - 16]; 186 return (unsigned long __user *)&win32->locals[reg - 16];
182 } else { 187 } else {
183 struct reg_window __user *win; 188 struct reg_window __user *win;
184 win = (struct reg_window __user *)(regs->u_regs[UREG_FP] + STACK_BIAS); 189 win = (struct reg_window __user *)(fp + STACK_BIAS);
185 return &win->locals[reg - 16]; 190 return &win->locals[reg - 16];
186 } 191 }
187} 192}
@@ -204,7 +209,7 @@ static void store_reg(struct pt_regs *regs, unsigned long val, unsigned long rd)
204 } else { 209 } else {
205 unsigned long __user *rd_user = __fetch_reg_addr_user(rd, regs); 210 unsigned long __user *rd_user = __fetch_reg_addr_user(rd, regs);
206 211
207 if (test_thread_flag(TIF_32BIT)) 212 if (!test_thread_64bit_stack(regs->u_regs[UREG_FP]))
208 __put_user((u32)val, (u32 __user *)rd_user); 213 __put_user((u32)val, (u32 __user *)rd_user);
209 else 214 else
210 __put_user(val, rd_user); 215 __put_user(val, rd_user);
diff --git a/arch/sparc/kernel/winfixup.S b/arch/sparc/kernel/winfixup.S
index a6b0863c27df..1e67ce958369 100644
--- a/arch/sparc/kernel/winfixup.S
+++ b/arch/sparc/kernel/winfixup.S
@@ -43,6 +43,8 @@ spill_fixup_mna:
43spill_fixup_dax: 43spill_fixup_dax:
44 TRAP_LOAD_THREAD_REG(%g6, %g1) 44 TRAP_LOAD_THREAD_REG(%g6, %g1)
45 ldx [%g6 + TI_FLAGS], %g1 45 ldx [%g6 + TI_FLAGS], %g1
46 andcc %sp, 0x1, %g0
47 movne %icc, 0, %g1
46 andcc %g1, _TIF_32BIT, %g0 48 andcc %g1, _TIF_32BIT, %g0
47 ldub [%g6 + TI_WSAVED], %g1 49 ldub [%g6 + TI_WSAVED], %g1
48 sll %g1, 3, %g3 50 sll %g1, 3, %g3
diff --git a/arch/sparc/math-emu/math_64.c b/arch/sparc/math-emu/math_64.c
index 1704068da928..034aadbff036 100644
--- a/arch/sparc/math-emu/math_64.c
+++ b/arch/sparc/math-emu/math_64.c
@@ -320,7 +320,7 @@ int do_mathemu(struct pt_regs *regs, struct fpustate *f, bool illegal_insn_trap)
320 XR = 0; 320 XR = 0;
321 else if (freg < 16) 321 else if (freg < 16)
322 XR = regs->u_regs[freg]; 322 XR = regs->u_regs[freg];
323 else if (test_thread_flag(TIF_32BIT)) { 323 else if (!test_thread_64bit_stack(regs->u_regs[UREG_FP])) {
324 struct reg_window32 __user *win32; 324 struct reg_window32 __user *win32;
325 flushw_user (); 325 flushw_user ();
326 win32 = (struct reg_window32 __user *)((unsigned long)((u32)regs->u_regs[UREG_FP])); 326 win32 = (struct reg_window32 __user *)((unsigned long)((u32)regs->u_regs[UREG_FP]));
diff --git a/arch/sparc/mm/ultra.S b/arch/sparc/mm/ultra.S
index 874162a11ceb..f8e13d421fcb 100644
--- a/arch/sparc/mm/ultra.S
+++ b/arch/sparc/mm/ultra.S
@@ -481,8 +481,8 @@ xcall_sync_tick:
481 481
482 .globl xcall_fetch_glob_regs 482 .globl xcall_fetch_glob_regs
483xcall_fetch_glob_regs: 483xcall_fetch_glob_regs:
484 sethi %hi(global_reg_snapshot), %g1 484 sethi %hi(global_cpu_snapshot), %g1
485 or %g1, %lo(global_reg_snapshot), %g1 485 or %g1, %lo(global_cpu_snapshot), %g1
486 __GET_CPUID(%g2) 486 __GET_CPUID(%g2)
487 sllx %g2, 6, %g3 487 sllx %g2, 6, %g3
488 add %g1, %g3, %g1 488 add %g1, %g3, %g1
@@ -509,6 +509,66 @@ xcall_fetch_glob_regs:
509 stx %g3, [%g1 + GR_SNAP_THREAD] 509 stx %g3, [%g1 + GR_SNAP_THREAD]
510 retry 510 retry
511 511
512 .globl xcall_fetch_glob_pmu
513xcall_fetch_glob_pmu:
514 sethi %hi(global_cpu_snapshot), %g1
515 or %g1, %lo(global_cpu_snapshot), %g1
516 __GET_CPUID(%g2)
517 sllx %g2, 6, %g3
518 add %g1, %g3, %g1
519 rd %pic, %g7
520 stx %g7, [%g1 + (4 * 8)]
521 rd %pcr, %g7
522 stx %g7, [%g1 + (0 * 8)]
523 retry
524
525 .globl xcall_fetch_glob_pmu_n4
526xcall_fetch_glob_pmu_n4:
527 sethi %hi(global_cpu_snapshot), %g1
528 or %g1, %lo(global_cpu_snapshot), %g1
529 __GET_CPUID(%g2)
530 sllx %g2, 6, %g3
531 add %g1, %g3, %g1
532
533 ldxa [%g0] ASI_PIC, %g7
534 stx %g7, [%g1 + (4 * 8)]
535 mov 0x08, %g3
536 ldxa [%g3] ASI_PIC, %g7
537 stx %g7, [%g1 + (5 * 8)]
538 mov 0x10, %g3
539 ldxa [%g3] ASI_PIC, %g7
540 stx %g7, [%g1 + (6 * 8)]
541 mov 0x18, %g3
542 ldxa [%g3] ASI_PIC, %g7
543 stx %g7, [%g1 + (7 * 8)]
544
545 mov %o0, %g2
546 mov %o1, %g3
547 mov %o5, %g7
548
549 mov HV_FAST_VT_GET_PERFREG, %o5
550 mov 3, %o0
551 ta HV_FAST_TRAP
552 stx %o1, [%g1 + (3 * 8)]
553 mov HV_FAST_VT_GET_PERFREG, %o5
554 mov 2, %o0
555 ta HV_FAST_TRAP
556 stx %o1, [%g1 + (2 * 8)]
557 mov HV_FAST_VT_GET_PERFREG, %o5
558 mov 1, %o0
559 ta HV_FAST_TRAP
560 stx %o1, [%g1 + (1 * 8)]
561 mov HV_FAST_VT_GET_PERFREG, %o5
562 mov 0, %o0
563 ta HV_FAST_TRAP
564 stx %o1, [%g1 + (0 * 8)]
565
566 mov %g2, %o0
567 mov %g3, %o1
568 mov %g7, %o5
569
570 retry
571
512#ifdef DCACHE_ALIASING_POSSIBLE 572#ifdef DCACHE_ALIASING_POSSIBLE
513 .align 32 573 .align 32
514 .globl xcall_flush_dcache_page_cheetah 574 .globl xcall_flush_dcache_page_cheetah