Create instrumentation/ kernel directory
Subsystems (18)
cover Create instrumentation/ kernel directory
Hi,
Since we already have the Instrumentation menu in kernel/Kconfig.instrumentation and instrumentation code all over the kernel tree:
arch/*/oprofile/*.ckernel/kprobes.carch/*/kernel/kprobes.ckernel/marker.ckernel/profile.ckernel/lockdep.cvm/vmstat.cblock/blktrace.c
We could move them to
instrumentation/arch/*/instrumentation/
Therefore, we could also move the kprobes and marker samples under
instrumentation/samples/
I submit these patches for review/comments, especially about kernel build integration. instrumentation/ is currently a core-y and arch/*/instrumentation/ is a drivers-y because of oprofile.
Mathieu
Signature · 3 lines
Mathieu Desnoyers Computer Engineering Ph.D. Student, Ecole Polytechnique de Montreal OpenPGP key fingerprint: 8CD5 52C3 8E3C 4140 715F BA06 3F25 A8FE 3BAE 9A68
PATCH 1/10 Create instrumentation directory
Since we already have the Instrumentation menu in kernel/Kconfig.instrumentation and instrumentation code all over the kernel tree:
arch/*/oprofile/*.ckernel/kprobes.carch/*/kernel/kprobes.ckernel/marker.ckernel/profile.ckernel/lockdep.cvm/vmstat.cblock/blktrace.c
We could move them to
instrumentation/arch/*/instrumentation/
Therefore, we could also move the kprobes and marker samples under
instrumentation/samples/
--- arch/alpha/Kconfig | 2 - arch/arm/Kconfig | 2 - arch/blackfin/Kconfig | 2 - arch/cris/Kconfig | 2 - arch/frv/Kconfig | 2 - arch/h8300/Kconfig | 2 - arch/i386/Kconfig | 2 - arch/ia64/Kconfig | 2 - arch/m32r/Kconfig | 2 - arch/m68k/Kconfig | 2 - arch/m68knommu/Kconfig | 2 - arch/mips/Kconfig | 2 - arch/parisc/Kconfig | 2 - arch/powerpc/Kconfig | 2 - arch/ppc/Kconfig | 2 - arch/s390/Kconfig | 2 - arch/sh/Kconfig | 2 - arch/sh64/Kconfig | 2 - arch/sparc/Kconfig | 2 - arch/sparc64/Kconfig | 2 - arch/um/Kconfig | 2 - arch/v850/Kconfig | 2 - arch/x86_64/Kconfig | 2 - arch/xtensa/Kconfig | 2 - instrumentation/Kconfig | 49 +++++++++++++++++++++++++++++++++++++++++ instrumentation/Makefile | 3 ++ kernel/Kconfig.instrumentation | 49 ----------------------------------------- 27 files changed, 76 insertions(+), 73 deletions(-)
instrumentation/Kconfig new file +49 -0
@@ -0,0 +1,49 @@ +menuconfig INSTRUMENTATION + bool "Instrumentation Support" + default y + ---help--- + Say Y here to get to see options related to performance measurement, + system-wide debugging, and testing. This option alone does not add any + kernel code. + + If you say N, all options in this submenu will be skipped and + disabled. If you're trying to debug the kernel itself, go see the + Kernel Hacking menu. + +if INSTRUMENTATION + +config PROFILING + bool "Profiling support (EXPERIMENTAL)" + help + Say Y here to enable the extended profiling support mechanisms used + by profilers such as OProfile. + +config OPROFILE + tristate "OProfile system profiling (EXPERIMENTAL)" + depends on PROFILING + depends on ALPHA || ARM || BLACKFIN || X86_32 || IA64 || M32R || MIPS || PARISC || PPC || S390 || SUPERH || SPARC || X86_64 + help + OProfile is a profiling system capable of profiling the + whole system, include the kernel, kernel modules, libraries, + and applications. + + If unsure, say N. + +config KPROBES + bool "Kprobes" + depends on KALLSYMS && MODULES + depends on X86_32 || IA64 || PPC || S390 || SPARC64 || X86_64 || AVR32 + help + Kprobes allows you to trap at almost any kernel address and + execute a callback function. register_kprobe() establishes + a probepoint and specifies the callback. Kprobes is useful + for kernel debugging, non-intrusive instrumentation and testing. + If in doubt, say "N". + +config MARKERS + bool "Activate markers" + help + Place an empty function call at each marker site. Can be + dynamically changed for a probe function. + +endif # INSTRUMENTATION
kernel/Kconfig.instrumentation deleted +0 -49
49 lines not on this page · raw message
arch/alpha/Kconfig +1 -1
@@ -654,7 +654,7 @@ source "drivers/Kconfig" source "fs/Kconfig" -source "kernel/Kconfig.instrumentation" +source "instrumentation/Kconfig" source "arch/alpha/Kconfig.debug"
arch/arm/Kconfig +1 -1
@@ -1068,7 +1068,7 @@ endmenu source "fs/Kconfig" -source "kernel/Kconfig.instrumentation" +source "instrumentation/Kconfig" source "arch/arm/Kconfig.debug"
arch/blackfin/Kconfig +1 -1
@@ -1062,7 +1062,7 @@ source "drivers/Kconfig" source "fs/Kconfig" -source "kernel/Kconfig.instrumentation" +source "instrumentation/Kconfig" menu "Kernel hacking"
arch/cris/Kconfig +1 -1
@@ -196,7 +196,7 @@ source "sound/Kconfig" source "drivers/usb/Kconfig" -source "kernel/Kconfig.instrumentation" +source "instrumentation/Kconfig" source "arch/cris/Kconfig.debug"
arch/frv/Kconfig +1 -1
@@ -375,7 +375,7 @@ source "drivers/Kconfig" source "fs/Kconfig" -source "kernel/Kconfig.instrumentation" +source "instrumentation/Kconfig" source "arch/frv/Kconfig.debug"
arch/h8300/Kconfig +1 -1
@@ -223,7 +223,7 @@ endmenu source "fs/Kconfig" -source "kernel/Kconfig.instrumentation" +source "instrumentation/Kconfig" source "arch/h8300/Kconfig.debug"
arch/i386/Kconfig +1 -1
@@ -1270,7 +1270,7 @@ source "drivers/Kconfig" source "fs/Kconfig" -source "kernel/Kconfig.instrumentation" +source "instrumentation/Kconfig" source "arch/i386/Kconfig.debug"
arch/ia64/Kconfig +1 -1
@@ -592,7 +592,7 @@ config IRQ_PER_CPU source "arch/ia64/hp/sim/Kconfig" -source "kernel/Kconfig.instrumentation" +source "instrumentation/Kconfig" source "arch/ia64/Kconfig.debug"
arch/m32r/Kconfig +1 -1
@@ -426,7 +426,7 @@ source "drivers/Kconfig" source "fs/Kconfig" -source "kernel/Kconfig.instrumentation" +source "instrumentation/Kconfig" source "arch/m32r/Kconfig.debug"
arch/m68k/Kconfig +1 -1
@@ -683,7 +683,7 @@ endmenu source "fs/Kconfig" -source "kernel/Kconfig.instrumentation" +source "instrumentation/Kconfig" source "arch/m68k/Kconfig.debug"
arch/m68knommu/Kconfig +1 -1
@@ -707,7 +707,7 @@ source "drivers/Kconfig" source "fs/Kconfig" -source "kernel/Kconfig.instrumentation" +source "instrumentation/Kconfig" source "arch/m68knommu/Kconfig.debug"
arch/mips/Kconfig +1 -1
@@ -2009,7 +2009,7 @@ source "drivers/Kconfig" source "fs/Kconfig" -source "kernel/Kconfig.instrumentation" +source "instrumentation/Kconfig" source "arch/mips/Kconfig.debug"
arch/parisc/Kconfig +1 -1
@@ -267,7 +267,7 @@ source "drivers/Kconfig" source "fs/Kconfig" -source "kernel/Kconfig.instrumentation" +source "instrumentation/Kconfig" source "arch/parisc/Kconfig.debug"
arch/powerpc/Kconfig +1 -1
@@ -669,7 +669,7 @@ source "arch/powerpc/sysdev/qe_lib/Kconf source "lib/Kconfig" -source "kernel/Kconfig.instrumentation" +source "instrumentation/Kconfig" source "arch/powerpc/Kconfig.debug"
arch/ppc/Kconfig +1 -1
@@ -1317,7 +1317,7 @@ endmenu source "lib/Kconfig" -source "kernel/Kconfig.instrumentation" +source "instrumentation/Kconfig" source "arch/ppc/Kconfig.debug"
arch/s390/Kconfig +1 -1
@@ -529,7 +529,7 @@ source "drivers/Kconfig" source "fs/Kconfig" -source "kernel/Kconfig.instrumentation" +source "instrumentation/Kconfig" source "arch/s390/Kconfig.debug"
arch/sh/Kconfig +1 -1
@@ -758,7 +758,7 @@ source "drivers/Kconfig" source "fs/Kconfig" -source "kernel/Kconfig.instrumentation" +source "instrumentation/Kconfig" source "arch/sh/Kconfig.debug"
arch/sh64/Kconfig +1 -1
@@ -284,7 +284,7 @@ source "drivers/Kconfig" source "fs/Kconfig" -source "kernel/Kconfig.instrumentation" +source "instrumentation/Kconfig" source "arch/sh64/Kconfig.debug"
arch/sparc/Kconfig +1 -1
@@ -320,7 +320,7 @@ endmenu source "fs/Kconfig" -source "kernel/Kconfig.instrumentation" +source "instrumentation/Kconfig" source "arch/sparc/Kconfig.debug"
arch/sparc64/Kconfig +1 -1
@@ -462,7 +462,7 @@ source "drivers/sbus/char/Kconfig" source "fs/Kconfig" -source "kernel/Kconfig.instrumentation" +source "instrumentation/Kconfig" source "arch/sparc64/Kconfig.debug"
arch/um/Kconfig +1 -1
@@ -289,6 +289,6 @@ config INPUT bool default n -source "kernel/Kconfig.instrumentation" +source "instrumentation/Kconfig" source "arch/um/Kconfig.debug"
arch/v850/Kconfig +1 -1
@@ -331,7 +331,7 @@ source "sound/Kconfig" source "drivers/usb/Kconfig" -source "kernel/Kconfig.instrumentation" +source "instrumentation/Kconfig" source "arch/v850/Kconfig.debug"
arch/x86_64/Kconfig +1 -1
@@ -833,7 +833,7 @@ source "drivers/firmware/Kconfig" source fs/Kconfig -source "kernel/Kconfig.instrumentation" +source "instrumentation/Kconfig" source "arch/x86_64/Kconfig.debug"
arch/xtensa/Kconfig +1 -1
@@ -251,7 +251,7 @@ config EMBEDDED_RAMDISK_IMAGE provide one yourself. endmenu -source "kernel/Kconfig.instrumentation" +source "instrumentation/Kconfig" source "arch/xtensa/Kconfig.debug"
instrumentation/Makefile new file +3 -0
@@ -0,0 +1,3 @@ +# +# Makefile for the linux kernel instrumentation +#
Signature · 3 lines
Mathieu Desnoyers Computer Engineering Ph.D. Student, Ecole Polytechnique de Montreal OpenPGP key fingerprint: 8CD5 52C3 8E3C 4140 715F BA06 3F25 A8FE 3BAE 9A68
PATCH 1/10 Move oprofile to arch/*/instrumentation
In reply to Mathieu DesnoyersThis patch is way too big for LKML (524k). I'll split it into each different architectures for next submission.
Here is the changelog:
Move oprofile to arch/*/instrumentation
- Move oprofile to arch/*/instrumentation
- Fix per architecture Makefiles to follow this change
- Did _not_ fix whitespaces in oprofile so the file move is easy to follow.
--- arch/alpha/Makefile | 2 arch/alpha/instrumentation/Makefile | 19 arch/alpha/instrumentation/common.c | 189 +++ arch/alpha/instrumentation/op_impl.h | 55 arch/alpha/instrumentation/op_model_ev4.c | 116 ++ arch/alpha/instrumentation/op_model_ev5.c | 211 +++ arch/alpha/instrumentation/op_model_ev6.c | 103 + arch/alpha/instrumentation/op_model_ev67.c | 263 ++++ arch/alpha/oprofile/Makefile | 19 arch/alpha/oprofile/common.c | 189 --- arch/alpha/oprofile/op_impl.h | 55 arch/alpha/oprofile/op_model_ev4.c | 116 -- arch/alpha/oprofile/op_model_ev5.c | 211 --- arch/alpha/oprofile/op_model_ev6.c | 103 - arch/alpha/oprofile/op_model_ev67.c | 263 ---- arch/arm/Makefile | 2 arch/arm/instrumentation/Makefile | 13 arch/arm/instrumentation/backtrace.c | 81 + arch/arm/instrumentation/common.c | 179 +++ arch/arm/instrumentation/op_arm_model.h | 34 arch/arm/instrumentation/op_counter.h | 27 arch/arm/instrumentation/op_model_arm11_core.c | 162 ++ arch/arm/instrumentation/op_model_arm11_core.h | 45 arch/arm/instrumentation/op_model_mpcore.c | 303 +++++ arch/arm/instrumentation/op_model_mpcore.h | 61 + arch/arm/instrumentation/op_model_v6.c | 67 + arch/arm/instrumentation/op_model_xscale.c | 441 ++++++++ arch/arm/oprofile/Makefile | 13 arch/arm/oprofile/backtrace.c | 81 - arch/arm/oprofile/common.c | 179 --- arch/arm/oprofile/op_arm_model.h | 34 arch/arm/oprofile/op_counter.h | 27 arch/arm/oprofile/op_model_arm11_core.c | 162 -- arch/arm/oprofile/op_model_arm11_core.h | 45 arch/arm/oprofile/op_model_mpcore.c | 303 ----- arch/arm/oprofile/op_model_mpcore.h | 61 - arch/arm/oprofile/op_model_v6.c | 67 - arch/arm/oprofile/op_model_xscale.c | 441 -------- arch/avr32/Makefile | 1 arch/avr32/instrumentation/Makefile | 3 arch/blackfin/Makefile | 3 arch/blackfin/instrumentation/Makefile | 14 arch/blackfin/instrumentation/common.c | 168 +++ arch/blackfin/instrumentation/op_blackfin.h | 98 + arch/blackfin/instrumentation/op_model_bf533.c | 161 ++ arch/blackfin/instrumentation/timer_int.c | 73 + arch/blackfin/oprofile/Makefile | 14 arch/blackfin/oprofile/common.c | 168 --- arch/blackfin/oprofile/op_blackfin.h | 98 - arch/blackfin/oprofile/op_model_bf533.c | 161 -- arch/blackfin/oprofile/timer_int.c | 73 - arch/i386/Makefile | 2 arch/ia64/Makefile | 2 arch/ia64/instrumentation/Makefile | 10 arch/ia64/instrumentation/backtrace.c | 150 ++ arch/ia64/instrumentation/init.c | 38 arch/ia64/instrumentation/perfmon.c | 99 + arch/ia64/oprofile/Makefile | 10 arch/ia64/oprofile/backtrace.c | 150 -- arch/ia64/oprofile/init.c | 38 arch/ia64/oprofile/perfmon.c | 99 - arch/m32r/Makefile | 2 arch/m32r/instrumentation/Makefile | 9 arch/m32r/instrumentation/init.c | 22 arch/m32r/oprofile/Makefile | 9 arch/m32r/oprofile/init.c | 22 arch/mips/Makefile | 2 arch/mips/instrumentation/Makefile | 17 arch/mips/instrumentation/common.c | 123 ++ arch/mips/instrumentation/op_impl.h | 40 arch/mips/instrumentation/op_model_mipsxx.c | 348 ++++++ arch/mips/instrumentation/op_model_rm9000.c | 138 ++ arch/mips/oprofile/Makefile | 17 arch/mips/oprofile/common.c | 123 -- arch/mips/oprofile/op_impl.h | 40 arch/mips/oprofile/op_model_mipsxx.c | 348 ------ arch/mips/oprofile/op_model_rm9000.c | 138 -- arch/parisc/Makefile | 2 arch/parisc/instrumentation/Makefile | 9 arch/parisc/instrumentation/init.c | 23 arch/parisc/oprofile/Makefile | 9 arch/parisc/oprofile/init.c | 23 arch/powerpc/Makefile | 2 arch/powerpc/instrumentation/Makefile | 19 arch/powerpc/instrumentation/backtrace.c | 127 ++ arch/powerpc/instrumentation/common.c | 232 ++++ arch/powerpc/instrumentation/op_model_7450.c | 212 +++ arch/powerpc/instrumentation/op_model_cell.c | 1211 ++++++++++++++++++++++ arch/powerpc/instrumentation/op_model_fsl_booke.c | 371 ++++++ arch/powerpc/instrumentation/op_model_pa6t.c | 240 ++++ arch/powerpc/instrumentation/op_model_power4.c | 317 +++++ arch/powerpc/instrumentation/op_model_rs64.c | 224 ++++ arch/powerpc/oprofile/Makefile | 19 arch/powerpc/oprofile/backtrace.c | 127 -- arch/powerpc/oprofile/common.c | 232 ---- arch/powerpc/oprofile/op_model_7450.c | 212 --- arch/powerpc/oprofile/op_model_cell.c | 1211 ---------------------- arch/powerpc/oprofile/op_model_fsl_booke.c | 371 ------ arch/powerpc/oprofile/op_model_pa6t.c | 240 ---- arch/powerpc/oprofile/op_model_power4.c | 317 ----- arch/powerpc/oprofile/op_model_rs64.c | 224 ---- arch/ppc/Makefile | 2 arch/s390/Makefile | 2 arch/s390/instrumentation/Makefile | 9 arch/s390/instrumentation/backtrace.c | 79 + arch/s390/instrumentation/init.c | 26 arch/s390/oprofile/Makefile | 9 arch/s390/oprofile/backtrace.c | 79 - arch/s390/oprofile/init.c | 26 arch/sh/Makefile | 2 arch/sh/instrumentation/Makefile | 17 arch/sh/instrumentation/op_model_null.c | 23 arch/sh/instrumentation/op_model_sh7750.c | 281 +++++ arch/sh/oprofile/Makefile | 17 arch/sh/oprofile/op_model_null.c | 23 arch/sh/oprofile/op_model_sh7750.c | 281 ----- arch/sh64/Makefile | 2 arch/sh64/instrumentation/Makefile | 12 arch/sh64/instrumentation/op_model_null.c | 23 arch/sh64/oprofile/Makefile | 12 arch/sh64/oprofile/op_model_null.c | 23 arch/sparc/Makefile | 2 arch/sparc/instrumentation/Makefile | 9 arch/sparc/instrumentation/init.c | 23 arch/sparc/oprofile/Makefile | 9 arch/sparc/oprofile/init.c | 23 arch/sparc64/Makefile | 2 arch/sparc64/instrumentation/Makefile | 9 arch/sparc64/instrumentation/init.c | 23 arch/sparc64/oprofile/Makefile | 9 arch/sparc64/oprofile/init.c | 23 arch/x86/instrumentation/Makefile | 12 arch/x86/instrumentation/backtrace.c | 91 + arch/x86/instrumentation/init.c | 48 arch/x86/instrumentation/nmi_int.c | 477 ++++++++ arch/x86/instrumentation/nmi_timer_int.c | 69 + arch/x86/instrumentation/op_counter.h | 29 arch/x86/instrumentation/op_model_athlon.c | 180 +++ arch/x86/instrumentation/op_model_p4.c | 722 +++++++++++++ arch/x86/instrumentation/op_model_ppro.c | 192 +++ arch/x86/instrumentation/op_x86_model.h | 51 arch/x86/oprofile/Makefile | 12 arch/x86/oprofile/backtrace.c | 91 - arch/x86/oprofile/init.c | 48 arch/x86/oprofile/nmi_int.c | 477 -------- arch/x86/oprofile/nmi_timer_int.c | 69 - arch/x86/oprofile/op_counter.h | 29 arch/x86/oprofile/op_model_athlon.c | 180 --- arch/x86/oprofile/op_model_p4.c | 722 ------------- arch/x86/oprofile/op_model_ppro.c | 192 --- arch/x86/oprofile/op_x86_model.h | 51 arch/x86_64/Makefile | 2 152 files changed, 9287 insertions(+), 9284 deletions(-)
Signature · 3 lines
Mathieu Desnoyers Computer Engineering Ph.D. Student, Ecole Polytechnique de Montreal OpenPGP key fingerprint: 8CD5 52C3 8E3C 4140 715F BA06 3F25 A8FE 3BAE 9A68
PATCH 3/10 Move kprobes to instrumentation/ and arch/*/instrumentation/
In reply to Mathieu DesnoyersConsolidate the kprobes in the instrumentation directory.
- /instrumentation is compiled as a core-y
- Note : arch/*/instrumentation/kprobes.c is now compiled as a drivers-y. Was a core-y before. It is caused by oprofile being a drivers-y.
--- Makefile | 3 arch/avr32/instrumentation/Makefile | 2 arch/avr32/instrumentation/kprobes.c | 268 ++++++++ arch/avr32/kernel/Makefile | 1 arch/avr32/kernel/kprobes.c | 268 -------- arch/ia64/instrumentation/Makefile | 2 arch/ia64/instrumentation/kprobes.c | 1027 +++++++++++++++++++++++++++++++ arch/ia64/kernel/kprobes.c | 1027 ------------------------------- arch/powerpc/instrumentation/Makefile | 2 arch/powerpc/instrumentation/kprobes.c | 559 +++++++++++++++++ arch/powerpc/kernel/kprobes.c | 559 ----------------- arch/s390/instrumentation/Makefile | 2 arch/s390/instrumentation/kprobes.c | 672 ++++++++++++++++++++ arch/s390/kernel/kprobes.c | 672 -------------------- arch/sparc64/instrumentation/Makefile | 2 arch/sparc64/instrumentation/kprobes.c | 487 +++++++++++++++ arch/sparc64/kernel/kprobes.c | 487 --------------- arch/x86/instrumentation/Makefile | 6 arch/x86/instrumentation/kprobes_32.c | 763 +++++++++++++++++++++++ arch/x86/instrumentation/kprobes_64.c | 761 +++++++++++++++++++++++ arch/x86/kernel/Makefile_32 | 1 arch/x86/kernel/Makefile_64 | 1 arch/x86/kernel/kprobes_32.c | 763 ----------------------- arch/x86/kernel/kprobes_64.c | 761 ----------------------- instrumentation/Makefile | 2 instrumentation/kprobes.c | 1063 +++++++++++++++++++++++++++++++++ kernel/Makefile | 1 kernel/kprobes.c | 1063 --------------------------------- 28 files changed, 5620 insertions(+), 5605 deletions(-)
instrumentation/kprobes.c new file +1063 -0
@@ -0,0 +1,1063 @@ +/* +* Kernel Probes (KProbes) +* kernel/kprobes.c +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 2 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +* +* Copyright (C) IBM Corporation, 2002, 2004 +* +* 2002-Oct Created by Vamsi Krishna S <[email protected]> Kernel +* Probes initial implementation (includes suggestions from +* Rusty Russell). +* 2004-Aug Updated by Prasanna S Panchamukhi <[email protected]> with +* hlists and exceptions notifier as suggested by Andi Kleen. +* 2004-July Suparna Bhattacharya <[email protected]> added jumper probes +* interface to access function arguments. +* 2004-Sep Prasanna S Panchamukhi <[email protected]> Changed Kprobes +* exceptions notifier to be first on the priority list. +* 2005-May Hien Nguyen <[email protected]>, Jim Keniston +* <[email protected]> and Prasanna S Panchamukhi +* <[email protected]> added function-return probes. +*/ +#include <linux/kprobes.h> +#include <linux/hash.h> +#include <linux/init.h> +#include <linux/slab.h> +#include <linux/stddef.h> +#include <linux/module.h> +#include <linux/moduleloader.h> +#include <linux/kallsyms.h> +#include <linux/freezer.h> +#include <linux/seq_file.h> +#include <linux/debugfs.h> +#include <linux/kdebug.h> + +#include <asm-generic/sections.h> +#include <asm/cacheflush.h> +#include <asm/errno.h> +#include <asm/uaccess.h> + +#define KPROBE_HASH_BITS 6 +#define KPROBE_TABLE_SIZE (1 << KPROBE_HASH_BITS) + + +/* +* Some oddball architectures like 64bit powerpc have function descriptors +* so this must be overridable. +*/ +#ifndef kprobe_lookup_name +#define kprobe_lookup_name (name, addr) \ + addr = ((kprobe_opcode_t *)(kallsyms_lookup_name(name))) +#endif + +static struct hlist_head kprobe_table[KPROBE_TABLE_SIZE ]; +static struct hlist_head kretprobe_inst_table[KPROBE_TABLE_SIZE ]; + +/* NOTE: change this value only with kprobe_mutex held */ +static bool kprobe_enabled; + +DEFINE_MUTEX (kprobe_mutex);/* Protects kprobe_table */ +DEFINE_SPINLOCK (kretprobe_lock);/* Protects kretprobe_inst_table */ +static DEFINE_PER_CPU(struct kprobe *, kprobe_instance) = NULL; + +#ifdef __ARCH_WANT_KPROBES_INSN_SLOT +/* +* kprobe->ainsn.insn points to the copy of the instruction to be +* single-stepped. x86_64, POWER4 and above have no-exec support and +* stepping on the instruction on a vmalloced/kmalloced/data page +* is a recipe for disaster +*/ +#define INSNS_PER_PAGE (PAGE_SIZE/(MAX_INSN_SIZE * sizeof(kprobe_opcode_t))) + +struct kprobe_insn_page { +struct hlist_node hlist; +kprobe_opcode_t *insns;/* Page of instruction slots */ +char slot_used[INSNS_PER_PAGE ]; +int nused; +int ngarbage; +}; + +enum kprobe_slot_state { +SLOT_CLEAN =0 , +SLOT_DIRTY =1 , +SLOT_USED =2 , +}; + +static struct hlist_head kprobe_insn_pages; +static int kprobe_garbage_slots; +static int collect_garbage_slots (void ); + +static int __kprobes check_safety (void ) +{ +int ret =0 ; +#if defined(CONFIG_PREEMPT ) && defined(CONFIG_PM ) + ret =freeze_processes (); +if (ret ==0 ) { +struct task_struct *p, *q; + do_each_thread(p, q) { +if (p != current && p->state ==TASK_RUNNING && + p->pid !=0 ) { +printk ("Check failed: %s is running\n" ,p->comm); + ret =-1 ; + goto loop_end; + } + }while_each_thread (p, q); + } +loop_end: +thaw_processes (); +#else +synchronize_sched (); +#endif +return ret; +} + +/** +* get_insn_slot() - Find a slot on an executable page for an instruction. +* We allocate an executable page if there's no room on existing ones. +*/ +kprobe_opcode_t __kprobes *get_insn_slot (void ) +{ +struct kprobe_insn_page *kip; +struct hlist_node *pos; + + retry: +hlist_for_each_entry (kip, pos, &kprobe_insn_pages, hlist) { +if (kip->nused <INSNS_PER_PAGE ) { +int i; +for (i =0 ; i <INSNS_PER_PAGE ; i++) { +if (kip->slot_used[i] ==SLOT_CLEAN ) { + kip->slot_used[i] =SLOT_USED ; + kip->nused++; +return kip->insns + (i *MAX_INSN_SIZE ); + } + } +/* Surprise! No unused slots. Fix kip->nused. */ + kip->nused =INSNS_PER_PAGE ; + } + } + +/* If there are any garbage slots, collect it and try again. */ +if (kprobe_garbage_slots &&collect_garbage_slots () ==0 ) { + goto retry; + } +/* All out of space. Need to allocate a new page. Use slot 0. */ + kip =kmalloc (sizeof (struct kprobe_insn_page ),GFP_KERNEL ); +if (!kip) +return NULL ; + +/* +* Use module_alloc so this page is within +/- 2GB of where the +* kernel image and loaded module images reside. This is required +* so x86_64 can correctly handle the %rip-relative fixups. +*/ + kip->insns =module_alloc (PAGE_SIZE ); +if (!kip->insns) { +kfree (kip); +return NULL ; + } +INIT_HLIST_NODE (&kip->hlist); +hlist_add_head (&kip->hlist, &kprobe_insn_pages); +memset (kip->slot_used,SLOT_CLEAN ,INSNS_PER_PAGE ); + kip->slot_used[0 ] =SLOT_USED ; + kip->nused =1 ; + kip->ngarbage =0 ; +return kip->insns; +} + +/* Return 1 if all garbages are collected, otherwise 0. */ +static int __kprobes collect_one_slot (struct kprobe_insn_page *kip,int idx) +{ + kip->slot_used[idx] =SLOT_CLEAN ; + kip->nused--; +if (kip->nused ==0 ) { +/* +* Page is no longer in use. Free it unless +* it's the last one. We keep the last one +* so as not to have to set it up again the +* next time somebody inserts a probe. +*/ +hlist_del (&kip->hlist); +if (hlist_empty (&kprobe_insn_pages)) { +INIT_HLIST_NODE (&kip->hlist); +hlist_add_head (&kip->hlist, + &kprobe_insn_pages); + }else { +module_free (NULL , kip->insns); +kfree (kip); + } +return 1 ; + } +return 0 ; +} + +static int __kprobes collect_garbage_slots (void ) +{ +struct kprobe_insn_page *kip; +struct hlist_node *pos, *next; + +/* Ensure no-one is preepmted on the garbages */ +if (check_safety () !=0 ) +return -EAGAIN ; + +hlist_for_each_entry_safe (kip, pos, next, &kprobe_insn_pages, hlist) { +int i; +if (kip->ngarbage ==0 ) +continue ; + kip->ngarbage =0 ;/* we will collect all garbages */ +for (i =0 ; i <INSNS_PER_PAGE ; i++) { +if (kip->slot_used[i] ==SLOT_DIRTY && +collect_one_slot (kip, i)) +break ; + } + } + kprobe_garbage_slots =0 ; +return 0 ; +} + +void __kprobes free_insn_slot (kprobe_opcode_t * slot,int dirty) +{ +struct kprobe_insn_page *kip; +struct hlist_node *pos; + +hlist_for_each_entry (kip, pos, &kprobe_insn_pages, hlist) { +if (kip->insns <= slot && + slot < kip->insns + (INSNS_PER_PAGE *MAX_INSN_SIZE )) { +int i = (slot - kip->insns) /MAX_INSN_SIZE ; +if (dirty) { + kip->slot_used[i] =SLOT_DIRTY ; + kip->ngarbage++; + }else { +collect_one_slot (kip, i); + } +break ; + } + } + +if (dirty && ++kprobe_garbage_slots >INSNS_PER_PAGE ) +collect_garbage_slots (); +} +#endif + +/* We have preemption disabled.. so it is safe to use __ versions */ +static inline void set_kprobe_instance (struct kprobe *kp) +{ +__get_cpu_var (kprobe_instance) = kp; +} + +static inline void reset_kprobe_instance (void ) +{ +__get_cpu_var (kprobe_instance) =NULL ; +} + +/* +* This routine is called either: +* - under the kprobe_mutex - during kprobe_[un]register() +* OR +* - with preemption disabled - from arch/xxx/kernel/kprobes.c +*/ +struct kprobe __kprobes *get_kprobe (void *addr) +{ +struct hlist_head *head; +struct hlist_node *node; +struct kprobe *p; + + head = &kprobe_table[hash_ptr (addr,KPROBE_HASH_BITS )]; +hlist_for_each_entry_rcu (p, node, head, hlist) { +if (p->addr == addr) +return p; + } +return NULL ; +} + +/* +* Aggregate handlers for multiple kprobes support - these handlers +* take care of invoking the individual kprobe handlers on p->list +*/ +static int __kprobes aggr_pre_handler (struct kprobe *p,struct pt_regs *regs) +{ +struct kprobe *kp; + +list_for_each_entry_rcu (kp, &p->list, list) { +if (kp->pre_handler) { +set_kprobe_instance (kp); +if (kp->pre_handler (kp, regs)) +return 1 ; + } +reset_kprobe_instance (); + } +return 0 ; +} + +static void __kprobes aggr_post_handler (struct kprobe *p,struct pt_regs *regs, +unsigned long flags) +{ +struct kprobe *kp; + +list_for_each_entry_rcu (kp, &p->list, list) { +if (kp->post_handler) { +set_kprobe_instance (kp); + kp->post_handler (kp, regs, flags); +reset_kprobe_instance (); + } + } +} + +static int __kprobes aggr_fault_handler (struct kprobe *p,struct pt_regs *regs, +int trapnr) +{ +struct kprobe *cur =__get_cpu_var (kprobe_instance); + +/* +* if we faulted "during" the execution of a user specified +* probe handler, invoke just that probe's fault handler +*/ +if (cur && cur->fault_handler) { +if (cur->fault_handler (cur, regs, trapnr)) +return 1 ; + } +return 0 ; +} + +static int __kprobes aggr_break_handler (struct kprobe *p,struct pt_regs *regs) +{ +struct kprobe *cur =__get_cpu_var (kprobe_instance); +int ret =0 ; + +if (cur && cur->break_handler) { +if (cur->break_handler (cur, regs)) + ret =1 ; + } +reset_kprobe_instance (); +return ret; +} + +/* Walks the list and increments nmissed count for multiprobe case */ +void __kprobes kprobes_inc_nmissed_count (struct kprobe *p) +{ +struct kprobe *kp; +if (p->pre_handler != aggr_pre_handler) { + p->nmissed++; + }else { +list_for_each_entry_rcu (kp, &p->list, list) + kp->nmissed++; + } +return ; +} + +/* Called with kretprobe_lock held */ +void __kprobes recycle_rp_inst (struct kretprobe_instance *ri, +struct hlist_head *head) +{ +/* remove rp inst off the rprobe_inst_table */ +hlist_del (&ri->hlist); +if (ri->rp) { +/* remove rp inst off the used list */ +hlist_del (&ri->uflist); +/* put rp inst back onto the free list */ +INIT_HLIST_NODE (&ri->uflist); +hlist_add_head (&ri->uflist, &ri->rp->free_instances); + }else +/* Unregistering */ +hlist_add_head (&ri->hlist, head); +} + +struct hlist_head __kprobes *kretprobe_inst_table_head (struct task_struct *tsk) +{ +return &kretprobe_inst_table[hash_ptr (tsk,KPROBE_HASH_BITS )]; +} + +/* +* This function is called from finish_task_switch when task tk becomes dead, +* so that we can recycle any function-return probe instances associated +* with this task. These left over instances represent probed functions +* that have been called but will never return. +*/ +void __kprobes kprobe_flush_task (struct task_struct *tk) +{ +struct kretprobe_instance *ri; +struct hlist_head *head, empty_rp; +struct hlist_node *node, *tmp; +unsigned long flags =0 ; + +INIT_HLIST_HEAD (&empty_rp); +spin_lock_irqsave (&kretprobe_lock, flags); + head =kretprobe_inst_table_head (tk); +hlist_for_each_entry_safe (ri, node, tmp, head, hlist) { +if (ri->task == tk) +recycle_rp_inst (ri, &empty_rp); + } +spin_unlock_irqrestore (&kretprobe_lock, flags); + +hlist_for_each_entry_safe (ri, node, tmp, &empty_rp, hlist) { +hlist_del (&ri->hlist); +kfree (ri); + } +} + +static inline void free_rp_inst (struct kretprobe *rp) +{ +struct kretprobe_instance *ri; +struct hlist_node *pos, *next; + +hlist_for_each_entry_safe (ri, pos, next, &rp->free_instances, uflist) { +hlist_del (&ri->uflist); +kfree (ri); + } +} + +/* +* Keep all fields in the kprobe consistent +*/ +static inline void copy_kprobe (struct kprobe *old_p,struct kprobe *p) +{ +memcpy (&p->opcode, &old_p->opcode,sizeof (kprobe_opcode_t)); +memcpy (&p->ainsn, &old_p->ainsn,sizeof (struct arch_specific_insn )); +} + +/* +* Add the new probe to old_p->list. Fail if this is the +* second jprobe at the address - two jprobes can't coexist +*/ +static int __kprobes add_new_kprobe (struct kprobe *old_p,struct kprobe *p) +{ +if (p->break_handler) { +if (old_p->break_handler) +return -EEXIST ; +list_add_tail_rcu (&p->list, &old_p->list); + old_p->break_handler = aggr_break_handler; + }else +list_add_rcu (&p->list, &old_p->list); +if (p->post_handler && !old_p->post_handler) + old_p->post_handler = aggr_post_handler; +return 0 ; +} + +/* +* Fill in the required fields of the "manager kprobe". Replace the +* earlier kprobe in the hlist with the manager kprobe +*/ +static inline void add_aggr_kprobe (struct kprobe *ap,struct kprobe *p) +{ +copy_kprobe (p, ap); +flush_insn_slot (ap); + ap->addr = p->addr; + ap->pre_handler = aggr_pre_handler; + ap->fault_handler = aggr_fault_handler; +if (p->post_handler) + ap->post_handler = aggr_post_handler; +if (p->break_handler) + ap->break_handler = aggr_break_handler; + +INIT_LIST_HEAD (&ap->list); +list_add_rcu (&p->list, &ap->list); + +hlist_replace_rcu (&p->hlist, &ap->hlist); +} + +/* +* This is the second or subsequent kprobe at the address - handle +* the intricacies +*/ +static int __kprobes register_aggr_kprobe (struct kprobe *old_p, +struct kprobe *p) +{ +int ret =0 ; +struct kprobe *ap; + +if (old_p->pre_handler == aggr_pre_handler) { +copy_kprobe (old_p, p); + ret =add_new_kprobe (old_p, p); + }else { + ap =kzalloc (sizeof (struct kprobe ),GFP_KERNEL ); +if (!ap) +return -ENOMEM ; +add_aggr_kprobe (ap, old_p); +copy_kprobe (ap, p); + ret =add_new_kprobe (ap, p); + } +return ret; +} + +static int __kprobes in_kprobes_functions (unsigned long addr) +{ +if (addr >= (unsigned long )__kprobes_text_start && + addr < (unsigned long )__kprobes_text_end) +return -EINVAL ; +return 0 ; +} + +static int __kprobes __register_kprobe (struct kprobe *p, +unsigned long called_from) +{ +int ret =0 ; +struct kprobe *old_p; +struct module *probed_mod; + +/* +* If we have a symbol_name argument look it up, +* and add it to the address. That way the addr +* field can either be global or relative to a symbol. +*/ +if (p->symbol_name) { +if (p->addr) +return -EINVAL ; +kprobe_lookup_name (p->symbol_name, p->addr); + } + +if (!p->addr) +return -EINVAL ; + p->addr = (kprobe_opcode_t *)(((char *)p->addr)+ p->offset); + +if (!kernel_text_address ((unsigned long ) p->addr) || +in_kprobes_functions ((unsigned long ) p->addr)) +return -EINVAL ; + + p->mod_refcounted =0 ; + +/* +* Check if are we probing a module. +*/ + probed_mod =module_text_address ((unsigned long ) p->addr); +if (probed_mod) { +struct module *calling_mod =module_text_address (called_from); +/* +* We must allow modules to probe themself and in this case +* avoid incrementing the module refcount, so as to allow +* unloading of self probing modules. +*/ +if (calling_mod && calling_mod != probed_mod) { +if (unlikely (!try_module_get (probed_mod))) +return -EINVAL ; + p->mod_refcounted =1 ; + }else + probed_mod =NULL ; + } + + p->nmissed =0 ; +mutex_lock (&kprobe_mutex); + old_p =get_kprobe (p->addr); +if (old_p) { + ret =register_aggr_kprobe (old_p, p); + goto out; + } + + ret =arch_prepare_kprobe (p); +if (ret) + goto out; + +INIT_HLIST_NODE (&p->hlist); +hlist_add_head_rcu (&p->hlist, + &kprobe_table[hash_ptr (p->addr,KPROBE_HASH_BITS )]); + +if (kprobe_enabled) +arch_arm_kprobe (p); + +out: +mutex_unlock (&kprobe_mutex); + +if (ret && probed_mod) +module_put (probed_mod); +return ret; +} + +int __kprobes register_kprobe (struct kprobe *p) +{ +return __register_kprobe (p, (unsigned long )__builtin_return_address (0 )); +} + +void __kprobes unregister_kprobe (struct kprobe *p) +{ +struct module *mod; +struct kprobe *old_p, *list_p; +int cleanup_p; + +mutex_lock (&kprobe_mutex); + old_p =get_kprobe (p->addr); +if (unlikely (!old_p)) { +mutex_unlock (&kprobe_mutex); +return ; + } +if (p != old_p) { +list_for_each_entry_rcu (list_p, &old_p->list, list) +if (list_p == p) +/* kprobe p is a valid probe */ + goto valid_p; +mutex_unlock (&kprobe_mutex); +return ; + } +valid_p: +if (old_p == p || + (old_p->pre_handler == aggr_pre_handler && + p->list.next == &old_p->list && p->list.prev == &old_p->list)) { +/* +* Only probe on the hash list. Disarm only if kprobes are +* enabled - otherwise, the breakpoint would already have +* been removed. We save on flushing icache. +*/ +if (kprobe_enabled) +arch_disarm_kprobe (p); +hlist_del_rcu (&old_p->hlist); + cleanup_p =1 ; + }else { +list_del_rcu (&p->list); + cleanup_p =0 ; + } + +mutex_unlock (&kprobe_mutex); + +synchronize_sched (); +if (p->mod_refcounted) { + mod =module_text_address ((unsigned long )p->addr); +if (mod) +module_put (mod); + } + +if (cleanup_p) { +if (p != old_p) { +list_del_rcu (&p->list); +kfree (old_p); + } +arch_remove_kprobe (p); + }else { +mutex_lock (&kprobe_mutex); +if (p->break_handler) + old_p->break_handler =NULL ; +if (p->post_handler){ +list_for_each_entry_rcu (list_p, &old_p->list, list){ +if (list_p->post_handler){ + cleanup_p =2 ; +break ; + } + } +if (cleanup_p ==0 ) + old_p->post_handler =NULL ; + } +mutex_unlock (&kprobe_mutex); + } +} + +static struct notifier_block kprobe_exceptions_nb = { + .notifier_call = kprobe_exceptions_notify, + .priority =0x7fffffff /* we need to be notified first */ +}; + +unsigned long __weak arch_deref_entry_point (void *entry) +{ +return (unsigned long )entry; +} + +int __kprobes register_jprobe (struct jprobe *jp) +{ +unsigned long addr =arch_deref_entry_point (jp->entry); + +if (!kernel_text_address (addr)) +return -EINVAL ; + +/* Todo: Verify probepoint is a function entry point */ + jp->kp.pre_handler = setjmp_pre_handler; + jp->kp.break_handler = longjmp_break_handler; + +return __register_kprobe (&jp->kp, + (unsigned long )__builtin_return_address (0 )); +} + +void __kprobes unregister_jprobe (struct jprobe *jp) +{ +unregister_kprobe (&jp->kp); +} + +#ifdef ARCH_SUPPORTS_KRETPROBES + +/* +* This kprobe pre_handler is registered with every kretprobe. When probe +* hits it will set up the return probe. +*/ +static int __kprobes pre_handler_kretprobe (struct kprobe *p, +struct pt_regs *regs) +{ + struct kretprobe *rp = container_of(p, struct kretprobe, kp); +unsigned long flags =0 ; + +/*TODO: consider to only swap the RA after the last pre_handler fired */ +spin_lock_irqsave (&kretprobe_lock, flags); +if (!hlist_empty (&rp->free_instances)) { +struct kretprobe_instance *ri; + + ri =hlist_entry (rp->free_instances.first, + struct kretprobe_instance, uflist); + ri->rp = rp; + ri->task = current; +arch_prepare_kretprobe (ri, regs); + +/* XXX(hch): why is there no hlist_move_head? */ +hlist_del (&ri->uflist); +hlist_add_head (&ri->uflist, &ri->rp->used_instances); +hlist_add_head (&ri->hlist,kretprobe_inst_table_head (ri->task)); + }else + rp->nmissed++; +spin_unlock_irqrestore (&kretprobe_lock, flags); +return 0 ; +} + +int __kprobes register_kretprobe (struct kretprobe *rp) +{ +int ret =0 ; +struct kretprobe_instance *inst; +int i; +void *addr = rp->kp.addr; + +if (kretprobe_blacklist_size) { +if (addr ==NULL ) +kprobe_lookup_name (rp->kp.symbol_name, addr); + addr += rp->kp.offset; + +for (i =0 ; kretprobe_blacklist[i].name !=NULL ; i++) { +if (kretprobe_blacklist[i].addr == addr) +return -EINVAL ; + } + } + + rp->kp.pre_handler = pre_handler_kretprobe; + rp->kp.post_handler =NULL ; + rp->kp.fault_handler =NULL ; + rp->kp.break_handler =NULL ; + +/* Pre-allocate memory for max kretprobe instances */ +if (rp->maxactive <=0 ) { +#ifdef CONFIG_PREEMPT + rp->maxactive =max (10 ,2 *NR_CPUS ); +#else + rp->maxactive =NR_CPUS ; +#endif + } +INIT_HLIST_HEAD (&rp->used_instances); +INIT_HLIST_HEAD (&rp->free_instances); +for (i =0 ; i < rp->maxactive; i++) { + inst =kmalloc (sizeof (struct kretprobe_instance ),GFP_KERNEL ); +if (inst ==NULL ) { +free_rp_inst (rp); +return -ENOMEM ; + } +INIT_HLIST_NODE (&inst->uflist); +hlist_add_head (&inst->uflist, &rp->free_instances); + } + + rp->nmissed =0 ; +/* Establish function entry probe point */ +if ((ret =__register_kprobe (&rp->kp, + (unsigned long )__builtin_return_address (0 ))) !=0 ) +free_rp_inst (rp); +return ret; +} + +#else /* ARCH_SUPPORTS_KRETPROBES */ + +int __kprobes register_kretprobe (struct kretprobe *rp) +{ +return -ENOSYS ; +} + +static int __kprobes pre_handler_kretprobe (struct kprobe *p, +struct pt_regs *regs) +{ +return 0 ; +} + +#endif /* ARCH_SUPPORTS_KRETPROBES */ + +void __kprobes unregister_kretprobe (struct kretprobe *rp) +{ +unsigned long flags; +struct kretprobe_instance *ri; +struct hlist_node *pos, *next; + +unregister_kprobe (&rp->kp); + +/* No race here */ +spin_lock_irqsave (&kretprobe_lock, flags); +hlist_for_each_entry_safe (ri, pos, next, &rp->used_instances, uflist) { + ri->rp =NULL ; +hlist_del (&ri->uflist); + } +spin_unlock_irqrestore (&kretprobe_lock, flags); +free_rp_inst (rp); +} + +static int __init init_kprobes (void ) +{ +int i, err =0 ; + +/* FIXME allocate the probe table, currently defined statically */ +/* initialize all list heads */ +for (i =0 ; i <KPROBE_TABLE_SIZE ; i++) { +INIT_HLIST_HEAD (&kprobe_table[i]); +INIT_HLIST_HEAD (&kretprobe_inst_table[i]); + } + +if (kretprobe_blacklist_size) { +/* lookup the function address from its name */ +for (i =0 ; kretprobe_blacklist[i].name !=NULL ; i++) { +kprobe_lookup_name (kretprobe_blacklist[i].name, + kretprobe_blacklist[i].addr); +if (!kretprobe_blacklist[i].addr) +printk ("kretprobe: lookup failed: %s\n" , + kretprobe_blacklist[i].name); + } + } + +/* By default, kprobes are enabled */ + kprobe_enabled = true; + + err =arch_init_kprobes (); +if (!err) + err =register_die_notifier (&kprobe_exceptions_nb); + +return err; +} + +#ifdef CONFIG_DEBUG_FS +static void __kprobes report_probe (struct seq_file *pi,struct kprobe *p, +const char *sym,int offset,char *modname) +{ +char *kprobe_type; + +if (p->pre_handler == pre_handler_kretprobe) + kprobe_type ="r" ; +else if (p->pre_handler == setjmp_pre_handler) + kprobe_type ="j" ; +else + kprobe_type ="k" ; +if (sym) +seq_printf (pi,"%p %s %s+0x%x %s\n" , p->addr, kprobe_type, + sym, offset, (modname ? modname :" " )); +else +seq_printf (pi,"%p %s %p\n" , p->addr, kprobe_type, p->addr); +} + +static void __kprobes *kprobe_seq_start (struct seq_file *f,loff_t *pos) +{ +return (*pos <KPROBE_TABLE_SIZE ) ? pos :NULL ; +} + +static void __kprobes *kprobe_seq_next (struct seq_file *f,void *v,loff_t *pos) +{ + (*pos)++; +if (*pos >=KPROBE_TABLE_SIZE ) +return NULL ; +return pos; +} + +static void __kprobes kprobe_seq_stop (struct seq_file *f,void *v) +{ +/* Nothing to do */ +} + +static int __kprobes show_kprobe_addr (struct seq_file *pi,void *v) +{ +struct hlist_head *head; +struct hlist_node *node; +struct kprobe *p, *kp; +const char *sym =NULL ; +unsigned int i = *(loff_t *) v; +unsigned long offset =0 ; +char *modname, namebuf[128 ]; + + head = &kprobe_table[i]; +preempt_disable (); +hlist_for_each_entry_rcu (p, node, head, hlist) { + sym =kallsyms_lookup ((unsigned long )p->addr,NULL , + &offset, &modname, namebuf); +if (p->pre_handler == aggr_pre_handler) { +list_for_each_entry_rcu (kp, &p->list, list) +report_probe (pi, kp, sym, offset, modname); + }else +report_probe (pi, p, sym, offset, modname); + } +preempt_enable (); +return 0 ; +} + +static struct seq_operations kprobes_seq_ops = { + .start = kprobe_seq_start, + .next = kprobe_seq_next, + .stop = kprobe_seq_stop, + .show = show_kprobe_addr +}; + +static int __kprobes kprobes_open (struct inode *inode,struct file *filp) +{ +return seq_open (filp, &kprobes_seq_ops); +} + +static struct file_operations debugfs_kprobes_operations = { + .open = kprobes_open, + .read = seq_read, + .llseek = seq_lseek, + .release = seq_release, +}; + +static void __kprobes enable_all_kprobes (void ) +{ +struct hlist_head *head; +struct hlist_node *node; +struct kprobe *p; +unsigned int i; + +mutex_lock (&kprobe_mutex); + +/* If kprobes are already enabled, just return */ +if (kprobe_enabled) + goto already_enabled; + +for (i =0 ; i <KPROBE_TABLE_SIZE ; i++) { + head = &kprobe_table[i]; +hlist_for_each_entry_rcu (p, node, head, hlist) +arch_arm_kprobe (p); + } + + kprobe_enabled = true; +printk (KERN_INFO "Kprobes globally enabled\n" ); + +already_enabled: +mutex_unlock (&kprobe_mutex); +return ; +} + +static void __kprobes disable_all_kprobes (void ) +{ +struct hlist_head *head; +struct hlist_node *node; +struct kprobe *p; +unsigned int i; + +mutex_lock (&kprobe_mutex); + +/* If kprobes are already disabled, just return */ +if (!kprobe_enabled) + goto already_disabled; + + kprobe_enabled = false; +printk (KERN_INFO "Kprobes globally disabled\n" ); +for (i =0 ; i <KPROBE_TABLE_SIZE ; i++) { + head = &kprobe_table[i]; +hlist_for_each_entry_rcu (p, node, head, hlist) { +if (!arch_trampoline_kprobe (p)) +arch_disarm_kprobe (p); + } + } + +mutex_unlock (&kprobe_mutex); +/* Allow all currently running kprobes to complete */ +synchronize_sched (); +return ; + +already_disabled: +mutex_unlock (&kprobe_mutex); +return ; +} + +/* +* XXX: The debugfs bool file interface doesn't allow for callbacks +* when the bool state is switched. We can reuse that facility when +* available +*/ +static ssize_t read_enabled_file_bool (struct file *file, +char __user *user_buf,size_t count,loff_t *ppos) +{ +char buf[3 ]; + +if (kprobe_enabled) + buf[0 ] ='1' ; +else + buf[0 ] ='0' ; + buf[1 ] ='\n' ; + buf[2 ] =0x00 ; +return simple_read_from_buffer (user_buf, count, ppos, buf,2 ); +} + +static ssize_t write_enabled_file_bool (struct file *file, +const char __user *user_buf,size_t count,loff_t *ppos) +{ +char buf[32 ]; +int buf_size; + + buf_size =min (count, (sizeof (buf)-1 )); +if (copy_from_user (buf, user_buf, buf_size)) +return -EFAULT ; + +switch (buf[0 ]) { +case 'y' : +case 'Y' : +case '1' : +enable_all_kprobes (); +break ; +case 'n' : +case 'N' : +case '0' : +disable_all_kprobes (); +break ; + } + +return count; +} + +static struct file_operations fops_kp = { + .read = read_enabled_file_bool, + .write = write_enabled_file_bool, +}; + +static int __kprobes debugfs_kprobe_init (void ) +{ +struct dentry *dir, *file; +unsigned int value =1 ; + + dir =debugfs_create_dir ("kprobes" ,NULL ); +if (!dir) +return -ENOMEM ; + + file =debugfs_create_file ("list" ,0444 , dir,NULL , + &debugfs_kprobes_operations); +if (!file) { +debugfs_remove (dir); +return -ENOMEM ; + } + + file =debugfs_create_file ("enabled" ,0600 , dir, + &value, &fops_kp); +if (!file) { +debugfs_remove (dir); +return -ENOMEM ; + } + +return 0 ; +} + +late_initcall (debugfs_kprobe_init); +#endif /* CONFIG_DEBUG_FS */ + +module_init (init_kprobes); + +EXPORT_SYMBOL_GPL (register_kprobe); +EXPORT_SYMBOL_GPL (unregister_kprobe); +EXPORT_SYMBOL_GPL (register_jprobe); +EXPORT_SYMBOL_GPL (unregister_jprobe); +#ifdef CONFIG_KPROBES +EXPORT_SYMBOL_GPL (jprobe_return); +#endif + +#ifdef CONFIG_KPROBES +EXPORT_SYMBOL_GPL (register_kretprobe); +EXPORT_SYMBOL_GPL (unregister_kretprobe); +#endif
kernel/kprobes.c deleted +0 -1063
1,063 lines not on this page · raw message
instrumentation/Makefile +2 -0
@@ -1,3 +1,5 @@ # # Makefile for the linux kernel instrumentation # + +obj-$(CONFIG_KPROBES) += kprobes.o
kernel/Makefile +0 -1
@@ -47,7 +47,6 @@ obj-$(CONFIG_STOP_MACHINE) += stop_machi obj-$(CONFIG_AUDIT) += audit.o auditfilter.o obj-$(CONFIG_AUDITSYSCALL) += auditsc.o obj-$(CONFIG_AUDIT_TREE) += audit_tree.o -obj-$(CONFIG_KPROBES) += kprobes.o obj-$(CONFIG_SYSFS) += ksysfs.o obj-$(CONFIG_DETECT_SOFTLOCKUP) += softlockup.o obj-$(CONFIG_GENERIC_HARDIRQS) += irq/
Makefile +2 -1
@@ -574,7 +574,8 @@ export mod_strip_cmd ifeq ($(KBUILD_EXTMOD),) -core-y += kernel/ mm/ fs/ ipc/ security/ crypto/ block/ +core-y += kernel/ mm/ fs/ ipc/ security/ crypto/ block/ \ + instrumentation/ vmlinux-dirs := $(patsubst %/,%,$(filter %/, $(init-y) $(init-m) \ $(core-y) $(core-m) $(drivers-y) $(drivers-m) \
arch/avr32/instrumentation/kprobes.c new file +268 -0
268 lines not on this page · raw message
arch/avr32/kernel/kprobes.c deleted +0 -268
268 lines not on this page · raw message
arch/ia64/instrumentation/kprobes.c new file +1027 -0
317 lines not on this page · raw message
arch/ia64/kernel/kprobes.c deleted +0 -1027
1,027 lines not on this page · raw message
arch/powerpc/instrumentation/kprobes.c new file +559 -0
559 lines not on this page · raw message
arch/powerpc/kernel/kprobes.c deleted +0 -559
559 lines not on this page · raw message
arch/s390/instrumentation/kprobes.c new file +672 -0
672 lines not on this page · raw message
arch/s390/kernel/kprobes.c deleted +0 -672
672 lines not on this page · raw message
arch/sparc64/instrumentation/kprobes.c new file +487 -0
487 lines not on this page · raw message
arch/sparc64/kernel/kprobes.c deleted +0 -487
487 lines not on this page · raw message
arch/x86/instrumentation/kprobes_32.c new file +763 -0
763 lines not on this page · raw message
arch/x86/instrumentation/kprobes_64.c new file +761 -0
761 lines not on this page · raw message
arch/x86/kernel/kprobes_32.c deleted +0 -763
763 lines not on this page · raw message
arch/x86/kernel/kprobes_64.c deleted +0 -761
761 lines not on this page · raw message
The rest of this diff is not shown. View the raw message.
Signature · 3 lines
Mathieu Desnoyers Computer Engineering Ph.D. Student, Ecole Polytechnique de Montreal OpenPGP key fingerprint: 8CD5 52C3 8E3C 4140 715F BA06 3F25 A8FE 3BAE 9A68
Part of the diff is not shown here. View the raw message.
PATCH 4/10 Move Linux Kernel Markers to instrumentation directory
In reply to Mathieu Desnoyers--- instrumentation/Makefile | 1 instrumentation/marker.c | 525 +++++++++++++++++++++++++++++++++++++++++++++++ kernel/Makefile | 1 kernel/marker.c | 525 ----------------------------------------------- 4 files changed, 526 insertions(+), 526 deletions(-)
instrumentation/Makefile +1 -0
@@ -3,3 +3,4 @@ # obj-$(CONFIG_KPROBES) += kprobes.o +obj-$(CONFIG_MARKERS) += marker.o
instrumentation/marker.c new file +525 -0
525 lines not on this page · raw message
kernel/Makefile +0 -1
@@ -56,7 +56,6 @@ obj-$(CONFIG_RELAY) += relay.o obj-$(CONFIG_SYSCTL) += utsname_sysctl.o obj-$(CONFIG_TASK_DELAY_ACCT) += delayacct.o obj-$(CONFIG_TASKSTATS) += taskstats.o tsacct.o -obj-$(CONFIG_MARKERS) += marker.o ifneq ($(CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER),y) # According to Alan Modra <[email protected]>, the -fno-omit-frame-pointer is
kernel/marker.c deleted +0 -525
525 lines not on this page · raw message
Signature · 3 lines
Mathieu Desnoyers Computer Engineering Ph.D. Student, Ecole Polytechnique de Montreal OpenPGP key fingerprint: 8CD5 52C3 8E3C 4140 715F BA06 3F25 A8FE 3BAE 9A68
PATCH 5/10 Move profiling to instrumentation
In reply to Mathieu DesnoyersMove kernel/profile.c to instrumentation/.
--- instrumentation/Makefile | 2 instrumentation/profile.c | 597 ++++++++++++++++++++++++++++++++++++++++++++++ kernel/Makefile | 2 kernel/profile.c | 597 ---------------------------------------------- 4 files changed, 600 insertions(+), 598 deletions(-)
instrumentation/Makefile +2 -0
@@ -2,5 +2,7 @@ # Makefile for the linux kernel instrumentation # +obj-y += profile.o + obj-$(CONFIG_KPROBES) += kprobes.o obj-$(CONFIG_MARKERS) += marker.o
instrumentation/profile.c new file +597 -0
597 lines not on this page · raw message
kernel/Makefile +1 -1
@@ -2,7 +2,7 @@ # Makefile for the linux kernel. # -obj-y = sched.o fork.o exec_domain.o panic.o printk.o profile.o \ +obj-y = sched.o fork.o exec_domain.o panic.o printk.o \ exit.o itimer.o time.o softirq.o resource.o \ sysctl.o capability.o ptrace.o timer.o user.o user_namespace.o \ signal.o sys.o kmod.o workqueue.o pid.o \
kernel/profile.c deleted +0 -597
597 lines not on this page · raw message
Signature · 3 lines
Mathieu Desnoyers Computer Engineering Ph.D. Student, Ecole Polytechnique de Montreal OpenPGP key fingerprint: 8CD5 52C3 8E3C 4140 715F BA06 3F25 A8FE 3BAE 9A68
Re: [patch 05/10] Move profiling to instrumentation
Quoted 1 line · On Mon, 29 Oct 2007 10:26:51 -0400 Mathieu Desnoyers…
Move
kernel/profile.cto instrumentation/.
I have one question... can this be done via a git move command so that history is properly maintained?
Signature · 3 lines
If you want to reach me at my work email, use [email protected] For development, discussion and tips for power savings, visit http://www.lesswatts.org
Re: [patch 05/10] Move profiling to instrumentation
Quoted 9 lines · * Arjan van de Ven ([email protected]) wrote:
Quoted 1 line · On Mon, 29 Oct 2007 10:26:51 -0400 Mathieu Desnoyers…
Move
kernel/profile.cto instrumentation/.I have one question... can this be done via a git move command so that history is properly maintained?
moving kernel/profile.c to instrumentation/profile.c should be done through a git mv. Moving the Makefile lines should be done through a patch.
But since I use quilt to manage my patchset, I guess I don't have this ability. Should I switch to git to perform this change to make everyone's life easier or should I simply ask kindly for maintainers to perform git mv in their tree ?
Mathieu
Signature · 3 lines
Mathieu Desnoyers Computer Engineering Ph.D. Student, Ecole Polytechnique de Montreal OpenPGP key fingerprint: 8CD5 52C3 8E3C 4140 715F BA06 3F25 A8FE 3BAE 9A68
PATCH 6/10 Move lockdep to instrumentation
In reply to Mathieu DesnoyersMove lockdep.c, lockdep_internals.h and lock_proc.c to instrumentation/.
Should we move the lockdep Kconfig menu entry to Instrumentation support? It is currently automatically selected by "Kernel debugging" in Kernel hacking.
--- instrumentation/Makefile | 4 instrumentation/lockdep.c | 3217 ++++++++++++++++++++++++++++++++++++ instrumentation/lockdep_internals.h | 78 instrumentation/lockdep_proc.c | 683 +++++++ kernel/Makefile | 4 kernel/lockdep.c | 3217 ------------------------------------ kernel/lockdep_internals.h | 78 kernel/lockdep_proc.c | 683 ------- 8 files changed, 3982 insertions(+), 3982 deletions(-)
instrumentation/Makefile +4 -0
@@ -6,3 +6,7 @@ obj-y += profile.o obj-$(CONFIG_KPROBES) += kprobes.o obj-$(CONFIG_MARKERS) += marker.o +obj-$(CONFIG_LOCKDEP) += lockdep.o +ifeq ($(CONFIG_PROC_FS),y) +obj-$(CONFIG_LOCKDEP) += lockdep_proc.o +endif
instrumentation/lockdep.c new file +3217 -0
2,993 lines not on this page · raw message
kernel/lockdep.c deleted +0 -3217
3,217 lines not on this page · raw message
instrumentation/lockdep_internals.h new file +78 -0
78 lines not on this page · raw message
instrumentation/lockdep_proc.c new file +683 -0
683 lines not on this page · raw message
kernel/lockdep_internals.h deleted +0 -78
78 lines not on this page · raw message
kernel/lockdep_proc.c deleted +0 -683
683 lines not on this page · raw message
The rest of this diff is not shown. View the raw message.
Signature · 3 lines
Mathieu Desnoyers Computer Engineering Ph.D. Student, Ecole Polytechnique de Montreal OpenPGP key fingerprint: 8CD5 52C3 8E3C 4140 715F BA06 3F25 A8FE 3BAE 9A68
Part of the diff is not shown here. View the raw message.
PATCH 7/10 Move vmstat to instrumentation/.
In reply to Mathieu DesnoyersMove mm/vmstat.c to instrumentation/.
--- instrumentation/Makefile | 2 instrumentation/vmstat.c | 863 +++++++++++++++++++++++++++++++++++++++++++++++ mm/Makefile | 2 mm/vmstat.c | 863 ----------------------------------------------- 4 files changed, 865 insertions(+), 865 deletions(-)
instrumentation/Makefile +1 -1
@@ -2,7 +2,7 @@ # Makefile for the linux kernel instrumentation # -obj-y += profile.o +obj-y += profile.o vmstat.o obj-$(CONFIG_KPROBES) += kprobes.o obj-$(CONFIG_MARKERS) += marker.o
mm/Makefile +1 -1
@@ -10,7 +10,7 @@ mmu-$(CONFIG_MMU) := fremap.o highmem.o obj-y := bootmem.o filemap.o mempool.o oom_kill.o fadvise.o \ page_alloc.o page-writeback.o pdflush.o \ readahead.o swap.o truncate.o vmscan.o \ - prio_tree.o util.o mmzone.o vmstat.o backing-dev.o \ + prio_tree.o util.o mmzone.o backing-dev.o \ page_isolation.o $(mmu-y) obj-$(CONFIG_BOUNCE) += bounce.o
instrumentation/vmstat.c new file +863 -0
863 lines not on this page · raw message
mm/vmstat.c deleted +0 -863
863 lines not on this page · raw message
Signature · 3 lines
Mathieu Desnoyers Computer Engineering Ph.D. Student, Ecole Polytechnique de Montreal OpenPGP key fingerprint: 8CD5 52C3 8E3C 4140 715F BA06 3F25 A8FE 3BAE 9A68
PATCH 8/10 Move blktrace Kconfig entry to instrumentation menu
In reply to Mathieu DesnoyersThis block layer isntrumentation should appear in the instrumentation menu, not in the block layer menu.
--- block/Kconfig | 13 ------------- instrumentation/Kconfig | 13 +++++++++++++ 2 files changed, 13 insertions(+), 13 deletions(-)
block/Kconfig +0 -13
@@ -27,19 +27,6 @@ config LBD your machine, or if you want to have a raid or loopback device bigger than 2TB. Otherwise say N. -config BLK_DEV_IO_TRACE - bool "Support for tracing block io actions" - depends on SYSFS - select RELAY - select DEBUG_FS - help - Say Y here, if you want to be able to trace the block layer actions - on a given queue. Tracing allows you to see any traffic happening - on a block device queue. For more information (and the user space - support tools needed), fetch the blktrace app from: - - git://brick.kernel.dk/data/git/blktrace.git - config LSF bool "Support for Large Single Files" depends on !64BIT
instrumentation/Kconfig +13 -0
@@ -46,4 +46,17 @@ config MARKERS Place an empty function call at each marker site. Can be dynamically changed for a probe function. +config BLK_DEV_IO_TRACE + bool "Support for tracing block io actions" + depends on SYSFS + select RELAY + select DEBUG_FS + help + Say Y here, if you want to be able to trace the block layer actions + on a given queue. Tracing allows you to see any traffic happening + on a block device queue. For more information (and the user space + support tools needed), fetch the blktrace app from: + + git://brick.kernel.dk/data/git/blktrace.git + endif # INSTRUMENTATION
Signature · 3 lines
Mathieu Desnoyers Computer Engineering Ph.D. Student, Ecole Polytechnique de Montreal OpenPGP key fingerprint: 8CD5 52C3 8E3C 4140 715F BA06 3F25 A8FE 3BAE 9A68
PATCH 9/10 Move blktrace to instrumentation directory
In reply to Mathieu DesnoyersThis block IO tracing belongs to the instrumentation category.
--- block/Makefile | 1 block/blktrace.c | 576 --------------------------------------------- instrumentation/Makefile | 1 instrumentation/blktrace.c | 576 +++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 577 insertions(+), 577 deletions(-)
block/Makefile +0 -1
@@ -10,5 +10,4 @@ obj-$(CONFIG_IOSCHED_AS) += as-iosched.o obj-$(CONFIG_IOSCHED_DEADLINE) += deadline-iosched.o obj-$(CONFIG_IOSCHED_CFQ) += cfq-iosched.o -obj-$(CONFIG_BLK_DEV_IO_TRACE) += blktrace.o obj-$(CONFIG_BLOCK_COMPAT) += compat_ioctl.o
block/blktrace.c deleted +0 -576
576 lines not on this page · raw message
instrumentation/Makefile +1 -0
@@ -10,3 +10,4 @@ obj-$(CONFIG_LOCKDEP) += lockdep.o ifeq ($(CONFIG_PROC_FS),y) obj-$(CONFIG_LOCKDEP) += lockdep_proc.o endif +obj-$(CONFIG_BLK_DEV_IO_TRACE) += blktrace.o
instrumentation/blktrace.c new file +576 -0
576 lines not on this page · raw message
Signature · 3 lines
Mathieu Desnoyers Computer Engineering Ph.D. Student, Ecole Polytechnique de Montreal OpenPGP key fingerprint: 8CD5 52C3 8E3C 4140 715F BA06 3F25 A8FE 3BAE 9A68
PATCH 10/10 Move samples to instrumentation/samples
In reply to Mathieu DesnoyersMove the markers samples to instrumentation/samples.
Was previously built late in the kernel build, but is now built at the same time as instrumentation/ (core-y).
--- Makefile | 3 instrumentation/Kconfig | 6 + instrumentation/Makefile | 2 instrumentation/samples/Makefile | 4 + instrumentation/samples/marker-example.c | 54 +++++++++++++++++ instrumentation/samples/probe-example.c | 98 +++++++++++++++++++++++++++++++ lib/Kconfig.debug | 2 samples/Kconfig | 16 ----- samples/Makefile | 3 samples/markers/Makefile | 4 - samples/markers/marker-example.c | 54 ----------------- samples/markers/probe-example.c | 98 ------------------------------- 12 files changed, 164 insertions(+), 180 deletions(-)
instrumentation/Kconfig +6 -0
@@ -59,4 +59,10 @@ config BLK_DEV_IO_TRACE git://brick.kernel.dk/data/git/blktrace.git +config SAMPLE_MARKERS + tristate "Build markers examples -- loadable modules only" + depends on MARKERS && m + help + This build markers example modules. + endif # INSTRUMENTATION
samples/Kconfig deleted +0 -16
@@ -1,16 +0,0 @@ -# samples/Kconfig - -menuconfig SAMPLES - bool "Sample kernel code" - help - You can build and test sample kernel code here. - -if SAMPLES - -config SAMPLE_MARKERS - tristate "Build markers examples -- loadable modules only" - depends on MARKERS && m - help - This build markers example modules. - -endif # SAMPLES
instrumentation/Makefile +2 -0
@@ -11,3 +11,5 @@ ifeq ($(CONFIG_PROC_FS),y) obj-$(CONFIG_LOCKDEP) += lockdep_proc.o endif obj-$(CONFIG_BLK_DEV_IO_TRACE) += blktrace.o + +obj-y += samples/
instrumentation/samples/Makefile new file +4 -0
@@ -0,0 +1,4 @@ +# builds the kprobes example kernel modules; +# then to use one (as root): insmod <module_name.ko> + +obj-$(CONFIG_SAMPLE_MARKERS) += probe-example.o marker-example.o
samples/Makefile deleted +0 -3
@@ -1,3 +0,0 @@ -# Makefile for Linux samples code - -obj-$(CONFIG_SAMPLES) += markers/
samples/markers/marker-example.c deleted +0 -54
54 lines not on this page · raw message
samples/markers/probe-example.c deleted +0 -98
98 lines not on this page · raw message
lib/Kconfig.debug +0 -2
@@ -508,5 +508,3 @@ config FAULT_INJECTION_STACKTRACE_FILTER select FRAME_POINTER help Provide stacktrace filter for fault-injection capabilities - -source "samples/Kconfig"
Makefile +0 -3
@@ -775,9 +775,6 @@ vmlinux: $(vmlinux-lds) $(vmlinux-init) ifdef CONFIG_HEADERS_CHECK $(Q)$(MAKE) -f $(srctree)/Makefile headers_check endif -ifdef CONFIG_SAMPLES - $(Q)$(MAKE) $(build)=samples -endif $(call vmlinux-modpost) $(call if_changed_rule,vmlinux__) $(Q)rm -f .old_version
samples/markers/Makefile deleted +0 -4
@@ -1,4 +0,0 @@ -# builds the kprobes example kernel modules; -# then to use one (as root): insmod <module_name.ko> - -obj-$(CONFIG_SAMPLE_MARKERS) += probe-example.o marker-example.o
instrumentation/samples/marker-example.c new file +54 -0
54 lines not on this page · raw message
instrumentation/samples/probe-example.c new file +98 -0
98 lines not on this page · raw message
Signature · 3 lines
Mathieu Desnoyers Computer Engineering Ph.D. Student, Ecole Polytechnique de Montreal OpenPGP key fingerprint: 8CD5 52C3 8E3C 4140 715F BA06 3F25 A8FE 3BAE 9A68