From a4cfcd7cce65addecc70db2f194d5a208ae39604 Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Fri, 5 Mar 2010 16:29:14 +0100 Subject: [PATCH] --- yaml --- r: 191059 b: refs/heads/master c: a562b1871f7f7d2f3a835c3c1e07fa58d473cfb7 h: refs/heads/master i: 191057: f3389c3d8a84f68fc0d065409cdb626ef42082e7 191055: 6a4f288cf52ab35a1385234dd46b239a50c71f05 v: v3 --- [refs] | 2 +- .../arch/x86/kernel/cpu/perf_event_intel_ds.c | 21 +++++++++++++++++-- 2 files changed, 20 insertions(+), 3 deletions(-) diff --git a/[refs] b/[refs] index 43ef3285c9f1..bfff3ae7c611 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 74846d35b24b6efd61bb88a0a750b6bb257e6e78 +refs/heads/master: a562b1871f7f7d2f3a835c3c1e07fa58d473cfb7 diff --git a/trunk/arch/x86/kernel/cpu/perf_event_intel_ds.c b/trunk/arch/x86/kernel/cpu/perf_event_intel_ds.c index a67fff14475e..e7ac51770d4d 100644 --- a/trunk/arch/x86/kernel/cpu/perf_event_intel_ds.c +++ b/trunk/arch/x86/kernel/cpu/perf_event_intel_ds.c @@ -399,10 +399,23 @@ static int intel_pmu_pebs_fixup_ip(struct pt_regs *regs) if (!x86_pmu.intel_cap.pebs_trap) return 1; + /* + * No LBR entry, no basic block, no rewinding + */ if (!cpuc->lbr_stack.nr || !from || !to) return 0; - if (ip < to) + /* + * Basic blocks should never cross user/kernel boundaries + */ + if (kernel_ip(ip) != kernel_ip(to)) + return 0; + + /* + * unsigned math, either ip is before the start (impossible) or + * the basic block is larger than 1 page (sanity) + */ + if ((ip - to) > PAGE_SIZE) return 0; /* @@ -420,7 +433,7 @@ static int intel_pmu_pebs_fixup_ip(struct pt_regs *regs) old_to = to; if (!kernel_ip(ip)) { - int bytes, size = min_t(int, MAX_INSN_SIZE, ip - to); + int bytes, size = MAX_INSN_SIZE; bytes = copy_from_user_nmi(buf, (void __user *)to, size); if (bytes != size) @@ -440,6 +453,10 @@ static int intel_pmu_pebs_fixup_ip(struct pt_regs *regs) return 1; } + /* + * Even though we decoded the basic block, the instruction stream + * never matched the given IP, either the TO or the IP got corrupted. + */ return 0; }