Commit c52f1179 authored by Venkatesh Pallipadi's avatar Venkatesh Pallipadi Committed by David Mosberger

[PATCH] ia64: Save/Restore of IA32 fpstate in sigcontext

The IA32 fpstate information is not getting saved/restored during IA32
exception handling. The issue was first observed due to an IA32 binary
(which runs fine on IA32 system), failing on Itanium based system. The
binary was trying to access the fpstate information during an FPE and got a
SEGV, as the fpstate was not getting saved and the sigcontext->fpstate
pointer was NULL.
parent de8adf68
This diff is collapsed.
......@@ -2836,20 +2836,6 @@ putreg (struct task_struct *child, int regno, unsigned int value)
}
}
static inline void
ia32f2ia64f (void *dst, void *src)
{
asm volatile ("ldfe f6=[%1];; stf.spill [%0]=f6" :: "r"(dst), "r"(src) : "memory");
return;
}
static inline void
ia64f2ia32f (void *dst, void *src)
{
asm volatile ("ldf.fill f6=[%1];; stfe [%0]=f6" :: "r"(dst), "r"(src) : "memory");
return;
}
static void
put_fpreg (int regno, struct _fpreg_ia32 *reg, struct pt_regs *ptp, struct switch_stack *swp,
int tos)
......
......@@ -41,6 +41,16 @@
# define GET_SIGSET(k,u) __get_user((k)->sig[0], &(u)->sig[0])
#endif
register double f16 asm ("f16"); register double f17 asm ("f17");
register double f18 asm ("f18"); register double f19 asm ("f19");
register double f20 asm ("f20"); register double f21 asm ("f21");
register double f22 asm ("f22"); register double f23 asm ("f23");
register double f24 asm ("f24"); register double f25 asm ("f25");
register double f26 asm ("f26"); register double f27 asm ("f27");
register double f28 asm ("f28"); register double f29 asm ("f29");
register double f30 asm ("f30"); register double f31 asm ("f31");
long
ia64_rt_sigsuspend (sigset_t *uset, size_t sigsetsize, struct sigscratch *scr)
{
......
......@@ -73,6 +73,17 @@ struct _fpreg_ia32 {
unsigned short exponent;
};
struct _fpxreg_ia32 {
unsigned short significand[4];
unsigned short exponent;
unsigned short padding[3];
};
struct _xmmreg_ia32 {
unsigned int element[4];
};
struct _fpstate_ia32 {
unsigned int cw,
sw,
......@@ -82,7 +93,16 @@ struct _fpstate_ia32 {
dataoff,
datasel;
struct _fpreg_ia32 _st[8];
unsigned int status;
unsigned short status;
unsigned short magic; /* 0xffff = regular FPU data only */
/* FXSR FPU environment */
unsigned int _fxsr_env[6]; /* FXSR FPU env is ignored */
unsigned int mxcsr;
unsigned int reserved;
struct _fpxreg_ia32 _fxsr_st[8]; /* FXSR FPU reg data is ignored */
struct _xmmreg_ia32 _xmm[8];
unsigned int padding[56];
};
struct sigcontext_ia32 {
......@@ -486,6 +506,18 @@ extern int ia32_intercept (struct pt_regs *regs, unsigned long isr);
extern unsigned long ia32_do_mmap (struct file *, unsigned long, unsigned long, int, int, loff_t);
extern void ia32_load_segment_descriptors (struct task_struct *task);
#define ia32f2ia64f(dst,src) \
do { \
register double f6 asm ("f6"); \
asm volatile ("ldfe f6=[%2];; stf.spill [%1]=f6" : "=f"(f6): "r"(dst), "r"(src) : "memory"); \
} while(0)
#define ia64f2ia32f(dst,src) \
do { \
register double f6 asm ("f6"); \
asm volatile ("ldf.fill f6=[%2];; stfe [%1]=f6" : "=f"(f6): "r"(dst), "r"(src) : "memory"); \
} while(0)
#endif /* !CONFIG_IA32_SUPPORT */
#endif /* _ASM_IA64_IA32_H */
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