All of lore.kernel.org
 help / color / mirror / Atom feed
* X86 fpu registers in a signal handler's ucontext
@ 2013-04-29 14:34 Warlich, Christof
  2013-04-29 17:57 ` Andi Kleen
  2013-05-03  3:18 ` H. Peter Anvin
  0 siblings, 2 replies; 12+ messages in thread
From: Warlich, Christof @ 2013-04-29 14:34 UTC (permalink / raw)
  To: linux-kernel

Hi,

I want my signal handler to return from a SIGFPE and continue normal
execution right _after_ the instruction that caused the signal.

My first attempt workes quite well: I just modify the EIP register
though the ucontext pointer being passed to the signal handler:

void fpeHandler(int, siginfo_t *info, void *context) {
    // The following function calculates the size of the instruction being pointed to.
    int size = instructionSize((unsigned char *) info->si_addr);
    ((ucontext_t *) context)->uc_mcontext.gregs[REG_EIP] += size;
}

Doing this, my main program continues as expected as long as no other
floating point instructions are involved, but as the exception
condition is still active in the FP status register, any subsequent
and _valid_ floating point calculation cause another exception.

Thus, I tried to clear the exceptions in a similar way:

void fpeHandler(int, siginfo_t *info, void *context) {
    // This function calculates the size of the instruction being poined to.
    int size = instructionSize((unsigned char *) info->si_addr);
    ((ucontext_t *) context)->uc_mcontext.gregs[REG_EIP] += size;
    ((ucontext_t *) context)->uc_mcontext.fpregs->status &= ~FE_ALL_EXCEPT
}

But unfortunately, this doesn't work:

First, this link:
http://valgrind.10908.n7.nabble.com/need-FPU-and-SSE-state-in-sigcontext-ucontext-td19844.html
suggests that unlike the GPRs, the FP registers are _not_ restored after
returnung from the signal handler. 

Second, only FP state seems to be available through ucontext_t, and I would
need to clear exceptions for SSE as well.

Can anyone give me some advice on how to I could proceed?

Thanks a lot,

Chris

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: X86 fpu registers in a signal handler's ucontext
  2013-04-29 14:34 X86 fpu registers in a signal handler's ucontext Warlich, Christof
@ 2013-04-29 17:57 ` Andi Kleen
  2013-04-30  6:35   ` Warlich, Christof
  2013-05-03  3:18 ` H. Peter Anvin
  1 sibling, 1 reply; 12+ messages in thread
From: Andi Kleen @ 2013-04-29 17:57 UTC (permalink / raw)
  To: Warlich, Christof; +Cc: linux-kernel

"Warlich, Christof" <christof.warlich@siemens.com> writes:
>
> First, this link:
> http://valgrind.10908.n7.nabble.com/need-FPU-and-SSE-state-in-sigcontext-ucontext-td19844.html
> suggests that unlike the GPRs, the FP registers are _not_ restored after
> returnung from the signal handler. 

The FP registers are restored lazily, but the state for this is kept in
the kernel.

One easy way may be to catch the FPU exception too and clear from there?

There can be some complications with different save formats too (XSAVE
vs FXSAVE). So your solution may not be necessarily 100% portable
to all systems.

-Andi

-- 
ak@linux.intel.com -- Speaking for myself only

^ permalink raw reply	[flat|nested] 12+ messages in thread

* RE: X86 fpu registers in a signal handler's ucontext
  2013-04-29 17:57 ` Andi Kleen
@ 2013-04-30  6:35   ` Warlich, Christof
  2013-04-30 11:28     ` Mikael Pettersson
  0 siblings, 1 reply; 12+ messages in thread
From: Warlich, Christof @ 2013-04-30  6:35 UTC (permalink / raw)
  To: Andi Kleen; +Cc: linux-kernel

Andi Kleen <andi@firstfloor.org> writes:
> The FP registers are restored lazily, but the state for this is kept in
> the kernel.

I'm not sure if I understand "lazily" in this context: Do you mean that FP
registers _are_ restored within the kernel, but _not_ from a (possibly modified)
ucontext of a userspace signal handler? If so, do you know a reason why the GP
registers are so nicely restored from userspace, but not the FP registers?
 
> One easy way may be to catch the FPU exception too and clear from there?

Hmm - I _do_ catch SIGFPE in my userspace signal handler, but I obviously
can't clear the FP exceptions from there. This, together with your answer
so far, makes me conclude that there may be no way to achieve my goal from
userspace, right :-(?

Ok, still assuming I'm (terribly) right so far: The kernel calls
do_coprocessor_error() when the FP exception occurs. As I don't want to patch
the kernel, is there a "best practise" way to hook my module code into the FP
exception handler? The only way that comes to my mind is modifying the vector
table in modul_init() to let the FP exception point to my code and restoring
it in module_exit().  

> There can be some complications with different save formats too (XSAVE
> vs FXSAVE). So your solution may not be necessarily 100% portable
> to all systems.
Yes, I'm certainly arch specific in many ways here, but that wouldn't be much
of a problem for me though.

^ permalink raw reply	[flat|nested] 12+ messages in thread

* RE: X86 fpu registers in a signal handler's ucontext
  2013-04-30  6:35   ` Warlich, Christof
@ 2013-04-30 11:28     ` Mikael Pettersson
  2013-04-30 13:45       ` Warlich, Christof
  0 siblings, 1 reply; 12+ messages in thread
From: Mikael Pettersson @ 2013-04-30 11:28 UTC (permalink / raw)
  To: Warlich, Christof; +Cc: Andi Kleen, linux-kernel

Warlich, Christof writes:
 > Andi Kleen <andi@firstfloor.org> writes:
 > > The FP registers are restored lazily, but the state for this is kept in
 > > the kernel.
 > 
 > I'm not sure if I understand "lazily" in this context: Do you mean that FP
 > registers _are_ restored within the kernel, but _not_ from a (possibly modified)
 > ucontext of a userspace signal handler? If so, do you know a reason why the GP
 > registers are so nicely restored from userspace, but not the FP registers?
 >  
 > > One easy way may be to catch the FPU exception too and clear from there?
 > 
 > Hmm - I _do_ catch SIGFPE in my userspace signal handler, but I obviously
 > can't clear the FP exceptions from there. This, together with your answer
 > so far, makes me conclude that there may be no way to achieve my goal from
 > userspace, right :-(?

Write to the fpstate ->mxcsr and ->swd fields in the sigaction handler's uc_mcontext.

^ permalink raw reply	[flat|nested] 12+ messages in thread

* RE: X86 fpu registers in a signal handler's ucontext
  2013-04-30 11:28     ` Mikael Pettersson
@ 2013-04-30 13:45       ` Warlich, Christof
  2013-04-30 14:42         ` Mikael Pettersson
  0 siblings, 1 reply; 12+ messages in thread
From: Warlich, Christof @ 2013-04-30 13:45 UTC (permalink / raw)
  To: Mikael Pettersson; +Cc: Andi Kleen, linux-kernel

Mikael Pettersson <mikpe@it.uu.se> writes:
> Write to the fpstate ->mxcsr and ->swd fields in the sigaction handler's uc_mcontext.

To me, "sigaction handler's uc_mcontext" sounds like userspace, which really confuses me:
Even in most recent glibc-2.17, uc_mcontext is of type mcontext_t, which us defined as:

typedef struct {
  gregset_t gregs;
  fpregset_t fpregs;
} mcontext_t;

typedef struct fpregset {
    union {
	struct fpchip_state {
	    int state[27];
	    int status;
	} fpchip_state;
	struct fp_emul_space {
	    char fp_emul[246];
	    char fp_epad[2];
	} fp_emul_space;
	int f_fpregs[62];
    } fp_reg_set;
    long int f_wregs[33];
} fpregset_t;

So there is no fpstate whatsoever.

However, these elements seem to be available in the uc_mcontext definition of the
kernel, but I can't have a sigaction handler there, can I? Then, how does the
kernel's uc_mcontext definition help me in my (userspace) signal handler?

^ permalink raw reply	[flat|nested] 12+ messages in thread

* RE: X86 fpu registers in a signal handler's ucontext
  2013-04-30 13:45       ` Warlich, Christof
@ 2013-04-30 14:42         ` Mikael Pettersson
  2013-05-02  5:42           ` Warlich, Christof
  0 siblings, 1 reply; 12+ messages in thread
From: Mikael Pettersson @ 2013-04-30 14:42 UTC (permalink / raw)
  To: Warlich, Christof; +Cc: Mikael Pettersson, Andi Kleen, linux-kernel

Warlich, Christof writes:
 > Mikael Pettersson <mikpe@it.uu.se> writes:
 > > Write to the fpstate ->mxcsr and ->swd fields in the sigaction handler's uc_mcontext.
 > 
 > To me, "sigaction handler's uc_mcontext" sounds like userspace, which really confuses me:
 > Even in most recent glibc-2.17, uc_mcontext is of type mcontext_t, which us defined as:
 > 
 > typedef struct {
 >   gregset_t gregs;
 >   fpregset_t fpregs;
 > } mcontext_t;
 > 
 > typedef struct fpregset {
 >     union {
 > 	struct fpchip_state {
 > 	    int state[27];
 > 	    int status;
 > 	} fpchip_state;
 > 	struct fp_emul_space {
 > 	    char fp_emul[246];
 > 	    char fp_epad[2];
 > 	} fp_emul_space;
 > 	int f_fpregs[62];
 >     } fp_reg_set;
 >     long int f_wregs[33];
 > } fpregset_t;
 > 
 > So there is no fpstate whatsoever.

You're looking at the wrong header: glibc-2.17/sysdeps/i386/sys/ucontext.h is legacy SVR4.
Instead look at glibc-2.17/sysdeps/unix/sysv/linux/x86/sys/ucontext.h.

(If the old one got installed on your system then something there is seriously wrong.)

The only quirk is that to access ->mxcsr on 32-bit you have to check if the high half of
->status contains FXSR_MAGIC and if so you need to cast that pointer to struct _fpstate*.

^ permalink raw reply	[flat|nested] 12+ messages in thread

* RE: X86 fpu registers in a signal handler's ucontext
  2013-04-30 14:42         ` Mikael Pettersson
@ 2013-05-02  5:42           ` Warlich, Christof
  2013-05-02  7:06             ` richard -rw- weinberger
  0 siblings, 1 reply; 12+ messages in thread
From: Warlich, Christof @ 2013-05-02  5:42 UTC (permalink / raw)
  To: Mikael Pettersson; +Cc: Andi Kleen, linux-kernel

Mikael Pettersson <mikpe@it.uu.se> writes:
> You're looking at the wrong header: glibc-2.17/sysdeps/i386/sys/ucontext.h is legacy SVR4.
> Instead look at glibc-2.17/sysdeps/unix/sysv/linux/x86/sys/ucontext.h.
> 
> (If the old one got installed on your system then something there is seriously wrong.)

Oh-oh: It looks like my system was simply too old: Initially, I was looking at Ubuntu 11.10
with an eglibc-2.13, and a double-check with a newly downloaded glibc-2.17 lead me to the
wrong file.

Many thanks for your help!  
   

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: X86 fpu registers in a signal handler's ucontext
  2013-05-02  5:42           ` Warlich, Christof
@ 2013-05-02  7:06             ` richard -rw- weinberger
  2013-05-02  7:43               ` Warlich, Christof
  2013-05-02  9:04               ` Warlich, Christof
  0 siblings, 2 replies; 12+ messages in thread
From: richard -rw- weinberger @ 2013-05-02  7:06 UTC (permalink / raw)
  To: Warlich, Christof; +Cc: Mikael Pettersson, Andi Kleen, linux-kernel

On Thu, May 2, 2013 at 7:42 AM, Warlich, Christof
<christof.warlich@siemens.com> wrote:
> Mikael Pettersson <mikpe@it.uu.se> writes:
>> You're looking at the wrong header: glibc-2.17/sysdeps/i386/sys/ucontext.h is legacy SVR4.
>> Instead look at glibc-2.17/sysdeps/unix/sysv/linux/x86/sys/ucontext.h.
>>
>> (If the old one got installed on your system then something there is seriously wrong.)
>
> Oh-oh: It looks like my system was simply too old: Initially, I was looking at Ubuntu 11.10
> with an eglibc-2.13, and a double-check with a newly downloaded glibc-2.17 lead me to the
> wrong file.

Are you telling us that Ubuntu shipped the wrong header file?

--
Thanks,
//richard

^ permalink raw reply	[flat|nested] 12+ messages in thread

* RE: X86 fpu registers in a signal handler's ucontext
  2013-05-02  7:06             ` richard -rw- weinberger
@ 2013-05-02  7:43               ` Warlich, Christof
  2013-05-02  9:04               ` Warlich, Christof
  1 sibling, 0 replies; 12+ messages in thread
From: Warlich, Christof @ 2013-05-02  7:43 UTC (permalink / raw)
  To: richard -rw- weinberger; +Cc: Mikael Pettersson, Andi Kleen, linux-kernel

richard -rw- weinberger <richard.weinberger@gmail.com> writes:
> Are you telling us that Ubuntu shipped the wrong header file?

Grmpf ... no. :-*

Here again, I obviously started looking at the wrong file
(i386-linux-gnu/sys/ucontext.h), which defines uc_mcontext
to be of type mcontext_t.

So the right header to be used seems to be asm-generic/ucontext.h,
which _does_ include the right definition of uc_mcontext to be of
type struct sigcontext even in Ubuntu 11.10.

Thanks again and sorry for the confusion, I hope I have my lesson
learned.



^ permalink raw reply	[flat|nested] 12+ messages in thread

* RE: X86 fpu registers in a signal handler's ucontext
  2013-05-02  7:06             ` richard -rw- weinberger
  2013-05-02  7:43               ` Warlich, Christof
@ 2013-05-02  9:04               ` Warlich, Christof
  2013-05-02 11:12                 ` Mikael Pettersson
  1 sibling, 1 reply; 12+ messages in thread
From: Warlich, Christof @ 2013-05-02  9:04 UTC (permalink / raw)
  To: richard -rw- weinberger; +Cc: Mikael Pettersson, Andi Kleen, linux-kernel

richard -rw- weinberger <richard.weinberger@gmail.com> writes:
> Are you telling us that Ubuntu shipped the wrong header file?

Hmm - at least I still don't know how to get the right definition
of uc_mcontext (with eglibc-2.13 on Ubuntu 11.10) ...

If I include both signal.h and asm-generic/ucontext.h, gcc reports
this error:

/usr/include/asm-generic/ucontext.h:4:8: error: redefinition of 'struct ucontext'
/usr/include/i386-linux-gnu/sys/ucontext.h:119:16: error: previous definition of 'struct ucontext'

Thus, signal.h obviously includes the wrong i386-linux-gnu/sys/ucontext.h
defining uc_mcontext to be of type mcontext_t.

So is it still me doing something wrong or or _did_ Ubuntu ship
the wrong header files?

^ permalink raw reply	[flat|nested] 12+ messages in thread

* RE: X86 fpu registers in a signal handler's ucontext
  2013-05-02  9:04               ` Warlich, Christof
@ 2013-05-02 11:12                 ` Mikael Pettersson
  0 siblings, 0 replies; 12+ messages in thread
From: Mikael Pettersson @ 2013-05-02 11:12 UTC (permalink / raw)
  To: Warlich, Christof
  Cc: richard -rw- weinberger, Mikael Pettersson, Andi Kleen, linux-kernel

Warlich, Christof writes:
 > richard -rw- weinberger <richard.weinberger@gmail.com> writes:
 > > Are you telling us that Ubuntu shipped the wrong header file?
 > 
 > Hmm - at least I still don't know how to get the right definition
 > of uc_mcontext (with eglibc-2.13 on Ubuntu 11.10) ...
 > 
 > If I include both signal.h and asm-generic/ucontext.h, gcc reports
 > this error:
 > 
 > /usr/include/asm-generic/ucontext.h:4:8: error: redefinition of 'struct ucontext'
 > /usr/include/i386-linux-gnu/sys/ucontext.h:119:16: error: previous definition of 'struct ucontext'
 > 
 > Thus, signal.h obviously includes the wrong i386-linux-gnu/sys/ucontext.h
 > defining uc_mcontext to be of type mcontext_t.
 > 
 > So is it still me doing something wrong or or _did_ Ubuntu ship
 > the wrong header files?

#include <signal.h>
#include <ucontext.h>

has worked for my SIGFPE handlers on Linux for the last 10+ years on various distros
and target architectures.

Can we stop this thread now?  There is no _kernel_ issue here.

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: X86 fpu registers in a signal handler's ucontext
  2013-04-29 14:34 X86 fpu registers in a signal handler's ucontext Warlich, Christof
  2013-04-29 17:57 ` Andi Kleen
@ 2013-05-03  3:18 ` H. Peter Anvin
  1 sibling, 0 replies; 12+ messages in thread
From: H. Peter Anvin @ 2013-05-03  3:18 UTC (permalink / raw)
  To: Warlich, Christof; +Cc: linux-kernel

On 04/29/2013 07:34 AM, Warlich, Christof wrote:
> Second, only FP state seems to be available through ucontext_t, and I would
> need to clear exceptions for SSE as well.

Not true.

> Can anyone give me some advice on how to I could proceed?

To optimize the common case, if the signal handler doesn't touch the FPU
the state is not reloaded from the signal stack.  Therefore you need to
execute an FPU instruction -- pretty much any FPU instruction -- in your
signal handler in order to force the reload.

	-hpa


^ permalink raw reply	[flat|nested] 12+ messages in thread

end of thread, other threads:[~2013-05-03  3:18 UTC | newest]

Thread overview: 12+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2013-04-29 14:34 X86 fpu registers in a signal handler's ucontext Warlich, Christof
2013-04-29 17:57 ` Andi Kleen
2013-04-30  6:35   ` Warlich, Christof
2013-04-30 11:28     ` Mikael Pettersson
2013-04-30 13:45       ` Warlich, Christof
2013-04-30 14:42         ` Mikael Pettersson
2013-05-02  5:42           ` Warlich, Christof
2013-05-02  7:06             ` richard -rw- weinberger
2013-05-02  7:43               ` Warlich, Christof
2013-05-02  9:04               ` Warlich, Christof
2013-05-02 11:12                 ` Mikael Pettersson
2013-05-03  3:18 ` H. Peter Anvin

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.