[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Message-ID: <AANLkTi=i3RP6x8ns09-6r4UCVay56U=DA3Ln_VupHbh5@mail.gmail.com>
Date: Sun, 8 Aug 2010 05:28:25 +0200
From: cyp@...esend.de
To: linux-kernel@...r.kernel.org
Subject: signo issues in arch/x86/kernel/traps.c
There are several -- to me, peculiar -- signal number choices being
made in arch/x86/kernel/traps.c. Here are my observations...
#1. Exception 9 -- "coprocessor segment overrun" -- should not be
forwarded, leave alone forwarded as a SIGFPE. Exception 9 is not a
fault, but an abort-class exception. The task _must_ die. Exception 9
occurs when a discrete coprocessor -- i.e. one that is not on the same
die as the processor -- writes to an operand in memory that crosses a
page boundary, _and_ one page is writeable but the other is not. So,
under these conditions, when the coprocessor writes to mem, part of
the write succeeds and the other part fails. Since the operand in
memory then contains garbage, subsequent cpu and fpu instructions must
be prevented from using it, and with the fpu confused (should its
state be that from before or after the computation that precipitated
the write?), the task cannot be allowed to recover from the exception.
Incidentally: it seems that the math emulator is trying to avoid just
that sort of partial-write-success situation with all the limits
checking that its doing. (pm_address() in math-emu/get_address.c)
Perhaps a uaccess function for atomic writes (either write completely
or not at all) would be generally useful?
#2. An exception 7 -- "device not available" -- exception should not
result in a SIGFPE being sent to the task. An FPE can -- nomen est
omen -- (what is it with traps.c's reticence in passing siginfo?)
precipitate fiddling with the state of the (non-existent) fpu, which
will naturally trip another "device not available". Since the "device
not available" exception is just a particular kind of "cannot handle
this opcode" event, and the appropriate signal for "cannot handle this
opcode" events is SIGILL, exception 7 should cause a SIGILL.
#3. Exception 12 -- named "stack segment" in traps.c -- should
translate into a SEGV, not a SIGBUS. Exception 12 is a segment
violation, even if it is a particular kind of segment violation. The
"Stack-Segment Fault" is the %ss selector's equivalent of a GPF that
occurs for an access with %cs/ds/es/fs/gs. Just as loading
cs/es/ds/fs/gs with a bad/null selector will trip exception 13, so
will loading ss with a bad/null selector cause an exception 12. The
principle function of exception 12 is to automatically grow an
expand-down stack segment when an access occurs beyond the limit
defined in the %ss selector's descriptor. But a simple mov <bad
address>, %ebp; mov (%ebp), %eax can trip it too since %ebp is
implicitly based against %ss. Not functionally any different from a
simple mov <bad address>, %ebx; mov (%ebx), %eax. I can't think of any
reason why exception 12 should be a SIGBUS while exception 13 is a
SEGV.
#4. Exception 5 -- "bounds" -- should not translate to a SEGV.
Exception 5 occurs when a programmer deliberately wants to test
whether an integer is within a certain range, for which he/she uses
the BOUND instruction.
if (foo < range.lo || foo > range.hi)
printf("hey! out of bounds\n");
The if() is simple signed integer math comparison, not a bad memory
access. (if there were a fault accessing range.{hi|lo}, the exception
being raised would be a GPF, not a bounds).
#5. Exception 4 -- "overflow" -- should probably not translate to a
SEGV. Exception 4 ("interrupt 4"), generated by INTO, is like
exception 3 ("interrupt 3"), generated by INT3. It too is a trap-class
exception, and really a debug instruction. As with all trap-class
exceptions, the task's eip is pointing to the next instruction, and a
simple ret will seamlessly continue execution as if nothing had
happened (unlike a real SEGV). In this sense, its probably not a good
idea to deal with it as a SEGV. There is also no violation there,
leave alone a segment violation. It isn't like an INT x for an
unhandled interrupt vector. After all, the interrupt is being handled.
I suggest treating it just like int3 is treated. i.e. SIGTRAP.
Regards,
Cyrus
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
Powered by blists - more mailing lists