From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753980AbbLJS4a (ORCPT ); Thu, 10 Dec 2015 13:56:30 -0500 Received: from www.linutronix.de ([62.245.132.108]:36393 "EHLO Galois.linutronix.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751136AbbLJS40 (ORCPT ); Thu, 10 Dec 2015 13:56:26 -0500 Date: Thu, 10 Dec 2015 19:55:35 +0100 (CET) From: Thomas Gleixner To: Jeff Merkey cc: LKML , mingo@redhat.com, "H. Peter Anvin" , x86@kernel.org, Peter Zijlstra , Andy Lutomirski , Masami Hiramatsu , Steven Rostedt Subject: Re: [PATCH 1/1] Fix int1 recursion when no perf_bp_event is registered In-Reply-To: Message-ID: References: User-Agent: Alpine 2.11 (DEB 23 2013-08-11) MIME-Version: 1.0 Content-Type: TEXT/PLAIN; charset=US-ASCII X-Linutronix-Spam-Score: -1.0 X-Linutronix-Spam-Level: - X-Linutronix-Spam-Status: No , -1.0 points, 5.0 required, ALL_TRUSTED=-1,SHORTCIRCUIT=-0.0001 Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Jeff, On Thu, 10 Dec 2015, Jeff Merkey wrote: > If an int1 hardware breakpoint exception is triggered, but no perf bp > pevent block was registered from arch_install_hw_breakpoint, the > system will hard hang with the CPU stuck constantly re-interrupting at > the same execution address because the resume flag never gets set, and > the NOTIFY_DONE state prevents other int1 handlers, including the > default handler in do_debug, from running to handle the condition. > Can be reproduced by writing a program that sets an execute breakpoint > at schedule() without calling arch_install_hw_breakpoint. > > The proposed fix checks the dr7 register and sets the resume flag in > pt->regs if it determines an executed breakpoint was triggered just in > case the check lower down fails. I have seen this bug and its a bug. > Signed-off-by: jeffmerkey@gmail.com > diff --git a/arch/x86/kernel/hw_breakpoint.c b/arch/x86/kernel/hw_breakpoint.c > index 50a3fad..6effcae 100644 > --- a/arch/x86/kernel/hw_breakpoint.c > +++ b/arch/x86/kernel/hw_breakpoint.c > @@ -475,6 +475,14 @@ static int hw_breakpoint_handler(struct die_args *args) > for (i = 0; i < HBP_NUM; ++i) { > if (likely(!(dr6 & (DR_TRAP0 << i)))) > continue; > + /* > + * Set up resume flag to avoid breakpoint recursion when > + * returning back to origin in the event an int1 > + * exception is triggered and no event handler > + * is present. > + */ > + if ((dr7 & (3 << ((i * 4) + 16))) == 0) We have proper defines for all of this. See __encode_dr7(). > + args->regs->flags |= X86_EFLAGS_RF; If there is a break point installed, then we do the same thing after calling perf_bp_event() again. Thanks, tglx