Skip to contentSkip to conversation

mmio probes

RFC PATCH New Rusty Lynch 1 participant 1 message Jan 29, 2003

lore
Share & tools
lore
#0 lore raw

RFC PATCH 1/1 mmio probes

As I previously noted in an earlier message at
http://marc.theaimsgroup.com/?l=linux-kernel&m=104386132315914&w=2,
while kicking around ideas in the fault injection project, the need for some additional non-fi specific features has surfaced.

One of these needs is the ability to hook (in same way that kprobes can add a hook) to a specific memory mapped IO region before the user of the region gets access. A fault injection test case may need to just note when a given region is being read/written, take some action before the caller returns from the read or write operation, or change the value that is being read or written.

The following is a patch for a 2.5.59 kernel with the kprobes patch (posted at
http://marc.theaimsgroup.com/?l=linux-kernel&m=104254476428330&w=2 ) already applied that provides this feature for the i368 architecture. The patch does not call the kprobes functions, but depends on the same tweaks to traps.c and fault.c that kprobes provides.

We also followed the same usage that kprobes provides, with a register_kmmio_probe() function for adding the hook/probe, and a unregister_kmmio_probe() function for removing the hook/probe.

As with the kirq patch, this patch is an early request for comments with the goal of an acceptable patch for the 2.7 kernel.

--rustyl

# This is a BitKeeper generated patch for the following project:
# Project Name: Linux kernel tree
# This patch format is intended for GNU patch command version 2.5 or higher. # This patch includes the following deltas:

#	           ChangeSet	1.957   -> 1.958  
#	arch/i386/mm/fault.c	1.24    -> 1.25   
#	   arch/i386/Kconfig	1.35    -> 1.36   
#	arch/i386/kernel/traps.c	1.43    -> 1.44   
#	arch/i386/kernel/Makefile	1.33    -> 1.34   
#	     kernel/Makefile	1.26    -> 1.27   
#	               (new)	        -> 1.1     include/linux/kmmio.h
#	               (new)	        -> 1.1     kernel/kmmio.c 
#	               (new)	        -> 1.1     arch/i386/kernel/kmmio.c
#	               (new)	        -> 1.1     include/asm-i386/kmmio.h

#
# The following is the BitKeeper ChangeSet Log
# --------------------------------------------
# 03/01/23 rusty@vmhack.(none) 1.958
# Adding kmmio
# --------------------------------------------
#

arch/i386/Kconfig +9 -0
diff -Nru a/arch/i386/Kconfig b/arch/i386/Kconfig
@@ -1554,6 +1554,15 @@
 	  for kernel debugging, non-intrusive instrumentation and testing.  If
 	  in doubt, say "N".
 
+config KMMIO
+	bool "KMMIO (EXPERIMENTAL)"
+	depends on EXPERIMENTAL
+	depends on KPROBES 
+	help
+	  KMMIO is a Kprobes add-ons for placing a probe on MMIO access, using
+	  register_kmmio(), and providing a callback function. This is useful
+	  for monitoring driver access specific MMIO address.
+
 config DEBUG_STACKOVERFLOW
 	bool "Check for stack overflows"
 	depends on DEBUG_KERNEL
arch/i386/kernel/Makefile +2 -1
diff -Nru a/arch/i386/kernel/Makefile b/arch/i386/kernel/Makefile
@@ -4,7 +4,7 @@
 
 EXTRA_TARGETS := head.o init_task.o
 
-export-objs     := mca.o i386_ksyms.o time.o
+export-objs     := mca.o i386_ksyms.o time.o kmmio.o
 
 obj-y	:= process.o semaphore.o signal.o entry.o traps.o irq.o vm86.o \
 		ptrace.o i8259.o ioport.o ldt.o setup.o time.o sys_i386.o \
@@ -30,6 +30,7 @@
 obj-$(CONFIG_PROFILING)		+= profile.o
 obj-$(CONFIG_EDD)             	+= edd.o
 obj-$(CONFIG_KPROBES)		+= kprobes.o
+obj-$(CONFIG_KMMIO)		+= kmmio.o
 obj-$(CONFIG_MODULES)		+= module.o
 obj-y				+= sysenter.o
 
arch/i386/kernel/kmmio.c new file +159 -0

159 lines not on this page · raw message

arch/i386/kernel/traps.c +4 -0
diff -Nru a/arch/i386/kernel/traps.c b/arch/i386/kernel/traps.c
@@ -25,6 +25,7 @@
 #include <linux/highmem.h>
 #include <linux/kallsyms.h>
 #include <linux/kprobes.h>
+#include <linux/kmmio.h>
 
 #ifdef CONFIG_EISA
 #include <linux/ioport.h>
@@ -529,6 +530,9 @@
 	__asm__ __volatile__("movl %%db6,%0" : "=r" (condition));
 
 	if (post_kprobe_handler(regs))
+		return 1;
+
+	if (post_kmmio_handler(condition, regs))
 		return 1;
 
 	/* Interrupts not disabled for normal trap handling. */
arch/i386/mm/fault.c +4 -0
diff -Nru a/arch/i386/mm/fault.c b/arch/i386/mm/fault.c
@@ -21,6 +21,7 @@
 #include <linux/vt_kern.h>		/* For unblank_screen() */
 #include <linux/module.h>
 #include <linux/kprobes.h>
+#include <linux/kmmio.h>
 
 #include <asm/system.h>
 #include <asm/uaccess.h>
@@ -163,6 +164,9 @@
 	__asm__("movl %%cr2,%0":"=r" (address));
 
 	if (kprobe_running() && kprobe_fault_handler(regs, 14))
+		return;
+
+	if (is_kmmio_active() && kmmio_handler(regs, address))
 		return;
 
 	/* It's safe to allow irq's after cr2 has been saved */
include/asm-i386/kmmio.h new file +33 -0
diff -Nru a/include/asm-i386/kmmio.h b/include/asm-i386/kmmio.h
@@ -0,0 +1,33 @@
+/*
+ * Benfit many code from kprobes
+ * (C) 2002 Louis Zhuang <[email protected]>.
+ */
+
+#ifndef _ASM_KMMIO_H
+#define _ASM_KMMIO_H
+#include <linux/types.h>
+#include <linux/ptrace.h>
+
+struct pt_regs;
+
+typedef void* kmmio_addr_t;
+
+#ifdef CONFIG_KMMIO
+extern void arm_kmmio_fault_page(kmmio_addr_t page);
+extern void disarm_kmmio_fault_page(kmmio_addr_t page);
+extern int post_kmmio_handler(unsigned long condition, 
+			      struct pt_regs *regs);
+extern int kmmio_handler(struct pt_regs *regs, unsigned long addr);
+extern void *kmmio_invert_map(void *virt_addr, unsigned long bus_addr);
+#else /* !CONFIG_KMMIO */
+static inline int post_kmmio_handler(unsigned long condition, 
+				     struct pt_regs *regs) 
+{ 
+	return 0; 
+}
+static inline int kmmio_handler(struct pt_regs *regs, unsigned long addr) 
+{ 
+	return 0; 
+}
+#endif
+#endif /* _ASM_KMMIO_H */
include/linux/kmmio.h new file +67 -0

67 lines not on this page · raw message

kernel/Makefile +2 -1
diff -Nru a/kernel/Makefile b/kernel/Makefile
@@ -4,7 +4,7 @@
 
 export-objs = signal.o sys.o kmod.o workqueue.o ksyms.o pm.o exec_domain.o \
 		printk.o suspend.o dma.o module.o cpufreq.o \
-		profile.o rcupdate.o intermodule.o params.o
+		profile.o rcupdate.o intermodule.o params.o kmmio.o
 
 obj-y     = sched.o fork.o exec_domain.o panic.o printk.o profile.o \
 	    exit.o itimer.o time.o softirq.o resource.o \
@@ -23,6 +23,7 @@
 obj-$(CONFIG_SOFTWARE_SUSPEND) += suspend.o
 obj-$(CONFIG_COMPAT) += compat.o
 obj-$(CONFIG_KPROBES) += kprobes.o
+obj-$(CONFIG_KMMIO)   += kmmio.o
 
 ifneq ($(CONFIG_IA64),y)
 # According to Alan Modra <[email protected]>, the -fno-omit-frame-pointer is
kernel/kmmio.c new file +149 -0

149 lines not on this page · raw message