diff options
author | Jonas Bonn <jonas@southpole.se> | 2011-07-30 10:15:42 -0400 |
---|---|---|
committer | Jonas Bonn <jonas@southpole.se> | 2011-09-05 08:29:12 -0400 |
commit | d7cb6667090511755fc8bb294982783b087baef7 (patch) | |
tree | 26a3ec9893bb31dd1945f3f3db9869d590a268e3 | |
parent | 93ee7a9340d64f20295aacc3fb6a22b759323280 (diff) |
openrisc: don't use pt_regs in struct sigcontext
As it was decided not to export struct pt_regs to userspace, struct
sigcontext shouldn't be using it either. The pt_regs struct for OpenRISC
is kernel internal and the layout of the registers may change in the
future. The struct user_regs_struct is what is guaranteed to remain
stable, so struct sigcontext may use that instead.
This patch removes the usage of struct pt_regs in struct sigcontext and
makes according changes in signal.c to get the register layout right.
The usp field is removed from the sigcontext structure as this information
is already contained in the user_regs_struct.
Signed-off-by: Jonas Bonn <jonas@southpole.se>
Reviewed-by: Emilio Cota <cota@braap.org>
-rw-r--r-- | arch/openrisc/include/asm/sigcontext.h | 7 | ||||
-rw-r--r-- | arch/openrisc/kernel/signal.c | 29 |
2 files changed, 12 insertions, 24 deletions
diff --git a/arch/openrisc/include/asm/sigcontext.h b/arch/openrisc/include/asm/sigcontext.h index 54a5c50132e3..b79c2b19afbe 100644 --- a/arch/openrisc/include/asm/sigcontext.h +++ b/arch/openrisc/include/asm/sigcontext.h | |||
@@ -23,16 +23,11 @@ | |||
23 | 23 | ||
24 | /* This struct is saved by setup_frame in signal.c, to keep the current | 24 | /* This struct is saved by setup_frame in signal.c, to keep the current |
25 | context while a signal handler is executed. It's restored by sys_sigreturn. | 25 | context while a signal handler is executed. It's restored by sys_sigreturn. |
26 | |||
27 | To keep things simple, we use pt_regs here even though normally you just | ||
28 | specify the list of regs to save. Then we can use copy_from_user on the | ||
29 | entire regs instead of a bunch of get_user's as well... | ||
30 | */ | 26 | */ |
31 | 27 | ||
32 | struct sigcontext { | 28 | struct sigcontext { |
33 | struct pt_regs regs; /* needs to be first */ | 29 | struct user_regs_struct regs; /* needs to be first */ |
34 | unsigned long oldmask; | 30 | unsigned long oldmask; |
35 | unsigned long usp; /* usp before stacking this gunk on it */ | ||
36 | }; | 31 | }; |
37 | 32 | ||
38 | #endif /* __ASM_OPENRISC_SIGCONTEXT_H */ | 33 | #endif /* __ASM_OPENRISC_SIGCONTEXT_H */ |
diff --git a/arch/openrisc/kernel/signal.c b/arch/openrisc/kernel/signal.c index 5f759c76834e..95207ab0c99e 100644 --- a/arch/openrisc/kernel/signal.c +++ b/arch/openrisc/kernel/signal.c | |||
@@ -52,31 +52,25 @@ struct rt_sigframe { | |||
52 | static int restore_sigcontext(struct pt_regs *regs, struct sigcontext *sc) | 52 | static int restore_sigcontext(struct pt_regs *regs, struct sigcontext *sc) |
53 | { | 53 | { |
54 | unsigned int err = 0; | 54 | unsigned int err = 0; |
55 | unsigned long old_usp; | ||
56 | 55 | ||
57 | /* Alwys make any pending restarted system call return -EINTR */ | 56 | /* Alwys make any pending restarted system call return -EINTR */ |
58 | current_thread_info()->restart_block.fn = do_no_restart_syscall; | 57 | current_thread_info()->restart_block.fn = do_no_restart_syscall; |
59 | 58 | ||
60 | /* restore the regs from &sc->regs (same as sc, since regs is first) | 59 | /* |
60 | * Restore the regs from &sc->regs. | ||
61 | * (sc is already checked for VERIFY_READ since the sigframe was | 61 | * (sc is already checked for VERIFY_READ since the sigframe was |
62 | * checked in sys_sigreturn previously) | 62 | * checked in sys_sigreturn previously) |
63 | */ | 63 | */ |
64 | 64 | if (__copy_from_user(regs, sc->regs.gpr, 32 * sizeof(unsigned long))) | |
65 | if (__copy_from_user(regs, sc, sizeof(struct pt_regs))) | 65 | goto badframe; |
66 | if (__copy_from_user(®s->pc, &sc->regs.pc, sizeof(unsigned long))) | ||
67 | goto badframe; | ||
68 | if (__copy_from_user(®s->sr, &sc->regs.sr, sizeof(unsigned long))) | ||
66 | goto badframe; | 69 | goto badframe; |
67 | 70 | ||
68 | /* make sure the SM-bit is cleared so user-mode cannot fool us */ | 71 | /* make sure the SM-bit is cleared so user-mode cannot fool us */ |
69 | regs->sr &= ~SPR_SR_SM; | 72 | regs->sr &= ~SPR_SR_SM; |
70 | 73 | ||
71 | /* restore the old USP as it was before we stacked the sc etc. | ||
72 | * (we cannot just pop the sigcontext since we aligned the sp and | ||
73 | * stuff after pushing it) | ||
74 | */ | ||
75 | |||
76 | err |= __get_user(old_usp, &sc->usp); | ||
77 | |||
78 | regs->sp = old_usp; | ||
79 | |||
80 | /* TODO: the other ports use regs->orig_XX to disable syscall checks | 74 | /* TODO: the other ports use regs->orig_XX to disable syscall checks |
81 | * after this completes, but we don't use that mechanism. maybe we can | 75 | * after this completes, but we don't use that mechanism. maybe we can |
82 | * use it now ? | 76 | * use it now ? |
@@ -137,18 +131,17 @@ static int setup_sigcontext(struct sigcontext *sc, struct pt_regs *regs, | |||
137 | unsigned long mask) | 131 | unsigned long mask) |
138 | { | 132 | { |
139 | int err = 0; | 133 | int err = 0; |
140 | unsigned long usp = regs->sp; | ||
141 | 134 | ||
142 | /* copy the regs. they are first in sc so we can use sc directly */ | 135 | /* copy the regs */ |
143 | 136 | ||
144 | err |= __copy_to_user(sc, regs, sizeof(struct pt_regs)); | 137 | err |= __copy_to_user(sc->regs.gpr, regs, 32 * sizeof(unsigned long)); |
138 | err |= __copy_to_user(&sc->regs.pc, ®s->pc, sizeof(unsigned long)); | ||
139 | err |= __copy_to_user(&sc->regs.sr, ®s->sr, sizeof(unsigned long)); | ||
145 | 140 | ||
146 | /* then some other stuff */ | 141 | /* then some other stuff */ |
147 | 142 | ||
148 | err |= __put_user(mask, &sc->oldmask); | 143 | err |= __put_user(mask, &sc->oldmask); |
149 | 144 | ||
150 | err |= __put_user(usp, &sc->usp); | ||
151 | |||
152 | return err; | 145 | return err; |
153 | } | 146 | } |
154 | 147 | ||