diff options
author | Stephen Rothwell <sfr@canb.auug.org.au> | 2008-06-27 02:18:27 -0400 |
---|---|---|
committer | Paul Mackerras <paulus@samba.org> | 2008-06-30 21:28:59 -0400 |
commit | fcbc5a976b1cafe2e866871c86d239d57503bfd5 (patch) | |
tree | 9f9727a0d86a52ee663db438495ef25889ff6319 /arch/powerpc/kernel/signal_64.c | |
parent | 3420b5daffbf5892634fd89a04c010e71e8aeebf (diff) |
powerpc: Explicitly copy elements of pt_regs
Gcc 4.3 produced this warning:
arch/powerpc/kernel/signal_64.c: In function 'restore_sigcontext':
arch/powerpc/kernel/signal_64.c:161: warning: array subscript is above array bounds
This is caused by us copying to aliases of elements of the pt_regs
structure. Make those explicit.
This adds one extra __get_user and unrolls a loop.
Signed-off-by: Stephen Rothwell <sfr@canb.auug.org.au>
Signed-off-by: Paul Mackerras <paulus@samba.org>
Diffstat (limited to 'arch/powerpc/kernel/signal_64.c')
-rw-r--r-- | arch/powerpc/kernel/signal_64.c | 24 |
1 files changed, 12 insertions, 12 deletions
diff --git a/arch/powerpc/kernel/signal_64.c b/arch/powerpc/kernel/signal_64.c index 34f37e59bacc..6e6b01a6db5f 100644 --- a/arch/powerpc/kernel/signal_64.c +++ b/arch/powerpc/kernel/signal_64.c | |||
@@ -170,29 +170,29 @@ static long restore_sigcontext(struct pt_regs *regs, sigset_t *set, int sig, | |||
170 | #endif | 170 | #endif |
171 | unsigned long err = 0; | 171 | unsigned long err = 0; |
172 | unsigned long save_r13 = 0; | 172 | unsigned long save_r13 = 0; |
173 | elf_greg_t *gregs = (elf_greg_t *)regs; | ||
174 | unsigned long msr; | 173 | unsigned long msr; |
175 | int i; | ||
176 | 174 | ||
177 | /* If this is not a signal return, we preserve the TLS in r13 */ | 175 | /* If this is not a signal return, we preserve the TLS in r13 */ |
178 | if (!sig) | 176 | if (!sig) |
179 | save_r13 = regs->gpr[13]; | 177 | save_r13 = regs->gpr[13]; |
180 | 178 | ||
181 | /* copy everything before MSR */ | 179 | /* copy the GPRs */ |
182 | err |= __copy_from_user(regs, &sc->gp_regs, | 180 | err |= __copy_from_user(regs->gpr, sc->gp_regs, sizeof(regs->gpr)); |
183 | PT_MSR*sizeof(unsigned long)); | 181 | err |= __get_user(regs->nip, &sc->gp_regs[PT_NIP]); |
184 | |||
185 | /* get MSR separately, transfer the LE bit if doing signal return */ | 182 | /* get MSR separately, transfer the LE bit if doing signal return */ |
186 | err |= __get_user(msr, &sc->gp_regs[PT_MSR]); | 183 | err |= __get_user(msr, &sc->gp_regs[PT_MSR]); |
187 | if (sig) | 184 | if (sig) |
188 | regs->msr = (regs->msr & ~MSR_LE) | (msr & MSR_LE); | 185 | regs->msr = (regs->msr & ~MSR_LE) | (msr & MSR_LE); |
189 | 186 | err |= __get_user(regs->orig_gpr3, &sc->gp_regs[PT_ORIG_R3]); | |
187 | err |= __get_user(regs->ctr, &sc->gp_regs[PT_CTR]); | ||
188 | err |= __get_user(regs->link, &sc->gp_regs[PT_LNK]); | ||
189 | err |= __get_user(regs->xer, &sc->gp_regs[PT_XER]); | ||
190 | err |= __get_user(regs->ccr, &sc->gp_regs[PT_CCR]); | ||
190 | /* skip SOFTE */ | 191 | /* skip SOFTE */ |
191 | for (i = PT_MSR+1; i <= PT_RESULT; i++) { | 192 | err |= __get_user(regs->trap, &sc->gp_regs[PT_TRAP]); |
192 | if (i == PT_SOFTE) | 193 | err |= __get_user(regs->dar, &sc->gp_regs[PT_DAR]); |
193 | continue; | 194 | err |= __get_user(regs->dsisr, &sc->gp_regs[PT_DSISR]); |
194 | err |= __get_user(gregs[i], &sc->gp_regs[i]); | 195 | err |= __get_user(regs->result, &sc->gp_regs[PT_RESULT]); |
195 | } | ||
196 | 196 | ||
197 | if (!sig) | 197 | if (!sig) |
198 | regs->gpr[13] = save_r13; | 198 | regs->gpr[13] = save_r13; |