• J
    kgdbts: (1 of 2) fix single step awareness to work correctly with SMP · 486c5987
    Jason Wessel 提交于
    The do_fork and sys_open tests have never worked properly on anything
    other than a UP configuration with the kgdb test suite.  This is
    because the test suite did not fully implement the behavior of a real
    debugger.  A real debugger tracks the state of what thread it asked to
    single step and can correctly continue other threads of execution or
    conditionally stop while waiting for the original thread single step
    request to return.
    
    Below is a simple method to cause a fatal kernel oops with the kgdb
    test suite on a 4 processor x86 system:
    
    while [ 1 ] ; do ls > /dev/null 2> /dev/null; done&
    while [ 1 ] ; do ls > /dev/null 2> /dev/null; done&
    while [ 1 ] ; do ls > /dev/null 2> /dev/null; done&
    while [ 1 ] ; do ls > /dev/null 2> /dev/null; done&
    echo V1I1F1000 > /sys/module/kgdbts/parameters/kgdbts
    
    Very soon after starting the test the kernel will oops with a message like:
    
    kgdbts: BP mismatch 3b7da66480 expected ffffffff8106a590
    WARNING: at drivers/misc/kgdbts.c:303 check_and_rewind_pc+0xe0/0x100()
    Call Trace:
     [<ffffffff812994a0>] check_and_rewind_pc+0xe0/0x100
     [<ffffffff81298945>] validate_simple_test+0x25/0xc0
     [<ffffffff81298f77>] run_simple_test+0x107/0x2c0
     [<ffffffff81298a18>] kgdbts_put_char+0x18/0x20
    
    The warn will turn to a hard kernel crash shortly after that because
    the pc will not get properly rewound to the right value after hitting
    a breakpoint leading to a hard lockup.
    
    This change is broken up into 2 pieces because archs that have hw
    single stepping (2.6.26 and up) need different changes than archs that
    do not have hw single stepping (3.0 and up).  This change implements
    the correct behavior for an arch that supports hw single stepping.
    
    A minor defect was fixed where sys_open should be do_sys_open
    for the sys_open break point test.  This solves the problem of running
    a 64 bit with a 32 bit user space.  The sys_open() never gets called
    when using the 32 bit file system for the kgdb testsuite because the
    32 bit binaries invoke the compat_sys_open() call leading to the test
    never completing.
    
    In order to mimic a real debugger, the kgdb test suite now tracks the
    most recent thread that was continued (cont_thread_id), with the
    intent to single step just this thread.  When the response to the
    single step request stops in a different thread that hit the original
    break point that thread will now get continued, while the debugger
    waits for the thread with the single step pending.  Here is a high
    level description of the sequence of events.
    
       cont_instead_of_sstep = 0;
    
    1) set breakpoint at do_fork
    2) continue
    3)   Save the thread id where we stop to cont_thread_id
    4) Remove breakpoint at do_fork
    5) Reset the PC if needed depending on kernel exception type
    6) if (cont_instead_of_sstep) { continue } else { single step }
    7)   Check where we stopped
           if current thread != cont_thread_id {
               cont_instead_of_sstep = 1;
               goto step 5
           } else {
               cont_instead_of_sstep = 0;
           }
    8) clean up and run test again if needed
    
    Cc: stable@vger.kernel.org # >= 2.6.26
    Signed-off-by: NJason Wessel <jason.wessel@windriver.com>
    486c5987
kgdbts.c 29.7 KB