Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751799AbcDNT3f (ORCPT ); Thu, 14 Apr 2016 15:29:35 -0400 Received: from mail-ob0-f169.google.com ([209.85.214.169]:33109 "EHLO mail-ob0-f169.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1750913AbcDNT3d (ORCPT ); Thu, 14 Apr 2016 15:29:33 -0400 MIME-Version: 1.0 In-Reply-To: <1460657414-12530-4-git-send-email-dsafonov@virtuozzo.com> References: <1460657414-12530-1-git-send-email-dsafonov@virtuozzo.com> <1460657414-12530-4-git-send-email-dsafonov@virtuozzo.com> From: Andy Lutomirski Date: Thu, 14 Apr 2016 12:29:12 -0700 Message-ID: Subject: Re: [PATCH 3/4] x86/intel lbr: down with test_thread_flag(TIF_IA32) To: Dmitry Safonov , Peter Zijlstra Cc: "linux-kernel@vger.kernel.org" , Thomas Gleixner , Ingo Molnar , "H. Peter Anvin" , X86 ML , Robert Richter , oprofile-list@lists.sf.net, Dmitry Safonov <0x7f454c46@gmail.com> Content-Type: text/plain; charset=UTF-8 Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 2942 Lines: 81 On Thu, Apr 14, 2016 at 11:10 AM, Dmitry Safonov wrote: > Use user_mode64_bit to check process state. For that pass > interrupt register set from irq handler. > This should fix opcode decoder misinterpreting ABI for > tasks that change their code selector. > > Signed-off-by: Dmitry Safonov > --- > arch/x86/events/intel/core.c | 2 +- > arch/x86/events/intel/lbr.c | 17 ++++++++++------- > arch/x86/events/perf_event.h | 2 +- > 3 files changed, 12 insertions(+), 9 deletions(-) > > diff --git a/arch/x86/events/intel/core.c b/arch/x86/events/intel/core.c > index 68fa55b4d42e..df13d1d6dbf6 100644 > --- a/arch/x86/events/intel/core.c > +++ b/arch/x86/events/intel/core.c > @@ -1860,7 +1860,7 @@ static int intel_pmu_handle_irq(struct pt_regs *regs) > > loops = 0; > again: > - intel_pmu_lbr_read(); > + intel_pmu_lbr_read(regs); > intel_pmu_ack_status(status); > if (++loops > 100) { > static bool warned = false; > diff --git a/arch/x86/events/intel/lbr.c b/arch/x86/events/intel/lbr.c > index 6c3b7c1780c9..f1a1dbc77dea 100644 > --- a/arch/x86/events/intel/lbr.c > +++ b/arch/x86/events/intel/lbr.c > @@ -136,7 +136,9 @@ enum { > X86_BR_IRQ |\ > X86_BR_INT) > > -static void intel_pmu_lbr_filter(struct cpu_hw_events *cpuc); > + > +static void > +intel_pmu_lbr_filter(struct pt_regs *regs, struct cpu_hw_events *cpuc); > > /* > * We only support LBR implementations that have FREEZE_LBRS_ON_PMI > @@ -500,7 +502,7 @@ static void intel_pmu_lbr_read_64(struct cpu_hw_events *cpuc) > cpuc->lbr_stack.nr = out; > } > > -void intel_pmu_lbr_read(void) > +void intel_pmu_lbr_read(struct pt_regs *regs) > { > struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events); > > @@ -512,7 +514,7 @@ void intel_pmu_lbr_read(void) > else > intel_pmu_lbr_read_64(cpuc); > > - intel_pmu_lbr_filter(cpuc); > + intel_pmu_lbr_filter(regs, cpuc); > } > > /* > @@ -658,7 +660,8 @@ int intel_pmu_setup_lbr_filter(struct perf_event *event) > * decoded (e.g., text page not present), then X86_BR_NONE is > * returned. > */ > -static int branch_type(unsigned long from, unsigned long to, int abort) > +static int branch_type(unsigned long from, unsigned long to, int abort, > + struct pt_regs *regs) > { > struct insn insn; > void *addr; > @@ -724,7 +727,7 @@ static int branch_type(unsigned long from, unsigned long to, int abort) > * on 64-bit systems running 32-bit apps > */ > #ifdef CONFIG_X86_64 > - is64 = kernel_ip((unsigned long)addr) || !test_thread_flag(TIF_IA32); > + is64 = kernel_ip((unsigned long)addr) || user_64bit_mode(regs); Peterz, looking at this some more, would it make sense to pass user_regs and interrupt_regs (or whatever we'd call it) all the way through to here? --Andy