aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorHiroshi Shimamoto <h-shimamoto@ct.jp.nec.com>2008-10-03 01:09:20 -0400
committerIngo Molnar <mingo@elte.hu>2008-10-03 04:09:12 -0400
commita2e8d3dcfd420177aaa0c53aca60a869bad75f4b (patch)
tree9eab473a9aa2dd386fed7a3cf89fe4dfc683b68c /arch
parent7b9cee16ffb495558c1e3ada55cba906e520006e (diff)
x86: signal: move macros out from restore_sigcontext()
move macros, COPY, COPY_SEG*, GET_SEG, out from restore_sigcontext(). x86_64: introduce COPY_SEG_STRICT for cs. Signed-off-by: Hiroshi Shimamoto <h-shimamoto@ct.jp.nec.com> Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'arch')
-rw-r--r--arch/x86/kernel/signal_32.c38
-rw-r--r--arch/x86/kernel/signal_64.c18
2 files changed, 32 insertions, 24 deletions
diff --git a/arch/x86/kernel/signal_32.c b/arch/x86/kernel/signal_32.c
index 4337cd510f0a..545448b7aeba 100644
--- a/arch/x86/kernel/signal_32.c
+++ b/arch/x86/kernel/signal_32.c
@@ -113,6 +113,27 @@ asmlinkage int sys_sigaltstack(unsigned long bx)
113 return do_sigaltstack(uss, uoss, regs->sp); 113 return do_sigaltstack(uss, uoss, regs->sp);
114} 114}
115 115
116#define COPY(x) { \
117 err |= __get_user(regs->x, &sc->x); \
118}
119
120#define COPY_SEG(seg) { \
121 unsigned short tmp; \
122 err |= __get_user(tmp, &sc->seg); \
123 regs->seg = tmp; \
124}
125
126#define COPY_SEG_STRICT(seg) { \
127 unsigned short tmp; \
128 err |= __get_user(tmp, &sc->seg); \
129 regs->seg = tmp | 3; \
130}
131
132#define GET_SEG(seg) { \
133 unsigned short tmp; \
134 err |= __get_user(tmp, &sc->seg); \
135 loadsegment(seg, tmp); \
136}
116 137
117/* 138/*
118 * Do a signal return; undo the signal stack. 139 * Do a signal return; undo the signal stack.
@@ -126,23 +147,6 @@ restore_sigcontext(struct pt_regs *regs, struct sigcontext __user *sc,
126 /* Always make any pending restarted system calls return -EINTR */ 147 /* Always make any pending restarted system calls return -EINTR */
127 current_thread_info()->restart_block.fn = do_no_restart_syscall; 148 current_thread_info()->restart_block.fn = do_no_restart_syscall;
128 149
129#define COPY(x) err |= __get_user(regs->x, &sc->x)
130
131#define COPY_SEG(seg) \
132 { unsigned short tmp; \
133 err |= __get_user(tmp, &sc->seg); \
134 regs->seg = tmp; }
135
136#define COPY_SEG_STRICT(seg) \
137 { unsigned short tmp; \
138 err |= __get_user(tmp, &sc->seg); \
139 regs->seg = tmp|3; }
140
141#define GET_SEG(seg) \
142 { unsigned short tmp; \
143 err |= __get_user(tmp, &sc->seg); \
144 loadsegment(seg, tmp); }
145
146 GET_SEG(gs); 150 GET_SEG(gs);
147 COPY_SEG(fs); 151 COPY_SEG(fs);
148 COPY_SEG(es); 152 COPY_SEG(es);
diff --git a/arch/x86/kernel/signal_64.c b/arch/x86/kernel/signal_64.c
index 53f86d95985b..feff4a91d095 100644
--- a/arch/x86/kernel/signal_64.c
+++ b/arch/x86/kernel/signal_64.c
@@ -52,6 +52,16 @@ sys_sigaltstack(const stack_t __user *uss, stack_t __user *uoss,
52 return do_sigaltstack(uss, uoss, regs->sp); 52 return do_sigaltstack(uss, uoss, regs->sp);
53} 53}
54 54
55#define COPY(x) { \
56 err |= __get_user(regs->x, &sc->x); \
57}
58
59#define COPY_SEG_STRICT(seg) { \
60 unsigned short tmp; \
61 err |= __get_user(tmp, &sc->seg); \
62 regs->seg = tmp | 3; \
63}
64
55/* 65/*
56 * Do a signal return; undo the signal stack. 66 * Do a signal return; undo the signal stack.
57 */ 67 */
@@ -64,8 +74,6 @@ restore_sigcontext(struct pt_regs *regs, struct sigcontext __user *sc,
64 /* Always make any pending restarted system calls return -EINTR */ 74 /* Always make any pending restarted system calls return -EINTR */
65 current_thread_info()->restart_block.fn = do_no_restart_syscall; 75 current_thread_info()->restart_block.fn = do_no_restart_syscall;
66 76
67#define COPY(x) (err |= __get_user(regs->x, &sc->x))
68
69 COPY(di); COPY(si); COPY(bp); COPY(sp); COPY(bx); 77 COPY(di); COPY(si); COPY(bp); COPY(sp); COPY(bx);
70 COPY(dx); COPY(cx); COPY(ip); 78 COPY(dx); COPY(cx); COPY(ip);
71 COPY(r8); 79 COPY(r8);
@@ -80,11 +88,7 @@ restore_sigcontext(struct pt_regs *regs, struct sigcontext __user *sc,
80 /* Kernel saves and restores only the CS segment register on signals, 88 /* Kernel saves and restores only the CS segment register on signals,
81 * which is the bare minimum needed to allow mixed 32/64-bit code. 89 * which is the bare minimum needed to allow mixed 32/64-bit code.
82 * App's signal handler can save/restore other segments if needed. */ 90 * App's signal handler can save/restore other segments if needed. */
83 { 91 COPY_SEG_STRICT(cs);
84 unsigned cs;
85 err |= __get_user(cs, &sc->cs);
86 regs->cs = cs | 3; /* Force into user mode */
87 }
88 92
89 { 93 {
90 unsigned int tmpflags; 94 unsigned int tmpflags;