lkml.org 
[lkml]   [2012]   [Apr]   [11]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    Date
    From
    Subject[ 34/59] kgdbts: Fix kernel oops with CONFIG_DEBUG_RODATA
    3.2-stable review patch.  If anyone has any objections, please let me know.

    ------------------
    From: Jason Wessel <jason.wessel@windriver.com>

    commit 456ca7ff24841bf2d2a2dfd690fe7d42ef70d932 upstream.

    On x86 the kgdb test suite will oops when the kernel is compiled with
    CONFIG_DEBUG_RODATA and you run the tests after boot time. This is
    regression has existed since 2.6.26 by commit: b33cb815 (kgdbts: Use
    HW breakpoints with CONFIG_DEBUG_RODATA).

    The test suite can use hw breakpoints for all the tests, but it has to
    execute the hardware breakpoint specific tests first in order to
    determine that the hw breakpoints actually work. Specifically the
    very first test causes an oops:

    # echo V1I1 > /sys/module/kgdbts/parameters/kgdbts
    kgdb: Registered I/O driver kgdbts.
    kgdbts:RUN plant and detach test
    Entering kdb (current=0xffff880017aa9320, pid 1078) on processor 0 due to Keyboard Entry
    [0]kdb> kgdbts: ERROR PUT: end of test buffer on 'plant_and_detach_test' line 1 expected OK got $E14#aa
    WARNING: at drivers/misc/kgdbts.c:730 run_simple_test+0x151/0x2c0()
    [...oops clipped...]
    This commit re-orders the running of the tests and puts the RODATA
    check into its own function so as to correctly avoid the kernel oops
    by detecting and using the hw breakpoints.

    Signed-off-by: Jason Wessel <jason.wessel@windriver.com>
    Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

    ---
    drivers/misc/kgdbts.c | 52 ++++++++++++++++++++++++++------------------------
    1 file changed, 28 insertions(+), 24 deletions(-)
    --- a/drivers/misc/kgdbts.c
    +++ b/drivers/misc/kgdbts.c
    @@ -885,6 +885,22 @@ static void run_singlestep_break_test(vo
    kgdbts_break_test();
    }

    +static void test_debug_rodata(void)
    +{
    +#ifdef CONFIG_DEBUG_RODATA
    + /* Until there is an api to write to read-only text segments, use
    + * HW breakpoints for the remainder of any tests, else print a
    + * failure message if hw breakpoints do not work.
    + */
    + if (!(arch_kgdb_ops.flags & KGDB_HW_BREAKPOINT && hwbreaks_ok)) {
    + eprintk("kgdbts: HW breakpoints BROKEN, ending tests\n");
    + return;
    + }
    + force_hwbrks = 1;
    + v1printk("kgdbts:Using HW breakpoints for SW breakpoint tests\n");
    +#endif /* CONFIG_DEBUG_RODATA */
    +}
    +
    static void kgdbts_run_tests(void)
    {
    char *ptr;
    @@ -907,6 +923,18 @@ static void kgdbts_run_tests(void)
    if (ptr)
    sstep_test = simple_strtol(ptr+1, NULL, 10);

    + /* All HW break point tests */
    + if (arch_kgdb_ops.flags & KGDB_HW_BREAKPOINT) {
    + hwbreaks_ok = 1;
    + v1printk("kgdbts:RUN hw breakpoint test\n");
    + run_breakpoint_test(1);
    + v1printk("kgdbts:RUN hw write breakpoint test\n");
    + run_hw_break_test(1);
    + v1printk("kgdbts:RUN access write breakpoint test\n");
    + run_hw_break_test(0);
    + }
    + test_debug_rodata();
    +
    /* required internal KGDB tests */
    v1printk("kgdbts:RUN plant and detach test\n");
    run_plant_and_detach_test(0);
    @@ -924,35 +952,11 @@ static void kgdbts_run_tests(void)

    /* ===Optional tests=== */

    - /* All HW break point tests */
    - if (arch_kgdb_ops.flags & KGDB_HW_BREAKPOINT) {
    - hwbreaks_ok = 1;
    - v1printk("kgdbts:RUN hw breakpoint test\n");
    - run_breakpoint_test(1);
    - v1printk("kgdbts:RUN hw write breakpoint test\n");
    - run_hw_break_test(1);
    - v1printk("kgdbts:RUN access write breakpoint test\n");
    - run_hw_break_test(0);
    - }
    -
    if (nmi_sleep) {
    v1printk("kgdbts:RUN NMI sleep %i seconds test\n", nmi_sleep);
    run_nmi_sleep_test(nmi_sleep);
    }

    -#ifdef CONFIG_DEBUG_RODATA
    - /* Until there is an api to write to read-only text segments, use
    - * HW breakpoints for the remainder of any tests, else print a
    - * failure message if hw breakpoints do not work.
    - */
    - if (!(arch_kgdb_ops.flags & KGDB_HW_BREAKPOINT && hwbreaks_ok)) {
    - eprintk("kgdbts: HW breakpoints do not work,"
    - "skipping remaining tests\n");
    - return;
    - }
    - force_hwbrks = 1;
    -#endif /* CONFIG_DEBUG_RODATA */
    -
    /* If the do_fork test is run it will be the last test that is
    * executed because a kernel thread will be spawned at the very
    * end to unregister the debug hooks.



    \
     
     \ /
      Last update: 2012-04-12 01:43    [from the cache]
    ©2003-2014 Jasper Spaans. Advertise on this site