aboutsummaryrefslogtreecommitdiffstats
path: root/arch/ia64/kernel/signal.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/ia64/kernel/signal.c')
-rw-r--r--arch/ia64/kernel/signal.c7
1 files changed, 5 insertions, 2 deletions
diff --git a/arch/ia64/kernel/signal.c b/arch/ia64/kernel/signal.c
index 499b7e5317cf..b8a0a7d257a9 100644
--- a/arch/ia64/kernel/signal.c
+++ b/arch/ia64/kernel/signal.c
@@ -94,7 +94,7 @@ sys_sigaltstack (const stack_t __user *uss, stack_t __user *uoss, long arg2,
94static long 94static long
95restore_sigcontext (struct sigcontext __user *sc, struct sigscratch *scr) 95restore_sigcontext (struct sigcontext __user *sc, struct sigscratch *scr)
96{ 96{
97 unsigned long ip, flags, nat, um, cfm; 97 unsigned long ip, flags, nat, um, cfm, rsc;
98 long err; 98 long err;
99 99
100 /* Always make any pending restarted system calls return -EINTR */ 100 /* Always make any pending restarted system calls return -EINTR */
@@ -106,7 +106,7 @@ restore_sigcontext (struct sigcontext __user *sc, struct sigscratch *scr)
106 err |= __get_user(ip, &sc->sc_ip); /* instruction pointer */ 106 err |= __get_user(ip, &sc->sc_ip); /* instruction pointer */
107 err |= __get_user(cfm, &sc->sc_cfm); 107 err |= __get_user(cfm, &sc->sc_cfm);
108 err |= __get_user(um, &sc->sc_um); /* user mask */ 108 err |= __get_user(um, &sc->sc_um); /* user mask */
109 err |= __get_user(scr->pt.ar_rsc, &sc->sc_ar_rsc); 109 err |= __get_user(rsc, &sc->sc_ar_rsc);
110 err |= __get_user(scr->pt.ar_unat, &sc->sc_ar_unat); 110 err |= __get_user(scr->pt.ar_unat, &sc->sc_ar_unat);
111 err |= __get_user(scr->pt.ar_fpsr, &sc->sc_ar_fpsr); 111 err |= __get_user(scr->pt.ar_fpsr, &sc->sc_ar_fpsr);
112 err |= __get_user(scr->pt.ar_pfs, &sc->sc_ar_pfs); 112 err |= __get_user(scr->pt.ar_pfs, &sc->sc_ar_pfs);
@@ -119,6 +119,7 @@ restore_sigcontext (struct sigcontext __user *sc, struct sigscratch *scr)
119 err |= __copy_from_user(&scr->pt.r15, &sc->sc_gr[15], 8); /* r15 */ 119 err |= __copy_from_user(&scr->pt.r15, &sc->sc_gr[15], 8); /* r15 */
120 120
121 scr->pt.cr_ifs = cfm | (1UL << 63); 121 scr->pt.cr_ifs = cfm | (1UL << 63);
122 scr->pt.ar_rsc = rsc | (3 << 2); /* force PL3 */
122 123
123 /* establish new instruction pointer: */ 124 /* establish new instruction pointer: */
124 scr->pt.cr_iip = ip & ~0x3UL; 125 scr->pt.cr_iip = ip & ~0x3UL;
@@ -142,6 +143,7 @@ restore_sigcontext (struct sigcontext __user *sc, struct sigscratch *scr)
142 143
143 __copy_from_user(current->thread.fph, &sc->sc_fr[32], 96*16); 144 __copy_from_user(current->thread.fph, &sc->sc_fr[32], 96*16);
144 psr->mfh = 0; /* drop signal handler's fph contents... */ 145 psr->mfh = 0; /* drop signal handler's fph contents... */
146 preempt_disable();
145 if (psr->dfh) 147 if (psr->dfh)
146 ia64_drop_fpu(current); 148 ia64_drop_fpu(current);
147 else { 149 else {
@@ -149,6 +151,7 @@ restore_sigcontext (struct sigcontext __user *sc, struct sigscratch *scr)
149 __ia64_load_fpu(current->thread.fph); 151 __ia64_load_fpu(current->thread.fph);
150 ia64_set_local_fpu_owner(current); 152 ia64_set_local_fpu_owner(current);
151 } 153 }
154 preempt_enable();
152 } 155 }
153 return err; 156 return err;
154} 157}