Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1759810AbYLDTNe (ORCPT ); Thu, 4 Dec 2008 14:13:34 -0500 Received: (majordomo@vger.kernel.org) by vger.kernel.org id S1759577AbYLDTMk (ORCPT ); Thu, 4 Dec 2008 14:12:40 -0500 Received: from e28smtp03.in.ibm.com ([59.145.155.3]:51882 "EHLO e28smtp03.in.ibm.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1759564AbYLDTMj (ORCPT ); Thu, 4 Dec 2008 14:12:39 -0500 Date: Fri, 5 Dec 2008 00:42:31 +0530 From: "K.Prasad" To: Linux Kernel Mailing List Cc: Alan Stern , Roland McGrath , akpm@linux-foundation.org, mingo@elte.hu, richardj_moore@uk.ibm.com Subject: [RFC Patch 3/9] Modifying generic debug exception to use virtual debug registers Message-ID: <20081204191231.GC20563@in.ibm.com> Reply-To: prasad@linux.vnet.ibm.com References: <20081204190804.GA15134@in.ibm.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20081204190804.GA15134@in.ibm.com> User-Agent: Mutt/1.5.18 (2008-05-17) Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 3635 Lines: 115 This patch modifies the breakpoint exception handler code to use the abstract register names. Signed-off-by: K.Prasad Signed-off-by: Alan Stern --- arch/x86/kernel/traps.c | 68 ++++++++++++++++-------------------------------- 1 file changed, 24 insertions(+), 44 deletions(-) Index: linux-HBKPT-2.6.28-rc7/arch/x86/kernel/traps.c =================================================================== --- linux-HBKPT-2.6.28-rc7.orig/arch/x86/kernel/traps.c +++ linux-HBKPT-2.6.28-rc7/arch/x86/kernel/traps.c @@ -573,10 +573,11 @@ asmlinkage __kprobes struct pt_regs *syn dotraplinkage void __kprobes do_debug(struct pt_regs *regs, long error_code) { struct task_struct *tsk = current; - unsigned long condition; + unsigned long dr6; int si_code; - get_debugreg(condition, 6); + get_debugreg(dr6, 6); + set_debugreg(0, 6); /* DR6 may or may not be cleared by the CPU */ /* * The processor cleared BTF, so don't mark that we need it set. @@ -584,61 +585,40 @@ dotraplinkage void __kprobes do_debug(st clear_tsk_thread_flag(tsk, TIF_DEBUGCTLMSR); tsk->thread.debugctlmsr = 0; - if (notify_die(DIE_DEBUG, "debug", regs, condition, error_code, + /* Store the virtualized DR6 value */ + tsk->thread.vdr6 = dr6; + + if (notify_die(DIE_DEBUG, "debug", regs, dr6, error_code, SIGTRAP) == NOTIFY_STOP) return; /* It's safe to allow irq's after DR6 has been saved */ preempt_conditional_sti(regs); - /* Mask out spurious debug traps due to lazy DR7 setting */ - if (condition & (DR_TRAP0|DR_TRAP1|DR_TRAP2|DR_TRAP3)) { - if (!tsk->thread.debugreg7) - goto clear_dr7; + if (regs->flags & X86_VM_MASK) { + handle_vm86_trap((struct kernel_vm86_regs *) regs, + error_code, 1); + return; } #ifdef CONFIG_X86_32 - if (regs->flags & X86_VM_MASK) - goto debug_vm86; #endif - /* Save debug status register where ptrace can see it */ - tsk->thread.debugreg6 = condition; - - /* - * Single-stepping through TF: make sure we ignore any events in - * kernel space (but re-enable TF when returning to user mode). - */ - if (condition & DR_STEP) { - if (!user_mode(regs)) - goto clear_TF_reenable; - } - - si_code = get_si_code(condition); - /* Ok, finally something we can handle */ - send_sigtrap(tsk, regs, error_code, si_code); - /* - * Disable additional traps. They'll be re-enabled when - * the signal is delivered. + * Single-stepping through system calls: ignore any exceptions in + * kernel space, but re-enable TF when returning to user mode. + * + * We already checked v86 mode above, so we can check for kernel mode + * by just checking the CPL of CS. */ -clear_dr7: - set_debugreg(0, 7); - preempt_conditional_cli(regs); - return; - -#ifdef CONFIG_X86_32 -debug_vm86: - handle_vm86_trap((struct kernel_vm86_regs *) regs, error_code, 1); - preempt_conditional_cli(regs); - return; -#endif - -clear_TF_reenable: - set_tsk_thread_flag(tsk, TIF_SINGLESTEP); - regs->flags &= ~X86_EFLAGS_TF; - preempt_conditional_cli(regs); - return; + if ((dr6 & DR_STEP) && !user_mode(regs)) { + tsk->thread.vdr6 &= ~DR_STEP; + set_tsk_thread_flag(tsk, TIF_SINGLESTEP); + regs->flags &= ~X86_EFLAGS_TF; + } + si_code = get_si_code(dr6); + if (tsk->thread.vdr6 & (DR_STEP|DR_TRAP0|DR_TRAP1|DR_TRAP2|DR_TRAP3)) + send_sigtrap(tsk, regs, error_code, si_code); } #ifdef CONFIG_X86_64 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/