diff options
author | Steven Rostedt <srostedt@redhat.com> | 2012-06-07 17:03:00 +0200 |
---|---|---|
committer | Steven Rostedt <rostedt@goodmis.org> | 2012-06-09 00:48:05 +0200 |
commit | c7d65a78fc18ed70353baeb7497ec71a7c775ac5 (patch) | |
tree | 1cf4651a56b972cbaa66361f41246d1e107548cd /net/nfc/llcp/sock.c | |
parent | x86: Save cr2 in NMI in case NMIs take a page fault (diff) | |
download | linux-c7d65a78fc18ed70353baeb7497ec71a7c775ac5.tar.xz linux-c7d65a78fc18ed70353baeb7497ec71a7c775ac5.zip |
x86: Remove cmpxchg from i386 NMI nesting code
I've been informed by someone on LWN called 'slashdot' that
some i386 machines do not support a true cmpxchg. The cmpxchg
used by the i386 NMI nesting code must be a true cmpxchg as
disabling interrupts will not work for NMIs (which is the work
around for i386s that do not have a true cmpxchg).
This 'slashdot' character also suggested a fix to the issue.
As the state of the nesting NMIs goes as follows:
NOT_RUNNING -> EXECUTING
EXECUTING -> NOT_RUNNING
EXECUTING -> LATCHED
LATCHED -> EXECUTING
Having these states as enum values of:
NOT_RUNNING = 0
EXECUTING = 1
LATCHED = 2
Instead of a cmpxchg to make EXECUTING -> NOT_RUNNING a
dec_and_test() would work as well. If the dec_and_test brings
the state to NOT_RUNNING, that is the same as a cmpxchg
succeeding to change EXECUTING to NOT_RUNNING. If a nested NMI
were to come in and change it to LATCHED, the dec_and_test() would
convert the state to EXECUTING (what we want it to be in such a
case anyway).
I asked 'slashdot' to post this as a patch, but it never came to
be. I decided to do the work instead.
Thanks to H. Peter Anvin for suggesting to use this_cpu_dec_and_return()
instead of local_dec_and_test(&__get_cpu_var()).
Link: http://lwn.net/Articles/484932/
Cc: H. Peter Anvin <hpa@zytor.com>
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
Diffstat (limited to 'net/nfc/llcp/sock.c')
0 files changed, 0 insertions, 0 deletions