LBR_FORMAT_EIP          = 0x02,
        LBR_FORMAT_EIP_FLAGS    = 0x03,
        LBR_FORMAT_EIP_FLAGS2   = 0x04,
-       LBR_FORMAT_MAX_KNOWN    = LBR_FORMAT_EIP_FLAGS2,
+       LBR_FORMAT_INFO         = 0x05,
+       LBR_FORMAT_MAX_KNOWN    = LBR_FORMAT_INFO,
 };
 
 static enum {
        for (i = 0; i < x86_pmu.lbr_nr; i++) {
                wrmsrl(x86_pmu.lbr_from + i, 0);
                wrmsrl(x86_pmu.lbr_to   + i, 0);
+               if (x86_pmu.intel_cap.lbr_format == LBR_FORMAT_INFO)
+                       wrmsrl(MSR_LBR_INFO_0 + i, 0);
        }
 }
 
                lbr_idx = (tos - i) & mask;
                wrmsrl(x86_pmu.lbr_from + lbr_idx, task_ctx->lbr_from[i]);
                wrmsrl(x86_pmu.lbr_to + lbr_idx, task_ctx->lbr_to[i]);
+               if (x86_pmu.intel_cap.lbr_format == LBR_FORMAT_INFO)
+                       wrmsrl(MSR_LBR_INFO_0 + i, task_ctx->lbr_info[i]);
        }
        task_ctx->lbr_stack_state = LBR_NONE;
 }
                lbr_idx = (tos - i) & mask;
                rdmsrl(x86_pmu.lbr_from + lbr_idx, task_ctx->lbr_from[i]);
                rdmsrl(x86_pmu.lbr_to + lbr_idx, task_ctx->lbr_to[i]);
+               if (x86_pmu.intel_cap.lbr_format == LBR_FORMAT_INFO)
+                       rdmsrl(MSR_LBR_INFO_0 + i, task_ctx->lbr_info[i]);
        }
        task_ctx->lbr_stack_state = LBR_VALID;
 }
                unsigned long lbr_idx = (tos - i) & mask;
                u64 from, to, mis = 0, pred = 0, in_tx = 0, abort = 0;
                int skip = 0;
+               u16 cycles = 0;
                int lbr_flags = lbr_desc[lbr_format];
 
                rdmsrl(x86_pmu.lbr_from + lbr_idx, from);
                rdmsrl(x86_pmu.lbr_to   + lbr_idx, to);
 
+               if (lbr_format == LBR_FORMAT_INFO) {
+                       u64 info;
+
+                       rdmsrl(MSR_LBR_INFO_0 + lbr_idx, info);
+                       mis = !!(info & LBR_INFO_MISPRED);
+                       pred = !mis;
+                       in_tx = !!(info & LBR_INFO_IN_TX);
+                       abort = !!(info & LBR_INFO_ABORT);
+                       cycles = (info & LBR_INFO_CYCLES);
+               }
                if (lbr_flags & LBR_EIP_FLAGS) {
                        mis = !!(from & LBR_FROM_FLAG_MISPRED);
                        pred = !mis;
                cpuc->lbr_entries[out].predicted = pred;
                cpuc->lbr_entries[out].in_tx     = in_tx;
                cpuc->lbr_entries[out].abort     = abort;
+               cpuc->lbr_entries[out].cycles    = cycles;
                cpuc->lbr_entries[out].reserved  = 0;
                out++;
        }