diff options
Diffstat (limited to 'arch/ia64/kernel/signal.c')
-rw-r--r-- | arch/ia64/kernel/signal.c | 7 |
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, | |||
94 | static long | 94 | static long |
95 | restore_sigcontext (struct sigcontext __user *sc, struct sigscratch *scr) | 95 | restore_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 | } |