Commit e9370ae1 authored by Paul Mackerras's avatar Paul Mackerras

[PATCH] powerpc: Implement PR_[GS]ET_UNALIGN prctls for powerpc

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: default avatarPaul Mackerras <paulus@samba.org>
parent fab5db97
...@@ -752,6 +752,17 @@ int get_endian(struct task_struct *tsk, unsigned long adr) ...@@ -752,6 +752,17 @@ int get_endian(struct task_struct *tsk, unsigned long adr)
return put_user(val, (unsigned int __user *)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)) #define TRUNC_PTR(x) ((typeof(x))(((unsigned long)(x)) & 0xffffffff))
int sys_clone(unsigned long clone_flags, unsigned long usp, int sys_clone(unsigned long clone_flags, unsigned long usp,
......
...@@ -805,8 +805,10 @@ void __kprobes program_check_exception(struct pt_regs *regs) ...@@ -805,8 +805,10 @@ void __kprobes program_check_exception(struct pt_regs *regs)
void alignment_exception(struct pt_regs *regs) void alignment_exception(struct pt_regs *regs)
{ {
int fixed; int fixed = 0;
/* we don't implement logging of alignment exceptions */
if (!(current->thread.align_ctl & PR_UNALIGN_SIGBUS))
fixed = fix_alignment(regs); fixed = fix_alignment(regs);
if (fixed == 1) { if (fixed == 1) {
......
...@@ -149,6 +149,7 @@ struct thread_struct { ...@@ -149,6 +149,7 @@ struct thread_struct {
unsigned int val; /* Floating point status */ unsigned int val; /* Floating point status */
} fpscr; } fpscr;
int fpexc_mode; /* floating-point exception mode */ int fpexc_mode; /* floating-point exception mode */
unsigned int align_ctl; /* alignment handling control */
#ifdef CONFIG_PPC64 #ifdef CONFIG_PPC64
unsigned long start_tb; /* Start purr when proc switched in */ unsigned long start_tb; /* Start purr when proc switched in */
unsigned long accum_tb; /* Total accumilated purr for process */ unsigned long accum_tb; /* Total accumilated purr for process */
...@@ -217,6 +218,12 @@ extern int set_fpexc_mode(struct task_struct *tsk, unsigned int val); ...@@ -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 get_endian(struct task_struct *tsk, unsigned long adr);
extern int set_endian(struct task_struct *tsk, unsigned int val); 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) static inline unsigned int __unpack_fe01(unsigned long msr_bits)
{ {
return ((msr_bits & MSR_FE0) >> 10) | ((msr_bits & MSR_FE1) >> 8); return ((msr_bits & MSR_FE0) >> 10) | ((msr_bits & MSR_FE1) >> 8);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment