Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 29623
b: refs/heads/master
c: 85fe068
h: refs/heads/master
i:
  29621: 325e189
  29619: c43bc25
  29615: 966dbeb
v: v3
  • Loading branch information
Daniel Jacobowitz authored and Russell King committed Jun 24, 2006
1 parent 6033297 commit 97c9fc7
Show file tree
Hide file tree
Showing 3 changed files with 90 additions and 33 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: ca195cfec9fff622a61b1b72534e73360747f735
refs/heads/master: 85fe068123aa11d3477ce88c7d365e233b1f2e10
42 changes: 11 additions & 31 deletions trunk/arch/arm/kernel/signal.c
Original file line number Diff line number Diff line change
Expand Up @@ -134,26 +134,15 @@ sys_sigaction(int sig, const struct old_sigaction __user *act,

#ifdef CONFIG_IWMMXT

/* iwmmxt_area is 0x98 bytes long, preceeded by 8 bytes of signature */
#define IWMMXT_STORAGE_SIZE (0x98 + 8)
#define IWMMXT_MAGIC0 0x12ef842a
#define IWMMXT_MAGIC1 0x1c07ca71

struct iwmmxt_sigframe {
unsigned long magic0;
unsigned long magic1;
unsigned long storage[0x98/4];
};

static int preserve_iwmmxt_context(struct iwmmxt_sigframe *frame)
{
char kbuf[sizeof(*frame) + 8];
struct iwmmxt_sigframe *kframe;

/* the iWMMXt context must be 64 bit aligned */
kframe = (struct iwmmxt_sigframe *)((unsigned long)(kbuf + 8) & ~7);
kframe->magic0 = IWMMXT_MAGIC0;
kframe->magic1 = IWMMXT_MAGIC1;
kframe->magic = IWMMXT_MAGIC;
kframe->size = IWMMXT_STORAGE_SIZE;
iwmmxt_task_copy(current_thread_info(), &kframe->storage);
return __copy_to_user(frame, kframe, sizeof(*frame));
}
Expand All @@ -167,35 +156,21 @@ static int restore_iwmmxt_context(struct iwmmxt_sigframe *frame)
kframe = (struct iwmmxt_sigframe *)((unsigned long)(kbuf + 8) & ~7);
if (__copy_from_user(kframe, frame, sizeof(*frame)))
return -1;
if (kframe->magic0 != IWMMXT_MAGIC0 ||
kframe->magic1 != IWMMXT_MAGIC1)
if (kframe->magic != IWMMXT_MAGIC ||
kframe->size != IWMMXT_STORAGE_SIZE)
return -1;
iwmmxt_task_restore(current_thread_info(), &kframe->storage);
return 0;
}

#endif

/*
* Auxiliary signal frame. This saves stuff like FP state.
* The layout of this structure is not part of the user ABI.
*/
struct aux_sigframe {
#ifdef CONFIG_IWMMXT
struct iwmmxt_sigframe iwmmxt;
#endif
#ifdef CONFIG_VFP
union vfp_state vfp;
#endif
};

/*
* Do a signal return; undo the signal stack. These are aligned to 64-bit.
*/
struct sigframe {
struct ucontext uc;
unsigned long retcode[2];
struct aux_sigframe aux __attribute__((aligned(8)));
};

struct rt_sigframe {
Expand All @@ -205,6 +180,7 @@ struct rt_sigframe {

static int restore_sigframe(struct pt_regs *regs, struct sigframe __user *sf)
{
struct aux_sigframe __user *aux;
sigset_t set;
int err;

Expand Down Expand Up @@ -237,9 +213,10 @@ static int restore_sigframe(struct pt_regs *regs, struct sigframe __user *sf)

err |= !valid_user_regs(regs);

aux = (struct aux_sigframe __user *) sf->uc.uc_regspace;
#ifdef CONFIG_IWMMXT
if (err == 0 && test_thread_flag(TIF_USING_IWMMXT))
err |= restore_iwmmxt_context(&sf->aux.iwmmxt);
err |= restore_iwmmxt_context(&aux->iwmmxt);
#endif
#ifdef CONFIG_VFP
// if (err == 0)
Expand Down Expand Up @@ -327,6 +304,7 @@ asmlinkage int sys_rt_sigreturn(struct pt_regs *regs)
static int
setup_sigframe(struct sigframe __user *sf, struct pt_regs *regs, sigset_t *set)
{
struct aux_sigframe __user *aux;
int err = 0;

__put_user_error(regs->ARM_r0, &sf->uc.uc_mcontext.arm_r0, err);
Expand Down Expand Up @@ -354,14 +332,16 @@ setup_sigframe(struct sigframe __user *sf, struct pt_regs *regs, sigset_t *set)

err |= __copy_to_user(&sf->uc.uc_sigmask, set, sizeof(*set));

aux = (struct aux_sigframe __user *) sf->uc.uc_regspace;
#ifdef CONFIG_IWMMXT
if (err == 0 && test_thread_flag(TIF_USING_IWMMXT))
err |= preserve_iwmmxt_context(&sf->aux.iwmmxt);
err |= preserve_iwmmxt_context(&aux->iwmmxt);
#endif
#ifdef CONFIG_VFP
// if (err == 0)
// err |= vfp_save_state(&sf->aux.vfp);
#endif
__put_user_error(0, &aux->end_magic, err);

return err;
}
Expand Down
79 changes: 78 additions & 1 deletion trunk/include/asm-arm/ucontext.h
Original file line number Diff line number Diff line change
@@ -1,12 +1,89 @@
#ifndef _ASMARM_UCONTEXT_H
#define _ASMARM_UCONTEXT_H

#include <asm/fpstate.h>

/*
* struct sigcontext only has room for the basic registers, but struct
* ucontext now has room for all registers which need to be saved and
* restored. Coprocessor registers are stored in uc_regspace. Each
* coprocessor's saved state should start with a documented 32-bit magic
* number, followed by a 32-bit word giving the coproccesor's saved size.
* uc_regspace may be expanded if necessary, although this takes some
* coordination with glibc.
*/

struct ucontext {
unsigned long uc_flags;
struct ucontext *uc_link;
stack_t uc_stack;
struct sigcontext uc_mcontext;
sigset_t uc_sigmask; /* mask last for extensibility */
sigset_t uc_sigmask;
/* Allow for uc_sigmask growth. Glibc uses a 1024-bit sigset_t. */
int __unused[32 - (sizeof (sigset_t) / sizeof (int))];
/* Last for extensibility. Eight byte aligned because some
coprocessors require eight byte alignment. */
unsigned long uc_regspace[128] __attribute__((__aligned__(8)));
};

#ifdef __KERNEL__

/*
* Coprocessor save state. The magic values and specific
* coprocessor's layouts are part of the userspace ABI. Each one of
* these should be a multiple of eight bytes and aligned to eight
* bytes, to prevent unpredictable padding in the signal frame.
*/

#ifdef CONFIG_IWMMXT
/* iwmmxt_area is 0x98 bytes long, preceeded by 8 bytes of signature */
#define IWMMXT_MAGIC 0x12ef842a
#define IWMMXT_STORAGE_SIZE (IWMMXT_SIZE + 8)

struct iwmmxt_sigframe {
unsigned long magic;
unsigned long size;
struct iwmmxt_struct storage;
} __attribute__((__aligned__(8)));
#endif /* CONFIG_IWMMXT */

#ifdef CONFIG_VFP
#if __LINUX_ARM_ARCH__ < 6
/* For ARM pre-v6, we use fstmiax and fldmiax. This adds one extra
* word after the registers, and a word of padding at the end for
* alignment. */
#define VFP_MAGIC 0x56465001
#define VFP_STORAGE_SIZE 152
#else
#define VFP_MAGIC 0x56465002
#define VFP_STORAGE_SIZE 144
#endif

struct vfp_sigframe
{
unsigned long magic;
unsigned long size;
union vfp_state storage;
};
#endif /* CONFIG_VFP */

/*
* Auxiliary signal frame. This saves stuff like FP state.
* The layout of this structure is not part of the user ABI,
* because the config options aren't. uc_regspace is really
* one of these.
*/
struct aux_sigframe {
#ifdef CONFIG_IWMMXT
struct iwmmxt_sigframe iwmmxt;
#endif
#if 0 && defined CONFIG_VFP /* Not yet saved. */
struct vfp_sigframe vfp;
#endif
/* Something that isn't a valid magic number for any coprocessor. */
unsigned long end_magic;
} __attribute__((__aligned__(8)));

#endif

#endif /* !_ASMARM_UCONTEXT_H */

0 comments on commit 97c9fc7

Please sign in to comment.