hw-breakpoints: Simplify error handling in breakpoint creation requests
[safe/jmp/linux-2.6] / kernel / hw_breakpoint.c
index e662dc9..dd3fb4a 100644 (file)
  * Copyright (C) 2009, Frederic Weisbecker <fweisbec@gmail.com>
  *
  * Thanks to Ingo Molnar for his many suggestions.
+ *
+ * Authors: Alan Stern <stern@rowland.harvard.edu>
+ *          K.Prasad <prasad@linux.vnet.ibm.com>
+ *          Frederic Weisbecker <fweisbec@gmail.com>
  */
 
 /*
 
 #include <linux/hw_breakpoint.h>
 
-#include <asm/processor.h>
-
-#ifdef CONFIG_X86
-#include <asm/debugreg.h>
-#endif
-
 /*
  * Constraints data
  */
@@ -269,7 +267,16 @@ int __register_perf_hw_breakpoint(struct perf_event *bp)
        if (ret)
                return ret;
 
-       if (!bp->attr.disabled)
+       /*
+        * Ptrace breakpoints can be temporary perf events only
+        * meant to reserve a slot. In this case, it is created disabled and
+        * we don't want to check the params right now (as we put a null addr)
+        * But perf tools create events as disabled and we want to check
+        * the params for them.
+        * This is a quick hack that will be removed soon, once we remove
+        * the tmp breakpoints from ptrace
+        */
+       if (!bp->attr.disabled || bp->callback == perf_bp_event)
                ret = arch_validate_hwbkpt_settings(bp, bp->ctx->task);
 
        return ret;
@@ -435,7 +442,7 @@ register_wide_hw_breakpoint(unsigned long addr,
 
                *pevent = bp;
 
-               if (IS_ERR(bp) || !bp) {
+               if (IS_ERR(bp)) {
                        err = PTR_ERR(bp);
                        goto fail;
                }
@@ -446,7 +453,7 @@ register_wide_hw_breakpoint(unsigned long addr,
 fail:
        for_each_possible_cpu(cpu) {
                pevent = per_cpu_ptr(cpu_events, cpu);
-               if (IS_ERR(*pevent) || !*pevent)
+               if (IS_ERR(*pevent))
                        break;
                unregister_hw_breakpoint(*pevent);
        }
@@ -454,6 +461,7 @@ fail:
        /* return the error if any */
        return ERR_PTR(err);
 }
+EXPORT_SYMBOL_GPL(register_wide_hw_breakpoint);
 
 /**
  * unregister_wide_hw_breakpoint - unregister a wide breakpoint in the kernel
@@ -470,7 +478,7 @@ void unregister_wide_hw_breakpoint(struct perf_event **cpu_events)
        }
        free_percpu(cpu_events);
 }
-
+EXPORT_SYMBOL_GPL(unregister_wide_hw_breakpoint);
 
 static struct notifier_block hw_breakpoint_exceptions_nb = {
        .notifier_call = hw_breakpoint_exceptions_notify,