aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/kernel
diff options
context:
space:
mode:
authorDaniel Jacobowitz <drow@false.org>2006-06-24 18:46:21 -0400
committerRussell King <rmk+kernel@arm.linux.org.uk>2006-06-24 18:46:21 -0400
commit85fe068123aa11d3477ce88c7d365e233b1f2e10 (patch)
tree2b4d4a255737dc3b2bc031e0853902637250e125 /arch/arm/kernel
parentca195cfec9fff622a61b1b72534e73360747f735 (diff)
[ARM] 3648/1: Update struct ucontext layout for coprocessor registers
Patch from Daniel Jacobowitz In order for userspace to find saved coprocessor registers, move them from struct rt_sigframe into struct ucontext. Also allow space for glibc's sigset_t, so that userspace and kernelspace can use the same ucontext layout. Define the magic numbers for iWMMXt in the header file for easier reference. Include the size of the coprocessor data in the magic numbers. Also define magic numbers and layout for VFP, not yet saved. Signed-off-by: Daniel Jacobowitz <dan@codesourcery.com> Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
Diffstat (limited to 'arch/arm/kernel')
-rw-r--r--arch/arm/kernel/signal.c42
1 files changed, 11 insertions, 31 deletions
diff --git a/arch/arm/kernel/signal.c b/arch/arm/kernel/signal.c
index c0ba8afee42f..e5802bfda31d 100644
--- a/arch/arm/kernel/signal.c
+++ b/arch/arm/kernel/signal.c
@@ -134,17 +134,6 @@ sys_sigaction(int sig, const struct old_sigaction __user *act,
134 134
135#ifdef CONFIG_IWMMXT 135#ifdef CONFIG_IWMMXT
136 136
137/* iwmmxt_area is 0x98 bytes long, preceeded by 8 bytes of signature */
138#define IWMMXT_STORAGE_SIZE (0x98 + 8)
139#define IWMMXT_MAGIC0 0x12ef842a
140#define IWMMXT_MAGIC1 0x1c07ca71
141
142struct iwmmxt_sigframe {
143 unsigned long magic0;
144 unsigned long magic1;
145 unsigned long storage[0x98/4];
146};
147
148static int preserve_iwmmxt_context(struct iwmmxt_sigframe *frame) 137static int preserve_iwmmxt_context(struct iwmmxt_sigframe *frame)
149{ 138{
150 char kbuf[sizeof(*frame) + 8]; 139 char kbuf[sizeof(*frame) + 8];
@@ -152,8 +141,8 @@ static int preserve_iwmmxt_context(struct iwmmxt_sigframe *frame)
152 141
153 /* the iWMMXt context must be 64 bit aligned */ 142 /* the iWMMXt context must be 64 bit aligned */
154 kframe = (struct iwmmxt_sigframe *)((unsigned long)(kbuf + 8) & ~7); 143 kframe = (struct iwmmxt_sigframe *)((unsigned long)(kbuf + 8) & ~7);
155 kframe->magic0 = IWMMXT_MAGIC0; 144 kframe->magic = IWMMXT_MAGIC;
156 kframe->magic1 = IWMMXT_MAGIC1; 145 kframe->size = IWMMXT_STORAGE_SIZE;
157 iwmmxt_task_copy(current_thread_info(), &kframe->storage); 146 iwmmxt_task_copy(current_thread_info(), &kframe->storage);
158 return __copy_to_user(frame, kframe, sizeof(*frame)); 147 return __copy_to_user(frame, kframe, sizeof(*frame));
159} 148}
@@ -167,8 +156,8 @@ static int restore_iwmmxt_context(struct iwmmxt_sigframe *frame)
167 kframe = (struct iwmmxt_sigframe *)((unsigned long)(kbuf + 8) & ~7); 156 kframe = (struct iwmmxt_sigframe *)((unsigned long)(kbuf + 8) & ~7);
168 if (__copy_from_user(kframe, frame, sizeof(*frame))) 157 if (__copy_from_user(kframe, frame, sizeof(*frame)))
169 return -1; 158 return -1;
170 if (kframe->magic0 != IWMMXT_MAGIC0 || 159 if (kframe->magic != IWMMXT_MAGIC ||
171 kframe->magic1 != IWMMXT_MAGIC1) 160 kframe->size != IWMMXT_STORAGE_SIZE)
172 return -1; 161 return -1;
173 iwmmxt_task_restore(current_thread_info(), &kframe->storage); 162 iwmmxt_task_restore(current_thread_info(), &kframe->storage);
174 return 0; 163 return 0;
@@ -177,25 +166,11 @@ static int restore_iwmmxt_context(struct iwmmxt_sigframe *frame)
177#endif 166#endif
178 167
179/* 168/*
180 * Auxiliary signal frame. This saves stuff like FP state.
181 * The layout of this structure is not part of the user ABI.
182 */
183struct aux_sigframe {
184#ifdef CONFIG_IWMMXT
185 struct iwmmxt_sigframe iwmmxt;
186#endif
187#ifdef CONFIG_VFP
188 union vfp_state vfp;
189#endif
190};
191
192/*
193 * Do a signal return; undo the signal stack. These are aligned to 64-bit. 169 * Do a signal return; undo the signal stack. These are aligned to 64-bit.
194 */ 170 */
195struct sigframe { 171struct sigframe {
196 struct ucontext uc; 172 struct ucontext uc;
197 unsigned long retcode[2]; 173 unsigned long retcode[2];
198 struct aux_sigframe aux __attribute__((aligned(8)));
199}; 174};
200 175
201struct rt_sigframe { 176struct rt_sigframe {
@@ -205,6 +180,7 @@ struct rt_sigframe {
205 180
206static int restore_sigframe(struct pt_regs *regs, struct sigframe __user *sf) 181static int restore_sigframe(struct pt_regs *regs, struct sigframe __user *sf)
207{ 182{
183 struct aux_sigframe __user *aux;
208 sigset_t set; 184 sigset_t set;
209 int err; 185 int err;
210 186
@@ -237,9 +213,10 @@ static int restore_sigframe(struct pt_regs *regs, struct sigframe __user *sf)
237 213
238 err |= !valid_user_regs(regs); 214 err |= !valid_user_regs(regs);
239 215
216 aux = (struct aux_sigframe __user *) sf->uc.uc_regspace;
240#ifdef CONFIG_IWMMXT 217#ifdef CONFIG_IWMMXT
241 if (err == 0 && test_thread_flag(TIF_USING_IWMMXT)) 218 if (err == 0 && test_thread_flag(TIF_USING_IWMMXT))
242 err |= restore_iwmmxt_context(&sf->aux.iwmmxt); 219 err |= restore_iwmmxt_context(&aux->iwmmxt);
243#endif 220#endif
244#ifdef CONFIG_VFP 221#ifdef CONFIG_VFP
245// if (err == 0) 222// if (err == 0)
@@ -327,6 +304,7 @@ badframe:
327static int 304static int
328setup_sigframe(struct sigframe __user *sf, struct pt_regs *regs, sigset_t *set) 305setup_sigframe(struct sigframe __user *sf, struct pt_regs *regs, sigset_t *set)
329{ 306{
307 struct aux_sigframe __user *aux;
330 int err = 0; 308 int err = 0;
331 309
332 __put_user_error(regs->ARM_r0, &sf->uc.uc_mcontext.arm_r0, err); 310 __put_user_error(regs->ARM_r0, &sf->uc.uc_mcontext.arm_r0, err);
@@ -354,14 +332,16 @@ setup_sigframe(struct sigframe __user *sf, struct pt_regs *regs, sigset_t *set)
354 332
355 err |= __copy_to_user(&sf->uc.uc_sigmask, set, sizeof(*set)); 333 err |= __copy_to_user(&sf->uc.uc_sigmask, set, sizeof(*set));
356 334
335 aux = (struct aux_sigframe __user *) sf->uc.uc_regspace;
357#ifdef CONFIG_IWMMXT 336#ifdef CONFIG_IWMMXT
358 if (err == 0 && test_thread_flag(TIF_USING_IWMMXT)) 337 if (err == 0 && test_thread_flag(TIF_USING_IWMMXT))
359 err |= preserve_iwmmxt_context(&sf->aux.iwmmxt); 338 err |= preserve_iwmmxt_context(&aux->iwmmxt);
360#endif 339#endif
361#ifdef CONFIG_VFP 340#ifdef CONFIG_VFP
362// if (err == 0) 341// if (err == 0)
363// err |= vfp_save_state(&sf->aux.vfp); 342// err |= vfp_save_state(&sf->aux.vfp);
364#endif 343#endif
344 __put_user_error(0, &aux->end_magic, err);
365 345
366 return err; 346 return err;
367} 347}