aboutsummaryrefslogtreecommitdiffstats
path: root/arch/sparc
diff options
context:
space:
mode:
Diffstat (limited to 'arch/sparc')
-rw-r--r--arch/sparc/Kconfig9
-rw-r--r--arch/sparc/include/asm/io_32.h31
-rw-r--r--arch/sparc/include/asm/io_64.h31
-rw-r--r--arch/sparc/include/asm/jump_label.h2
-rw-r--r--arch/sparc/include/asm/pci_64.h2
-rw-r--r--arch/sparc/kernel/irq_32.c4
-rw-r--r--arch/sparc/kernel/leon_smp.c4
-rw-r--r--arch/sparc/kernel/ptrace_32.c57
-rw-r--r--arch/sparc/kernel/ptrace_64.c15
-rw-r--r--arch/sparc/kernel/rtrap_32.S6
-rw-r--r--arch/sparc/kernel/rtrap_64.S36
-rw-r--r--arch/sparc/mm/fault_32.c12
-rw-r--r--arch/sparc/mm/highmem.c4
13 files changed, 119 insertions, 94 deletions
diff --git a/arch/sparc/Kconfig b/arch/sparc/Kconfig
index 8e7bafc5dd0e..45d9c87d083a 100644
--- a/arch/sparc/Kconfig
+++ b/arch/sparc/Kconfig
@@ -1,9 +1,3 @@
1# For a description of the syntax of this configuration file,
2# see Documentation/kbuild/kconfig-language.txt.
3#
4
5mainmenu "Linux/SPARC Kernel Configuration"
6
7config 64BIT 1config 64BIT
8 bool "64-bit kernel" if ARCH = "sparc" 2 bool "64-bit kernel" if ARCH = "sparc"
9 default ARCH = "sparc64" 3 default ARCH = "sparc64"
@@ -28,8 +22,6 @@ config SPARC
28 select RTC_CLASS 22 select RTC_CLASS
29 select RTC_DRV_M48T59 23 select RTC_DRV_M48T59
30 select HAVE_IRQ_WORK 24 select HAVE_IRQ_WORK
31 select HAVE_PERF_EVENTS
32 select PERF_USE_VMALLOC
33 select HAVE_DMA_ATTRS 25 select HAVE_DMA_ATTRS
34 select HAVE_DMA_API_DEBUG 26 select HAVE_DMA_API_DEBUG
35 select HAVE_ARCH_JUMP_LABEL 27 select HAVE_ARCH_JUMP_LABEL
@@ -56,7 +48,6 @@ config SPARC64
56 select RTC_DRV_BQ4802 48 select RTC_DRV_BQ4802
57 select RTC_DRV_SUN4V 49 select RTC_DRV_SUN4V
58 select RTC_DRV_STARFIRE 50 select RTC_DRV_STARFIRE
59 select HAVE_IRQ_WORK
60 select HAVE_PERF_EVENTS 51 select HAVE_PERF_EVENTS
61 select PERF_USE_VMALLOC 52 select PERF_USE_VMALLOC
62 53
diff --git a/arch/sparc/include/asm/io_32.h b/arch/sparc/include/asm/io_32.h
index 2889574608db..c2ced21c9dc1 100644
--- a/arch/sparc/include/asm/io_32.h
+++ b/arch/sparc/include/asm/io_32.h
@@ -208,6 +208,21 @@ _memset_io(volatile void __iomem *dst, int c, __kernel_size_t n)
208#define memset_io(d,c,sz) _memset_io(d,c,sz) 208#define memset_io(d,c,sz) _memset_io(d,c,sz)
209 209
210static inline void 210static inline void
211_sbus_memcpy_fromio(void *dst, const volatile void __iomem *src,
212 __kernel_size_t n)
213{
214 char *d = dst;
215
216 while (n--) {
217 char tmp = sbus_readb(src);
218 *d++ = tmp;
219 src++;
220 }
221}
222
223#define sbus_memcpy_fromio(d, s, sz) _sbus_memcpy_fromio(d, s, sz)
224
225static inline void
211_memcpy_fromio(void *dst, const volatile void __iomem *src, __kernel_size_t n) 226_memcpy_fromio(void *dst, const volatile void __iomem *src, __kernel_size_t n)
212{ 227{
213 char *d = dst; 228 char *d = dst;
@@ -222,6 +237,22 @@ _memcpy_fromio(void *dst, const volatile void __iomem *src, __kernel_size_t n)
222#define memcpy_fromio(d,s,sz) _memcpy_fromio(d,s,sz) 237#define memcpy_fromio(d,s,sz) _memcpy_fromio(d,s,sz)
223 238
224static inline void 239static inline void
240_sbus_memcpy_toio(volatile void __iomem *dst, const void *src,
241 __kernel_size_t n)
242{
243 const char *s = src;
244 volatile void __iomem *d = dst;
245
246 while (n--) {
247 char tmp = *s++;
248 sbus_writeb(tmp, d);
249 d++;
250 }
251}
252
253#define sbus_memcpy_toio(d, s, sz) _sbus_memcpy_toio(d, s, sz)
254
255static inline void
225_memcpy_toio(volatile void __iomem *dst, const void *src, __kernel_size_t n) 256_memcpy_toio(volatile void __iomem *dst, const void *src, __kernel_size_t n)
226{ 257{
227 const char *s = src; 258 const char *s = src;
diff --git a/arch/sparc/include/asm/io_64.h b/arch/sparc/include/asm/io_64.h
index 9517d063c79c..9c8965415f0a 100644
--- a/arch/sparc/include/asm/io_64.h
+++ b/arch/sparc/include/asm/io_64.h
@@ -419,6 +419,21 @@ _memset_io(volatile void __iomem *dst, int c, __kernel_size_t n)
419#define memset_io(d,c,sz) _memset_io(d,c,sz) 419#define memset_io(d,c,sz) _memset_io(d,c,sz)
420 420
421static inline void 421static inline void
422_sbus_memcpy_fromio(void *dst, const volatile void __iomem *src,
423 __kernel_size_t n)
424{
425 char *d = dst;
426
427 while (n--) {
428 char tmp = sbus_readb(src);
429 *d++ = tmp;
430 src++;
431 }
432}
433
434#define sbus_memcpy_fromio(d, s, sz) _sbus_memcpy_fromio(d, s, sz)
435
436static inline void
422_memcpy_fromio(void *dst, const volatile void __iomem *src, __kernel_size_t n) 437_memcpy_fromio(void *dst, const volatile void __iomem *src, __kernel_size_t n)
423{ 438{
424 char *d = dst; 439 char *d = dst;
@@ -433,6 +448,22 @@ _memcpy_fromio(void *dst, const volatile void __iomem *src, __kernel_size_t n)
433#define memcpy_fromio(d,s,sz) _memcpy_fromio(d,s,sz) 448#define memcpy_fromio(d,s,sz) _memcpy_fromio(d,s,sz)
434 449
435static inline void 450static inline void
451_sbus_memcpy_toio(volatile void __iomem *dst, const void *src,
452 __kernel_size_t n)
453{
454 const char *s = src;
455 volatile void __iomem *d = dst;
456
457 while (n--) {
458 char tmp = *s++;
459 sbus_writeb(tmp, d);
460 d++;
461 }
462}
463
464#define sbus_memcpy_toio(d, s, sz) _sbus_memcpy_toio(d, s, sz)
465
466static inline void
436_memcpy_toio(volatile void __iomem *dst, const void *src, __kernel_size_t n) 467_memcpy_toio(volatile void __iomem *dst, const void *src, __kernel_size_t n)
437{ 468{
438 const char *s = src; 469 const char *s = src;
diff --git a/arch/sparc/include/asm/jump_label.h b/arch/sparc/include/asm/jump_label.h
index 62e66d7b2fb6..427d4684e0d2 100644
--- a/arch/sparc/include/asm/jump_label.h
+++ b/arch/sparc/include/asm/jump_label.h
@@ -4,7 +4,6 @@
4#ifdef __KERNEL__ 4#ifdef __KERNEL__
5 5
6#include <linux/types.h> 6#include <linux/types.h>
7#include <asm/system.h>
8 7
9#define JUMP_LABEL_NOP_SIZE 4 8#define JUMP_LABEL_NOP_SIZE 4
10 9
@@ -14,6 +13,7 @@
14 "nop\n\t" \ 13 "nop\n\t" \
15 "nop\n\t" \ 14 "nop\n\t" \
16 ".pushsection __jump_table, \"a\"\n\t"\ 15 ".pushsection __jump_table, \"a\"\n\t"\
16 ".align 4\n\t" \
17 ".word 1b, %l[" #label "], %c0\n\t" \ 17 ".word 1b, %l[" #label "], %c0\n\t" \
18 ".popsection \n\t" \ 18 ".popsection \n\t" \
19 : : "i" (key) : : label);\ 19 : : "i" (key) : : label);\
diff --git a/arch/sparc/include/asm/pci_64.h b/arch/sparc/include/asm/pci_64.h
index 5312782f0b5e..948b686ec089 100644
--- a/arch/sparc/include/asm/pci_64.h
+++ b/arch/sparc/include/asm/pci_64.h
@@ -38,7 +38,7 @@ static inline void pcibios_penalize_isa_irq(int irq, int active)
38 * types on sparc64. However, it requires that the device 38 * types on sparc64. However, it requires that the device
39 * can drive enough of the 64 bits. 39 * can drive enough of the 64 bits.
40 */ 40 */
41#define PCI64_REQUIRED_MASK (~(dma64_addr_t)0) 41#define PCI64_REQUIRED_MASK (~(u64)0)
42#define PCI64_ADDR_BASE 0xfffc000000000000UL 42#define PCI64_ADDR_BASE 0xfffc000000000000UL
43 43
44#ifdef CONFIG_PCI 44#ifdef CONFIG_PCI
diff --git a/arch/sparc/kernel/irq_32.c b/arch/sparc/kernel/irq_32.c
index 0116d8d10def..5ad6e5c5dbb3 100644
--- a/arch/sparc/kernel/irq_32.c
+++ b/arch/sparc/kernel/irq_32.c
@@ -365,7 +365,7 @@ static int request_fast_irq(unsigned int irq,
365 unsigned long flags; 365 unsigned long flags;
366 unsigned int cpu_irq; 366 unsigned int cpu_irq;
367 int ret; 367 int ret;
368#ifdef CONFIG_SMP 368#if defined CONFIG_SMP && !defined CONFIG_SPARC_LEON
369 struct tt_entry *trap_table; 369 struct tt_entry *trap_table;
370 extern struct tt_entry trapbase_cpu1, trapbase_cpu2, trapbase_cpu3; 370 extern struct tt_entry trapbase_cpu1, trapbase_cpu2, trapbase_cpu3;
371#endif 371#endif
@@ -425,7 +425,7 @@ static int request_fast_irq(unsigned int irq,
425 table[SP_TRAP_IRQ1+(cpu_irq-1)].inst_four = SPARC_NOP; 425 table[SP_TRAP_IRQ1+(cpu_irq-1)].inst_four = SPARC_NOP;
426 426
427 INSTANTIATE(sparc_ttable) 427 INSTANTIATE(sparc_ttable)
428#ifdef CONFIG_SMP 428#if defined CONFIG_SMP && !defined CONFIG_SPARC_LEON
429 trap_table = &trapbase_cpu1; INSTANTIATE(trap_table) 429 trap_table = &trapbase_cpu1; INSTANTIATE(trap_table)
430 trap_table = &trapbase_cpu2; INSTANTIATE(trap_table) 430 trap_table = &trapbase_cpu2; INSTANTIATE(trap_table)
431 trap_table = &trapbase_cpu3; INSTANTIATE(trap_table) 431 trap_table = &trapbase_cpu3; INSTANTIATE(trap_table)
diff --git a/arch/sparc/kernel/leon_smp.c b/arch/sparc/kernel/leon_smp.c
index e1656fc41ccb..7524689b03d2 100644
--- a/arch/sparc/kernel/leon_smp.c
+++ b/arch/sparc/kernel/leon_smp.c
@@ -56,8 +56,8 @@ void __init leon_configure_cache_smp(void);
56static inline unsigned long do_swap(volatile unsigned long *ptr, 56static inline unsigned long do_swap(volatile unsigned long *ptr,
57 unsigned long val) 57 unsigned long val)
58{ 58{
59 __asm__ __volatile__("swapa [%1] %2, %0\n\t" : "=&r"(val) 59 __asm__ __volatile__("swapa [%2] %3, %0\n\t" : "=&r"(val)
60 : "r"(ptr), "i"(ASI_LEON_DCACHE_MISS) 60 : "0"(val), "r"(ptr), "i"(ASI_LEON_DCACHE_MISS)
61 : "memory"); 61 : "memory");
62 return val; 62 return val;
63} 63}
diff --git a/arch/sparc/kernel/ptrace_32.c b/arch/sparc/kernel/ptrace_32.c
index e608f397e11f..27b9e93d0121 100644
--- a/arch/sparc/kernel/ptrace_32.c
+++ b/arch/sparc/kernel/ptrace_32.c
@@ -323,18 +323,35 @@ const struct user_regset_view *task_user_regset_view(struct task_struct *task)
323 return &user_sparc32_view; 323 return &user_sparc32_view;
324} 324}
325 325
326long arch_ptrace(struct task_struct *child, long request, long addr, long data) 326struct fps {
327 unsigned long regs[32];
328 unsigned long fsr;
329 unsigned long flags;
330 unsigned long extra;
331 unsigned long fpqd;
332 struct fq {
333 unsigned long *insnaddr;
334 unsigned long insn;
335 } fpq[16];
336};
337
338long arch_ptrace(struct task_struct *child, long request,
339 unsigned long addr, unsigned long data)
327{ 340{
328 unsigned long addr2 = current->thread.kregs->u_regs[UREG_I4]; 341 unsigned long addr2 = current->thread.kregs->u_regs[UREG_I4];
342 void __user *addr2p;
329 const struct user_regset_view *view; 343 const struct user_regset_view *view;
344 struct pt_regs __user *pregs;
345 struct fps __user *fps;
330 int ret; 346 int ret;
331 347
332 view = task_user_regset_view(current); 348 view = task_user_regset_view(current);
349 addr2p = (void __user *) addr2;
350 pregs = (struct pt_regs __user *) addr;
351 fps = (struct fps __user *) addr;
333 352
334 switch(request) { 353 switch(request) {
335 case PTRACE_GETREGS: { 354 case PTRACE_GETREGS: {
336 struct pt_regs __user *pregs = (struct pt_regs __user *) addr;
337
338 ret = copy_regset_to_user(child, view, REGSET_GENERAL, 355 ret = copy_regset_to_user(child, view, REGSET_GENERAL,
339 32 * sizeof(u32), 356 32 * sizeof(u32),
340 4 * sizeof(u32), 357 4 * sizeof(u32),
@@ -348,8 +365,6 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
348 } 365 }
349 366
350 case PTRACE_SETREGS: { 367 case PTRACE_SETREGS: {
351 struct pt_regs __user *pregs = (struct pt_regs __user *) addr;
352
353 ret = copy_regset_from_user(child, view, REGSET_GENERAL, 368 ret = copy_regset_from_user(child, view, REGSET_GENERAL,
354 32 * sizeof(u32), 369 32 * sizeof(u32),
355 4 * sizeof(u32), 370 4 * sizeof(u32),
@@ -363,19 +378,6 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
363 } 378 }
364 379
365 case PTRACE_GETFPREGS: { 380 case PTRACE_GETFPREGS: {
366 struct fps {
367 unsigned long regs[32];
368 unsigned long fsr;
369 unsigned long flags;
370 unsigned long extra;
371 unsigned long fpqd;
372 struct fq {
373 unsigned long *insnaddr;
374 unsigned long insn;
375 } fpq[16];
376 };
377 struct fps __user *fps = (struct fps __user *) addr;
378
379 ret = copy_regset_to_user(child, view, REGSET_FP, 381 ret = copy_regset_to_user(child, view, REGSET_FP,
380 0 * sizeof(u32), 382 0 * sizeof(u32),
381 32 * sizeof(u32), 383 32 * sizeof(u32),
@@ -397,19 +399,6 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
397 } 399 }
398 400
399 case PTRACE_SETFPREGS: { 401 case PTRACE_SETFPREGS: {
400 struct fps {
401 unsigned long regs[32];
402 unsigned long fsr;
403 unsigned long flags;
404 unsigned long extra;
405 unsigned long fpqd;
406 struct fq {
407 unsigned long *insnaddr;
408 unsigned long insn;
409 } fpq[16];
410 };
411 struct fps __user *fps = (struct fps __user *) addr;
412
413 ret = copy_regset_from_user(child, view, REGSET_FP, 402 ret = copy_regset_from_user(child, view, REGSET_FP,
414 0 * sizeof(u32), 403 0 * sizeof(u32),
415 32 * sizeof(u32), 404 32 * sizeof(u32),
@@ -424,8 +413,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
424 413
425 case PTRACE_READTEXT: 414 case PTRACE_READTEXT:
426 case PTRACE_READDATA: 415 case PTRACE_READDATA:
427 ret = ptrace_readdata(child, addr, 416 ret = ptrace_readdata(child, addr, addr2p, data);
428 (void __user *) addr2, data);
429 417
430 if (ret == data) 418 if (ret == data)
431 ret = 0; 419 ret = 0;
@@ -435,8 +423,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
435 423
436 case PTRACE_WRITETEXT: 424 case PTRACE_WRITETEXT:
437 case PTRACE_WRITEDATA: 425 case PTRACE_WRITEDATA:
438 ret = ptrace_writedata(child, (void __user *) addr2, 426 ret = ptrace_writedata(child, addr2p, addr, data);
439 addr, data);
440 427
441 if (ret == data) 428 if (ret == data)
442 ret = 0; 429 ret = 0;
diff --git a/arch/sparc/kernel/ptrace_64.c b/arch/sparc/kernel/ptrace_64.c
index aa90da08bf61..9ccc812bc09e 100644
--- a/arch/sparc/kernel/ptrace_64.c
+++ b/arch/sparc/kernel/ptrace_64.c
@@ -969,16 +969,19 @@ struct fps {
969 unsigned long fsr; 969 unsigned long fsr;
970}; 970};
971 971
972long arch_ptrace(struct task_struct *child, long request, long addr, long data) 972long arch_ptrace(struct task_struct *child, long request,
973 unsigned long addr, unsigned long data)
973{ 974{
974 const struct user_regset_view *view = task_user_regset_view(current); 975 const struct user_regset_view *view = task_user_regset_view(current);
975 unsigned long addr2 = task_pt_regs(current)->u_regs[UREG_I4]; 976 unsigned long addr2 = task_pt_regs(current)->u_regs[UREG_I4];
976 struct pt_regs __user *pregs; 977 struct pt_regs __user *pregs;
977 struct fps __user *fps; 978 struct fps __user *fps;
979 void __user *addr2p;
978 int ret; 980 int ret;
979 981
980 pregs = (struct pt_regs __user *) (unsigned long) addr; 982 pregs = (struct pt_regs __user *) addr;
981 fps = (struct fps __user *) (unsigned long) addr; 983 fps = (struct fps __user *) addr;
984 addr2p = (void __user *) addr2;
982 985
983 switch (request) { 986 switch (request) {
984 case PTRACE_PEEKUSR: 987 case PTRACE_PEEKUSR:
@@ -1029,8 +1032,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
1029 1032
1030 case PTRACE_READTEXT: 1033 case PTRACE_READTEXT:
1031 case PTRACE_READDATA: 1034 case PTRACE_READDATA:
1032 ret = ptrace_readdata(child, addr, 1035 ret = ptrace_readdata(child, addr, addr2p, data);
1033 (char __user *)addr2, data);
1034 if (ret == data) 1036 if (ret == data)
1035 ret = 0; 1037 ret = 0;
1036 else if (ret >= 0) 1038 else if (ret >= 0)
@@ -1039,8 +1041,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
1039 1041
1040 case PTRACE_WRITETEXT: 1042 case PTRACE_WRITETEXT:
1041 case PTRACE_WRITEDATA: 1043 case PTRACE_WRITEDATA:
1042 ret = ptrace_writedata(child, (char __user *) addr2, 1044 ret = ptrace_writedata(child, addr2p, addr, data);
1043 addr, data);
1044 if (ret == data) 1045 if (ret == data)
1045 ret = 0; 1046 ret = 0;
1046 else if (ret >= 0) 1047 else if (ret >= 0)
diff --git a/arch/sparc/kernel/rtrap_32.S b/arch/sparc/kernel/rtrap_32.S
index 4da2e1f66290..5f5f74c2c2ca 100644
--- a/arch/sparc/kernel/rtrap_32.S
+++ b/arch/sparc/kernel/rtrap_32.S
@@ -78,9 +78,9 @@ signal_p:
78 call do_notify_resume 78 call do_notify_resume
79 add %sp, STACKFRAME_SZ, %o0 ! pt_regs ptr 79 add %sp, STACKFRAME_SZ, %o0 ! pt_regs ptr
80 80
81 /* Fall through. */ 81 b signal_p
82 ld [%sp + STACKFRAME_SZ + PT_PSR], %t_psr 82 ld [%curptr + TI_FLAGS], %g2
83 clr %l6 83
84ret_trap_continue: 84ret_trap_continue:
85 sethi %hi(PSR_SYSCALL), %g1 85 sethi %hi(PSR_SYSCALL), %g1
86 andn %t_psr, %g1, %t_psr 86 andn %t_psr, %g1, %t_psr
diff --git a/arch/sparc/kernel/rtrap_64.S b/arch/sparc/kernel/rtrap_64.S
index 090b9e9ad5e3..77f1b95e0806 100644
--- a/arch/sparc/kernel/rtrap_64.S
+++ b/arch/sparc/kernel/rtrap_64.S
@@ -34,37 +34,9 @@ __handle_preemption:
34__handle_user_windows: 34__handle_user_windows:
35 call fault_in_user_windows 35 call fault_in_user_windows
36 wrpr %g0, RTRAP_PSTATE, %pstate 36 wrpr %g0, RTRAP_PSTATE, %pstate
37 wrpr %g0, RTRAP_PSTATE_IRQOFF, %pstate 37 ba,pt %xcc, __handle_preemption_continue
38 /* Redo sched+sig checks */ 38 wrpr %g0, RTRAP_PSTATE_IRQOFF, %pstate
39 ldx [%g6 + TI_FLAGS], %l0
40 andcc %l0, _TIF_NEED_RESCHED, %g0
41
42 be,pt %xcc, 1f
43 nop
44 call schedule
45 wrpr %g0, RTRAP_PSTATE, %pstate
46 wrpr %g0, RTRAP_PSTATE_IRQOFF, %pstate
47 ldx [%g6 + TI_FLAGS], %l0
48
491: andcc %l0, _TIF_DO_NOTIFY_RESUME_MASK, %g0
50 be,pt %xcc, __handle_user_windows_continue
51 nop
52 mov %l5, %o1
53 add %sp, PTREGS_OFF, %o0
54 mov %l0, %o2
55
56 call do_notify_resume
57 wrpr %g0, RTRAP_PSTATE, %pstate
58 wrpr %g0, RTRAP_PSTATE_IRQOFF, %pstate
59 /* Signal delivery can modify pt_regs tstate, so we must
60 * reload it.
61 */
62 ldx [%sp + PTREGS_OFF + PT_V9_TSTATE], %l1
63 sethi %hi(0xf << 20), %l4
64 and %l1, %l4, %l4
65 ba,pt %xcc, __handle_user_windows_continue
66 39
67 andn %l1, %l4, %l1
68__handle_userfpu: 40__handle_userfpu:
69 rd %fprs, %l5 41 rd %fprs, %l5
70 andcc %l5, FPRS_FEF, %g0 42 andcc %l5, FPRS_FEF, %g0
@@ -87,7 +59,7 @@ __handle_signal:
87 ldx [%sp + PTREGS_OFF + PT_V9_TSTATE], %l1 59 ldx [%sp + PTREGS_OFF + PT_V9_TSTATE], %l1
88 sethi %hi(0xf << 20), %l4 60 sethi %hi(0xf << 20), %l4
89 and %l1, %l4, %l4 61 and %l1, %l4, %l4
90 ba,pt %xcc, __handle_signal_continue 62 ba,pt %xcc, __handle_preemption_continue
91 andn %l1, %l4, %l1 63 andn %l1, %l4, %l1
92 64
93 /* When returning from a NMI (%pil==15) interrupt we want to 65 /* When returning from a NMI (%pil==15) interrupt we want to
@@ -177,11 +149,9 @@ __handle_preemption_continue:
177 bne,pn %xcc, __handle_preemption 149 bne,pn %xcc, __handle_preemption
178 andcc %l0, _TIF_DO_NOTIFY_RESUME_MASK, %g0 150 andcc %l0, _TIF_DO_NOTIFY_RESUME_MASK, %g0
179 bne,pn %xcc, __handle_signal 151 bne,pn %xcc, __handle_signal
180__handle_signal_continue:
181 ldub [%g6 + TI_WSAVED], %o2 152 ldub [%g6 + TI_WSAVED], %o2
182 brnz,pn %o2, __handle_user_windows 153 brnz,pn %o2, __handle_user_windows
183 nop 154 nop
184__handle_user_windows_continue:
185 sethi %hi(TSTATE_PEF), %o0 155 sethi %hi(TSTATE_PEF), %o0
186 andcc %l1, %o0, %g0 156 andcc %l1, %o0, %g0
187 157
diff --git a/arch/sparc/mm/fault_32.c b/arch/sparc/mm/fault_32.c
index bd8601601afa..5b836f5aea90 100644
--- a/arch/sparc/mm/fault_32.c
+++ b/arch/sparc/mm/fault_32.c
@@ -539,6 +539,12 @@ do_sigbus:
539 __do_fault_siginfo(BUS_ADRERR, SIGBUS, tsk->thread.kregs, address); 539 __do_fault_siginfo(BUS_ADRERR, SIGBUS, tsk->thread.kregs, address);
540} 540}
541 541
542static void check_stack_aligned(unsigned long sp)
543{
544 if (sp & 0x7UL)
545 force_sig(SIGILL, current);
546}
547
542void window_overflow_fault(void) 548void window_overflow_fault(void)
543{ 549{
544 unsigned long sp; 550 unsigned long sp;
@@ -547,6 +553,8 @@ void window_overflow_fault(void)
547 if(((sp + 0x38) & PAGE_MASK) != (sp & PAGE_MASK)) 553 if(((sp + 0x38) & PAGE_MASK) != (sp & PAGE_MASK))
548 force_user_fault(sp + 0x38, 1); 554 force_user_fault(sp + 0x38, 1);
549 force_user_fault(sp, 1); 555 force_user_fault(sp, 1);
556
557 check_stack_aligned(sp);
550} 558}
551 559
552void window_underflow_fault(unsigned long sp) 560void window_underflow_fault(unsigned long sp)
@@ -554,6 +562,8 @@ void window_underflow_fault(unsigned long sp)
554 if(((sp + 0x38) & PAGE_MASK) != (sp & PAGE_MASK)) 562 if(((sp + 0x38) & PAGE_MASK) != (sp & PAGE_MASK))
555 force_user_fault(sp + 0x38, 0); 563 force_user_fault(sp + 0x38, 0);
556 force_user_fault(sp, 0); 564 force_user_fault(sp, 0);
565
566 check_stack_aligned(sp);
557} 567}
558 568
559void window_ret_fault(struct pt_regs *regs) 569void window_ret_fault(struct pt_regs *regs)
@@ -564,4 +574,6 @@ void window_ret_fault(struct pt_regs *regs)
564 if(((sp + 0x38) & PAGE_MASK) != (sp & PAGE_MASK)) 574 if(((sp + 0x38) & PAGE_MASK) != (sp & PAGE_MASK))
565 force_user_fault(sp + 0x38, 0); 575 force_user_fault(sp + 0x38, 0);
566 force_user_fault(sp, 0); 576 force_user_fault(sp, 0);
577
578 check_stack_aligned(sp);
567} 579}
diff --git a/arch/sparc/mm/highmem.c b/arch/sparc/mm/highmem.c
index 5e50c09b7dce..4730eac0747b 100644
--- a/arch/sparc/mm/highmem.c
+++ b/arch/sparc/mm/highmem.c
@@ -75,7 +75,7 @@ void __kunmap_atomic(void *kvaddr)
75 return; 75 return;
76 } 76 }
77 77
78 type = kmap_atomic_idx_pop(); 78 type = kmap_atomic_idx();
79 79
80#ifdef CONFIG_DEBUG_HIGHMEM 80#ifdef CONFIG_DEBUG_HIGHMEM
81 { 81 {
@@ -104,6 +104,8 @@ void __kunmap_atomic(void *kvaddr)
104#endif 104#endif
105 } 105 }
106#endif 106#endif
107
108 kmap_atomic_idx_pop();
107 pagefault_enable(); 109 pagefault_enable();
108} 110}
109EXPORT_SYMBOL(__kunmap_atomic); 111EXPORT_SYMBOL(__kunmap_atomic);