Skip to content
  • Steven Rostedt's avatar
    x86: Remove cmpxchg from i386 NMI nesting code · c7d65a78
    Steven Rostedt authored
    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: default avatarSteven Rostedt <rostedt@goodmis.org>
    c7d65a78