From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 9244 invoked by alias); 7 Mar 2006 13:39:54 -0000 Received: (qmail 9236 invoked by uid 22791); 7 Mar 2006 13:39:53 -0000 X-Spam-Status: No, hits=-0.8 required=5.0 tests=AWL,BAYES_00,DNS_FROM_RFC_ABUSE,SPF_SOFTFAIL X-Spam-Check-By: sourceware.org Received: from e34.co.us.ibm.com (HELO e34.co.us.ibm.com) (32.97.110.152) by sourceware.org (qpsmtpd/0.31) with ESMTP; Tue, 07 Mar 2006 13:39:49 +0000 Received: from westrelay02.boulder.ibm.com (westrelay02.boulder.ibm.com [9.17.195.11]) by e34.co.us.ibm.com (8.12.11/8.12.11) with ESMTP id k27Ddkmi014275 for ; Tue, 7 Mar 2006 08:39:46 -0500 Received: from d03av02.boulder.ibm.com (d03av02.boulder.ibm.com [9.17.195.168]) by westrelay02.boulder.ibm.com (8.12.10/NCO/VER6.8) with ESMTP id k27Db5v9061072 for ; Tue, 7 Mar 2006 06:37:05 -0700 Received: from d03av02.boulder.ibm.com (loopback [127.0.0.1]) by d03av02.boulder.ibm.com (8.12.11/8.13.3) with ESMTP id k27Ddkpl025658 for ; Tue, 7 Mar 2006 06:39:46 -0700 Received: from newton.in.ibm.com ([9.124.35.47]) by d03av02.boulder.ibm.com (8.12.11/8.12.11) with ESMTP id k27Ddjf8025599 for ; Tue, 7 Mar 2006 06:39:45 -0700 Received: by newton.in.ibm.com (Postfix, from userid 500) id 80D73CE3; Tue, 7 Mar 2006 19:11:19 +0530 (IST) Date: Tue, 07 Mar 2006 13:39:00 -0000 From: Prasanna S Panchamukhi To: systemtap@sources.redhat.com Subject: Re: [3/5 PATCH] Kprobes fix for broken fault handling for ppc64 Message-ID: <20060307134119.GB32071@in.ibm.com> Reply-To: prasanna@in.ibm.com References: <20060307133832.GA2245@in.ibm.com> <20060307134010.GA32071@in.ibm.com> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20060307134010.GA32071@in.ibm.com> User-Agent: Mutt/1.4.1i X-IsSubscribed: yes Mailing-List: contact systemtap-help@sourceware.org; run by ezmlm Precedence: bulk List-Subscribe: List-Post: List-Help: , Sender: systemtap-owner@sourceware.org X-SW-Source: 2006-q1/txt/msg00724.txt.bz2 This patch fixes the broken kprobes fault handling similar to i386 architecture. Signed-off-by: Prasanna S Panchamukhi arch/powerpc/kernel/kprobes.c | 61 +++++++++++++++++++++++++++++++++++++----- 1 files changed, 54 insertions(+), 7 deletions(-) diff -puN arch/powerpc/kernel/kprobes.c~kprobes-powerpc-pagefault-handling arch/powerpc/kernel/kprobes.c --- linux-2.6.16-rc5-mm2/arch/powerpc/kernel/kprobes.c~kprobes-powerpc-pagefault-handling 2006-03-07 12:34:49.000000000 +0530 +++ linux-2.6.16-rc5-mm2-prasanna/arch/powerpc/kernel/kprobes.c 2006-03-07 12:34:49.000000000 +0530 @@ -30,9 +30,11 @@ #include #include #include +#include #include #include #include +#include DEFINE_PER_CPU(struct kprobe *, current_kprobe) = NULL; DEFINE_PER_CPU(struct kprobe_ctlblk, kprobe_ctlblk); @@ -372,17 +374,62 @@ static inline int kprobe_fault_handler(s { struct kprobe *cur = kprobe_running(); struct kprobe_ctlblk *kcb = get_kprobe_ctlblk(); + const struct exception_table_entry *entry; - if (cur->fault_handler && cur->fault_handler(cur, regs, trapnr)) - return 1; - - if (kcb->kprobe_status & KPROBE_HIT_SS) { - resume_execution(cur, regs); + switch(kcb->kprobe_status) { + case KPROBE_HIT_SS: + case KPROBE_REENTER: + /* + * We are here because the instruction being single + * stepped caused a page fault. We reset the current + * kprobe and the nip points back to the probe address + * and allow the page fault handler to continue as a + * normal page fault. + */ + regs->nip = (unsigned long)cur->addr; regs->msr &= ~MSR_SE; regs->msr |= kcb->kprobe_saved_msr; - - reset_current_kprobe(); + if (kcb->kprobe_status == KPROBE_REENTER) + restore_previous_kprobe(kcb); + else + reset_current_kprobe(); preempt_enable_no_resched(); + break; + case KPROBE_HIT_ACTIVE: + case KPROBE_HIT_SSDONE: + /* + * We increment the nmissed count for accounting, + * we can also use npre/npostfault count for accouting + * these specific fault cases. + */ + kprobes_inc_nmissed_count(cur); + + /* + * We come here because instructions in the pre/post + * handler caused the page_fault, this could happen + * if handler tries to access user space by + * copy_from_user(), get_user() etc. Let the + * user-specified handler try to fix it first. + */ + if (cur->fault_handler && cur->fault_handler(cur, regs, trapnr)) + return 1; + + /* + * In case the user-specified fault handler returned + * zero, try to fix up. + */ + if ((entry = search_exception_tables(regs->nip)) != NULL) { + regs->nip = entry->fixup; + return 1; + } + + /* + * fixup_exception() could not handle it, + * Let do_page_fault() fix it. + */ + break; + default: + break; } return 0; } _ -- Prasanna S Panchamukhi Linux Technology Center India Software Labs, IBM Bangalore Email: prasanna@in.ibm.com Ph: 91-80-51776329