From patchwork Sun Nov 16 21:24:32 2008 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Steven Rostedt X-Patchwork-Id: 9024 Return-Path: X-Original-To: patchwork-incoming@ozlabs.org Delivered-To: patchwork-incoming@ozlabs.org Received: from ozlabs.org (localhost [127.0.0.1]) by ozlabs.org (Postfix) with ESMTP id 5730DDE295 for ; Mon, 17 Nov 2008 08:27:44 +1100 (EST) X-Original-To: linuxppc-dev@ozlabs.org Delivered-To: linuxppc-dev@ozlabs.org Received: from hrndva-omtalb.mail.rr.com (hrndva-omtalb.mail.rr.com [71.74.56.124]) by ozlabs.org (Postfix) with ESMTP id 4C8E1DDE1F for ; Mon, 17 Nov 2008 08:25:18 +1100 (EST) Received: from gandalf.stny.rr.com ([74.67.89.75]) by hrndva-omta06.mail.rr.com with ESMTP id <20081116212516.HCNC26861.hrndva-omta06.mail.rr.com@gandalf.stny.rr.com>; Sun, 16 Nov 2008 21:25:16 +0000 Received: from rostedt by gandalf.stny.rr.com with local (Exim 4.69) (envelope-from ) id 1L1p7L-0006q9-SA; Sun, 16 Nov 2008 16:25:15 -0500 Message-Id: <20081116212515.728019601@goodmis.org> References: <20081116212428.938752312@goodmis.org> User-Agent: quilt/0.46-1 Date: Sun, 16 Nov 2008 16:24:32 -0500 From: Steven Rostedt To: linux-kernel@vger.kernel.org Subject: [PATCH 4/7] ftrace, PPC: use probe_kernel API to modify code Content-Disposition: inline; filename=0004-ftrace-PPC-use-probe_kernel-API-to-modify-code.patch Cc: Andrew Morton , Peter Zijlstra , Rusty Russell , Pekka Paalanen , David Miller , linuxppc-dev@ozlabs.org, Steven Rostedt , Paul Mundt , Paul Mackerras , Frederic Weisbecker , Ingo Molnar , Thomas Gleixner X-BeenThere: linuxppc-dev@ozlabs.org X-Mailman-Version: 2.1.11 Precedence: list List-Id: Linux on PowerPC Developers Mail List List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: linuxppc-dev-bounces+patchwork-incoming=ozlabs.org@ozlabs.org Errors-To: linuxppc-dev-bounces+patchwork-incoming=ozlabs.org@ozlabs.org Impact: use cleaner probe_kernel API over assembly Using probe_kernel_read/write interface is a much cleaner approach than the current assembly version. Signed-off-by: Steven Rostedt --- arch/powerpc/kernel/ftrace.c | 53 ++++++++++++++++------------------------- 1 files changed, 21 insertions(+), 32 deletions(-) diff --git a/arch/powerpc/kernel/ftrace.c b/arch/powerpc/kernel/ftrace.c index aa5d0b2..3852919 100644 --- a/arch/powerpc/kernel/ftrace.c +++ b/arch/powerpc/kernel/ftrace.c @@ -9,6 +9,7 @@ #include #include +#include #include #include #include @@ -72,45 +73,33 @@ static int ftrace_modify_code(unsigned long ip, unsigned char *old_code, unsigned char *new_code) { - unsigned replaced; - unsigned old = *(unsigned *)old_code; - unsigned new = *(unsigned *)new_code; - int faulted = 0; + unsigned char replaced[MCOUNT_INSN_SIZE]; /* * Note: Due to modules and __init, code can * disappear and change, we need to protect against faulting - * as well as code changing. + * as well as code changing. We do this by using the + * probe_kernel_* functions. * * No real locking needed, this code is run through - * kstop_machine. + * kstop_machine, or before SMP starts. */ - asm volatile ( - "1: lwz %1, 0(%2)\n" - " cmpw %1, %5\n" - " bne 2f\n" - " stwu %3, 0(%2)\n" - "2:\n" - ".section .fixup, \"ax\"\n" - "3: li %0, 1\n" - " b 2b\n" - ".previous\n" - ".section __ex_table,\"a\"\n" - _ASM_ALIGN "\n" - _ASM_PTR "1b, 3b\n" - ".previous" - : "=r"(faulted), "=r"(replaced) - : "r"(ip), "r"(new), - "0"(faulted), "r"(old) - : "memory"); - - if (replaced != old && replaced != new) - faulted = 2; - - if (!faulted) - flush_icache_range(ip, ip + 8); - - return faulted; + + /* read the text we want to modify */ + if (probe_kernel_read(replaced, (void *)ip, MCOUNT_INSN_SIZE)) + return -EFAULT; + + /* Make sure it is what we expect it to be */ + if (memcmp(replaced, old_code, MCOUNT_INSN_SIZE) != 0) + return -EINVAL; + + /* replace the text with the new text */ + if (probe_kernel_write((void *)ip, new_code, MCOUNT_INSN_SIZE)) + return -EPERM; + + flush_icache_range(ip, ip + 8); + + return 0; } static int test_24bit_addr(unsigned long ip, unsigned long addr)