lkml.org 
[lkml]   [2011]   [Oct]   [19]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[V2][PATCH 2/5] oprofile: Fix crash when unloading module (hr timer mode)
    Date
    Oprofile may crash in a KVM guest while unlaoding modules. This
    happens if oprofile_arch_init() fails and oprofile switches to the hr
    timer mode as a fallback. In this case oprofile_arch_exit() is called,
    but it never was initialized properly which causes the crash. This
    patch fixes this.

    oprofile: using timer interrupt.
    BUG: unable to handle kernel NULL pointer dereference at 0000000000000008
    IP: [<ffffffff8123c226>] unregister_syscore_ops+0x41/0x58
    PGD 41da3f067 PUD 41d80e067 PMD 0
    Oops: 0002 [#1] PREEMPT SMP
    CPU 5
    Modules linked in: oprofile(-)

    Pid: 2382, comm: modprobe Not tainted 3.1.0-rc7-00018-g709a39d #18 Advanced Micro Device Anaheim/Anaheim
    RIP: 0010:[<ffffffff8123c226>] [<ffffffff8123c226>] unregister_syscore_ops+0x41/0x58
    RSP: 0018:ffff88041de1de98 EFLAGS: 00010296
    RAX: 0000000000000000 RBX: ffffffffa00060e0 RCX: dead000000200200
    RDX: 0000000000000000 RSI: dead000000100100 RDI: ffffffff8178c620
    RBP: ffff88041de1dea8 R08: 0000000000000001 R09: 0000000000000082
    R10: 0000000000000000 R11: ffff88041de1dde8 R12: 0000000000000080
    R13: fffffffffffffff5 R14: 0000000000000001 R15: 0000000000610210
    FS: 00007f9ae5bef700(0000) GS:ffff88042fd40000(0000) knlGS:0000000000000000
    CS: 0010 DS: 0000 ES: 0000 CR0: 000000008005003b
    CR2: 0000000000000008 CR3: 000000041ca44000 CR4: 00000000000006e0
    DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
    DR3: 0000000000000000 DR6: 00000000ffff0ff0 DR7: 0000000000000400
    Process modprobe (pid: 2382, threadinfo ffff88041de1c000, task ffff88042db6d040)
    Stack:
    ffff88041de1deb8 ffffffffa0006770 ffff88041de1deb8 ffffffffa000251e
    ffff88041de1dec8 ffffffffa00022c2 ffff88041de1ded8 ffffffffa0004993
    ffff88041de1df78 ffffffff81073115 656c69666f72706f 0000000000610200
    Call Trace:
    [<ffffffffa000251e>] op_nmi_exit+0x15/0x17 [oprofile]
    [<ffffffffa00022c2>] oprofile_arch_exit+0xe/0x10 [oprofile]
    [<ffffffffa0004993>] oprofile_exit+0x13/0x15 [oprofile]
    [<ffffffff81073115>] sys_delete_module+0x1c3/0x22f
    [<ffffffff811bf09e>] ? trace_hardirqs_on_thunk+0x3a/0x3f
    [<ffffffff8148070b>] system_call_fastpath+0x16/0x1b
    Code: 20 c6 78 81 e8 c5 cc 23 00 48 8b 13 48 8b 43 08 48 be 00 01 10 00 00 00 ad de 48 b9 00 02 20 00 00 00 ad de 48 c7 c7 20 c6 78 81
    89 42 08 48 89 10 48 89 33 48 89 4b 08 e8 a6 c0 23 00 5a 5b
    RIP [<ffffffff8123c226>] unregister_syscore_ops+0x41/0x58
    RSP <ffff88041de1de98>
    CR2: 0000000000000008
    ---[ end trace 06d4e95b6aa3b437 ]---

    CC: stable@kernel.org # 2.6.37+
    Signed-off-by: Robert Richter <robert.richter@amd.com>
    ---
    drivers/oprofile/oprof.c | 29 ++++++++++++++++++++++++-----
    drivers/oprofile/timer_int.c | 1 +
    2 files changed, 25 insertions(+), 5 deletions(-)

    diff --git a/drivers/oprofile/oprof.c b/drivers/oprofile/oprof.c
    index dccd863..f8c752e 100644
    --- a/drivers/oprofile/oprof.c
    +++ b/drivers/oprofile/oprof.c
    @@ -239,26 +239,45 @@ int oprofile_set_ulong(unsigned long *addr, unsigned long val)
    return err;
    }

    +static int timer_mode;
    +
    static int __init oprofile_init(void)
    {
    int err;

    + /* always init architecture to setup backtrace support */
    err = oprofile_arch_init(&oprofile_ops);
    - if (err < 0 || timer) {
    - printk(KERN_INFO "oprofile: using timer interrupt.\n");
    +
    + timer_mode = err || timer; /* fall back to timer mode on errors */
    + if (timer_mode) {
    + if (!err)
    + oprofile_arch_exit();
    err = oprofile_timer_init(&oprofile_ops);
    if (err)
    return err;
    }
    - return oprofilefs_register();
    +
    + err = oprofilefs_register();
    + if (!err)
    + return 0;
    +
    + /* failed */
    + if (timer_mode)
    + oprofile_timer_exit();
    + else
    + oprofile_arch_exit();
    +
    + return err;
    }


    static void __exit oprofile_exit(void)
    {
    - oprofile_timer_exit();
    oprofilefs_unregister();
    - oprofile_arch_exit();
    + if (timer_mode)
    + oprofile_timer_exit();
    + else
    + oprofile_arch_exit();
    }


    diff --git a/drivers/oprofile/timer_int.c b/drivers/oprofile/timer_int.c
    index 3ef4462..878fba1 100644
    --- a/drivers/oprofile/timer_int.c
    +++ b/drivers/oprofile/timer_int.c
    @@ -110,6 +110,7 @@ int oprofile_timer_init(struct oprofile_operations *ops)
    ops->start = oprofile_hrtimer_start;
    ops->stop = oprofile_hrtimer_stop;
    ops->cpu_type = "timer";
    + printk(KERN_INFO "oprofile: using timer interrupt.\n");
    return 0;
    }

    --
    1.7.7



    \
     
     \ /
      Last update: 2011-10-19 20:51    [W:0.037 / U:0.900 seconds]
    ©2003-2016 Jasper Spaans. hosted at Digital OceanAdvertise on this site