diff options
-rw-r--r-- | arch/powerpc/kernel/signal_32.c | 6 | ||||
-rw-r--r-- | arch/powerpc/kernel/signal_64.c | 11 |
2 files changed, 14 insertions, 3 deletions
diff --git a/arch/powerpc/kernel/signal_32.c b/arch/powerpc/kernel/signal_32.c index 6856276a91cc..d2745375f27e 100644 --- a/arch/powerpc/kernel/signal_32.c +++ b/arch/powerpc/kernel/signal_32.c @@ -699,6 +699,7 @@ static long restore_user_regs(struct pt_regs *regs, if (__copy_from_user(¤t->thread.vr_state, &sr->mc_vregs, sizeof(sr->mc_vregs))) return 1; + current->thread.used_vr = true; } else if (current->thread.used_vr) memset(¤t->thread.vr_state, 0, ELF_NVRREG * sizeof(vector128)); @@ -725,6 +726,7 @@ static long restore_user_regs(struct pt_regs *regs, */ if (copy_vsx_from_user(current, &sr->mc_vsregs)) return 1; + current->thread.used_vsr = true; } else if (current->thread.used_vsr) for (i = 0; i < 32 ; i++) current->thread.fp_state.fpr[i][TS_VSRLOWOFFSET] = 0; @@ -744,6 +746,7 @@ static long restore_user_regs(struct pt_regs *regs, if (__copy_from_user(current->thread.evr, &sr->mc_vregs, ELF_NEVRREG * sizeof(u32))) return 1; + current->thread.used_spe = true; } else if (current->thread.used_spe) memset(current->thread.evr, 0, ELF_NEVRREG * sizeof(u32)); @@ -800,6 +803,7 @@ static long restore_tm_user_regs(struct pt_regs *regs, &tm_sr->mc_vregs, sizeof(sr->mc_vregs))) return 1; + current->thread.used_vr = true; } else if (current->thread.used_vr) { memset(¤t->thread.vr_state, 0, ELF_NVRREG * sizeof(vector128)); @@ -833,6 +837,7 @@ static long restore_tm_user_regs(struct pt_regs *regs, if (copy_vsx_from_user(current, &sr->mc_vsregs) || copy_transact_vsx_from_user(current, &tm_sr->mc_vsregs)) return 1; + current->thread.used_vsr = true; } else if (current->thread.used_vsr) for (i = 0; i < 32 ; i++) { current->thread.fp_state.fpr[i][TS_VSRLOWOFFSET] = 0; @@ -849,6 +854,7 @@ static long restore_tm_user_regs(struct pt_regs *regs, if (__copy_from_user(current->thread.evr, &sr->mc_vregs, ELF_NEVRREG * sizeof(u32))) return 1; + current->thread.used_spe = true; } else if (current->thread.used_spe) memset(current->thread.evr, 0, ELF_NEVRREG * sizeof(u32)); diff --git a/arch/powerpc/kernel/signal_64.c b/arch/powerpc/kernel/signal_64.c index f08c9196f209..6faa8240b7c9 100644 --- a/arch/powerpc/kernel/signal_64.c +++ b/arch/powerpc/kernel/signal_64.c @@ -369,9 +369,11 @@ static long restore_sigcontext(struct pt_regs *regs, sigset_t *set, int sig, if (v_regs && !access_ok(VERIFY_READ, v_regs, 34 * sizeof(vector128))) return -EFAULT; /* Copy 33 vec registers (vr0..31 and vscr) from the stack */ - if (v_regs != NULL && (msr & MSR_VEC) != 0) + if (v_regs != NULL && (msr & MSR_VEC) != 0) { err |= __copy_from_user(¤t->thread.vr_state, v_regs, 33 * sizeof(vector128)); + current->thread.used_vr = true; + } else if (current->thread.used_vr) memset(¤t->thread.vr_state, 0, 33 * sizeof(vector128)); /* Always get VRSAVE back */ @@ -391,9 +393,10 @@ static long restore_sigcontext(struct pt_regs *regs, sigset_t *set, int sig, * buffer for formatting, then into the taskstruct. */ v_regs += ELF_NVRREG; - if ((msr & MSR_VSX) != 0) + if ((msr & MSR_VSX) != 0) { err |= copy_vsx_from_user(current, v_regs); - else + current->thread.used_vsr = true; + } else for (i = 0; i < 32 ; i++) current->thread.fp_state.fpr[i][TS_VSRLOWOFFSET] = 0; #endif @@ -488,6 +491,7 @@ static long restore_tm_sigcontexts(struct pt_regs *regs, 33 * sizeof(vector128)); err |= __copy_from_user(¤t->thread.transact_vr, tm_v_regs, 33 * sizeof(vector128)); + current->thread.used_vr = true; } else if (current->thread.used_vr) { memset(¤t->thread.vr_state, 0, 33 * sizeof(vector128)); @@ -521,6 +525,7 @@ static long restore_tm_sigcontexts(struct pt_regs *regs, tm_v_regs += ELF_NVRREG; err |= copy_vsx_from_user(current, v_regs); err |= copy_transact_vsx_from_user(current, tm_v_regs); + current->thread.used_vsr = true; } else { for (i = 0; i < 32 ; i++) { current->thread.fp_state.fpr[i][TS_VSRLOWOFFSET] = 0; |