• Ravi Bangoria's avatar
    powerpc/hw_breakpoint: Fix oops when destroying hw_breakpoint event · fb822e60
    Ravi Bangoria authored
    When destroying a hw_breakpoint event, the kernel oopses as follows:
    
      Unable to handle kernel paging request for data at address 0x00000c07
      NIP [c0000000000291d0] arch_unregister_hw_breakpoint+0x40/0x60
      LR [c00000000020b6b4] release_bp_slot+0x44/0x80
    
    Call chain:
    
      hw_breakpoint_event_init()
        bp->destroy = bp_perf_event_destroy;
    
      do_exit()
        perf_event_exit_task()
          perf_event_exit_task_context()
            WRITE_ONCE(child_ctx->task, TASK_TOMBSTONE);
            perf_event_exit_event()
              free_event()
                _free_event()
                  bp_perf_event_destroy() // event->destroy(event);
                    release_bp_slot()
                      arch_unregister_hw_breakpoint()
    
    perf_event_exit_task_context() sets child_ctx->task as TASK_TOMBSTONE
    which is (void *)-1. arch_unregister_hw_breakpoint() tries to fetch
    'thread' attribute of 'task' resulting in oops.
    
    Peterz points out that the code shouldn't be using bp->ctx anyway, but
    fixing that will require a decent amount of rework. So for now to fix
    the oops, check if bp->ctx->task has been set to (void *)-1, before
    dereferencing it. We don't use TASK_TOMBSTONE, because that would
    require exporting it and it's supposed to be an internal detail.
    
    Fixes: 63b6da39 ("perf: Fix perf_event_exit_task() race")
    Signed-off-by: default avatarRavi Bangoria <ravi.bangoria@linux.vnet.ibm.com>
    Acked-by: default avatarPeter Zijlstra (Intel) <peterz@infradead.org>
    Signed-off-by: default avatarMichael Ellerman <mpe@ellerman.id.au>
    fb822e60
hw_breakpoint.c 9.45 KB