aboutsummaryrefslogtreecommitdiffstats
path: root/arch/sh/kernel
diff options
context:
space:
mode:
Diffstat (limited to 'arch/sh/kernel')
-rw-r--r--arch/sh/kernel/cpu/sh5/entry.S82
-rw-r--r--arch/sh/kernel/process.c1
-rw-r--r--arch/sh/kernel/process_64.c1
-rw-r--r--arch/sh/kernel/sh_ksyms_64.c2
-rw-r--r--arch/sh/kernel/signal_32.c45
-rw-r--r--arch/sh/kernel/signal_64.c49
-rw-r--r--arch/sh/kernel/smp.c7
7 files changed, 24 insertions, 163 deletions
diff --git a/arch/sh/kernel/cpu/sh5/entry.S b/arch/sh/kernel/cpu/sh5/entry.S
index ff1f0e6e9bec..b7cf6a547f11 100644
--- a/arch/sh/kernel/cpu/sh5/entry.S
+++ b/arch/sh/kernel/cpu/sh5/entry.S
@@ -1569,86 +1569,6 @@ ___clear_user_exit:
1569#endif /* CONFIG_MMU */ 1569#endif /* CONFIG_MMU */
1570 1570
1571/* 1571/*
1572 * int __strncpy_from_user(unsigned long __dest, unsigned long __src,
1573 * int __count)
1574 *
1575 * Inputs:
1576 * (r2) target address
1577 * (r3) source address
1578 * (r4) maximum size in bytes
1579 *
1580 * Ouputs:
1581 * (*r2) copied data
1582 * (r2) -EFAULT (in case of faulting)
1583 * copied data (otherwise)
1584 */
1585 .global __strncpy_from_user
1586__strncpy_from_user:
1587 pta ___strncpy_from_user1, tr0
1588 pta ___strncpy_from_user_done, tr1
1589 or r4, ZERO, r5 /* r5 = original count */
1590 beq/u r4, r63, tr1 /* early exit if r4==0 */
1591 movi -(EFAULT), r6 /* r6 = reply, no real fixup */
1592 or ZERO, ZERO, r7 /* r7 = data, clear top byte of data */
1593
1594___strncpy_from_user1:
1595 ld.b r3, 0, r7 /* Fault address: only in reading */
1596 st.b r2, 0, r7
1597 addi r2, 1, r2
1598 addi r3, 1, r3
1599 beq/u ZERO, r7, tr1
1600 addi r4, -1, r4 /* return real number of copied bytes */
1601 bne/l ZERO, r4, tr0
1602
1603___strncpy_from_user_done:
1604 sub r5, r4, r6 /* If done, return copied */
1605
1606___strncpy_from_user_exit:
1607 or r6, ZERO, r2
1608 ptabs LINK, tr0
1609 blink tr0, ZERO
1610
1611/*
1612 * extern long __strnlen_user(const char *__s, long __n)
1613 *
1614 * Inputs:
1615 * (r2) source address
1616 * (r3) source size in bytes
1617 *
1618 * Ouputs:
1619 * (r2) -EFAULT (in case of faulting)
1620 * string length (otherwise)
1621 */
1622 .global __strnlen_user
1623__strnlen_user:
1624 pta ___strnlen_user_set_reply, tr0
1625 pta ___strnlen_user1, tr1
1626 or ZERO, ZERO, r5 /* r5 = counter */
1627 movi -(EFAULT), r6 /* r6 = reply, no real fixup */
1628 or ZERO, ZERO, r7 /* r7 = data, clear top byte of data */
1629 beq r3, ZERO, tr0
1630
1631___strnlen_user1:
1632 ldx.b r2, r5, r7 /* Fault address: only in reading */
1633 addi r3, -1, r3 /* No real fixup */
1634 addi r5, 1, r5
1635 beq r3, ZERO, tr0
1636 bne r7, ZERO, tr1
1637! The line below used to be active. This meant led to a junk byte lying between each pair
1638! of entries in the argv & envp structures in memory. Whilst the program saw the right data
1639! via the argv and envp arguments to main, it meant the 'flat' representation visible through
1640! /proc/$pid/cmdline was corrupt, causing trouble with ps, for example.
1641! addi r5, 1, r5 /* Include '\0' */
1642
1643___strnlen_user_set_reply:
1644 or r5, ZERO, r6 /* If done, return counter */
1645
1646___strnlen_user_exit:
1647 or r6, ZERO, r2
1648 ptabs LINK, tr0
1649 blink tr0, ZERO
1650
1651/*
1652 * extern long __get_user_asm_?(void *val, long addr) 1572 * extern long __get_user_asm_?(void *val, long addr)
1653 * 1573 *
1654 * Inputs: 1574 * Inputs:
@@ -1982,8 +1902,6 @@ asm_uaccess_start:
1982 .long ___copy_user2, ___copy_user_exit 1902 .long ___copy_user2, ___copy_user_exit
1983 .long ___clear_user1, ___clear_user_exit 1903 .long ___clear_user1, ___clear_user_exit
1984#endif 1904#endif
1985 .long ___strncpy_from_user1, ___strncpy_from_user_exit
1986 .long ___strnlen_user1, ___strnlen_user_exit
1987 .long ___get_user_asm_b1, ___get_user_asm_b_exit 1905 .long ___get_user_asm_b1, ___get_user_asm_b_exit
1988 .long ___get_user_asm_w1, ___get_user_asm_w_exit 1906 .long ___get_user_asm_w1, ___get_user_asm_w_exit
1989 .long ___get_user_asm_l1, ___get_user_asm_l_exit 1907 .long ___get_user_asm_l1, ___get_user_asm_l_exit
diff --git a/arch/sh/kernel/process.c b/arch/sh/kernel/process.c
index 9b7a459a4613..055d91b70305 100644
--- a/arch/sh/kernel/process.c
+++ b/arch/sh/kernel/process.c
@@ -4,6 +4,7 @@
4#include <linux/sched.h> 4#include <linux/sched.h>
5#include <linux/export.h> 5#include <linux/export.h>
6#include <linux/stackprotector.h> 6#include <linux/stackprotector.h>
7#include <asm/fpu.h>
7 8
8struct kmem_cache *task_xstate_cachep = NULL; 9struct kmem_cache *task_xstate_cachep = NULL;
9unsigned int xstate_size; 10unsigned int xstate_size;
diff --git a/arch/sh/kernel/process_64.c b/arch/sh/kernel/process_64.c
index 4264583eabac..602545b12a86 100644
--- a/arch/sh/kernel/process_64.c
+++ b/arch/sh/kernel/process_64.c
@@ -33,6 +33,7 @@
33#include <asm/switch_to.h> 33#include <asm/switch_to.h>
34 34
35struct task_struct *last_task_used_math = NULL; 35struct task_struct *last_task_used_math = NULL;
36struct pt_regs fake_swapper_regs = { 0, };
36 37
37void show_regs(struct pt_regs *regs) 38void show_regs(struct pt_regs *regs)
38{ 39{
diff --git a/arch/sh/kernel/sh_ksyms_64.c b/arch/sh/kernel/sh_ksyms_64.c
index 45afa5c51f67..26a0774f5272 100644
--- a/arch/sh/kernel/sh_ksyms_64.c
+++ b/arch/sh/kernel/sh_ksyms_64.c
@@ -32,8 +32,6 @@ EXPORT_SYMBOL(__get_user_asm_b);
32EXPORT_SYMBOL(__get_user_asm_w); 32EXPORT_SYMBOL(__get_user_asm_w);
33EXPORT_SYMBOL(__get_user_asm_l); 33EXPORT_SYMBOL(__get_user_asm_l);
34EXPORT_SYMBOL(__get_user_asm_q); 34EXPORT_SYMBOL(__get_user_asm_q);
35EXPORT_SYMBOL(__strnlen_user);
36EXPORT_SYMBOL(__strncpy_from_user);
37EXPORT_SYMBOL(__clear_user); 35EXPORT_SYMBOL(__clear_user);
38EXPORT_SYMBOL(copy_page); 36EXPORT_SYMBOL(copy_page);
39EXPORT_SYMBOL(__copy_user); 37EXPORT_SYMBOL(__copy_user);
diff --git a/arch/sh/kernel/signal_32.c b/arch/sh/kernel/signal_32.c
index cb4172c8af7d..d6b7b6154f87 100644
--- a/arch/sh/kernel/signal_32.c
+++ b/arch/sh/kernel/signal_32.c
@@ -32,8 +32,6 @@
32#include <asm/syscalls.h> 32#include <asm/syscalls.h>
33#include <asm/fpu.h> 33#include <asm/fpu.h>
34 34
35#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
36
37struct fdpic_func_descriptor { 35struct fdpic_func_descriptor {
38 unsigned long text; 36 unsigned long text;
39 unsigned long GOT; 37 unsigned long GOT;
@@ -226,7 +224,6 @@ asmlinkage int sys_sigreturn(unsigned long r4, unsigned long r5,
226 sizeof(frame->extramask)))) 224 sizeof(frame->extramask))))
227 goto badframe; 225 goto badframe;
228 226
229 sigdelsetmask(&set, ~_BLOCKABLE);
230 set_current_blocked(&set); 227 set_current_blocked(&set);
231 228
232 if (restore_sigcontext(regs, &frame->sc, &r0)) 229 if (restore_sigcontext(regs, &frame->sc, &r0))
@@ -256,7 +253,6 @@ asmlinkage int sys_rt_sigreturn(unsigned long r4, unsigned long r5,
256 if (__copy_from_user(&set, &frame->uc.uc_sigmask, sizeof(set))) 253 if (__copy_from_user(&set, &frame->uc.uc_sigmask, sizeof(set)))
257 goto badframe; 254 goto badframe;
258 255
259 sigdelsetmask(&set, ~_BLOCKABLE);
260 set_current_blocked(&set); 256 set_current_blocked(&set);
261 257
262 if (restore_sigcontext(regs, &frame->uc.uc_mcontext, &r0)) 258 if (restore_sigcontext(regs, &frame->uc.uc_mcontext, &r0))
@@ -522,10 +518,11 @@ handle_syscall_restart(unsigned long save_r0, struct pt_regs *regs,
522/* 518/*
523 * OK, we're invoking a handler 519 * OK, we're invoking a handler
524 */ 520 */
525static int 521static void
526handle_signal(unsigned long sig, struct k_sigaction *ka, siginfo_t *info, 522handle_signal(unsigned long sig, struct k_sigaction *ka, siginfo_t *info,
527 sigset_t *oldset, struct pt_regs *regs, unsigned int save_r0) 523 struct pt_regs *regs, unsigned int save_r0)
528{ 524{
525 sigset_t *oldset = sigmask_to_save();
529 int ret; 526 int ret;
530 527
531 /* Set up the stack frame */ 528 /* Set up the stack frame */
@@ -534,10 +531,10 @@ handle_signal(unsigned long sig, struct k_sigaction *ka, siginfo_t *info,
534 else 531 else
535 ret = setup_frame(sig, ka, oldset, regs); 532 ret = setup_frame(sig, ka, oldset, regs);
536 533
537 if (ret == 0) 534 if (ret)
538 block_sigmask(ka, sig); 535 return;
539 536 signal_delivered(sig, info, ka, regs,
540 return ret; 537 test_thread_flag(TIF_SINGLESTEP));
541} 538}
542 539
543/* 540/*
@@ -554,7 +551,6 @@ static void do_signal(struct pt_regs *regs, unsigned int save_r0)
554 siginfo_t info; 551 siginfo_t info;
555 int signr; 552 int signr;
556 struct k_sigaction ka; 553 struct k_sigaction ka;
557 sigset_t *oldset;
558 554
559 /* 555 /*
560 * We want the common case to go fast, which 556 * We want the common case to go fast, which
@@ -565,30 +561,12 @@ static void do_signal(struct pt_regs *regs, unsigned int save_r0)
565 if (!user_mode(regs)) 561 if (!user_mode(regs))
566 return; 562 return;
567 563
568 if (current_thread_info()->status & TS_RESTORE_SIGMASK)
569 oldset = &current->saved_sigmask;
570 else
571 oldset = &current->blocked;
572
573 signr = get_signal_to_deliver(&info, &ka, regs, NULL); 564 signr = get_signal_to_deliver(&info, &ka, regs, NULL);
574 if (signr > 0) { 565 if (signr > 0) {
575 handle_syscall_restart(save_r0, regs, &ka.sa); 566 handle_syscall_restart(save_r0, regs, &ka.sa);
576 567
577 /* Whee! Actually deliver the signal. */ 568 /* Whee! Actually deliver the signal. */
578 if (handle_signal(signr, &ka, &info, oldset, 569 handle_signal(signr, &ka, &info, regs, save_r0);
579 regs, save_r0) == 0) {
580 /*
581 * A signal was successfully delivered; the saved
582 * sigmask will have been stored in the signal frame,
583 * and will be restored by sigreturn, so we can simply
584 * clear the TS_RESTORE_SIGMASK flag
585 */
586 current_thread_info()->status &= ~TS_RESTORE_SIGMASK;
587
588 tracehook_signal_handler(signr, &info, &ka, regs,
589 test_thread_flag(TIF_SINGLESTEP));
590 }
591
592 return; 570 return;
593 } 571 }
594 572
@@ -610,10 +588,7 @@ static void do_signal(struct pt_regs *regs, unsigned int save_r0)
610 * If there's no signal to deliver, we just put the saved sigmask 588 * If there's no signal to deliver, we just put the saved sigmask
611 * back. 589 * back.
612 */ 590 */
613 if (current_thread_info()->status & TS_RESTORE_SIGMASK) { 591 restore_saved_sigmask();
614 current_thread_info()->status &= ~TS_RESTORE_SIGMASK;
615 sigprocmask(SIG_SETMASK, &current->saved_sigmask, NULL);
616 }
617} 592}
618 593
619asmlinkage void do_notify_resume(struct pt_regs *regs, unsigned int save_r0, 594asmlinkage void do_notify_resume(struct pt_regs *regs, unsigned int save_r0,
@@ -626,7 +601,5 @@ asmlinkage void do_notify_resume(struct pt_regs *regs, unsigned int save_r0,
626 if (thread_info_flags & _TIF_NOTIFY_RESUME) { 601 if (thread_info_flags & _TIF_NOTIFY_RESUME) {
627 clear_thread_flag(TIF_NOTIFY_RESUME); 602 clear_thread_flag(TIF_NOTIFY_RESUME);
628 tracehook_notify_resume(regs); 603 tracehook_notify_resume(regs);
629 if (current->replacement_session_keyring)
630 key_replace_session_keyring();
631 } 604 }
632} 605}
diff --git a/arch/sh/kernel/signal_64.c b/arch/sh/kernel/signal_64.c
index b589a354c069..6b5b3dfe886b 100644
--- a/arch/sh/kernel/signal_64.c
+++ b/arch/sh/kernel/signal_64.c
@@ -41,11 +41,9 @@
41 41
42#define DEBUG_SIG 0 42#define DEBUG_SIG 0
43 43
44#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP))) 44static void
45
46static int
47handle_signal(unsigned long sig, siginfo_t *info, struct k_sigaction *ka, 45handle_signal(unsigned long sig, siginfo_t *info, struct k_sigaction *ka,
48 sigset_t *oldset, struct pt_regs * regs); 46 struct pt_regs * regs);
49 47
50static inline void 48static inline void
51handle_syscall_restart(struct pt_regs *regs, struct sigaction *sa) 49handle_syscall_restart(struct pt_regs *regs, struct sigaction *sa)
@@ -88,7 +86,6 @@ static void do_signal(struct pt_regs *regs)
88 siginfo_t info; 86 siginfo_t info;
89 int signr; 87 int signr;
90 struct k_sigaction ka; 88 struct k_sigaction ka;
91 sigset_t *oldset;
92 89
93 /* 90 /*
94 * We want the common case to go fast, which 91 * We want the common case to go fast, which
@@ -99,28 +96,13 @@ static void do_signal(struct pt_regs *regs)
99 if (!user_mode(regs)) 96 if (!user_mode(regs))
100 return; 97 return;
101 98
102 if (current_thread_info()->status & TS_RESTORE_SIGMASK)
103 oldset = &current->saved_sigmask;
104 else
105 oldset = &current->blocked;
106
107 signr = get_signal_to_deliver(&info, &ka, regs, 0); 99 signr = get_signal_to_deliver(&info, &ka, regs, 0);
108 if (signr > 0) { 100 if (signr > 0) {
109 handle_syscall_restart(regs, &ka.sa); 101 handle_syscall_restart(regs, &ka.sa);
110 102
111 /* Whee! Actually deliver the signal. */ 103 /* Whee! Actually deliver the signal. */
112 if (handle_signal(signr, &info, &ka, oldset, regs) == 0) { 104 handle_signal(signr, &info, &ka, regs);
113 /* 105 return;
114 * If a signal was successfully delivered, the
115 * saved sigmask is in its frame, and we can
116 * clear the TS_RESTORE_SIGMASK flag.
117 */
118 current_thread_info()->status &= ~TS_RESTORE_SIGMASK;
119
120 tracehook_signal_handler(signr, &info, &ka, regs,
121 test_thread_flag(TIF_SINGLESTEP));
122 return;
123 }
124 } 106 }
125 107
126 /* Did we come from a system call? */ 108 /* Did we come from a system call? */
@@ -143,12 +125,7 @@ static void do_signal(struct pt_regs *regs)
143 } 125 }
144 126
145 /* No signal to deliver -- put the saved sigmask back */ 127 /* No signal to deliver -- put the saved sigmask back */
146 if (current_thread_info()->status & TS_RESTORE_SIGMASK) { 128 restore_saved_sigmask();
147 current_thread_info()->status &= ~TS_RESTORE_SIGMASK;
148 sigprocmask(SIG_SETMASK, &current->saved_sigmask, NULL);
149 }
150
151 return;
152} 129}
153 130
154/* 131/*
@@ -351,7 +328,6 @@ asmlinkage int sys_sigreturn(unsigned long r2, unsigned long r3,
351 sizeof(frame->extramask)))) 328 sizeof(frame->extramask))))
352 goto badframe; 329 goto badframe;
353 330
354 sigdelsetmask(&set, ~_BLOCKABLE);
355 set_current_blocked(&set); 331 set_current_blocked(&set);
356 332
357 if (restore_sigcontext(regs, &frame->sc, &ret)) 333 if (restore_sigcontext(regs, &frame->sc, &ret))
@@ -384,7 +360,6 @@ asmlinkage int sys_rt_sigreturn(unsigned long r2, unsigned long r3,
384 if (__copy_from_user(&set, &frame->uc.uc_sigmask, sizeof(set))) 360 if (__copy_from_user(&set, &frame->uc.uc_sigmask, sizeof(set)))
385 goto badframe; 361 goto badframe;
386 362
387 sigdelsetmask(&set, ~_BLOCKABLE);
388 set_current_blocked(&set); 363 set_current_blocked(&set);
389 364
390 if (restore_sigcontext(regs, &frame->uc.uc_mcontext, &ret)) 365 if (restore_sigcontext(regs, &frame->uc.uc_mcontext, &ret))
@@ -659,10 +634,11 @@ give_sigsegv:
659/* 634/*
660 * OK, we're invoking a handler 635 * OK, we're invoking a handler
661 */ 636 */
662static int 637static void
663handle_signal(unsigned long sig, siginfo_t *info, struct k_sigaction *ka, 638handle_signal(unsigned long sig, siginfo_t *info, struct k_sigaction *ka,
664 sigset_t *oldset, struct pt_regs * regs) 639 struct pt_regs * regs)
665{ 640{
641 sigset_t *oldset = sigmask_to_save();
666 int ret; 642 int ret;
667 643
668 /* Set up the stack frame */ 644 /* Set up the stack frame */
@@ -671,10 +647,11 @@ handle_signal(unsigned long sig, siginfo_t *info, struct k_sigaction *ka,
671 else 647 else
672 ret = setup_frame(sig, ka, oldset, regs); 648 ret = setup_frame(sig, ka, oldset, regs);
673 649
674 if (ret == 0) 650 if (ret)
675 block_sigmask(ka, sig); 651 return;
676 652
677 return ret; 653 signal_delivered(sig, info, ka, regs,
654 test_thread_flag(TIF_SINGLESTEP));
678} 655}
679 656
680asmlinkage void do_notify_resume(struct pt_regs *regs, unsigned long thread_info_flags) 657asmlinkage void do_notify_resume(struct pt_regs *regs, unsigned long thread_info_flags)
@@ -685,7 +662,5 @@ asmlinkage void do_notify_resume(struct pt_regs *regs, unsigned long thread_info
685 if (thread_info_flags & _TIF_NOTIFY_RESUME) { 662 if (thread_info_flags & _TIF_NOTIFY_RESUME) {
686 clear_thread_flag(TIF_NOTIFY_RESUME); 663 clear_thread_flag(TIF_NOTIFY_RESUME);
687 tracehook_notify_resume(regs); 664 tracehook_notify_resume(regs);
688 if (current->replacement_session_keyring)
689 key_replace_session_keyring();
690 } 665 }
691} 666}
diff --git a/arch/sh/kernel/smp.c b/arch/sh/kernel/smp.c
index b86e9ca79455..2062aa88af41 100644
--- a/arch/sh/kernel/smp.c
+++ b/arch/sh/kernel/smp.c
@@ -123,7 +123,6 @@ void native_play_dead(void)
123int __cpu_disable(void) 123int __cpu_disable(void)
124{ 124{
125 unsigned int cpu = smp_processor_id(); 125 unsigned int cpu = smp_processor_id();
126 struct task_struct *p;
127 int ret; 126 int ret;
128 127
129 ret = mp_ops->cpu_disable(cpu); 128 ret = mp_ops->cpu_disable(cpu);
@@ -153,11 +152,7 @@ int __cpu_disable(void)
153 flush_cache_all(); 152 flush_cache_all();
154 local_flush_tlb_all(); 153 local_flush_tlb_all();
155 154
156 read_lock(&tasklist_lock); 155 clear_tasks_mm_cpumask(cpu);
157 for_each_process(p)
158 if (p->mm)
159 cpumask_clear_cpu(cpu, mm_cpumask(p->mm));
160 read_unlock(&tasklist_lock);
161 156
162 return 0; 157 return 0;
163} 158}