Skip to content

Commit

Permalink
[PATCH] powerpc: Implement PR_[GS]ET_UNALIGN prctls for powerpc
Browse files Browse the repository at this point in the history
This gives the ability to control whether alignment exceptions get
fixed up or reported to the process as a SIGBUS, using the existing
PR_SET_UNALIGN and PR_GET_UNALIGN prctls.  We do not implement the
option of logging a message on alignment exceptions.

Signed-off-by: Paul Mackerras <paulus@samba.org>
  • Loading branch information
Paul Mackerras committed Jun 9, 2006
1 parent fab5db9 commit e9370ae
Show file tree
Hide file tree
Showing 3 changed files with 22 additions and 2 deletions.
11 changes: 11 additions & 0 deletions arch/powerpc/kernel/process.c
Original file line number Diff line number Diff line change
Expand Up @@ -752,6 +752,17 @@ int get_endian(struct task_struct *tsk, unsigned long adr)
return put_user(val, (unsigned int __user *)adr);
}

int set_unalign_ctl(struct task_struct *tsk, unsigned int val)
{
tsk->thread.align_ctl = val;
return 0;
}

int get_unalign_ctl(struct task_struct *tsk, unsigned long adr)
{
return put_user(tsk->thread.align_ctl, (unsigned int __user *)adr);
}

#define TRUNC_PTR(x) ((typeof(x))(((unsigned long)(x)) & 0xffffffff))

int sys_clone(unsigned long clone_flags, unsigned long usp,
Expand Down
6 changes: 4 additions & 2 deletions arch/powerpc/kernel/traps.c
Original file line number Diff line number Diff line change
Expand Up @@ -805,9 +805,11 @@ void __kprobes program_check_exception(struct pt_regs *regs)

void alignment_exception(struct pt_regs *regs)
{
int fixed;
int fixed = 0;

fixed = fix_alignment(regs);
/* we don't implement logging of alignment exceptions */
if (!(current->thread.align_ctl & PR_UNALIGN_SIGBUS))
fixed = fix_alignment(regs);

if (fixed == 1) {
regs->nip += 4; /* skip over emulated instruction */
Expand Down
7 changes: 7 additions & 0 deletions include/asm-powerpc/processor.h
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,7 @@ struct thread_struct {
unsigned int val; /* Floating point status */
} fpscr;
int fpexc_mode; /* floating-point exception mode */
unsigned int align_ctl; /* alignment handling control */
#ifdef CONFIG_PPC64
unsigned long start_tb; /* Start purr when proc switched in */
unsigned long accum_tb; /* Total accumilated purr for process */
Expand Down Expand Up @@ -217,6 +218,12 @@ extern int set_fpexc_mode(struct task_struct *tsk, unsigned int val);
extern int get_endian(struct task_struct *tsk, unsigned long adr);
extern int set_endian(struct task_struct *tsk, unsigned int val);

#define GET_UNALIGN_CTL(tsk, adr) get_unalign_ctl((tsk), (adr))
#define SET_UNALIGN_CTL(tsk, val) set_unalign_ctl((tsk), (val))

extern int get_unalign_ctl(struct task_struct *tsk, unsigned long adr);
extern int set_unalign_ctl(struct task_struct *tsk, unsigned int val);

static inline unsigned int __unpack_fe01(unsigned long msr_bits)
{
return ((msr_bits & MSR_FE0) >> 10) | ((msr_bits & MSR_FE1) >> 8);
Expand Down

0 comments on commit e9370ae

Please sign in to comment.