exclude_host   :  1, /* don't count in host   */
                                exclude_guest  :  1, /* don't count in guest  */
 
-                               __reserved_1   : 43;
+                               exclude_callchain_kernel : 1, /* exclude kernel callchains */
+                               exclude_callchain_user   : 1, /* exclude user callchains */
+
+                               __reserved_1   : 41;
 
        union {
                __u32           wakeup_events;    /* wakeup every n events */
 
        int rctx;
        struct perf_callchain_entry *entry;
 
+       int kernel = !event->attr.exclude_callchain_kernel;
+       int user   = !event->attr.exclude_callchain_user;
+
+       if (!kernel && !user)
+               return NULL;
 
        entry = get_callchain_entry(&rctx);
        if (rctx == -1)
 
        entry->nr = 0;
 
-       if (!user_mode(regs)) {
+       if (kernel && !user_mode(regs)) {
                perf_callchain_store(entry, PERF_CONTEXT_KERNEL);
                perf_callchain_kernel(entry, regs);
-               if (current->mm)
-                       regs = task_pt_regs(current);
-               else
-                       regs = NULL;
        }
 
-       if (regs) {
-               /*
-                * Disallow cross-task user callchains.
-                */
-               if (event->ctx->task && event->ctx->task != current)
-                       goto exit_put;
-
-               perf_callchain_store(entry, PERF_CONTEXT_USER);
-               perf_callchain_user(entry, regs);
+       if (user) {
+               if (!user_mode(regs)) {
+                       if  (current->mm)
+                               regs = task_pt_regs(current);
+                       else
+                               regs = NULL;
+               }
+
+               if (regs) {
+                       /*
+                        * Disallow cross-task user callchains.
+                        */
+                       if (event->ctx->task && event->ctx->task != current)
+                               goto exit_put;
+
+                       perf_callchain_store(entry, PERF_CONTEXT_USER);
+                       perf_callchain_user(entry, regs);
+               }
        }
 
 exit_put: